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

4.104.114.84.95
Last change on this file since c9b005a9 was c9b005a9, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/09/06 at 10:05:27

applied patches for PR1117/1118/1119/1120

  • Property mode set to 100644
File size: 46.7 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    free(areq);
532
533    if (!Chain_Is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
534    {
535        ENABLE_PREEMPTION(key);
536        ata_process_request(ctrl_minor);
537        return;
538    }
539    ENABLE_PREEMPTION(key);
540}
541
542/* ata_non_data_request_done --
543 *     Set up request status and release request's semaphore.
544 *
545 * PARAMETERS:
546 *     areq       - ATA request
547 *     ctrl_minor - controller identifier
548 *     status     - status with which request has been done
549 *     error      - error, if status != RTEMS_SUCCESSFUL
550 *
551 * RETURNS:
552 *     NONE
553 */
554static inline void
555ata_non_data_request_done(ata_req_t *areq,
556                          rtems_device_minor_number ctrl_minor,
557                          rtems_status_code status, int error)
558{
559    areq->status = status;
560    areq->error = error;
561    rtems_semaphore_release(areq->sema);
562}
563
564
565/* ata_add_to_controller_queue --
566 *     Add request to the controller's queue.
567 *
568 * PARAMETERS:
569 *     ctrl_minor - controller identifier
570 *     areq       - ATA request
571 *
572 * RETURNS:
573 *     NONE
574 */
575static void
576ata_add_to_controller_queue(rtems_device_minor_number  ctrl_minor,
577                            ata_req_t                 *areq)
578{
579    Chain_Append(&ata_ide_ctrls[ctrl_minor].reqs, &areq->link);
580    if (Chain_Has_only_one_node(&ata_ide_ctrls[ctrl_minor].reqs))
581    {
582
583        ata_queue_msg_t msg;
584
585#ifdef DEBUG
586        uint16_t      val;
587        /*
588         * read IDE_REGISTER_ALTERNATE_STATUS instead IDE_REGISTER_STATUS
589         * to prevent clearing of pending interrupt
590         */
591        ide_controller_read_register(ctrl_minor,
592                                     IDE_REGISTER_ALTERNATE_STATUS,
593                                     &val);
594        if (val & IDE_REGISTER_STATUS_BSY)
595            return;
596#endif
597        ATA_SEND_EVT(msg, ATA_MSG_PROCESS_NEXT_EVT, ctrl_minor, 0);
598    }
599}
600
601
602/* ata_interrupt_handler --
603 *     ATA driver interrrupt handler. If interrrupt happend it mapped it to
604 *     controller (controllerS, if a number of controllers share one int line)
605 *     and generates ATA event(s).
606 *
607 * PARAMETERS:
608 *     vec - interrupt vector
609 *
610 * RETURNS:
611 *     NONE
612 */
613#if defined(ATA_USE_OLD_EXCEPTIONS)
614rtems_isr
615ata_interrupt_handler(rtems_vector_number vec)
616{
617    Chain_Node      *the_node = ((Chain_Control *)(&ata_int_vec[vec]))->first;
618    ata_queue_msg_t  msg;
619    uint16_t         byte; /* emphasize that only 8 low bits is meaningful */
620
621    for ( ; !Chain_Is_tail(&ata_int_vec[vec], the_node) ; )
622    {
623        /* if (1) - is temporary hack - currently I don't know how to identify
624         * controller which asserted interrupt if few controllers share one
625         * interrupt line
626         */
627        if (1)
628        {
629            msg.ctrl_minor = ((ata_int_st_t *)the_node)->ctrl_minor;
630            ide_controller_read_register(msg.ctrl_minor, IDE_REGISTER_STATUS,
631                                         &byte);
632            ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, msg.ctrl_minor, 0);
633        }
634        the_node = the_node->next;
635    }
636}
637#else
638
639void ata_interrupt_handler(rtems_irq_hdl_param handle)
640{
641  int ata_irq_chain_index = (int) handle;
642    Chain_Node      *the_node =
643      ata_irq_chain[ata_irq_chain_index].irq_chain.last;
644    ata_queue_msg_t  msg;
645    uint16_t       byte; /* emphasize that only 8 low bits is meaningful */
646
647
648    for ( ; !Chain_Is_tail(&ata_irq_chain[ata_irq_chain_index].irq_chain,
649                           the_node) ; )
650    {
651        /* if (1) - is temporary hack - currently I don't know how to identify
652         * controller which asserted interrupt if few controllers share one
653         * interrupt line
654         */
655        if (1)
656        {
657            msg.ctrl_minor = ((ata_int_st_t *)the_node)->ctrl_minor;
658            ide_controller_read_register(msg.ctrl_minor, IDE_REGISTER_STATUS,
659                                         &byte);
660            ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, msg.ctrl_minor, 0);
661        }
662        the_node = the_node->next;
663    }
664}
665
666void ata_interrupt_on(const rtems_irq_connect_data *ptr)
667  {
668
669    /* enable ATA device interrupt */
670    ide_controller_write_register(0,
671                                  IDE_REGISTER_DEVICE_CONTROL_OFFSET,
672                                  0x00
673                                 );
674  }
675
676
677void ata_interrupt_off(const rtems_irq_connect_data *ptr)
678  {
679
680    /* disable ATA device interrupt */
681    ide_controller_write_register(0,
682                                  IDE_REGISTER_DEVICE_CONTROL_OFFSET,
683                                  IDE_REGISTER_DEVICE_CONTROL_nIEN
684                                 );
685  }
686
687
688int ata_interrupt_isOn(const rtems_irq_connect_data *ptr)
689  {
690  uint16_t byte; /* emphasize that only 8 low bits is meaningful */
691
692    /* return int. status od ATA device */
693    ide_controller_read_register(0,
694                                IDE_REGISTER_DEVICE_CONTROL_OFFSET,
695                                &byte
696                                );
697
698    return !(byte & IDE_REGISTER_DEVICE_CONTROL_nIEN);
699  }
700
701
702static rtems_irq_connect_data ata_irq_data =
703  {
704
705    0, /* filled out before use... */
706    (rtems_irq_hdl) ata_interrupt_handler,/* filled out before use... */
707    (rtems_irq_hdl_param) NULL,
708    (rtems_irq_enable) ata_interrupt_on,
709    (rtems_irq_disable) ata_interrupt_off,
710    (rtems_irq_is_enabled) ata_interrupt_isOn
711  };
712#endif
713
714/* ata_pio_in_protocol --
715 *     ATA PIO_IN protocol implementation, see specification
716 *
717 * PARAMETERS:
718 *     ctrl_minor - controller identifier
719 *     areq       - ATA request
720 *
721 * RETURNS:
722 *     NONE
723 */
724static inline void
725ata_pio_in_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
726{
727    uint16_t        bs, val;
728    uint8_t         dev;
729    uint32_t        min_val;
730    ata_queue_msg_t msg;
731
732    dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
733           IDE_REGISTER_DEVICE_HEAD_DEV;
734
735    bs = ATA_DEV_INFO(ctrl_minor, dev).current_multiple ?
736         ATA_DEV_INFO(ctrl_minor, dev).current_multiple : 1;
737    min_val = MIN(bs, areq->cnt);
738
739    ide_controller_read_data_block(ctrl_minor, min_val * ATA_SECTOR_SIZE,
740                                   areq->breq->bufs, &areq->cbuf, &areq->pos);
741
742    areq->cnt -= min_val;
743    if (areq->cnt == 0)
744    {
745        ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, RTEMS_SUCCESSFUL);
746    }
747    else if (IDE_Controller_Table[ctrl_minor].int_driven == 0)
748    {
749        do {
750           ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &val);
751        } while (val & IDE_REGISTER_STATUS_BSY);
752
753        ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
754    }
755}
756
757/* ata_pio_out_protocol --
758 *     ATA PIO_OUT protocol implementation, see specification
759 *
760 * PARAMETERS:
761 *     ctrl_minor - controller identifier
762 *     areq       - ATA request
763 *
764 * RETURNS:
765 *     NONE
766 */
767static inline void
768ata_pio_out_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
769{
770    uint16_t        bs, val;
771    uint8_t         dev;
772    uint32_t        min_val;
773    ata_queue_msg_t msg;
774
775    dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
776           IDE_REGISTER_DEVICE_HEAD_DEV;
777
778    bs = ATA_DEV_INFO(ctrl_minor, dev).current_multiple ?
779         ATA_DEV_INFO(ctrl_minor, dev).current_multiple : 1;
780
781    min_val = MIN(bs, areq->cnt);
782
783    if (areq->cnt == 0)
784    {
785        ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, RTEMS_SUCCESSFUL);
786    }
787    else
788    {
789        ide_controller_write_data_block(ctrl_minor, min_val * ATA_SECTOR_SIZE,
790                                        areq->breq->bufs, &areq->cbuf,
791                                        &areq->pos);
792        areq->cnt -= min_val;
793        if (IDE_Controller_Table[ctrl_minor].int_driven == 0)
794        {
795            do {
796                ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
797                                             &val);
798            } while (val & IDE_REGISTER_STATUS_BSY);
799
800            ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
801        }
802  }
803}
804
805/* ata_queue_task --
806 *     Task which manages ATA driver events queue.
807 *
808 * PARAMETERS:
809 *     arg - ignored
810 *
811 * RETURNS:
812 *     NONE
813 *
814 * NOTES:
815 *     should be non-preemptive
816 */
817static rtems_task
818ata_queue_task(rtems_task_argument arg)
819{
820    ata_queue_msg_t            msg;
821    uint32_t             size;
822    ata_req_t                 *areq;
823    rtems_device_minor_number  ctrl_minor;
824    uint16_t                   val;
825    uint16_t                   val1;
826    rtems_status_code          rc;
827    ISR_Level                  level;
828
829    while (1)
830    {
831        /* get event which has happend */
832        rc = rtems_message_queue_receive(ata_queue_id, &msg, &size, RTEMS_WAIT,
833                                         RTEMS_NO_TIMEOUT);
834        if (rc != RTEMS_SUCCESSFUL)
835            rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
836
837        /* get controller on which event has happend */
838        ctrl_minor = msg.ctrl_minor;
839
840        /* get current request to the controller */
841        _ISR_Disable(level);
842        areq = (ata_req_t *)(ata_ide_ctrls[ctrl_minor].reqs.first);
843        _ISR_Enable(level);
844
845        switch(msg.type)
846        {
847            case ATA_MSG_PROCESS_NEXT_EVT:
848                /* process next request in the controller queue */
849                ata_process_request(ctrl_minor);
850                break;
851
852            case ATA_MSG_SUCCESS_EVT:
853                /*
854                 * finish processing of current request with successful
855                 * status and start processing of the next request in the
856                 * controller queue
857                 */
858                ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL,
859                                 msg.error);
860                break;
861
862            case ATA_MSG_ERROR_EVT:
863                /*
864                 * finish processing of current request with error
865                 * status and start processing of the next request in the
866                 * controller queue
867                 */
868                ata_request_done(areq, ctrl_minor, RTEMS_UNSATISFIED,
869                                 msg.error);
870                break;
871
872            case ATA_MSG_GEN_EVT:
873                /*
874                 * continue processing of the current request to the
875                 * controller according to current request state and
876                 * ATA protocol
877                 */
878                ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
879                                           &val);
880                /* process error case */
881                if (val & IDE_REGISTER_STATUS_ERR)
882                {
883                    ide_controller_read_register(ctrl_minor,
884                                                 IDE_REGISTER_ERROR,
885                                                 &val);
886                    if (areq->type == ATA_COMMAND_TYPE_NON_DATA)
887                        ata_non_data_request_done(areq, ctrl_minor,
888                                                  RTEMS_UNSATISFIED,
889                                                  RTEMS_IO_ERROR);
890                    else
891                        ata_request_done(areq, ctrl_minor, RTEMS_UNSATISFIED,
892                                         RTEMS_IO_ERROR);
893                    break;
894                }
895
896                switch(areq->type)
897                {
898                    case ATA_COMMAND_TYPE_PIO_IN:
899                        ata_pio_in_protocol(ctrl_minor, areq);
900                        break;
901
902                    case ATA_COMMAND_TYPE_PIO_OUT:
903                        ata_pio_out_protocol(ctrl_minor, areq);
904                        break;
905
906                    case ATA_COMMAND_TYPE_NON_DATA:
907                        ide_controller_read_register(ctrl_minor,
908                                                      IDE_REGISTER_ERROR,
909                                                     &val1);
910                        ata_non_data_request_done(areq, ctrl_minor,
911                                                  RTEMS_SUCCESSFUL,
912                                                  val1);
913                        break;
914
915                    default:
916#ifdef DEBUG
917                        printf("ata_queue_task: non-supported command type\n");
918#endif
919                        ata_request_done(areq, ctrl_minor,
920                                         RTEMS_UNSATISFIED,
921                                         RTEMS_NOT_IMPLEMENTED);
922                        break;
923                }
924                break;
925
926            default:
927                rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
928                break;
929        }
930    }
931}
932
933/* ata_ioctl --
934 *     ATA driver ioctl interface.
935 *
936 * PARAMETERS:
937 *     device - device identifier
938 *     cmd    - command
939 *     argp   - arguments
940 *
941 * RETURNS:
942 *     depend on 'cmd'
943 */
944int
945ata_ioctl(dev_t device, int cmd, void *argp)
946{
947    rtems_status_code         status;
948    rtems_device_minor_number rel_minor;
949
950    rel_minor = (rtems_filesystem_dev_minor_t(device)) /
951                ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE;
952
953    /*
954     * in most cases this means that device 'device' is not an registred ATA
955     * device
956     */
957    if (ata_devs[rel_minor].device == ATA_UNDEFINED_VALUE)
958    {
959        errno = ENODEV;
960        return -1;
961    }
962
963    switch (cmd)
964    {
965        case BLKIO_REQUEST:
966            status = ata_io_data_request(device, (blkdev_request *)argp);
967            break;
968
969        case ATAIO_SET_MULTIPLE_MODE:
970            status = ata_non_data_request(device, cmd, argp);
971            break;
972
973        default:
974            errno = EBADRQC;
975            return -1;
976            break;
977    }
978
979    if (status != RTEMS_SUCCESSFUL)
980    {
981        errno = EIO;
982        return -1;
983    }
984    return 0;
985}
986
987/*
988 * ata_initialize --
989 *     Initializes all ATA devices found on initialized IDE controllers.
990 *
991 * PARAMETERS:
992 *     major - device major number
993 *     minor - device minor number
994 *     args   - arguments
995 *
996 * RETURNS:
997 *     RTEMS_SUCCESSFUL on success, or error code if
998 *     error occured
999 */
1000rtems_device_driver
1001ata_initialize(rtems_device_major_number major,
1002               rtems_device_minor_number minor_arg,
1003               void *args)
1004{
1005    uint32_t           ctrl_minor;
1006    rtems_status_code  status;
1007    ata_req_t          areq;
1008    blkdev_request1    breq;
1009    uint8_t            i, dev = 0;
1010    uint16_t          *buffer;
1011    uint16_t           ec;
1012    char               name[ATA_MAX_NAME_LENGTH];
1013    dev_t              device;
1014    ata_int_st_t      *int_st;
1015
1016#if defined(ATA_USE_OLD_EXCEPTIONS)
1017    rtems_isr_entry    old_isr;
1018#else
1019    int ata_irq_chain_use;
1020#endif
1021
1022    if (ata_initialized)
1023        return RTEMS_SUCCESSFUL;
1024
1025    /* initialization of disk devices library */
1026    status = rtems_disk_io_initialize();
1027    if (status != RTEMS_SUCCESSFUL)
1028        return status;
1029
1030    /* create queue for asynchronous requests handling */
1031    status = rtems_message_queue_create(
1032                 rtems_build_name('A', 'T', 'A', 'Q'),
1033                 ATA_DRIVER_MESSAGE_QUEUE_SIZE,
1034                 sizeof(ata_queue_msg_t),
1035                 RTEMS_FIFO | RTEMS_LOCAL,
1036                 &ata_queue_id);
1037    if (status != RTEMS_SUCCESSFUL)
1038    {
1039        rtems_disk_io_done();
1040        return status;
1041    }
1042
1043    /*
1044     * create ATA driver task, see comments for task implementation for
1045     * details
1046     */
1047    status = rtems_task_create(
1048                 rtems_build_name ('A', 'T', 'A', 'T'),
1049                 ((ata_driver_task_priority > 0)
1050                  ? ata_driver_task_priority
1051                  : ATA_DRIVER_TASK_DEFAULT_PRIORITY),
1052                 ATA_DRIVER_TASK_STACK_SIZE,
1053                 RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_ASR |
1054                 RTEMS_INTERRUPT_LEVEL(0),
1055                 RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
1056                 &ata_task_id);
1057    if (status != RTEMS_SUCCESSFUL)
1058    {
1059        rtems_message_queue_delete(ata_queue_id);
1060        rtems_disk_io_done();
1061        return status;
1062    }
1063
1064    /*
1065     * start ATA driver task. Actually the task will not start immediately -
1066     * it will start only after multitasking support will be started
1067     */
1068    status = rtems_task_start(ata_task_id, ata_queue_task, 0);
1069    if (status != RTEMS_SUCCESSFUL)
1070    {
1071        rtems_task_delete(ata_task_id);
1072        rtems_message_queue_delete(ata_queue_id);
1073        rtems_disk_io_done();
1074        return status;
1075    }
1076
1077    buffer = (uint16_t*)malloc(ATA_SECTOR_SIZE);
1078    if (buffer == NULL)
1079    {
1080        rtems_task_delete(ata_task_id);
1081        rtems_message_queue_delete(ata_queue_id);
1082        rtems_disk_io_done();
1083        return RTEMS_NO_MEMORY;
1084    }
1085
1086    ata_devs_number = 0;
1087
1088    for (i = 0; i < (2 * IDE_CTRL_MAX_MINOR_NUMBER); i++)
1089        ata_devs[i].device = ATA_UNDEFINED_VALUE;
1090
1091#if defined(ATA_USE_OLD_EXCEPTIONS)
1092    /* prepare ATA driver for handling  interrupt driven devices */
1093    for (i = 0; i < ATA_MAX_RTEMS_INT_VEC_NUMBER; i++)
1094        Chain_Initialize_empty(&ata_int_vec[i]);
1095#else
1096    for (i = 0; i < ATA_IRQ_CHAIN_MAX_CNT; i++) {
1097      Chain_Initialize_empty(&(ata_irq_chain[i].irq_chain));
1098    }
1099#endif
1100
1101    /*
1102     * during ATA driver initialization EXECUTE DEVICE DIAGNOSTIC and
1103     * IDENTIFY DEVICE ATA command should be issued; for these purposes ATA
1104     * requests should be formed; ATA requests contain block device request,
1105     * so form block device request first
1106     */
1107    memset(&breq, 0, sizeof(blkdev_request1));
1108    breq.req.req_done = NULL;
1109    breq.req.done_arg = &breq;
1110    breq.req.bufnum = 1;
1111    breq.req.count = 1;
1112    breq.req.bufs[0].length = ATA_SECTOR_SIZE;
1113    breq.req.bufs[0].buffer = buffer;
1114
1115    /*
1116     * for each presented IDE controller execute EXECUTE DEVICE DIAGNOSTIC
1117     * ATA command; for each found device execute IDENTIFY DEVICE ATA
1118     * command
1119     */
1120    for (ctrl_minor = 0; ctrl_minor < IDE_Controller_Count; ctrl_minor++)
1121    if (IDE_Controller_Table[ctrl_minor].status == IDE_CTRL_INITIALIZED)
1122    {
1123        Chain_Initialize_empty(&ata_ide_ctrls[ctrl_minor].reqs);
1124
1125        if (IDE_Controller_Table[ctrl_minor].int_driven == TRUE)
1126        {
1127            int_st = malloc(sizeof(ata_int_st_t));
1128            if (int_st == NULL)
1129            {
1130                free(buffer);
1131                rtems_task_delete(ata_task_id);
1132                rtems_message_queue_delete(ata_queue_id);
1133                rtems_disk_io_done();
1134                return RTEMS_NO_MEMORY;
1135            }
1136
1137            int_st->ctrl_minor = ctrl_minor;
1138#if defined(ATA_USE_OLD_EXCEPTIONS)
1139            status = rtems_interrupt_catch(
1140                         ata_interrupt_handler,
1141                         IDE_Controller_Table[ctrl_minor].int_vec,
1142                         &old_isr);
1143#else
1144            /*
1145             * FIXME: check existing entries. if they use the same
1146             * IRQ name, then append int_st to respective chain
1147             * otherwise, use new ata_irq_chain entry
1148             */
1149            ata_irq_chain_use = -1;
1150            for (i = 0;
1151                 ((i < ata_irq_chain_cnt) &&
1152                  (ata_irq_chain_use < 0));i++) {
1153              if (ata_irq_chain[i].name ==
1154                  IDE_Controller_Table[ctrl_minor].int_vec) {
1155                ata_irq_chain_use = i;
1156              }
1157            }
1158            if (ata_irq_chain_use < 0) {
1159              /*
1160               * no match found, try to use new channel entry
1161               */
1162              if (ata_irq_chain_cnt < ATA_IRQ_CHAIN_MAX_CNT) {
1163                ata_irq_chain_use = ata_irq_chain_cnt++;
1164
1165                ata_irq_chain[ata_irq_chain_use].name =
1166                  IDE_Controller_Table[ctrl_minor].int_vec;
1167                ata_irq_data.name   =
1168                  IDE_Controller_Table[ctrl_minor].int_vec;
1169                ata_irq_data.hdl    = ata_interrupt_handler;
1170                ata_irq_data.handle = ctrl_minor;
1171
1172                status = ((0 == BSP_install_rtems_irq_handler(&ata_irq_data))
1173                          ? RTEMS_INVALID_NUMBER
1174                          : RTEMS_SUCCESSFUL);
1175              }
1176              else {
1177                status = RTEMS_TOO_MANY;
1178              }
1179            }
1180#endif
1181            if (status != RTEMS_SUCCESSFUL)
1182            {
1183                free(int_st);
1184                free(buffer);
1185                rtems_task_delete(ata_task_id);
1186                rtems_message_queue_delete(ata_queue_id);
1187                rtems_disk_io_done();
1188                return status;
1189            }
1190#if defined(ATA_USE_OLD_EXCEPTIONS)
1191            Chain_Append(
1192                &ata_int_vec[IDE_Controller_Table[ctrl_minor].int_vec],
1193                &int_st->link);
1194#else
1195            Chain_Append(
1196                &(ata_irq_chain[ata_irq_chain_use].irq_chain),
1197                &int_st->link);
1198#endif
1199
1200            /* disable interrupts */
1201            ide_controller_write_register(ctrl_minor,
1202                                          IDE_REGISTER_DEVICE_CONTROL_OFFSET,
1203                                          IDE_REGISTER_DEVICE_CONTROL_nIEN);
1204        }
1205
1206        /*
1207         * Issue EXECUTE DEVICE DIAGNOSTIC ATA command for explore is
1208         * there any ATA device on the controller.
1209         */
1210        memset(&areq, 0, sizeof(ata_req_t));
1211        areq.type = ATA_COMMAND_TYPE_NON_DATA;
1212        areq.regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
1213        areq.regs.regs[IDE_REGISTER_COMMAND] =
1214                                  ATA_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC;
1215        areq.regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_ERROR);
1216
1217        areq.breq = (blkdev_request *)&breq;
1218
1219        /*
1220         * Process the request. Special processing of requests on
1221         * initialization phase is needed because at this moment there
1222         * is no multitasking enviroment
1223         */
1224        ata_process_request_on_init_phase(ctrl_minor, &areq);
1225
1226        /*
1227         * check status of I/O operation
1228         */
1229        if (breq.req.status != RTEMS_SUCCESSFUL)
1230            continue;
1231
1232        /* disassemble returned diagnostic codes */
1233        if (breq.req.error == ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT)
1234        {
1235            ATA_DEV_INFO(ctrl_minor, 0).present = 1;
1236            ATA_DEV_INFO(ctrl_minor,1).present = 1;
1237        }
1238        else if (breq.req.error == ATA_DEV0_PASSED_DEV1_FAILED)
1239        {
1240            ATA_DEV_INFO(ctrl_minor,0).present = 1;
1241            ATA_DEV_INFO(ctrl_minor,1).present = 0;
1242        }
1243        else if (breq.req.error < ATA_DEV1_PASSED_DEV0_FAILED)
1244        {
1245            ATA_DEV_INFO(ctrl_minor,0).present = 0;
1246            ATA_DEV_INFO(ctrl_minor,1).present = 1;
1247        }
1248        else
1249        {
1250            ATA_DEV_INFO(ctrl_minor, 0).present = 0;
1251            ATA_DEV_INFO(ctrl_minor, 1).present = 0;
1252        }
1253
1254        /* refine the returned codes */
1255        if (ATA_DEV_INFO(ctrl_minor, 1).present != 0)
1256        {
1257            ide_controller_read_register(ctrl_minor, IDE_REGISTER_ERROR, &ec);
1258            if (ec & ATA_DEV1_PASSED_DEV0_FAILED)
1259                ATA_DEV_INFO(ctrl_minor, 1).present = 1;
1260            else
1261                ATA_DEV_INFO(ctrl_minor, 1).present = 0;
1262        }
1263
1264        /* for each found ATA device obtain it configuration */
1265        for (dev = 0; dev < 2; dev++)
1266        if (ATA_DEV_INFO(ctrl_minor, dev).present)
1267        {
1268            /*
1269             * Issue DEVICE IDENTIFY ATA command and get device
1270             * configuration
1271             */
1272            memset(&areq, 0, sizeof(ata_req_t));
1273            areq.type = ATA_COMMAND_TYPE_PIO_IN;
1274            areq.regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
1275            areq.regs.regs[IDE_REGISTER_COMMAND] =
1276                                              ATA_COMMAND_IDENTIFY_DEVICE;
1277            areq.regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_STATUS);
1278            areq.breq = (blkdev_request *)&breq;
1279
1280            areq.cnt = breq.req.count;
1281
1282            areq.regs.regs[IDE_REGISTER_DEVICE_HEAD] |=
1283                                    (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS);
1284
1285            /*
1286             * Process the request. Special processing of requests on
1287             * initialization phase is needed because at this moment there
1288             * is no multitasking enviroment
1289             */
1290            ata_process_request_on_init_phase(ctrl_minor, &areq);
1291
1292            /* check status of I/O operation */
1293            if (breq.req.status != RTEMS_SUCCESSFUL)
1294                continue;
1295
1296            /*
1297             * Parse returned device configuration and fill in ATA internal
1298             * device info structure
1299             */
1300            ATA_DEV_INFO(ctrl_minor, dev).cylinders =
1301                CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_CLNDS]);
1302            ATA_DEV_INFO(ctrl_minor, dev).heads =
1303                CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_HEADS]);
1304            ATA_DEV_INFO(ctrl_minor, dev).sectors =
1305                CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_SECS]);
1306            ATA_DEV_INFO(ctrl_minor, dev).lba_sectors =
1307                (CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_USR_SECS0]) << 16) +
1308                 CF_LE_W(buffer[ATA_IDENT_WORD_NUM_OF_USR_SECS1]);
1309            ATA_DEV_INFO(ctrl_minor, dev).lba_avaible =
1310                (CF_LE_W(buffer[ATA_IDENT_WORD_CAPABILITIES]) >> 9) & 0x1;
1311            ATA_DEV_INFO(ctrl_minor, dev).max_multiple =
1312                (uint8_t) (CF_LE_W(buffer[ATA_IDENT_WORD_RW_MULT]));
1313            ATA_DEV_INFO(ctrl_minor, dev).current_multiple =
1314                (CF_LE_W(buffer[ATA_IDENT_WORD_MULT_SECS]) & 0x100) ?
1315                (uint8_t)(CF_LE_W(buffer[ATA_IDENT_WORD_MULT_SECS])) :
1316                 0;
1317
1318            if ((CF_LE_W(buffer[ATA_IDENT_WORD_FIELD_VALIDITY]) &
1319                 ATA_IDENT_BIT_VALID) == 0) {
1320              /* no "supported modes" info -> use default */
1321              ATA_DEV_INFO(ctrl_minor, dev).mode_active = ATA_MODES_PIO3;
1322            }
1323            else {
1324              ATA_DEV_INFO(ctrl_minor, dev).modes_available =
1325                ((CF_LE_W(buffer[64]) & 0x1) ? ATA_MODES_PIO3 : 0) |
1326                ((CF_LE_W(buffer[64]) & 0x2) ? ATA_MODES_PIO4 : 0) |
1327                ((CF_LE_W(buffer[63]) & 0x1) ? ATA_MODES_DMA0 : 0) |
1328                ((CF_LE_W(buffer[63]) & 0x2) ?
1329                 ATA_MODES_DMA0 | ATA_MODES_DMA1 : 0) |
1330                ((CF_LE_W(buffer[63]) & 0x4) ?
1331                 ATA_MODES_DMA0 | ATA_MODES_DMA1 | ATA_MODES_DMA2 : 0);
1332              if (ATA_DEV_INFO(ctrl_minor, dev).modes_available == 0)
1333                continue;
1334              /*
1335               * choose most appropriate ATA device data I/O speed supported
1336               * by the controller
1337               */
1338              status = ide_controller_config_io_speed(
1339                ctrl_minor,
1340                ATA_DEV_INFO(ctrl_minor, dev).modes_available);
1341              if (status != RTEMS_SUCCESSFUL)
1342                continue;
1343            }
1344            /*
1345             * Ok, let register new ATA device in the system
1346             */
1347            ata_devs[ata_devs_number].ctrl_minor = ctrl_minor;
1348            ata_devs[ata_devs_number].device = dev;
1349
1350            /* The space leaves a hole for the character. */
1351            strcpy(name, "/dev/hd ");
1352            name[7] = 'a' + 2 * ctrl_minor + dev;
1353
1354            device = rtems_filesystem_make_dev_t(
1355                         major,
1356                         (ata_devs_number *
1357                          ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE));
1358
1359            status = rtems_disk_create_phys(device, ATA_SECTOR_SIZE,
1360                ATA_DEV_INFO(ctrl_minor, dev).lba_avaible ?
1361                ATA_DEV_INFO(ctrl_minor, dev).lba_sectors :
1362                (ATA_DEV_INFO(ctrl_minor, dev).heads *
1363                 ATA_DEV_INFO(ctrl_minor, dev).cylinders *
1364                 ATA_DEV_INFO(ctrl_minor, dev).sectors),
1365                (block_device_ioctl) ata_ioctl, name);
1366            if (status != RTEMS_SUCCESSFUL)
1367            {
1368                ata_devs[ata_devs_number].device = ATA_UNDEFINED_VALUE;
1369                continue;
1370            }
1371            ata_devs_number++;
1372        }
1373        if (IDE_Controller_Table[ctrl_minor].int_driven == TRUE)
1374        {
1375            ide_controller_write_register(ctrl_minor,
1376                                          IDE_REGISTER_DEVICE_CONTROL_OFFSET,
1377                                          0x00);
1378        }
1379    }
1380
1381    free(buffer);
1382    ata_initialized = TRUE;
1383    return RTEMS_SUCCESSFUL;
1384}
1385
1386/* ata_process_request_on_init_phase --
1387 *     Process the ATA request during system initialization. Request
1388 *     processing is syncronous and doesn't use multiprocessing enviroment.
1389 *
1390 * PARAMETERS:
1391 *     ctrl_minor - controller identifier
1392 *     areq       - ATA request
1393 *
1394 * RETURNS:
1395 *     NONE
1396 */
1397static void
1398ata_process_request_on_init_phase(rtems_device_minor_number  ctrl_minor,
1399                                  ata_req_t                 *areq)
1400{
1401    uint16_t           byte;/* emphasize that only 8 low bits is meaningful */
1402    uint8_t            i, dev;
1403    uint16_t           val, val1;
1404    uint16_t           data_bs; /* the number of 512 bytes sectors into one
1405                                 * data block
1406                                 */
1407    assert(areq);
1408
1409    dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
1410           IDE_REGISTER_DEVICE_HEAD_DEV;
1411
1412    data_bs = ATA_DEV_INFO(ctrl_minor, dev).current_multiple ?
1413              ATA_DEV_INFO(ctrl_minor, dev).current_multiple : 1;
1414
1415    ide_controller_write_register(ctrl_minor, IDE_REGISTER_DEVICE_HEAD,
1416                                  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD]);
1417
1418    do {
1419        ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
1420    } while ((byte & IDE_REGISTER_STATUS_BSY) ||
1421             (!(byte & IDE_REGISTER_STATUS_DRDY)));
1422
1423    for (i=0; i< ATA_MAX_CMD_REG_OFFSET; i++)
1424    {
1425        uint32_t   reg = (1 << i);
1426        if (areq->regs.to_write & reg)
1427            ide_controller_write_register(ctrl_minor, i,
1428                                          areq->regs.regs[i]);
1429    }
1430
1431    do {
1432        ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
1433    } while (byte & IDE_REGISTER_STATUS_BSY);
1434
1435    ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &val);
1436    ide_controller_read_register(ctrl_minor, IDE_REGISTER_ERROR, &val1);
1437
1438    if (val & IDE_REGISTER_STATUS_ERR)
1439    {
1440        areq->breq->status = RTEMS_UNSATISFIED;
1441        areq->breq->error = RTEMS_IO_ERROR;
1442        return;
1443    }
1444
1445    switch(areq->type)
1446    {
1447        case ATA_COMMAND_TYPE_PIO_IN:
1448            ide_controller_read_data_block(
1449                ctrl_minor,
1450                MIN(data_bs, areq->cnt) * ATA_SECTOR_SIZE,
1451                areq->breq->bufs, &areq->cbuf,
1452                &areq->pos);
1453
1454            areq->cnt -= MIN(data_bs, areq->cnt);
1455            if (areq->cnt == 0)
1456            {
1457                areq->breq->status = RTEMS_SUCCESSFUL;
1458            }
1459            else
1460            {
1461                /*
1462                 * this shouldn't happend on the initialization
1463                 * phase!
1464                 */
1465                rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
1466            }
1467            break;
1468
1469        case ATA_COMMAND_TYPE_NON_DATA:
1470            areq->breq->status = RTEMS_SUCCESSFUL;
1471            areq->breq->error = val1;
1472            break;
1473
1474        default:
1475#ifdef DEBUG
1476            printf("ata_queue_task: non-supported command type\n");
1477#endif
1478            areq->breq->status = RTEMS_UNSATISFIED;
1479            areq->breq->error = RTEMS_NOT_IMPLEMENTED;
1480            break;
1481    }
1482}
Note: See TracBrowser for help on using the repository browser.