source: rtems/cpukit/libblock/src/ata.c @ 006fa1ef

4.104.114.84.9
Last change on this file since 006fa1ef was 006fa1ef, checked in by Ralf Corsepius <ralf.corsepius@…>, on Nov 20, 2003 at 12:14:50 PM

2003-11-20 Ralf Corsepius <corsepiu@…>

  • Makefile.am: AM_CPPFLAGS += -I$(top_builddir). Use AM_CPPFLAGS instead of AM_CFLAGS.
  • src/ata.c: Include config.h.
  • src/bdbuf.c: Ditto.
  • src/blkdev.c: Ditto.
  • src/diskdevs.c: Ditto.
  • src/ide_part_table.c: Ditto.
  • src/ramdisk.c: Ditto.
  • Property mode set to 100644
File size: 43.3 KB
Line 
1/*
2 * ata.c
3 *
4 * ATA RTEMS driver. ATA driver is hardware independant implementation of
5 * ATA-2 standart, working draft X3T10/0948D, revision 4c. ATA driver bases
6 * on RTEMS IDE controller driver.
7 *
8 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
9 * Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
10 *
11 * The license and distribution terms for this file may be
12 * found in the file LICENSE in this distribution or at
13 * http://www.rtems.com/license/LICENSE.
14 *
15 * $Id$
16 *
17 */
18
19#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <errno.h>
24#include <chain.h>
25#include <assert.h>
26#include <string.h> /* for "memset" declaration */
27
28#include <rtems/diskdevs.h>
29#include <rtems/blkdev.h>
30#include <libchip/ide_ctrl_io.h>
31#include <libchip/ide_ctrl_cfg.h>
32#include <rtems/ata_internal.h>
33#include <rtems/ata.h>
34
35#define DEBUG
36
37#ifdef DEBUG
38#include <stdio.h>
39#endif
40
41#define SAFE
42#ifdef SAFE
43typedef rtems_mode preemption_key;
44
45#define DISABLE_PREEMPTION(key) \
46    do {                                                               \
47        rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &(key)); \
48    } while (0)
49
50#define ENABLE_PREEMPTION(key) \
51    do {                                                        \
52        rtems_mode temp;                                        \
53        rtems_task_mode((key), RTEMS_PREEMPT_MASK, &temp);      \
54    } while (0)
55
56#else
57 
58typedef boolean preemption_key;
59
60#define DISABLE_PREEMPTION(key) \
61    do {                                             \
62        (key) = _Thread_Executing->is_preemptible;   \
63        _Thread_Executing->is_preemptible = 0;       \
64    } while (0)
65   
66#define ENABLE_PREEMPTION(key) \
67    do {                                             \
68        _Thread_Executing->is_preemptible = (key);   \
69        if (_Thread_Evaluate_mode())                 \
70            _Thread_Dispatch();                      \
71    } while (0)
72
73#endif
74
75/* FIXME: case if ATA device is FLASH device need more attention */
76#undef ATA_DEV_IS_FLASH_DISK
77
78/* Block device request with a single buffer provided */
79typedef struct blkdev_request1 {
80    blkdev_request   req;
81    blkdev_sg_buffer sg[1];
82} blkdev_request1;
83
84
85/* Array indexed by controllers minor number */
86static ata_ide_ctrl_t ata_ide_ctrls[IDE_CTRL_MAX_MINOR_NUMBER];
87
88/*
89 * Mapping from ATA-minor numbers to
90 * controller-minor and device on this controller.
91 */
92static ata_ide_dev_t ata_devs[2 * IDE_CTRL_MAX_MINOR_NUMBER];
93static int ata_devs_number;
94
95/* Flag meaning that ATA driver has already been initialized */
96static rtems_boolean ata_initialized = FALSE;
97
98
99/* task and queue used for asynchronous I/O operations */
100static rtems_id ata_task_id;
101static rtems_id ata_queue_id;
102
103/* Mapping of interrupt vectors to devices */
104static Chain_Control ata_int_vec[ATA_MAX_RTEMS_INT_VEC_NUMBER + 1]; 
105
106static void
107ata_process_request(rtems_device_minor_number ctrl_minor);
108
109static void
110ata_process_request_on_init_phase(rtems_device_minor_number  ctrl_minor,
111                                  ata_req_t                 *areq);
112
113static void 
114ata_add_to_controller_queue(rtems_device_minor_number  ctrl_minor, 
115                            ata_req_t                 *areq);
116
117/*
118 * read/write, open/close and ioctl are provided by general block device
119 * driver. Only initialization and ata-specific ioctl are here.
120 */
121
122/* ata_io_data_request --
123 *     Form read/write request for an ATA device and enqueue it to
124 *     IDE controller.
125 *
126 * PARAMETERS:
127 *     device - device identifier
128 *     req    - read/write request from block device driver
129 *
130 * RETURNS:
131 *     RTEMS_SUCCESSFUL on success, or error code if
132 *     error occured
133 */
134static rtems_status_code
135ata_io_data_request(dev_t device, blkdev_request *req)
136{
137    ata_req_t                 *areq; /* ATA request */
138    rtems_device_minor_number  rel_minor; /* relative minor which indexes
139                                           * ata_devs array
140                                           */
141    rtems_device_minor_number  ctrl_minor;
142    unsigned8                  dev;
143   
144    rel_minor = (rtems_filesystem_dev_minor_t(device)) / 
145                ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE;
146   
147    /* get controller which serves the ATA device */
148    ctrl_minor = ata_devs[rel_minor].ctrl_minor;
149
150    /* get ATA device identifier (0 or 1) */
151    dev = ata_devs[rel_minor].device;
152
153    areq = malloc(sizeof(ata_req_t));
154    if (areq == NULL)
155    {
156        return RTEMS_NO_MEMORY;
157    }
158                                                           
159    areq->breq = req;
160    areq->cnt = req->count;
161    areq->cbuf = 0;
162    areq->pos = 0;
163   
164    /* set up registers masks */   
165    areq->regs.to_write = ATA_REGISTERS_POSITION;
166    areq->regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_STATUS);
167   
168    /* choose device on the controller for which the command will be issued */
169    areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] = 
170                                    (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS);
171
172    /* Find ATA command and its type */
173    if (ATA_DEV_INFO(ctrl_minor, dev).mode_active & ATA_MODES_DMA)
174    {
175        /* XXX: never has been tested */
176        areq->type = ATA_COMMAND_TYPE_DMA;
177        if (req->req == BLKDEV_REQ_READ)
178            areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_READ_DMA;
179        else 
180            areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_WRITE_DMA;
181    }
182    else 
183    {
184        if (req->req == BLKDEV_REQ_READ)
185        {
186            areq->type = ATA_COMMAND_TYPE_PIO_IN;
187             
188            /*
189             * choose command to issue: if the number of blocks to be
190             * exchanged is greater then 1 and for ATA command READ MULTIPLE
191             * data block consists of more then 1 sector choose READ MULTIPLE
192             * otherwise READ SECTORS
193             */
194            areq->regs.regs[IDE_REGISTER_COMMAND] = 
195                ((ATA_DEV_INFO(ctrl_minor, dev).max_multiple) && 
196                 (req->count > 1) && 
197                 (ATA_DEV_INFO(ctrl_minor, dev).current_multiple > 1)) ? 
198                 ATA_COMMAND_READ_MULTIPLE : 
199                 ATA_COMMAND_READ_SECTORS;
200        }
201        else
202        {
203            areq->type = ATA_COMMAND_TYPE_PIO_OUT;
204
205            /*
206             * choose command to issue: if the number of blocks to be
207             * exchanged is greater then 1 and for ATA command WRITE MULTIPLE
208             * data block consists of more then 1 sector choose WRITE MULTIPLE
209             * otherwise WRITE SECTORS
210             */
211            areq->regs.regs[IDE_REGISTER_COMMAND] = 
212              ((ATA_DEV_INFO(ctrl_minor, dev).max_multiple) &&
213               (req->count > 1) &&
214               (ATA_DEV_INFO(ctrl_minor, dev).current_multiple > 1)) ? 
215               ATA_COMMAND_WRITE_MULTIPLE : 
216               ATA_COMMAND_WRITE_SECTORS;
217        }
218    }
219
220    /*
221     * Fill position registers
222     */
223    if (ATA_DEV_INFO(ctrl_minor, dev).lba_avaible)
224    {
225        areq->regs.regs[IDE_REGISTER_LBA0] = (unsigned8)req->start;
226        areq->regs.regs[IDE_REGISTER_LBA1] = (unsigned8)(req->start >> 8);
227        areq->regs.regs[IDE_REGISTER_LBA2] = (unsigned8)(req->start >> 16);
228        areq->regs.regs[IDE_REGISTER_LBA3] |= (unsigned8) (req->start >> 24);
229        areq->regs.regs[IDE_REGISTER_LBA3] |= IDE_REGISTER_LBA3_L;
230    }
231    else
232    {
233        unsigned32 count = req->start;
234
235        areq->regs.regs[IDE_REGISTER_SECTOR_NUMBER] =
236                        (count % ATA_DEV_INFO(ctrl_minor, dev).sectors) + 1;
237
238        /* now count = number of tracks: */
239        count /= ATA_DEV_INFO(ctrl_minor, dev).sectors;
240        areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] |= 
241                          (count / ATA_DEV_INFO(ctrl_minor, dev).cylinders);
242
243        /* now count = number of cylinders */
244        count %= ATA_DEV_INFO(ctrl_minor, dev).cylinders;
245        areq->regs.regs[IDE_REGISTER_CYLINDER_LOW] = (unsigned8)count;
246        areq->regs.regs[IDE_REGISTER_CYLINDER_HIGH] = (unsigned8)(count >> 8);
247        areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &= 
248                                                ~IDE_REGISTER_DEVICE_HEAD_L;
249    }
250
251    /* fill sector count register */
252    areq->regs.regs[IDE_REGISTER_SECTOR_COUNT] = areq->breq->count;
253   
254    /* add request to the queue of awaiting requests to the controller */
255    ata_add_to_controller_queue(ctrl_minor, areq);
256 
257    return RTEMS_SUCCESSFUL;
258}
259
260/* ata_non_data_request --
261 *     Form and serve request of NON DATA type for an ATA device.
262 *     Processing of NON DATA request is SYNChronous operation.
263 *
264 * PARAMETERS:
265 *     device - device identifier
266 *     cmd    - command
267 *     argp   - arguments for command
268 *
269 * RETURNS:
270 *     RTEMS_SUCCESSFUL on success, or error code if
271 *     error occured
272 */
273static rtems_status_code
274ata_non_data_request(dev_t device, int cmd, void *argp)
275{
276    rtems_status_code          rc;
277    ata_req_t                 *areq;       /* ATA request */
278    rtems_device_minor_number  rel_minor; /* relative minor which indexes
279                                           * ata_devs array
280                                           */
281    rtems_device_minor_number  ctrl_minor;
282    unsigned8                  dev;
283    ata_queue_msg_t            msg;   
284   
285    rel_minor = (rtems_filesystem_dev_minor_t(device)) /
286                ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE; 
287
288    /* get controller which serves the ATA device */
289    ctrl_minor = ata_devs[rel_minor].ctrl_minor;
290
291    /* get ATA device identifier (0 or 1) */
292    dev = ata_devs[rel_minor].device;
293
294    /* form the request */
295    areq = malloc(sizeof(ata_req_t));
296    if (areq == NULL)
297    {
298        return RTEMS_NO_MEMORY;
299    }
300    memset(areq, 0, sizeof(ata_req_t));   
301
302    areq->type = ATA_COMMAND_TYPE_NON_DATA;
303    areq->regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
304    areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] |= 
305                                    (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS);
306    areq->breq = NULL;
307    areq->regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_ERROR);
308   
309    /*
310     * depending on command fill command register and additional registers
311     * which are needed for command execution
312     */
313    switch(cmd)
314    { 
315        case ATAIO_SET_MULTIPLE_MODE:
316            areq->regs.regs[IDE_REGISTER_COMMAND] = 
317                                                ATA_COMMAND_SET_MULTIPLE_MODE;
318            areq->regs.to_write |= 
319                               ATA_REGISTERS_VALUE(IDE_REGISTER_SECTOR_COUNT);
320            areq->regs.regs[IDE_REGISTER_SECTOR_COUNT] = *(unsigned8 *)argp;
321            break;
322       
323        default:
324            free(areq);
325            return RTEMS_INVALID_NUMBER;
326            break;                               
327    } 
328
329    rc = rtems_semaphore_create(rtems_build_name('I', 'D', 'E', 'S'), 
330                                0, 
331                                RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE | 
332                                RTEMS_NO_INHERIT_PRIORITY |
333                                RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
334                                0,
335                                &(areq->sema));
336    if (rc != RTEMS_SUCCESSFUL)
337    {
338        free(areq);
339        return rc;
340    }                                 
341                                       
342    ata_add_to_controller_queue(ctrl_minor, areq);
343   
344    /* wait for request processing... */
345    rc = rtems_semaphore_obtain(areq->sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
346    if (rc != RTEMS_SUCCESSFUL)
347    {
348        free(areq);
349        return rc;
350    }                                 
351
352    rtems_semaphore_delete(areq->sema);
353   
354    /*
355     * if no error occurred and if necessary, update internal ata driver data
356     * structures to reflect changes (in device configuration, for example)
357     */ 
358    if (areq->status == RTEMS_SUCCESSFUL)
359    {
360        switch(cmd)
361        { 
362            case ATAIO_SET_MULTIPLE_MODE:
363                ATA_DEV_INFO(ctrl_minor, dev).current_multiple = 
364                                                           *(unsigned8 *)argp;
365                break;
366       
367            default:
368                rc = RTEMS_INVALID_NUMBER;
369                break;                               
370        } 
371    }   
372    else   
373    {   
374        /* XXX: should be correct error processing: for ex, may be
375         * ABRT and then we should return RTEMS_NOT_IMPLEMENTED
376         */
377        rc = RTEMS_IO_ERROR;
378    }   
379   
380    /* tell ata driver that controller ready to serve next request */
381    ATA_SEND_EVT(msg, ATA_MSG_SUCCESS_EVT, ctrl_minor, 0);
382                                                 
383    return rc;
384}
385
386/* ata_process_request --
387 *     Get first request from controller's queue and process it.
388 *
389 * PARAMETERS:
390 *     ctrl_minor - controller identifier
391 *
392 * RETURNS:
393 *     NONE
394 */
395static void
396ata_process_request(rtems_device_minor_number ctrl_minor)
397{
398    ata_req_t       *areq;
399    unsigned16       byte; /* emphasize that only 8 low bits is meaningful */
400    ata_queue_msg_t  msg;
401    unsigned8        i, dev;
402    unsigned16       val;
403    unsigned16       data_bs; /* the number of 512-bytes sectors in one
404                               * data block
405                               */
406    ISR_Level        level;                           
407       
408    /* if no requests to controller then do nothing */
409    if (Chain_Is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
410        return;
411
412    /* get first request in the controller's queue */
413    _ISR_Disable(level);
414    areq = (ata_req_t *)(ata_ide_ctrls[ctrl_minor].reqs.first);
415    _ISR_Enable(level);
416   
417    /* get ATA device identifier (0 or 1) */
418    dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] & 
419           IDE_REGISTER_DEVICE_HEAD_DEV;
420
421    /* get data block size */
422    data_bs = ATA_DEV_INFO(ctrl_minor, dev).current_multiple ? 
423              ATA_DEV_INFO(ctrl_minor, dev).current_multiple : 1;     
424   
425    /* execute device select protocol */
426    ide_controller_write_register(ctrl_minor, IDE_REGISTER_DEVICE_HEAD, 
427                                  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD]);
428   
429    do {
430        ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
431    } while ((byte & IDE_REGISTER_STATUS_BSY) || 
432             (!(byte & IDE_REGISTER_STATUS_DRDY)));
433
434    /* fill in all  necessary registers on the controller */
435    for (i=0; i< ATA_MAX_CMD_REG_OFFSET; i++)
436    {
437        unsigned32 reg = (1 << i);
438        if (areq->regs.to_write & reg)
439            ide_controller_write_register(ctrl_minor, i, areq->regs.regs[i]);
440    }
441
442    /* continue to execute ATA protocols depending on type of request */
443    if (areq->type == ATA_COMMAND_TYPE_PIO_OUT)
444    {
445        do {
446            ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, 
447                                         &byte);
448        } while (byte & IDE_REGISTER_STATUS_BSY);
449
450        if (byte & IDE_REGISTER_STATUS_DRQ)
451        {
452            ide_controller_write_data_block(
453                ctrl_minor, 
454                MIN(data_bs, areq->cnt) * ATA_SECTOR_SIZE,
455                areq->breq->bufs, &areq->cbuf,
456                &areq->pos);
457            areq->cnt -= MIN(data_bs, areq->cnt);
458        }   
459        else
460        {   
461            if (IDE_Controller_Table[ctrl_minor].int_driven == 0)
462            {
463                ide_controller_read_register(
464                    ctrl_minor, 
465                    IDE_REGISTER_ALTERNATE_STATUS_OFFSET,
466                    &val);
467                ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
468                                             &val);
469
470                ATA_SEND_EVT(msg, ATA_MSG_ERROR_EVT, ctrl_minor, 
471                             RTEMS_IO_ERROR);
472            }
473        }   
474    }
475
476    if (IDE_Controller_Table[ctrl_minor].int_driven == 0)
477    {
478        do {
479            ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, 
480                                         &byte);
481        } while (byte & IDE_REGISTER_STATUS_BSY);
482       
483        ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
484    }   
485}
486
487/* ata_request_done --
488 *     Extract request from controller queue, execute callback if necessary
489 *     and process next request for the controller.
490 *
491 * PARAMETERS:
492 *     areq       - ATA request
493 *     ctrl_minor - controller identifier
494 *     status     - status with which request has been done
495 *     error      - error, if status != RTEMS_SUCCESSFUL
496 *
497 * RETURNS:
498 *     NONE
499 */
500static inline void
501ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor,
502                 rtems_status_code status, int error)
503{
504    preemption_key key;
505
506    assert(areq);
507
508    DISABLE_PREEMPTION(key);
509    ATA_EXEC_CALLBACK(areq, status, error);
510    Chain_Extract(&areq->link);
511    free(areq);
512
513    if (!Chain_Is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
514    {
515        ENABLE_PREEMPTION(key);
516        ata_process_request(ctrl_minor);
517        return;
518    }
519    ENABLE_PREEMPTION(key); 
520}
521
522/* ata_non_data_request_done --
523 *     Set up request status and release request's semaphore.
524 *
525 * PARAMETERS:
526 *     areq       - ATA request
527 *     ctrl_minor - controller identifier
528 *     status     - status with which request has been done
529 *     error      - error, if status != RTEMS_SUCCESSFUL
530 *
531 * RETURNS:
532 *     NONE
533 */
534static inline void
535ata_non_data_request_done(ata_req_t *areq, 
536                          rtems_device_minor_number ctrl_minor,
537                          rtems_status_code status, int error)
538{
539    areq->status = status;
540    areq->error = error;
541    rtems_semaphore_release(areq->sema);
542}
543
544
545/* ata_add_to_controller_queue --
546 *     Add request to the controller's queue.
547 *
548 * PARAMETERS:
549 *     ctrl_minor - controller identifier
550 *     areq       - ATA request
551 *
552 * RETURNS:
553 *     NONE
554 */
555static void
556ata_add_to_controller_queue(rtems_device_minor_number  ctrl_minor, 
557                            ata_req_t                 *areq)
558{
559    Chain_Append(&ata_ide_ctrls[ctrl_minor].reqs, &areq->link);
560    if (Chain_Has_only_one_node(&ata_ide_ctrls[ctrl_minor].reqs))
561    {
562        unsigned16      val;
563        ata_queue_msg_t msg;
564
565#ifdef DEBUG
566        /*
567         * read IDE_REGISTER_ALTERNATE_STATUS instead IDE_REGISTER_STATUS
568         * to prevent clearing of pending interrupt
569         */
570        ide_controller_read_register(ctrl_minor, 
571                                     IDE_REGISTER_ALTERNATE_STATUS, 
572                                     &val);
573        if (val & IDE_REGISTER_STATUS_BSY)
574            return;
575#endif
576        ATA_SEND_EVT(msg, ATA_MSG_PROCESS_NEXT_EVT, ctrl_minor, 0);
577    }   
578}                           
579
580
581/* ata_interrupt_handler --
582 *     ATA driver interrrupt handler. If interrrupt happend it mapped it to
583 *     controller (controllerS, if a number of controllers share one int line)
584 *     and generates ATA event(s).
585 *
586 * PARAMETERS:
587 *     vec - interrupt vector 
588 *
589 * RETURNS:
590 *     NONE
591 */
592rtems_isr
593ata_interrupt_handler(rtems_vector_number vec)
594{
595    Chain_Node      *the_node = ((Chain_Control *)(&ata_int_vec[vec]))->first;
596    ata_queue_msg_t  msg;
597    unsigned16       byte; /* emphasize that only 8 low bits is meaningful */
598   
599    for ( ; !Chain_Is_tail(&ata_int_vec[vec], the_node) ; )
600    {
601        /* if (1) - is temporary hack - currently I don't know how to identify
602         * controller which asserted interrupt if few controllers share one
603         * interrupt line
604         */
605        if (1)
606        {
607            msg.ctrl_minor = ((ata_int_st_t *)the_node)->ctrl_minor;
608            ide_controller_read_register(msg.ctrl_minor, IDE_REGISTER_STATUS, 
609                                         &byte);
610            ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, msg.ctrl_minor, 0);                             
611        }
612        the_node = the_node->next;
613    }   
614}
615
616/* ata_pio_in_protocol --
617 *     ATA PIO_IN protocol implementation, see specification
618 *
619 * PARAMETERS:
620 *     ctrl_minor - controller identifier
621 *     areq       - ATA request
622 *
623 * RETURNS:
624 *     NONE
625 */
626static inline void
627ata_pio_in_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
628{
629    unsigned16      bs, val;
630    unsigned8       dev;
631    unsigned32      min_val;
632    ata_queue_msg_t msg;
633       
634    dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] & 
635           IDE_REGISTER_DEVICE_HEAD_DEV;
636
637    bs = ATA_DEV_INFO(ctrl_minor, dev).current_multiple ? 
638         ATA_DEV_INFO(ctrl_minor, dev).current_multiple : 1;     
639    min_val = MIN(bs, areq->cnt);
640   
641    ide_controller_read_data_block(ctrl_minor, min_val * ATA_SECTOR_SIZE, 
642                                   areq->breq->bufs, &areq->cbuf, &areq->pos);
643             
644    areq->cnt -= min_val;
645    if (areq->cnt == 0)
646    {
647        ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, RTEMS_SUCCESSFUL);
648    }
649    else if (IDE_Controller_Table[ctrl_minor].int_driven == 0)
650    {
651        do {
652           ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &val);
653        } while (val & IDE_REGISTER_STATUS_BSY);
654       
655        ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
656    }
657}
658
659/* ata_pio_out_protocol --
660 *     ATA PIO_OUT protocol implementation, see specification
661 *
662 * PARAMETERS:
663 *     ctrl_minor - controller identifier
664 *     areq       - ATA request
665 *
666 * RETURNS:
667 *     NONE
668 */
669static inline void
670ata_pio_out_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
671{
672    unsigned16      bs, val;
673    unsigned8       dev;
674    unsigned32      min_val;
675    ata_queue_msg_t msg;
676   
677    dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] & 
678           IDE_REGISTER_DEVICE_HEAD_DEV;
679
680    bs = ATA_DEV_INFO(ctrl_minor, dev).current_multiple ? 
681         ATA_DEV_INFO(ctrl_minor, dev).current_multiple : 1;     
682
683    min_val = MIN(bs, areq->cnt);     
684
685    if (areq->cnt == 0)
686    {
687        ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, RTEMS_SUCCESSFUL);
688    }
689    else 
690    {
691        ide_controller_write_data_block(ctrl_minor, min_val * ATA_SECTOR_SIZE,
692                                        areq->breq->bufs, &areq->cbuf, 
693                                        &areq->pos);
694        areq->cnt -= min_val;
695        if (IDE_Controller_Table[ctrl_minor].int_driven == 0)
696        {
697            do {
698                ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, 
699                                             &val);
700            } while (val & IDE_REGISTER_STATUS_BSY);
701
702            ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
703        }
704  }
705}
706
707/* ata_queue_task --
708 *     Task which manages ATA driver events queue.
709 *
710 * PARAMETERS:
711 *     arg - ignored
712 *
713 * RETURNS:
714 *     NONE
715 *
716 * NOTES:
717 *     should be non-preemptive
718 */
719static rtems_task
720ata_queue_task(rtems_task_argument arg)
721{
722    ata_queue_msg_t            msg;
723    rtems_unsigned32           size;
724    ata_req_t                 *areq;
725    rtems_device_minor_number  ctrl_minor;
726    unsigned16                 val;
727    unsigned16                 val1;
728    rtems_status_code          rc;
729    ISR_Level                  level;
730
731    while (1)
732    {
733        /* get event which has happend */
734        rc = rtems_message_queue_receive(ata_queue_id, &msg, &size, RTEMS_WAIT, 
735                                         RTEMS_NO_TIMEOUT);
736        if (rc != RTEMS_SUCCESSFUL)
737            rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
738                                             
739        /* get controller on which event has happend */
740        ctrl_minor = msg.ctrl_minor;
741       
742        /* get current request to the controller */
743        _ISR_Disable(level);       
744        areq = (ata_req_t *)(ata_ide_ctrls[ctrl_minor].reqs.first);
745        _ISR_Enable(level);
746       
747        switch(msg.type)
748        {
749            case ATA_MSG_PROCESS_NEXT_EVT:
750                /* process next request in the controller queue */
751                ata_process_request(ctrl_minor);
752                break;
753
754            case ATA_MSG_SUCCESS_EVT:
755                /*
756                 * finish processing of current request with successful
757                 * status and start processing of the next request in the
758                 * controller queue
759                 */
760                ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, 
761                                 msg.error);
762                break;
763               
764            case ATA_MSG_ERROR_EVT:
765                /*
766                 * finish processing of current request with error
767                 * status and start processing of the next request in the
768                 * controller queue
769                 */
770                ata_request_done(areq, ctrl_minor, RTEMS_UNSATISFIED, 
771                                 msg.error);
772                break;
773               
774            case ATA_MSG_GEN_EVT:
775                /*
776                 * continue processing of the current request to the
777                 * controller according to current request state and
778                 * ATA protocol
779                 */
780                ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, 
781                                           &val);
782                /* process error case */
783                if (val & IDE_REGISTER_STATUS_ERR)
784                { 
785                    ide_controller_read_register(ctrl_minor, 
786                                                 IDE_REGISTER_ERROR, 
787                                                 &val);
788                    if (areq->type == ATA_COMMAND_TYPE_NON_DATA)
789                        ata_non_data_request_done(areq, ctrl_minor, 
790                                                  RTEMS_UNSATISFIED, 
791                                                  RTEMS_IO_ERROR);
792                    else                             
793                        ata_request_done(areq, ctrl_minor, RTEMS_UNSATISFIED, 
794                                         RTEMS_IO_ERROR);
795                    break;                                 
796                }
797
798                switch(areq->type)
799                {
800                    case ATA_COMMAND_TYPE_PIO_IN:
801                        ata_pio_in_protocol(ctrl_minor, areq);
802                        break;
803               
804                    case ATA_COMMAND_TYPE_PIO_OUT:
805                        ata_pio_out_protocol(ctrl_minor, areq);
806                        break;
807               
808                    case ATA_COMMAND_TYPE_NON_DATA:
809                        ide_controller_read_register(ctrl_minor, 
810                                                      IDE_REGISTER_ERROR, 
811                                                     &val1);
812                        ata_non_data_request_done(areq, ctrl_minor,
813                                                  RTEMS_SUCCESSFUL,
814                                                  val1);
815                        break;
816           
817                    default:
818                        printf("ata_queue_task: non-supported command type\n");
819                        ata_request_done(areq, ctrl_minor,
820                                         RTEMS_UNSATISFIED,
821                                         RTEMS_NOT_IMPLEMENTED);
822                        break;         
823                }
824                break;   
825
826            default:
827                rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
828                break;
829        }
830    }
831}
832
833/* ata_ioctl --
834 *     ATA driver ioctl interface.
835 *
836 * PARAMETERS:
837 *     device - device identifier
838 *     cmd    - command
839 *     argp   - arguments
840 *
841 * RETURNS:
842 *     depend on 'cmd'
843 */
844int 
845ata_ioctl(dev_t device, int cmd, void *argp)
846{
847    rtems_status_code         status;
848    rtems_device_minor_number rel_minor;
849   
850    rel_minor = (rtems_filesystem_dev_minor_t(device)) /
851                ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE;
852
853    /*
854     * in most cases this means that device 'device' is not an registred ATA
855     * device
856     */ 
857    if (ata_devs[rel_minor].device == ATA_UNDEFINED_VALUE)
858    {
859        errno = ENODEV;
860        return -1;
861    }   
862
863    switch (cmd) 
864    {
865        case BLKIO_REQUEST:
866            status = ata_io_data_request(device, (blkdev_request *)argp);
867            break;
868       
869        case ATAIO_SET_MULTIPLE_MODE:
870            status = ata_non_data_request(device, cmd, argp);
871            break;
872     
873        default:
874            errno = EBADRQC;
875            return -1;
876            break;
877    }
878
879    if (status != RTEMS_SUCCESSFUL)
880    {
881        errno = EIO;
882        return -1; 
883    }
884    return 0;
885}
886
887/*
888 * ata_initialize --
889 *     Initializes all ATA devices found on initialized IDE controllers.
890 *
891 * PARAMETERS:
892 *     major - device major number
893 *     minor - device minor number
894 *     args   - arguments
895 *
896 * RETURNS:
897 *     RTEMS_SUCCESSFUL on success, or error code if
898 *     error occured
899 */
900rtems_device_driver
901ata_initialize(rtems_device_major_number major, 
902               rtems_device_minor_number minor_arg, 
903               void *args)
904{
905    unsigned32         ctrl_minor;
906    rtems_status_code  status;
907    ata_req_t          areq;
908    blkdev_request1    breq;     
909    unsigned8          i, dev = 0;
910    unsigned16        *buffer;
911    unsigned16         ec;
912    char               name[ATA_MAX_NAME_LENGTH];
913    dev_t              device;
914    ata_int_st_t      *int_st;
915    rtems_isr_entry    old_isr;
916
917    if (ata_initialized)
918        return RTEMS_SUCCESSFUL;
919           
920    /* initialization of disk devices library */
921    status = rtems_disk_io_initialize();
922    if (status != RTEMS_SUCCESSFUL)
923        return status;
924       
925    /* create queue for asynchronous requests handling */
926    status = rtems_message_queue_create(
927                 rtems_build_name('A', 'T', 'A', 'Q'),
928                 ATA_DRIVER_MESSAGE_QUEUE_SIZE,
929                 sizeof(ata_queue_msg_t),
930                 RTEMS_FIFO | RTEMS_LOCAL,
931                 &ata_queue_id);
932    if (status != RTEMS_SUCCESSFUL)
933    {
934        rtems_disk_io_done();
935        return status;
936    }   
937
938    /*
939     * create ATA driver task, see comments for task implementation for
940     * details
941     */
942    status = rtems_task_create(
943                 rtems_build_name ('A', 'T', 'A', 'T'),
944                 ATA_DRIVER_TASK_PRIORITY,
945                 ATA_DRIVER_TASK_STACK_SIZE,
946                 RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_ASR | 
947                 RTEMS_INTERRUPT_LEVEL(0),
948                 RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
949                 &ata_task_id);
950    if (status != RTEMS_SUCCESSFUL)
951    {
952        rtems_message_queue_delete(ata_queue_id);
953        rtems_disk_io_done();
954        return status;
955    }   
956   
957    /*
958     * start ATA driver task. Actually the task will not start immediately -
959     * it will start only after multitasking support will be started
960     */ 
961    status = rtems_task_start(ata_task_id, ata_queue_task, 0); 
962    if (status != RTEMS_SUCCESSFUL)
963    {
964        rtems_task_delete(ata_task_id);
965        rtems_message_queue_delete(ata_queue_id);
966        rtems_disk_io_done();
967        return status;
968    }   
969   
970    buffer = (unsigned16 *)malloc(ATA_SECTOR_SIZE);
971    if (buffer == NULL)
972    {
973        rtems_task_delete(ata_task_id);
974        rtems_message_queue_delete(ata_queue_id);
975        rtems_disk_io_done();
976        return RTEMS_NO_MEMORY;
977    }   
978       
979    ata_devs_number = 0;
980
981    for (i = 0; i < (2 * IDE_CTRL_MAX_MINOR_NUMBER); i++)
982        ata_devs[i].device = ATA_UNDEFINED_VALUE;
983
984    /* prepare ATA driver for handling  interrupt driven devices */
985    for (i = 0; i < ATA_MAX_RTEMS_INT_VEC_NUMBER; i++)
986        Chain_Initialize_empty(&ata_int_vec[i]);
987
988    /*
989     * during ATA driver initialization EXECUTE DEVICE DIAGNOSTIC and
990     * IDENTIFY DEVICE ATA command should be issued; for these purposes ATA
991     * requests should be formed; ATA requests contain block device request,
992     * so form block device request first
993     */
994    memset(&breq, 0, sizeof(blkdev_request1));
995    breq.req.req_done = NULL;
996    breq.req.done_arg = &breq;
997    breq.req.bufnum = 1;
998    breq.req.count = 1;
999    breq.req.bufs[0].length = ATA_SECTOR_SIZE;
1000    breq.req.bufs[0].buffer = buffer;
1001
1002    /*
1003     * for each presented IDE controller execute EXECUTE DEVICE DIAGNOSTIC
1004     * ATA command; for each found device execute IDENTIFY DEVICE ATA
1005     * command
1006     */
1007    for (ctrl_minor = 0; ctrl_minor < IDE_Controller_Count; ctrl_minor++)
1008    if (IDE_Controller_Table[ctrl_minor].status == IDE_CTRL_INITIALIZED)
1009    {
1010        Chain_Initialize_empty(&ata_ide_ctrls[ctrl_minor].reqs);
1011       
1012        if (IDE_Controller_Table[ctrl_minor].int_driven == TRUE)
1013        {
1014            int_st = malloc(sizeof(ata_int_st_t));
1015            if (int_st == NULL)
1016            {
1017                free(buffer);
1018                rtems_task_delete(ata_task_id);
1019                rtems_message_queue_delete(ata_queue_id);
1020                rtems_disk_io_done();
1021                return RTEMS_NO_MEMORY;
1022            }       
1023
1024            int_st->ctrl_minor = ctrl_minor;
1025
1026            status = rtems_interrupt_catch(
1027                         ata_interrupt_handler, 
1028                         IDE_Controller_Table[ctrl_minor].int_vec, 
1029                         &old_isr);
1030            if (status != RTEMS_SUCCESSFUL)
1031            {
1032                free(int_st);
1033                free(buffer);
1034                rtems_task_delete(ata_task_id);
1035                rtems_message_queue_delete(ata_queue_id);
1036                rtems_disk_io_done();
1037                return status;
1038            } 
1039            Chain_Append(
1040                &ata_int_vec[IDE_Controller_Table[ctrl_minor].int_vec],
1041                &int_st->link);
1042
1043            /* disable interrupts */
1044            ide_controller_write_register(ctrl_minor, 
1045                                          IDE_REGISTER_DEVICE_CONTROL_OFFSET, 
1046                                          IDE_REGISTER_DEVICE_CONTROL_nIEN);
1047        }
1048
1049        /*
1050         * Issue EXECUTE DEVICE DIAGNOSTIC ATA command for explore is
1051         * there any ATA device on the controller.
1052         */
1053        memset(&areq, 0, sizeof(ata_req_t));
1054        areq.type = ATA_COMMAND_TYPE_NON_DATA;
1055        areq.regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
1056        areq.regs.regs[IDE_REGISTER_COMMAND] = 
1057                                  ATA_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC;
1058        areq.regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_ERROR);
1059
1060        areq.breq = (blkdev_request *)&breq;
1061
1062        /*
1063         * Process the request. Special processing of requests on
1064         * initialization phase is needed because at this moment there
1065         * is no multitasking enviroment
1066         */
1067        ata_process_request_on_init_phase(ctrl_minor, &areq);
1068
1069        /*
1070         * check status of I/O operation
1071         */
1072        if (breq.req.status != RTEMS_SUCCESSFUL)
1073            continue;
1074     
1075        /* disassemble returned diagnostic codes */ 
1076        if (breq.req.error == ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT)
1077        {
1078            ATA_DEV_INFO(ctrl_minor, 0).present = 1;
1079            ATA_DEV_INFO(ctrl_minor,1).present = 1; 
1080        }
1081        else if (breq.req.error == ATA_DEV0_PASSED_DEV1_FAILED)
1082        {
1083            ATA_DEV_INFO(ctrl_minor,0).present = 1;
1084            ATA_DEV_INFO(ctrl_minor,1).present = 0;
1085        }
1086        else if (breq.req.error < ATA_DEV1_PASSED_DEV0_FAILED)
1087        {
1088            ATA_DEV_INFO(ctrl_minor,0).present = 0;
1089            ATA_DEV_INFO(ctrl_minor,1).present = 1;
1090        }
1091        else
1092        {
1093            ATA_DEV_INFO(ctrl_minor, 0).present = 0;
1094            ATA_DEV_INFO(ctrl_minor, 1).present = 0;
1095        }
1096
1097        /* refine the returned codes */
1098        if (ATA_DEV_INFO(ctrl_minor, 1).present != 0)
1099        {
1100            ide_controller_read_register(ctrl_minor, IDE_REGISTER_ERROR, &ec);
1101            if (ec & ATA_DEV1_PASSED_DEV0_FAILED)
1102                ATA_DEV_INFO(ctrl_minor, 1).present = 1;
1103            else
1104                ATA_DEV_INFO(ctrl_minor, 1).present = 0;
1105        }
1106
1107        /* for each found ATA device obtain it configuration */
1108        for (dev = 0; dev < 2; dev++)
1109        if (ATA_DEV_INFO(ctrl_minor, dev).present)
1110        {
1111            /*
1112             * Issue DEVICE IDENTIFY ATA command and get device
1113             * configuration           
1114             */
1115            memset(&areq, 0, sizeof(ata_req_t));
1116            areq.type = ATA_COMMAND_TYPE_PIO_IN;
1117            areq.regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
1118            areq.regs.regs[IDE_REGISTER_COMMAND] = 
1119                                              ATA_COMMAND_IDENTIFY_DEVICE;
1120            areq.regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_STATUS);
1121            areq.breq = (blkdev_request *)&breq;
1122           
1123            areq.cnt = breq.req.count;
1124
1125            areq.regs.regs[IDE_REGISTER_DEVICE_HEAD] |=
1126                                    (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS);
1127
1128            /*
1129             * Process the request. Special processing of requests on
1130             * initialization phase is needed because at this moment there
1131             * is no multitasking enviroment
1132             */
1133            ata_process_request_on_init_phase(ctrl_minor, &areq);
1134
1135            /* check status of I/O operation */
1136            if (breq.req.status != RTEMS_SUCCESSFUL)
1137                continue;
1138
1139            /*
1140             * Parse returned device configuration and fill in ATA internal
1141             * device info structure
1142             */
1143            ATA_DEV_INFO(ctrl_minor, dev).cylinders = 
1144                CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_CLNDS]);
1145            ATA_DEV_INFO(ctrl_minor, dev).heads = 
1146                CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_HEADS]);
1147            ATA_DEV_INFO(ctrl_minor, dev).sectors = 
1148                CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_SECS]);
1149            ATA_DEV_INFO(ctrl_minor, dev).lba_sectors = 
1150                (CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_USR_SECS0]) << 16) + 
1151                 CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_USR_SECS1]);
1152            ATA_DEV_INFO(ctrl_minor, dev).lba_avaible = 
1153                (CF_LE_W(buffer[ATA_IDENT_WORD_CAPABILITIES]) >> 9) & 0x1;
1154            ATA_DEV_INFO(ctrl_minor, dev).max_multiple = 
1155                (unsigned8) (CF_LE_W(buffer[ATA_IDENT_WORD_RW_MULT]));
1156            ATA_DEV_INFO(ctrl_minor, dev).current_multiple = 
1157                (CF_LE_W(buffer[ATA_IDENT_WORD_MULT_SECS]) & 0x100) ? 
1158                (unsigned8)(CF_LE_W(buffer[ATA_IDENT_WORD_MULT_SECS])) :
1159                 0;
1160
1161            if ((CF_LE_W(buffer[ATA_IDENT_WORD_FIELD_VALIDITY]) & 
1162                 ATA_IDENT_BIT_VALID) == 0) {
1163              /* no "supported modes" info -> use default */
1164              ATA_DEV_INFO(ctrl_minor, dev).mode_active = ATA_MODES_PIO3;
1165            }
1166            else {
1167              ATA_DEV_INFO(ctrl_minor, dev).modes_avaible =
1168                ((CF_LE_W(buffer[64]) & 0x1) ? ATA_MODES_PIO3 : 0) |
1169                ((CF_LE_W(buffer[64]) & 0x2) ? ATA_MODES_PIO4 : 0) |
1170                ((CF_LE_W(buffer[63]) & 0x1) ? ATA_MODES_DMA0 : 0) |
1171                ((CF_LE_W(buffer[63]) & 0x2) ? 
1172                 ATA_MODES_DMA0 | ATA_MODES_DMA1 : 0) |
1173                ((CF_LE_W(buffer[63]) & 0x4) ? 
1174                 ATA_MODES_DMA0 | ATA_MODES_DMA1 | ATA_MODES_DMA2 : 0);
1175              if (ATA_DEV_INFO(ctrl_minor, dev).modes_avaible == 0)
1176                continue;
1177              /*
1178               * choose most appropriate ATA device data I/O speed supported
1179               * by the controller
1180               */
1181              status = ide_controller_config_io_speed(
1182                ctrl_minor, 
1183                ATA_DEV_INFO(ctrl_minor, dev).modes_avaible);
1184              if (status != RTEMS_SUCCESSFUL)
1185                continue;
1186            }     
1187            /*
1188             * Ok, let register new ATA device in the system
1189             */
1190            ata_devs[ata_devs_number].ctrl_minor = ctrl_minor;
1191            ata_devs[ata_devs_number].device = dev;
1192
1193            snprintf(name, ATA_MAX_NAME_LENGTH, "/dev/hd%c", 
1194                     'a' + 2 * ctrl_minor + dev);
1195            device = rtems_filesystem_make_dev_t(
1196                         major, 
1197                         (ata_devs_number * 
1198                          ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE));
1199
1200            status = rtems_disk_create_phys(device, ATA_SECTOR_SIZE, 
1201                ATA_DEV_INFO(ctrl_minor, dev).lba_avaible ? 
1202                ATA_DEV_INFO(ctrl_minor, dev).lba_sectors : 
1203                (ATA_DEV_INFO(ctrl_minor, dev).heads *
1204                 ATA_DEV_INFO(ctrl_minor, dev).cylinders *
1205                 ATA_DEV_INFO(ctrl_minor, dev).sectors),
1206                (block_device_ioctl) ata_ioctl, name);
1207            if (status != RTEMS_SUCCESSFUL)
1208            {
1209                ata_devs[ata_devs_number].device = ATA_UNDEFINED_VALUE;
1210                continue;
1211            }       
1212            ata_devs_number++;
1213        }
1214        if (IDE_Controller_Table[ctrl_minor].int_driven == TRUE)
1215        {   
1216            ide_controller_write_register(ctrl_minor, 
1217                                          IDE_REGISTER_DEVICE_CONTROL_OFFSET, 
1218                                          0x00);
1219        }
1220    }
1221
1222    free(buffer);
1223    ata_initialized = TRUE;
1224    return RTEMS_SUCCESSFUL;
1225}
1226
1227/* ata_process_request_on_init_phase --
1228 *     Process the ATA request during system initialization. Request
1229 *     processing is syncronous and doesn't use multiprocessing enviroment.
1230 *
1231 * PARAMETERS:
1232 *     ctrl_minor - controller identifier
1233 *     areq       - ATA request
1234 *
1235 * RETURNS:
1236 *     NONE
1237 */
1238static void
1239ata_process_request_on_init_phase(rtems_device_minor_number  ctrl_minor,
1240                                  ata_req_t                 *areq)
1241{
1242    unsigned16         byte;/* emphasize that only 8 low bits is meaningful */
1243    unsigned8          i, dev;
1244    unsigned16         val, val1;
1245    unsigned16         data_bs; /* the number of 512 bytes sectors into one
1246                                 * data block
1247                                 */
1248    assert(areq);
1249   
1250    dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] & 
1251           IDE_REGISTER_DEVICE_HEAD_DEV;
1252
1253    data_bs = ATA_DEV_INFO(ctrl_minor, dev).current_multiple ? 
1254              ATA_DEV_INFO(ctrl_minor, dev).current_multiple : 1;     
1255   
1256    ide_controller_write_register(ctrl_minor, IDE_REGISTER_DEVICE_HEAD, 
1257                                  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD]);
1258   
1259    do {
1260        ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
1261    } while ((byte & IDE_REGISTER_STATUS_BSY) || 
1262             (!(byte & IDE_REGISTER_STATUS_DRDY)));
1263
1264    for (i=0; i< ATA_MAX_CMD_REG_OFFSET; i++)
1265    {
1266        unsigned32 reg = (1 << i);
1267        if (areq->regs.to_write & reg)
1268            ide_controller_write_register(ctrl_minor, i, 
1269                                          areq->regs.regs[i]);
1270    }
1271
1272    do {
1273        ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
1274    } while (byte & IDE_REGISTER_STATUS_BSY);
1275
1276    ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &val);
1277    ide_controller_read_register(ctrl_minor, IDE_REGISTER_ERROR, &val1);
1278
1279    if (val & IDE_REGISTER_STATUS_ERR)
1280    {
1281        areq->breq->status = RTEMS_UNSATISFIED;
1282        areq->breq->error = RTEMS_IO_ERROR;
1283        return;
1284    }
1285 
1286    switch(areq->type)
1287    {
1288        case ATA_COMMAND_TYPE_PIO_IN:
1289            ide_controller_read_data_block(
1290                ctrl_minor, 
1291                MIN(data_bs, areq->cnt) * ATA_SECTOR_SIZE,
1292                areq->breq->bufs, &areq->cbuf,
1293                &areq->pos);
1294             
1295            areq->cnt -= MIN(data_bs, areq->cnt);
1296            if (areq->cnt == 0)
1297            {
1298                areq->breq->status = RTEMS_SUCCESSFUL;
1299            }
1300            else 
1301            {
1302                /*
1303                 * this shouldn't happend on the initialization
1304                 * phase!
1305                 */
1306                rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR); 
1307            }
1308            break;
1309               
1310        case ATA_COMMAND_TYPE_NON_DATA:
1311            areq->breq->status = RTEMS_SUCCESSFUL;
1312            areq->breq->error = val1;
1313            break;
1314           
1315        default:
1316            printf("ata_queue_task: non-supported command type\n");
1317            areq->breq->status = RTEMS_UNSATISFIED;
1318            areq->breq->error = RTEMS_NOT_IMPLEMENTED;
1319            break;         
1320    }
1321}
Note: See TracBrowser for help on using the repository browser.