source: rtems/c/src/libchip/ide/ata.c @ bf474880

4.104.114.84.9
Last change on this file since bf474880 was bf474880, checked in by Ralf Corsepius <ralf.corsepius@…>, on Nov 20, 2004 at 4:03:21 AM

2004-11-20 Thomas Doerfler <Thomas.Doerfler@…>:

PR 703/filesystem

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