source: rtems/cpukit/libblock/src/ata.c @ a1f1011

4.104.114.84.95
Last change on this file since a1f1011 was ef142d7, checked in by Joel Sherrill <joel.sherrill@…>, on 10/28/02 at 14:00:43

2002-10-28 Eugeny S. Mints <Eugeny.Mints@…>

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