source: rtems/c/src/libchip/ide/ata.c @ 74172b7d

5
Last change on this file since 74172b7d was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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