mirror of
https://git.rtems.org/rtems-docs/
synced 2025-05-14 16:39:52 +08:00
187 lines
7.4 KiB
ReStructuredText
187 lines
7.4 KiB
ReStructuredText
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
|
.. Copyright (C) 1988, 2002 On-Line Applications Research Corporation (OAR)
|
|
|
|
ATA Driver
|
|
**********
|
|
|
|
.. warning::
|
|
|
|
The ATA/IDE Drivers are out of date and should not be used for new BSPs.
|
|
The preferred alternative is to port the ATA/SATA/SCSI/NVMe support from
|
|
FreeBSD to RTEMS using the `libbsd <https://git.rtems.org/rtems-libbsd>`_.
|
|
Ask on the mailing list if you plan to write a driver for an ATA/IDE device.
|
|
|
|
Terms
|
|
=====
|
|
|
|
ATA device - physical device attached to an IDE controller
|
|
|
|
Introduction
|
|
============
|
|
|
|
ATA driver provides generic interface to an ATA device. ATA driver is hardware
|
|
independent implementation of ATA standard defined in working draft "AT
|
|
Attachment Interface with Extensions (ATA-2)" X3T10/0948D revision 4c, March
|
|
18, 1996. ATA Driver based on IDE Controller Driver and may be used for
|
|
computer systems with single IDE controller and with multiple as well. Although
|
|
current implementation has several restrictions detailed below ATA driver
|
|
architecture allows easily extend the driver. Current restrictions are:
|
|
|
|
- Only mandatory (see draft p.29) and two optional (READ/WRITE MULTIPLE)
|
|
commands are implemented
|
|
|
|
- Only PIO mode is supported but both poll and interrupt driven
|
|
|
|
The reference implementation for ATA driver can be found in
|
|
``cpukit/libblock/src/ata.c``.
|
|
|
|
Initialization
|
|
==============
|
|
|
|
The ``ata_initialize`` routine is responsible for ATA driver
|
|
initialization. The main goal of the initialization is to detect and register
|
|
in the system all ATA devices attached to IDE controllers successfully
|
|
initialized by the IDE Controller driver.
|
|
|
|
In the implementation of the driver, the following actions are performed:
|
|
|
|
.. code-block:: c
|
|
|
|
rtems_device_driver ata_initialize(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *arg
|
|
)
|
|
{
|
|
initialize internal ATA driver data structure
|
|
|
|
for each IDE controller successfully initialized by the IDE Controller driver
|
|
if the controller is interrupt driven
|
|
set up interrupt handler
|
|
|
|
obtain information about ATA devices attached to the controller
|
|
with help of EXECUTE DEVICE DIAGNOSTIC command
|
|
|
|
for each ATA device detected on the controller
|
|
obtain device parameters with help of DEVICE IDENTIFY command
|
|
|
|
register new ATA device as new block device in the system
|
|
}
|
|
|
|
Special processing of ATA commands is required because of absence of
|
|
multitasking environment during the driver initialization.
|
|
|
|
Detected ATA devices are registered in the system as physical block devices
|
|
(see libblock library description). Device names are formed based on IDE
|
|
controller minor number device is attached to and device number on the
|
|
controller (0 - Master, 1 - Slave). In current implementation 64 minor numbers
|
|
are reserved for each ATA device which allows to support up to 63 logical
|
|
partitions per device.
|
|
|
|
================ ============= =========== ================
|
|
controller minor device number device name ata device minor
|
|
================ ============= =========== ================
|
|
0 0 hda 0
|
|
0 1 hdb 64
|
|
1 0 hdc 128
|
|
1 1 hdd 172
|
|
... ... ... ...
|
|
================ ============= =========== ================
|
|
|
|
ATA Driver Architecture
|
|
=======================
|
|
|
|
ATA Driver Main Internal Data Structures
|
|
----------------------------------------
|
|
|
|
ATA driver works with ATA requests. ATA request is described by the following
|
|
structure:
|
|
|
|
.. code-block:: c
|
|
|
|
/* ATA request */
|
|
typedef struct ata_req_s {
|
|
Chain_Node link; /* link in requests chain */
|
|
char type; /* request type */
|
|
ata_registers_t regs; /* ATA command */
|
|
uint32_t cnt; /* Number of sectors to be exchanged */
|
|
uint32_t cbuf; /* number of current buffer from breq in use */
|
|
uint32_t pos; /* current position in 'cbuf' */
|
|
blkdev_request *breq; /* blkdev_request which corresponds to the ata request */
|
|
rtems_id sema; /* semaphore which is used if synchronous
|
|
* processing of the ata request is required */
|
|
rtems_status_code status; /* status of ata request processing */
|
|
int error; /* error code */
|
|
} ata_req_t;
|
|
|
|
ATA driver supports separate ATA requests queues for each IDE controller (one
|
|
queue per controller). The following structure contains information about
|
|
controller's queue and devices attached to the controller:
|
|
|
|
.. code-block:: c
|
|
|
|
/*
|
|
* This structure describes controller state, devices configuration on the
|
|
* controller and chain of ATA requests to the controller.
|
|
*/
|
|
typedef struct ata_ide_ctrl_s {
|
|
bool present; /* controller state */
|
|
ata_dev_t device[2]; /* ata devices description */
|
|
Chain_Control reqs; /* requests chain */
|
|
} ata_ide_ctrl_t;
|
|
|
|
Driver uses array of the structures indexed by the controllers minor number.
|
|
|
|
The following structure allows to map an ATA device to the pair (IDE controller
|
|
minor number device is attached to, device number on the controller):
|
|
|
|
.. code-block:: c
|
|
|
|
/*
|
|
* Mapping of RTEMS ATA devices to the following pairs:
|
|
* (IDE controller number served the device, device number on the controller)
|
|
*/
|
|
typedef struct ata_ide_dev_s {
|
|
int ctrl_minor;/* minor number of IDE controller serves RTEMS ATA device */
|
|
int device; /* device number on IDE controller (0 or 1) */
|
|
} ata_ide_dev_t;
|
|
|
|
Driver uses array of the structures indexed by the ATA devices minor number.
|
|
|
|
ATA driver defines the following internal events:
|
|
|
|
.. code-block:: c
|
|
|
|
/* ATA driver events */
|
|
typedef enum ata_msg_type_s {
|
|
ATA_MSG_GEN_EVT = 1, /* general event */
|
|
ATA_MSG_SUCCESS_EVT, /* success event */
|
|
ATA_MSG_ERROR_EVT, /* error event */
|
|
ATA_MSG_PROCESS_NEXT_EVT /* process next ata request event */
|
|
} ata_msg_type_t;
|
|
|
|
Brief ATA Driver Core Overview
|
|
------------------------------
|
|
|
|
All ATA driver functionality is available via ATA driver ioctl. Current
|
|
implementation supports only two ioctls: ``BLKIO_REQUEST`` and
|
|
``ATAIO_SET_MULTIPLE_MODE``. Each ATA driver ``ioctl()`` call generates an ATA
|
|
request which is appended to the appropriate controller queue depending on ATA
|
|
device the request belongs to. If appended request is single request in the
|
|
controller's queue then ATA driver event is generated.
|
|
|
|
ATA driver task which manages queue of ATA driver events is core of ATA
|
|
driver. In current driver version queue of ATA driver events implemented as
|
|
RTEMS message queue. Each message contains event type, IDE controller minor
|
|
number on which event happened and error if an error occurred. Events may be
|
|
generated either by ATA driver ioctl call or by ATA driver task itself. Each
|
|
time ATA driver task receives an event it gets controller minor number from
|
|
event, takes first ATA request from controller queue and processes it depending
|
|
on request and event types. An ATA request processing may also includes sending
|
|
of several events. If ATA request processing is finished the ATA request is
|
|
removed from the controller queue. Note, that in current implementation maximum
|
|
one event per controller may be queued at any moment of the time.
|
|
|
|
(This part seems not very clear, hope I rewrite it soon)
|