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

4.104.114.84.9
Last change on this file since f610e83f was f610e83f, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Jul 10, 2007 at 4:00:28 PM

compilable release of virtex/gen83xx/gen5200 powerpc adaptations. Merged many different versions of new exception handling code to shared sources.

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