source: rtems/c/src/libchip/ide/ata.c @ 73b5bd5d

4.104.114.84.9
Last change on this file since 73b5bd5d was 73b5bd5d, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 15, 2004 at 1:33:58 PM

Remove stray white spaces.

  • Property mode set to 100644
File size: 43.3 KB
Line 
1/*
2 * ata.c
3 *
4 * ATA RTEMS driver. ATA driver is hardware independant implementation of
5 * ATA-2 standart, working draft X3T10/0948D, revision 4c. ATA driver bases
6 * on RTEMS IDE controller driver.
7 *
8 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
9 * Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
10 *
11 * The license and distribution terms for this file may be
12 * found in the file LICENSE in this distribution or at
13 * http://www.rtems.com/license/LICENSE.
14 *
15 * $Id$
16 *
17 */
18#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_avaible =
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_avaible == 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_avaible);
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.