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

4.104.114.84.95
Last change on this file since d5ed9e1 was d5ed9e1, checked in by Joel Sherrill <joel.sherrill@…>, on 03/07/06 at 22:05:22

2006-03-07 Thomas Doerfler <Thomas.Doerfler@…>

PR 853/filesystem

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