Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:04

0001 /*
0002  * ata.c
0003  *
0004  * ATA RTEMS driver. ATA driver is hardware independant implementation of
0005  * ATA-2 standard, working draft X3T10/0948D, revision 4c. ATA driver bases
0006  * on RTEMS IDE controller driver.
0007  *
0008  * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
0009  * Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
0010  *
0011  * The license and distribution terms for this file may be
0012  * found in the file LICENSE in this distribution or at
0013  * http://www.rtems.org/license/LICENSE.
0014  *
0015  */
0016 #include <errno.h>
0017 #include <rtems/chain.h>
0018 #include <assert.h>
0019 #include <string.h> /* for "memset" declaration */
0020 
0021 #include <rtems/blkdev.h>
0022 #include <libchip/ide_ctrl_io.h>
0023 #include <libchip/ide_ctrl_cfg.h>
0024 #include <libchip/ata_internal.h>
0025 #include <libchip/ata.h>
0026 
0027 #define ATA_DEBUG 0
0028 
0029 #if ATA_DEBUG
0030 #include <stdio.h>
0031 bool ata_trace;
0032 #define ata_printf if (ata_trace) printf
0033 #endif
0034 
0035 #if CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE
0036 #include <rtems/irq.h>
0037 #define ATA_IRQ_CHAIN_MAX_CNT 4 /* support up to 4 ATA devices */
0038 typedef struct {
0039   rtems_irq_number name;
0040   rtems_chain_control irq_chain;
0041 } ata_irq_chain_t;
0042 
0043 ata_irq_chain_t ata_irq_chain[ATA_IRQ_CHAIN_MAX_CNT];
0044 int ata_irq_chain_cnt = 0;
0045 #endif
0046 
0047 static rtems_id ata_lock;
0048 static void
0049 rtems_ata_lock (void)
0050 {
0051   rtems_status_code sc = rtems_semaphore_obtain (ata_lock,
0052                                                  RTEMS_WAIT,
0053                                                  RTEMS_NO_TIMEOUT);
0054   if (sc != RTEMS_SUCCESSFUL)
0055     rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
0056 }
0057 
0058 static void
0059 rtems_ata_unlock (void)
0060 {
0061   rtems_status_code sc = rtems_semaphore_release (ata_lock);
0062   if (sc != RTEMS_SUCCESSFUL)
0063     rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
0064 }
0065 
0066 #define RTEMS_ATA_LOCK_ATTRIBS \
0067   (RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | \
0068    RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL)
0069 
0070 /* FIXME: case if ATA device is FLASH device need more attention */
0071 #undef ATA_DEV_IS_FLASH_DISK
0072 
0073 /* Array indexed by controllers minor number */
0074 static ata_ide_ctrl_t ata_ide_ctrls[IDE_CTRL_MAX_MINOR_NUMBER];
0075 
0076 /*
0077  * Mapping from ATA-minor numbers to
0078  * controller-minor and device on this controller.
0079  */
0080 static ata_ide_dev_t ata_devs[2 * IDE_CTRL_MAX_MINOR_NUMBER];
0081 static int ata_devs_number;
0082 
0083 /* Flag meaning that ATA driver has already been initialized */
0084 static bool ata_initialized = false;
0085 
0086 
0087 /* task and queue used for asynchronous I/O operations */
0088 static rtems_id ata_task_id;
0089 static rtems_id ata_queue_id;
0090 
0091 #if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
0092 /* Mapping of interrupt vectors to devices */
0093 static rtems_chain_control ata_int_vec[ATA_MAX_RTEMS_INT_VEC_NUMBER + 1];
0094 #endif
0095 
0096 static void
0097 ata_process_request(rtems_device_minor_number ctrl_minor);
0098 
0099 static void
0100 ata_add_to_controller_queue(rtems_device_minor_number  ctrl_minor,
0101                             ata_req_t                 *areq);
0102 
0103 /*
0104  * read/write, open/close and ioctl are provided by general block device
0105  * driver. Only initialization and ata-specific ioctl are here.
0106  */
0107 
0108 /* ata_io_data_request --
0109  *     Form read/write request for an ATA device and enqueue it to
0110  *     IDE controller.
0111  *
0112  * PARAMETERS:
0113  *     device - device identifier
0114  *     req    - read/write request from block device driver
0115  *
0116  * RETURNS:
0117  *     RTEMS_SUCCESSFUL on success, or error code if
0118  *     error occured
0119  */
0120 static rtems_status_code
0121 ata_io_data_request(ata_ide_dev_t *ata_dev, rtems_blkdev_request *req)
0122 {
0123     ata_req_t                 *areq; /* ATA request */
0124     rtems_device_minor_number  ctrl_minor;
0125     uint8_t                    dev;
0126 
0127     /* get controller which serves the ATA device */
0128     ctrl_minor = ata_dev->ctrl_minor;
0129 
0130     /* get ATA device identifier (0 or 1) */
0131     dev = ata_dev->device;
0132 
0133     areq = malloc(sizeof(ata_req_t));
0134     if (areq == NULL)
0135     {
0136         rtems_blkdev_request_done(req, RTEMS_NO_MEMORY);
0137         return RTEMS_SUCCESSFUL;
0138     }
0139 
0140     areq->breq = req;
0141     areq->cnt = req->bufnum;
0142     areq->cbuf = 0;
0143     areq->pos = 0;
0144 
0145     /* set up registers masks */
0146     areq->regs.to_write = ATA_REGISTERS_POSITION;
0147     areq->regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_STATUS);
0148 
0149     /* choose device on the controller for which the command will be issued */
0150     areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] =
0151                                     (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS);
0152 
0153     /* Find ATA command and its type */
0154     if (ATA_DEV_INFO(ctrl_minor, dev).mode_active & ATA_MODES_DMA)
0155     {
0156         /* XXX: never has been tested */
0157         areq->type = ATA_COMMAND_TYPE_DMA;
0158         if (req->req == RTEMS_BLKDEV_REQ_READ)
0159             areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_READ_DMA;
0160         else
0161             areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_WRITE_DMA;
0162     }
0163     else
0164     {
0165         if (req->req == RTEMS_BLKDEV_REQ_READ)
0166         {
0167             areq->type = ATA_COMMAND_TYPE_PIO_IN;
0168             areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_READ_SECTORS;
0169 #if ATA_DEBUG
0170             ata_printf("ata_io_data_request: type: READ: %lu, %lu cmd:%02x\n",
0171                        req->bufs[0].block, req->bufnum,
0172                        areq->regs.regs[IDE_REGISTER_COMMAND]);
0173 #endif
0174         }
0175         else
0176         {
0177             areq->type = ATA_COMMAND_TYPE_PIO_OUT;
0178             areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_WRITE_SECTORS;
0179 #if ATA_DEBUG
0180             ata_printf("ata_io_data_request: type: WRITE: %lu, %lu cmd:%02x\n",
0181                        req->bufs[0].block, req->bufnum,
0182                        areq->regs.regs[IDE_REGISTER_COMMAND]);
0183 #endif
0184         }
0185     }
0186 
0187     /*
0188      * Fill position registers
0189      */
0190     if (ATA_DEV_INFO(ctrl_minor, dev).lba_avaible)
0191     {
0192         uint32_t start = req->bufs[0].block;
0193         areq->regs.regs[IDE_REGISTER_LBA0] = (uint8_t)start;
0194         areq->regs.regs[IDE_REGISTER_LBA1] = (uint8_t)(start >> 8);
0195         areq->regs.regs[IDE_REGISTER_LBA2] = (uint8_t)(start >> 16);
0196         /* Set as the head register write above */
0197         areq->regs.regs[IDE_REGISTER_LBA3] |= (uint8_t) (start >> 24);
0198         areq->regs.regs[IDE_REGISTER_LBA3] |= IDE_REGISTER_LBA3_L;
0199     }
0200     else
0201     {
0202         uint32_t   count = req->bufs[0].block;
0203 
0204         areq->regs.regs[IDE_REGISTER_SECTOR_NUMBER] =
0205                         (count % ATA_DEV_INFO(ctrl_minor, dev).sectors) + 1;
0206 
0207         /* now count = number of tracks: */
0208         count /= ATA_DEV_INFO(ctrl_minor, dev).sectors;
0209         areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] |=
0210                           (count / ATA_DEV_INFO(ctrl_minor, dev).cylinders);
0211 
0212         /* now count = number of cylinders */
0213         count %= ATA_DEV_INFO(ctrl_minor, dev).cylinders;
0214         areq->regs.regs[IDE_REGISTER_CYLINDER_LOW] = (uint8_t)count;
0215         areq->regs.regs[IDE_REGISTER_CYLINDER_HIGH] = (uint8_t)(count >> 8);
0216         areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &=
0217                                                 ~IDE_REGISTER_DEVICE_HEAD_L;
0218     }
0219 
0220     /*
0221      * Fill sector count register. We have a number of buffers (bufnum) which
0222      * can be of a specific length (bufs[0].length / ATA_SECTOR_SIZE).
0223      */
0224     areq->regs.regs[IDE_REGISTER_SECTOR_COUNT] =
0225       areq->breq->bufnum * (areq->breq->bufs[0].length / ATA_SECTOR_SIZE);
0226 
0227     /* add request to the queue of awaiting requests to the controller */
0228     ata_add_to_controller_queue(ctrl_minor, areq);
0229 
0230     return RTEMS_SUCCESSFUL;
0231 }
0232 
0233 /* ata_non_data_request --
0234  *     Form and serve request of NON DATA type for an ATA device.
0235  *     Processing of NON DATA request is SYNChronous operation.
0236  *
0237  * PARAMETERS:
0238  *     device - device identifier
0239  *     cmd    - command
0240  *     argp   - arguments for command
0241  *
0242  * RETURNS:
0243  *     RTEMS_SUCCESSFUL on success, or error code if
0244  *     error occured
0245  */
0246 static rtems_status_code
0247 ata_non_data_request(ata_ide_dev_t *ata_dev, uint32_t cmd, void *argp)
0248 {
0249     rtems_status_code          rc;
0250     ata_req_t                 *areq;       /* ATA request */
0251     rtems_device_minor_number  ctrl_minor;
0252     uint8_t                    dev;
0253     ata_queue_msg_t            msg;
0254 
0255     /* get controller which serves the ATA device */
0256     ctrl_minor = ata_dev->ctrl_minor;
0257 
0258     /* get ATA device identifier (0 or 1) */
0259     dev = ata_dev->device;
0260 
0261     /* form the request */
0262     areq = malloc(sizeof(ata_req_t));
0263     if (areq == NULL)
0264     {
0265         return RTEMS_NO_MEMORY;
0266     }
0267     memset(areq, 0, sizeof(ata_req_t));
0268 
0269     areq->type = ATA_COMMAND_TYPE_NON_DATA;
0270     areq->regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
0271     areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] |=
0272                                     (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS);
0273     areq->breq = NULL;
0274     areq->regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_ERROR);
0275 
0276     /*
0277      * depending on command fill command register and additional registers
0278      * which are needed for command execution
0279      */
0280     switch(cmd)
0281     {
0282         case ATAIO_SET_MULTIPLE_MODE:
0283             areq->regs.regs[IDE_REGISTER_COMMAND] =
0284                                                 ATA_COMMAND_SET_MULTIPLE_MODE;
0285             areq->regs.to_write |=
0286                                ATA_REGISTERS_VALUE(IDE_REGISTER_SECTOR_COUNT);
0287             areq->regs.regs[IDE_REGISTER_SECTOR_COUNT] = *(uint8_t*)argp;
0288             break;
0289 
0290         default:
0291             free(areq);
0292             return RTEMS_INVALID_NUMBER;
0293             break;
0294     }
0295 
0296     rc = rtems_semaphore_create(rtems_build_name('I', 'D', 'E', 'S'),
0297                                 0,
0298                                 RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE |
0299                                 RTEMS_NO_INHERIT_PRIORITY |
0300                                 RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
0301                                 0,
0302                                 &(areq->sema));
0303     if (rc != RTEMS_SUCCESSFUL)
0304     {
0305         free(areq);
0306         return rc;
0307     }
0308 
0309     ata_add_to_controller_queue(ctrl_minor, areq);
0310 
0311     /* wait for request processing... */
0312     rc = rtems_semaphore_obtain(areq->sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0313     if (rc != RTEMS_SUCCESSFUL)
0314     {
0315         free(areq);
0316         return rc;
0317     }
0318 
0319     rtems_semaphore_delete(areq->sema);
0320 
0321     /*
0322      * if no error occurred and if necessary, update internal ata driver data
0323      * structures to reflect changes (in device configuration, for example)
0324      */
0325     if (areq->status == RTEMS_SUCCESSFUL)
0326     {
0327         switch(cmd)
0328         {
0329             case ATAIO_SET_MULTIPLE_MODE:
0330               /* invalid operation now */
0331             default:
0332                 rc = RTEMS_INVALID_NUMBER;
0333                 break;
0334         }
0335     }
0336     else
0337     {
0338         /* XXX: should be correct error processing: for ex, may be
0339          * ABRT and then we should return RTEMS_NOT_IMPLEMENTED
0340          */
0341         rc = RTEMS_IO_ERROR;
0342     }
0343 
0344     /* tell ata driver that controller ready to serve next request */
0345     ATA_SEND_EVT(msg, ATA_MSG_SUCCESS_EVT, ctrl_minor, 0);
0346 
0347     return rc;
0348 }
0349 
0350 /* ata_process_request --
0351  *     Get first request from controller's queue and process it.
0352  *
0353  * PARAMETERS:
0354  *     ctrl_minor - controller identifier
0355  *
0356  * RETURNS:
0357  *     NONE
0358  */
0359 static void
0360 ata_process_request(rtems_device_minor_number ctrl_minor)
0361 {
0362     ata_req_t       *areq;
0363     uint16_t         byte; /* emphasize that only 8 low bits is meaningful */
0364     ata_queue_msg_t  msg;
0365     uint8_t          i;
0366 #if 0
0367     uint8_t          dev;
0368 #endif
0369     uint16_t         val;
0370     ISR_Level        level;
0371 
0372     /* if no requests to controller then do nothing */
0373     if (rtems_chain_is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
0374         return;
0375 
0376     /* get first request in the controller's queue */
0377     _ISR_Local_disable(level);
0378     areq = (ata_req_t *)rtems_chain_first(&ata_ide_ctrls[ctrl_minor].reqs);
0379     _ISR_Local_enable(level);
0380 
0381 #if 0
0382     /* get ATA device identifier (0 or 1) */
0383     dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
0384            IDE_REGISTER_DEVICE_HEAD_DEV;
0385 #endif
0386 
0387     /* execute device select protocol */
0388     ide_controller_write_register(ctrl_minor, IDE_REGISTER_DEVICE_HEAD,
0389                                   areq->regs.regs[IDE_REGISTER_DEVICE_HEAD]);
0390 
0391     do {
0392         ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
0393     } while ((byte & IDE_REGISTER_STATUS_BSY) ||
0394              (!(byte & IDE_REGISTER_STATUS_DRDY)));
0395 
0396     /* fill in all  necessary registers on the controller */
0397     for (i=0; i< ATA_MAX_CMD_REG_OFFSET; i++)
0398     {
0399         uint32_t   reg = (1 << i);
0400         if (areq->regs.to_write & reg)
0401             ide_controller_write_register(ctrl_minor, i, areq->regs.regs[i]);
0402     }
0403 
0404 #if ATA_DEBUG
0405     ata_printf("ata_process_request: type: %d\n", areq->type);
0406 #endif
0407 
0408     /* continue to execute ATA protocols depending on type of request */
0409     if (areq->type == ATA_COMMAND_TYPE_PIO_OUT)
0410     {
0411         do {
0412             ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
0413                                          &byte);
0414         } while (byte & IDE_REGISTER_STATUS_BSY);
0415 
0416         if (byte & IDE_REGISTER_STATUS_DRQ)
0417         {
0418             if (areq->cnt)
0419             {
0420               int ccbuf = areq->cbuf;
0421               ide_controller_write_data_block(ctrl_minor,
0422                                               areq->breq->bufs[0].length * areq->cnt,
0423                                               areq->breq->bufs, &areq->cbuf,
0424                                               &areq->pos);
0425               ccbuf = areq->cbuf - ccbuf;
0426               areq->cnt -= ccbuf;
0427             }
0428         }
0429         else
0430         {
0431             if (IDE_Controller_Table[ctrl_minor].int_driven == false)
0432             {
0433                 ide_controller_read_register(
0434                     ctrl_minor,
0435                     IDE_REGISTER_ALTERNATE_STATUS_OFFSET,
0436                     &val);
0437                 ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
0438                                              &val);
0439 
0440                 ATA_SEND_EVT(msg, ATA_MSG_ERROR_EVT, ctrl_minor,
0441                              RTEMS_IO_ERROR);
0442             }
0443         }
0444     }
0445 
0446     if (IDE_Controller_Table[ctrl_minor].int_driven == false)
0447     {
0448         do {
0449             ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
0450                                          &byte);
0451         } while (byte & IDE_REGISTER_STATUS_BSY);
0452 
0453         ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
0454     }
0455 }
0456 
0457 /* ata_request_done --
0458  *     Extract request from controller queue, execute callback if necessary
0459  *     and process next request for the controller.
0460  *
0461  * PARAMETERS:
0462  *     areq       - ATA request
0463  *     ctrl_minor - controller identifier
0464  *     status     - status with which request has been done
0465  *     error      - error, if status != RTEMS_SUCCESSFUL
0466  *
0467  * RETURNS:
0468  *     NONE
0469  */
0470 static inline void
0471 ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor,
0472                  rtems_status_code status)
0473 {
0474     assert(areq);
0475 
0476 #if ATA_DEBUG
0477     ata_printf("ata_request_done: entry\n");
0478 #endif
0479 
0480     ATA_EXEC_CALLBACK(areq, status);
0481     rtems_chain_extract(&areq->link);
0482 
0483     if (!rtems_chain_is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
0484     {
0485         free(areq);
0486         ata_process_request(ctrl_minor);
0487         return;
0488     }
0489 
0490     free(areq);
0491 
0492 #if ATA_DEBUG
0493     ata_printf("ata_request_done: exit\n");
0494 #endif
0495 }
0496 
0497 /* ata_non_data_request_done --
0498  *     Set up request status and release request's semaphore.
0499  *
0500  * PARAMETERS:
0501  *     areq       - ATA request
0502  *     ctrl_minor - controller identifier
0503  *     status     - status with which request has been done
0504  *     error      - error, if status != RTEMS_SUCCESSFUL
0505  *
0506  * RETURNS:
0507  *     NONE
0508  */
0509 static inline void
0510 ata_non_data_request_done(ata_req_t *areq,
0511                           rtems_device_minor_number ctrl_minor,
0512                           rtems_status_code status, int info)
0513 {
0514 #if ATA_DEBUG
0515     ata_printf("ata_non_data_request_done: entry\n");
0516 #endif
0517 
0518     areq->status = status;
0519     areq->info = info;
0520     rtems_semaphore_release(areq->sema);
0521 }
0522 
0523 
0524 /* ata_add_to_controller_queue --
0525  *     Add request to the controller's queue.
0526  *
0527  * PARAMETERS:
0528  *     ctrl_minor - controller identifier
0529  *     areq       - ATA request
0530  *
0531  * RETURNS:
0532  *     NONE
0533  */
0534 static void
0535 ata_add_to_controller_queue(rtems_device_minor_number  ctrl_minor,
0536                             ata_req_t                 *areq)
0537 {
0538     rtems_ata_lock();
0539 
0540     rtems_chain_append(&ata_ide_ctrls[ctrl_minor].reqs, &areq->link);
0541     if (rtems_chain_has_only_one_node(&ata_ide_ctrls[ctrl_minor].reqs))
0542     {
0543 
0544         ata_queue_msg_t msg;
0545 
0546 #if ATA_DEBUG_DOES_NOT_WORK_WITH_QEMU
0547     uint16_t      val;
0548         /*
0549          * read IDE_REGISTER_ALTERNATE_STATUS instead IDE_REGISTER_STATUS
0550          * to prevent clearing of pending interrupt
0551          */
0552         ide_controller_read_register(ctrl_minor,
0553                                      IDE_REGISTER_ALTERNATE_STATUS,
0554                                      &val);
0555         if (val & IDE_REGISTER_STATUS_BSY)
0556             return;
0557 #endif
0558         ATA_SEND_EVT(msg, ATA_MSG_PROCESS_NEXT_EVT, ctrl_minor, 0);
0559     }
0560 
0561     rtems_ata_unlock();
0562 }
0563 
0564 
0565 /* ata_interrupt_handler --
0566  *     ATA driver interrrupt handler. If interrrupt happend it mapped it to
0567  *     controller (controllerS, if a number of controllers share one int line)
0568  *     and generates ATA event(s).
0569  *
0570  * PARAMETERS:
0571  *     vec - interrupt vector
0572  *
0573  * RETURNS:
0574  *     NONE
0575  */
0576 #if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
0577 static rtems_isr ata_interrupt_handler(rtems_vector_number vec)
0578 {
0579     rtems_chain_node *the_node = rtems_chain_first(&ata_int_vec[vec]);
0580     ata_queue_msg_t  msg;
0581     uint16_t         byte; /* emphasize that only 8 low bits is meaningful */
0582 
0583     for ( ; !rtems_chain_is_tail(&ata_int_vec[vec], the_node) ; )
0584     {
0585         /* if (1) - is temporary hack - currently I don't know how to identify
0586          * controller which asserted interrupt if few controllers share one
0587          * interrupt line
0588          */
0589         if (1)
0590         {
0591             msg.ctrl_minor = ((ata_int_st_t *)the_node)->ctrl_minor;
0592             ide_controller_read_register(msg.ctrl_minor, IDE_REGISTER_STATUS,
0593                                          &byte);
0594             ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, msg.ctrl_minor, 0);
0595         }
0596         the_node = the_node->next;
0597     }
0598 }
0599 #else
0600 static void ata_interrupt_handler(rtems_irq_hdl_param handle)
0601 {
0602   uintptr_t ata_irq_chain_index = (uintptr_t) handle;
0603     rtems_chain_node *the_node =
0604       rtems_chain_last(&ata_irq_chain[ata_irq_chain_index].irq_chain);
0605     ata_queue_msg_t  msg;
0606     uint16_t       byte; /* emphasize that only 8 low bits is meaningful */
0607 
0608 
0609     for ( ; !rtems_chain_is_tail(&ata_irq_chain[ata_irq_chain_index].irq_chain,
0610                the_node) ; )
0611     {
0612         /* if (1) - is temporary hack - currently I don't know how to identify
0613          * controller which asserted interrupt if few controllers share one
0614          * interrupt line
0615          */
0616         if (1)
0617         {
0618             msg.ctrl_minor = ((ata_int_st_t *)the_node)->ctrl_minor;
0619             ide_controller_read_register(msg.ctrl_minor, IDE_REGISTER_STATUS,
0620                                          &byte);
0621             ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, msg.ctrl_minor, 0);
0622         }
0623         the_node = the_node->next;
0624     }
0625 }
0626 
0627 static void ata_interrupt_on(const rtems_irq_connect_data *ptr)
0628   {
0629 
0630     /* enable ATA device interrupt */
0631     ide_controller_write_register(0,
0632                                   IDE_REGISTER_DEVICE_CONTROL_OFFSET,
0633                                   0x00
0634                                  );
0635   }
0636 
0637 
0638 static void ata_interrupt_off(const rtems_irq_connect_data *ptr)
0639   {
0640 
0641     /* disable ATA device interrupt */
0642     ide_controller_write_register(0,
0643                                   IDE_REGISTER_DEVICE_CONTROL_OFFSET,
0644                                   IDE_REGISTER_DEVICE_CONTROL_nIEN
0645                                  );
0646   }
0647 
0648 
0649 static int ata_interrupt_isOn(const rtems_irq_connect_data *ptr)
0650   {
0651   uint16_t byte; /* emphasize that only 8 low bits is meaningful */
0652 
0653     /* return int. status od ATA device */
0654     ide_controller_read_register(0,
0655                                 IDE_REGISTER_DEVICE_CONTROL_OFFSET,
0656                                 &byte
0657                                 );
0658 
0659     return !(byte & IDE_REGISTER_DEVICE_CONTROL_nIEN);
0660   }
0661 
0662 
0663 static rtems_irq_connect_data ata_irq_data =
0664   {
0665 
0666     0, /* filled out before use... */
0667     ata_interrupt_handler,/* filled out before use... */
0668     NULL,
0669     ata_interrupt_on,
0670     ata_interrupt_off,
0671     ata_interrupt_isOn
0672   };
0673 #endif
0674 
0675 /* ata_pio_in_protocol --
0676  *     ATA PIO_IN protocol implementation, see specification
0677  *
0678  * PARAMETERS:
0679  *     ctrl_minor - controller identifier
0680  *     areq       - ATA request
0681  *
0682  * RETURNS:
0683  *     NONE
0684  */
0685 static inline void
0686 ata_pio_in_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
0687 {
0688     uint16_t        val;
0689 #if 0
0690     uint8_t         dev;
0691 #endif
0692     ata_queue_msg_t msg;
0693 
0694 #if 0
0695     dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
0696            IDE_REGISTER_DEVICE_HEAD_DEV;
0697 #endif
0698 
0699     if (areq->cnt)
0700     {
0701       int ccbuf = areq->cbuf;
0702       ide_controller_read_data_block(ctrl_minor,
0703                                      areq->breq->bufs[0].length * areq->cnt,
0704                                      areq->breq->bufs, &areq->cbuf, &areq->pos);
0705       ccbuf = areq->cbuf - ccbuf;
0706       areq->cnt -= ccbuf;
0707     }
0708 
0709     if (areq->cnt == 0)
0710     {
0711         ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
0712     }
0713     else if (IDE_Controller_Table[ctrl_minor].int_driven == false)
0714     {
0715         do {
0716            ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &val);
0717         } while (val & IDE_REGISTER_STATUS_BSY);
0718 
0719         ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
0720     }
0721 }
0722 
0723 /* ata_pio_out_protocol --
0724  *     ATA PIO_OUT protocol implementation, see specification
0725  *
0726  * PARAMETERS:
0727  *     ctrl_minor - controller identifier
0728  *     areq       - ATA request
0729  *
0730  * RETURNS:
0731  *     NONE
0732  */
0733 static inline void
0734 ata_pio_out_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
0735 {
0736     uint16_t        val;
0737 #if 0
0738     uint8_t         dev;
0739 #endif
0740     ata_queue_msg_t msg;
0741 
0742 #if ATA_DEBUG
0743     ata_printf("ata_pio_out_protocol:\n");
0744 #endif
0745 
0746 #if 0
0747     dev =  areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
0748            IDE_REGISTER_DEVICE_HEAD_DEV;
0749 #endif
0750 
0751     if (areq->cnt == 0)
0752     {
0753         ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
0754     }
0755     else
0756     {
0757         if (areq->cnt)
0758         {
0759           int ccbuf = areq->cbuf;
0760           ide_controller_write_data_block(ctrl_minor,
0761                                           areq->breq->bufs[0].length * areq->cnt,
0762                                           areq->breq->bufs, &areq->cbuf,
0763                                           &areq->pos);
0764           ccbuf = areq->cbuf - ccbuf;
0765           areq->cnt -= ccbuf;
0766         }
0767         if (IDE_Controller_Table[ctrl_minor].int_driven == false)
0768         {
0769             do {
0770                 ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
0771                                              &val);
0772             } while (val & IDE_REGISTER_STATUS_BSY);
0773 
0774             ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
0775         }
0776   }
0777 }
0778 
0779 /* ata_queue_task --
0780  *     Task which manages ATA driver events queue.
0781  *
0782  * PARAMETERS:
0783  *     arg - ignored
0784  *
0785  * RETURNS:
0786  *     NONE
0787  *
0788  * NOTES:
0789  *     should be non-preemptive
0790  */
0791 static rtems_task
0792 ata_queue_task(rtems_task_argument arg)
0793 {
0794     ata_queue_msg_t            msg;
0795     size_t                     size;
0796     ata_req_t                 *areq;
0797     rtems_device_minor_number  ctrl_minor;
0798     uint16_t                   val;
0799     uint16_t                   val1;
0800     rtems_status_code          rc;
0801     ISR_Level                  level;
0802 
0803     rtems_ata_lock();
0804 
0805     while (1)
0806     {
0807         rtems_ata_unlock();
0808 
0809         /* get event which has happend */
0810         rc = rtems_message_queue_receive(ata_queue_id, &msg, &size, RTEMS_WAIT,
0811                                          RTEMS_NO_TIMEOUT);
0812         if (rc != RTEMS_SUCCESSFUL)
0813             rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
0814 
0815         /* get controller on which event has happend */
0816         ctrl_minor = msg.ctrl_minor;
0817 
0818         rtems_ata_lock();
0819 
0820         /* get current request to the controller */
0821         _ISR_Local_disable(level);
0822         areq = (ata_req_t *)rtems_chain_first(&ata_ide_ctrls[ctrl_minor].reqs);
0823         _ISR_Local_enable(level);
0824 
0825         switch(msg.type)
0826         {
0827             case ATA_MSG_PROCESS_NEXT_EVT:
0828                 /* process next request in the controller queue */
0829                 ata_process_request(ctrl_minor);
0830                 break;
0831 
0832             case ATA_MSG_SUCCESS_EVT:
0833                 /*
0834                  * finish processing of current request with successful
0835                  * status and start processing of the next request in the
0836                  * controller queue
0837                  */
0838                 ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
0839                 break;
0840 
0841             case ATA_MSG_ERROR_EVT:
0842                 /*
0843                  * finish processing of current request with error
0844                  * status and start processing of the next request in the
0845                  * controller queue
0846                  */
0847                 ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
0848                 break;
0849 
0850             case ATA_MSG_GEN_EVT:
0851                 /*
0852                  * continue processing of the current request to the
0853                  * controller according to current request state and
0854                  * ATA protocol
0855                  */
0856                 ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
0857                                            &val);
0858                 /* process error case */
0859                 if (val & IDE_REGISTER_STATUS_ERR)
0860                 {
0861                     ide_controller_read_register(ctrl_minor,
0862                                                  IDE_REGISTER_ERROR,
0863                                                  &val);
0864                     if (val & (IDE_REGISTER_ERROR_UNC |
0865                                IDE_REGISTER_ERROR_ICRC |
0866                                IDE_REGISTER_ERROR_IDNF |
0867                                IDE_REGISTER_ERROR_NM |
0868                                IDE_REGISTER_ERROR_MED))
0869                     {
0870                         if (areq->type == ATA_COMMAND_TYPE_NON_DATA)
0871                             ata_non_data_request_done(areq, ctrl_minor,
0872                                                       RTEMS_UNSATISFIED,
0873                                                       RTEMS_IO_ERROR);
0874                         else
0875                             ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
0876                         break;
0877                     }
0878                 }
0879 
0880                 switch(areq->type)
0881                 {
0882                     case ATA_COMMAND_TYPE_PIO_IN:
0883                         ata_pio_in_protocol(ctrl_minor, areq);
0884                         break;
0885 
0886                     case ATA_COMMAND_TYPE_PIO_OUT:
0887                         ata_pio_out_protocol(ctrl_minor, areq);
0888                         break;
0889 
0890                     case ATA_COMMAND_TYPE_NON_DATA:
0891                         ide_controller_read_register(ctrl_minor,
0892                                                       IDE_REGISTER_ERROR,
0893                                                      &val1);
0894                         ata_non_data_request_done(areq, ctrl_minor,
0895                                                   RTEMS_SUCCESSFUL,
0896                                                   val1);
0897                         break;
0898 
0899                     default:
0900 #if ATA_DEBUG
0901                         ata_printf("ata_queue_task: non-supported command type\n");
0902 #endif
0903                         ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
0904                         break;
0905                 }
0906                 break;
0907 
0908             default:
0909 #if ATA_DEBUG
0910                 ata_printf("ata_queue_task: internal error\n");
0911                 rtems_task_exit();
0912 #endif
0913                 rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
0914                 break;
0915         }
0916     }
0917 }
0918 
0919 /* ata_ioctl --
0920  *     ATA driver ioctl interface.
0921  *
0922  * PARAMETERS:
0923  *     device - device identifier
0924  *     cmd    - command
0925  *     argp   - arguments
0926  *
0927  * RETURNS:
0928  *     depend on 'cmd'
0929  */
0930 static int
0931 ata_ioctl(rtems_disk_device *dd, uint32_t cmd, void *argp)
0932 {
0933     ata_ide_dev_t     *ata_dev = rtems_disk_get_driver_data(dd);
0934     rtems_status_code  status;
0935 
0936     /*
0937      * in most cases this means that device 'device' is not an registred ATA
0938      * device
0939      */
0940     if (ata_dev->device == ATA_UNDEFINED_VALUE)
0941     {
0942         errno = ENODEV;
0943         return -1;
0944     }
0945 
0946     switch (cmd)
0947     {
0948         case RTEMS_BLKIO_REQUEST:
0949             status = ata_io_data_request(ata_dev, (rtems_blkdev_request *)argp);
0950             break;
0951 
0952         case ATAIO_SET_MULTIPLE_MODE:
0953             status = ata_non_data_request(ata_dev, cmd, argp);
0954             break;
0955 
0956         case RTEMS_BLKIO_CAPABILITIES:
0957             *((uint32_t*) argp)  = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
0958             status = RTEMS_SUCCESSFUL;
0959             break;
0960 
0961         default:
0962             return rtems_blkdev_ioctl (dd, cmd, argp);
0963             break;
0964     }
0965 
0966     if (status != RTEMS_SUCCESSFUL)
0967     {
0968         errno = EIO;
0969         return -1;
0970     }
0971     return 0;
0972 }
0973 
0974 static void ata_execute_device_diagnostic(
0975   rtems_device_minor_number ctrl_minor,
0976   uint16_t *sector_buffer
0977 )
0978 {
0979 #if ATA_EXEC_DEVICE_DIAGNOSTIC
0980   ata_req_t areq;
0981   blkdev_request1 breq;
0982 
0983   ata_breq_init(&breq, sector_buffer);
0984 
0985   /*
0986    * Issue EXECUTE DEVICE DIAGNOSTIC ATA command for explore is
0987    * there any ATA device on the controller.
0988    *
0989    * This command may fail and it assumes we have a master device and may
0990    * be a slave device. I think the identify command will handle
0991    * detection better than this method.
0992    */
0993   memset(&areq, 0, sizeof(ata_req_t));
0994   areq.type = ATA_COMMAND_TYPE_NON_DATA;
0995   areq.regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
0996   areq.regs.regs[IDE_REGISTER_COMMAND] =
0997                             ATA_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC;
0998   areq.regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_ERROR);
0999 
1000   areq.breq = (rtems_blkdev_request *)&breq;
1001 
1002   /*
1003    * Process the request. Special processing of requests on
1004    * initialization phase is needed because at this moment there
1005    * is no multitasking enviroment
1006    */
1007   ata_process_request_on_init_phase(ctrl_minor, &areq);
1008 
1009   /*
1010    * check status of I/O operation
1011    */
1012   if (breq.req.status == RTEMS_SUCCESSFUL)
1013   {
1014     /* disassemble returned diagnostic codes */
1015     if (areq.info == ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT)
1016     {
1017       printk("ATA: ctrl:%d: primary, secondary\n", ctrl_minor);
1018       ATA_DEV_INFO(ctrl_minor,0).present = true;
1019       ATA_DEV_INFO(ctrl_minor,1).present = true;
1020     }
1021     else if (areq.info == ATA_DEV0_PASSED_DEV1_FAILED)
1022     {
1023       printk("ATA: ctrl:%d: primary\n", ctrl_minor);
1024       ATA_DEV_INFO(ctrl_minor,0).present = true;
1025       ATA_DEV_INFO(ctrl_minor,1).present = false;
1026     }
1027     else if (areq.info < ATA_DEV1_PASSED_DEV0_FAILED)
1028     {
1029       printk("ATA: ctrl:%d: secondary\n", ctrl_minor);
1030       ATA_DEV_INFO(ctrl_minor,0).present = false;
1031       ATA_DEV_INFO(ctrl_minor,1).present = true;
1032     }
1033     else
1034     {
1035       printk("ATA: ctrl:%d: none\n", ctrl_minor);
1036       ATA_DEV_INFO(ctrl_minor, 0).present = false;
1037       ATA_DEV_INFO(ctrl_minor, 1).present = false;
1038     }
1039 
1040     /* refine the returned codes */
1041     if (ATA_DEV_INFO(ctrl_minor, 1).present)
1042     {
1043       uint16_t ec = 0;
1044       ide_controller_read_register(ctrl_minor, IDE_REGISTER_ERROR, &ec);
1045       if (ec & ATA_DEV1_PASSED_DEV0_FAILED)
1046       {
1047         printk("ATA: ctrl:%d: secondary inforced\n", ctrl_minor);
1048         ATA_DEV_INFO(ctrl_minor, 1).present = true;
1049       }
1050       else
1051       {
1052         printk("ATA: ctrl:%d: secondary removed\n", ctrl_minor);
1053         ATA_DEV_INFO(ctrl_minor, 1).present = false;
1054       }
1055     }
1056   }
1057   else
1058 #endif
1059   {
1060     ATA_DEV_INFO(ctrl_minor, 0).present = true;
1061     ATA_DEV_INFO(ctrl_minor,1).present = true;
1062   }
1063 }
1064 
1065 /*
1066  * ata_initialize --
1067  *     Initializes all ATA devices found on initialized IDE controllers.
1068  *
1069  * PARAMETERS:
1070  *     major - device major number
1071  *     minor - device minor number
1072  *     args   - arguments
1073  *
1074  * RETURNS:
1075  *     RTEMS_SUCCESSFUL on success, or error code if
1076  *     error occured
1077  */
1078 rtems_device_driver
1079 rtems_ata_initialize(rtems_device_major_number major,
1080                      rtems_device_minor_number minor_arg,
1081                      void *args)
1082 {
1083     uint32_t           ctrl_minor;
1084     rtems_status_code  status;
1085     uint16_t          *buffer;
1086     int                i, dev = 0;
1087     char               name[ATA_MAX_NAME_LENGTH];
1088     ata_int_st_t      *int_st;
1089 
1090 #if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
1091     rtems_isr_entry    old_isr;
1092 #else
1093     int ata_irq_chain_use;
1094 #endif
1095 
1096     if (ata_initialized)
1097         return RTEMS_SUCCESSFUL;
1098 
1099     status = rtems_semaphore_create (rtems_build_name ('A', 'T', 'A', 'L'),
1100                                      1, RTEMS_ATA_LOCK_ATTRIBS, 0,
1101                                      &ata_lock);
1102     if (status != RTEMS_SUCCESSFUL)
1103         return status;
1104 
1105     /* create queue for asynchronous requests handling */
1106     status = rtems_message_queue_create(
1107                  rtems_build_name('A', 'T', 'A', 'Q'),
1108                  ATA_DRIVER_MESSAGE_QUEUE_SIZE,
1109                  sizeof(ata_queue_msg_t),
1110                  RTEMS_FIFO | RTEMS_LOCAL,
1111                  &ata_queue_id);
1112     if (status != RTEMS_SUCCESSFUL)
1113     {
1114         return status;
1115     }
1116 
1117     /*
1118      * create ATA driver task, see comments for task implementation for
1119      * details
1120      */
1121     status = rtems_task_create(
1122                  rtems_build_name ('A', 'T', 'A', 'T'),
1123                  ((rtems_ata_driver_task_priority > 0)
1124           ? rtems_ata_driver_task_priority
1125           : ATA_DRIVER_TASK_DEFAULT_PRIORITY),
1126                  ATA_DRIVER_TASK_STACK_SIZE,
1127                  RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR |
1128                  RTEMS_INTERRUPT_LEVEL(0),
1129                  RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
1130                  &ata_task_id);
1131     if (status != RTEMS_SUCCESSFUL)
1132     {
1133         rtems_message_queue_delete(ata_queue_id);
1134         return status;
1135     }
1136 
1137     /*
1138      * start ATA driver task. Actually the task will not start immediately -
1139      * it will start only after multitasking support will be started
1140      */
1141     status = rtems_task_start(ata_task_id, ata_queue_task, 0);
1142     if (status != RTEMS_SUCCESSFUL)
1143     {
1144         rtems_task_delete(ata_task_id);
1145         rtems_message_queue_delete(ata_queue_id);
1146         return status;
1147     }
1148 
1149     buffer = (uint16_t*)malloc(ATA_SECTOR_SIZE);
1150     if (buffer == NULL)
1151     {
1152         rtems_task_delete(ata_task_id);
1153         rtems_message_queue_delete(ata_queue_id);
1154         return RTEMS_NO_MEMORY;
1155     }
1156 
1157     ata_devs_number = 0;
1158 
1159     for (i = 0; i < (2 * IDE_CTRL_MAX_MINOR_NUMBER); i++)
1160         ata_devs[i].device = ATA_UNDEFINED_VALUE;
1161 
1162 #if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
1163     /* prepare ATA driver for handling  interrupt driven devices */
1164     for (i = 0; i < ATA_MAX_RTEMS_INT_VEC_NUMBER; i++)
1165         rtems_chain_initialize_empty(&ata_int_vec[i]);
1166 #else
1167     for (i = 0; i < ATA_IRQ_CHAIN_MAX_CNT; i++) {
1168       rtems_chain_initialize_empty(&(ata_irq_chain[i].irq_chain));
1169     }
1170 #endif
1171 
1172     /*
1173      * during ATA driver initialization EXECUTE DEVICE DIAGNOSTIC and
1174      * IDENTIFY DEVICE ATA command should be issued; for these purposes ATA
1175      * requests should be formed; ATA requests contain block device request,
1176      * so form block device request first
1177      */
1178 
1179     /*
1180      * for each presented IDE controller execute EXECUTE DEVICE DIAGNOSTIC
1181      * ATA command; for each found device execute IDENTIFY DEVICE ATA
1182      * command
1183      */
1184     for (ctrl_minor = 0; ctrl_minor < IDE_Controller_Count; ctrl_minor++)
1185     if (IDE_Controller_Table[ctrl_minor].status == IDE_CTRL_INITIALIZED)
1186     {
1187         rtems_chain_initialize_empty(&ata_ide_ctrls[ctrl_minor].reqs);
1188 
1189         if (IDE_Controller_Table[ctrl_minor].int_driven == true)
1190         {
1191             int_st = malloc(sizeof(ata_int_st_t));
1192             if (int_st == NULL)
1193             {
1194                 free(buffer);
1195                 rtems_task_delete(ata_task_id);
1196                 rtems_message_queue_delete(ata_queue_id);
1197                 return RTEMS_NO_MEMORY;
1198             }
1199 
1200             int_st->ctrl_minor = ctrl_minor;
1201 #if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
1202             status = rtems_interrupt_catch(
1203                          ata_interrupt_handler,
1204                          IDE_Controller_Table[ctrl_minor].int_vec,
1205                          &old_isr);
1206 #else
1207         /*
1208          * FIXME: check existing entries. if they use the same
1209          * IRQ name, then append int_st to respective chain
1210          * otherwise, use new ata_irq_chain entry
1211          */
1212         ata_irq_chain_use = -1;
1213         for (i = 0;
1214          ((i < ata_irq_chain_cnt) &&
1215           (ata_irq_chain_use < 0));i++) {
1216           if (ata_irq_chain[i].name ==
1217           IDE_Controller_Table[ctrl_minor].int_vec) {
1218         ata_irq_chain_use = i;
1219           }
1220         }
1221         if (ata_irq_chain_use < 0) {
1222           /*
1223            * no match found, try to use new channel entry
1224            */
1225           if (ata_irq_chain_cnt < ATA_IRQ_CHAIN_MAX_CNT) {
1226         ata_irq_chain_use = ata_irq_chain_cnt++;
1227 
1228         ata_irq_chain[ata_irq_chain_use].name =
1229           IDE_Controller_Table[ctrl_minor].int_vec;
1230         ata_irq_data.name   =
1231           IDE_Controller_Table[ctrl_minor].int_vec;
1232         ata_irq_data.hdl    = ata_interrupt_handler;
1233         ata_irq_data.handle = (rtems_irq_hdl_param) (uintptr_t) ctrl_minor;
1234 
1235         status = ((0 == BSP_install_rtems_irq_handler(&ata_irq_data))
1236               ? RTEMS_INVALID_NUMBER
1237               : RTEMS_SUCCESSFUL);
1238           }
1239           else {
1240         status = RTEMS_TOO_MANY;
1241           }
1242         }
1243 #endif
1244             if (status != RTEMS_SUCCESSFUL)
1245             {
1246                 free(int_st);
1247                 free(buffer);
1248                 rtems_task_delete(ata_task_id);
1249                 rtems_message_queue_delete(ata_queue_id);
1250                 return status;
1251             }
1252 #if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
1253             rtems_chain_append(
1254                 &ata_int_vec[IDE_Controller_Table[ctrl_minor].int_vec],
1255                 &int_st->link);
1256 #else
1257             rtems_chain_append(
1258         &(ata_irq_chain[ata_irq_chain_use].irq_chain),
1259                 &int_st->link);
1260 #endif
1261 
1262             /* disable interrupts */
1263             ide_controller_write_register(ctrl_minor,
1264                                           IDE_REGISTER_DEVICE_CONTROL_OFFSET,
1265                                           IDE_REGISTER_DEVICE_CONTROL_nIEN);
1266         }
1267 
1268         ata_execute_device_diagnostic(ctrl_minor, buffer);
1269 
1270         /* for each found ATA device obtain it configuration */
1271         for (dev = 0; dev < 2; dev++)
1272         if (ATA_DEV_INFO(ctrl_minor, dev).present)
1273         {
1274             status = ata_identify_device(
1275                ctrl_minor,
1276                dev,
1277                buffer,
1278                &ATA_DEV_INFO(ctrl_minor, dev));
1279             if (status != RTEMS_SUCCESSFUL)
1280                continue;
1281 
1282         /*
1283          * choose most appropriate ATA device data I/O speed supported
1284          * by the controller
1285          */
1286         status = ide_controller_config_io_speed(
1287                ctrl_minor,
1288                ATA_DEV_INFO(ctrl_minor, dev).modes_available);
1289         if (status != RTEMS_SUCCESSFUL)
1290                continue;
1291 
1292             /*
1293              * Ok, let register new ATA device in the system
1294              */
1295             ata_devs[ata_devs_number].ctrl_minor = ctrl_minor;
1296             ata_devs[ata_devs_number].device = dev;
1297 
1298             /* The space leaves a hole for the character. */
1299             strcpy(name, "/dev/hd ");
1300             name[7] = 'a' + 2 * ctrl_minor + dev;
1301 
1302             status = rtems_blkdev_create(name, ATA_SECTOR_SIZE,
1303                 ATA_DEV_INFO(ctrl_minor, dev).lba_avaible ?
1304                 ATA_DEV_INFO(ctrl_minor, dev).lba_sectors :
1305                 (ATA_DEV_INFO(ctrl_minor, dev).heads *
1306                  ATA_DEV_INFO(ctrl_minor, dev).cylinders *
1307                  ATA_DEV_INFO(ctrl_minor, dev).sectors),
1308                 ata_ioctl, &ata_devs[ata_devs_number]);
1309             if (status != RTEMS_SUCCESSFUL)
1310             {
1311                 ata_devs[ata_devs_number].device = ATA_UNDEFINED_VALUE;
1312                 continue;
1313             }
1314             ata_devs_number++;
1315         }
1316         if (IDE_Controller_Table[ctrl_minor].int_driven == true)
1317         {
1318             ide_controller_write_register(ctrl_minor,
1319                                           IDE_REGISTER_DEVICE_CONTROL_OFFSET,
1320                                           0x00);
1321         }
1322     }
1323 
1324     free(buffer);
1325     ata_initialized = true;
1326     return RTEMS_SUCCESSFUL;
1327 }