NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | ATTRIBUTES | SEE ALSO
#include <specAta.h>
The function or functions documented here may not be used safely in all application contexts with all APIs provided in the ChorusOS 5.0 product.
See API(5FEA) for details.
DDI
Provides an API for the employment of ATA bus Master (SFF8038i) IDE drivers for PCI devices.
The generic ATA bus master driver offers an API for ATA bus drivers (PCI devices) such as the Winbond 83C553, VIA 82C586 and Intel PIIX. The generic ATA driver provides the bulk of an ATA DDI implementation and certain specific functions such as device timing, interrupt management, and controller reset that are need to be implemented in the specific driver. Concerning the Bus Master (DMA) function, the generic ATA driver implements the SFF8038i standard (SFF committee).
At initialization time, the generic ATA driver registers itself in the driver registry (using svDriverRegister). The specific ATA driver (for example, w83c553_ata) scans the driver registry, looking for the generic ATA driver. If found, the specific ATA driver retrieves the generic ATA entry points and identifier (using svDeviceEntry). Then the specific ATA driver invokes the drv_init() function, if not null. The typical driver registry entry for the generic ATA driver should look like this:
static DrvRegEntry genAtaDrv = { GEN_ATA_DRV_NAME, "Generic ATA with Bus Master (PCI)", GEN_ATA_CLASS, /* parent bus class */ GEN_ATA_VERSION_INITIAL, /* required bus version */ NULL, /* probe method */ NULL, /* bind method */ drv_init, /* init method */ NULL /* unload method */ };
The driver sets its parent bus class to GEN_ATA_CLASS and the required bus version to the lowest possible value. As shown above, the generic ATA driver is an init only driver, so the probe, bind and unload methods are set to NULL. These methods can be implemented by the specific ATA driver. This registration allows the specific ATA driver to call the generic ATA driver drv_init() method.
The drv_init() is called with three arguments:
The device node, shared between the generic and specific ATA drivers.
The bus operation structure.
The bus operation Id.
Most of the initialization is done by the generic driver in the drv_init() routine:
A connection with the parent PCI bus is opened.
The device PCI configuration space is mapped on the bus.
The PCI I/O resources are mapped on the bus.
For both channels (ports):
the connected ATA devices are probed,
the bus master (DMA) resources are allocated.
For each device found, the ATA device is initialized and a device node is created in the device tree, populated with standard ATA properties.
A connection with the specific driver is opened.
The specific driver intr_attach() service routine is called.
If the drv_init() method fails, the generic driver stops the initialization and calls the specific driver to stop it.
On return, the specific driver assumes that the device is fully initialized. Otherwise, the specific driver must release the resources and return.
During the connection between the generic and the specific drivers a pointer to specific ATA service routines is given to the generic ATA driver. These routines will be called by the generic ATA driver at various times, and are described in the following structure:
typedef struct specAtaOps { GenAtaVersion version; KnError (*reset) (GenAtaData* ata_data); KnError (*intr_attach) (GenAtaData* ata_data, SpecAtaIntrOps** intr_ops, SpecAtaIntrId* intr_id); void (*intr_detach) (SpecAtaIntrId intr_id); uint32_f (*bm_chunk_size) (GenAtaData* ata_data); void (*tune_device) (GenAtaDev* ata_dev, AtaMode ata_mode); void (*shutdown) (GenAtaData* ata_data); } SpecAtaOps;
At initialization time, the generic ATA driver calls the SpecAtaOps.reset service routine to ask the specific ATA driver to reset the chip. At the time of this call, the PCI I/O resources and PCI device configuration space have been mapped by the generic driver and can be used. The ata_data argument is a pointer to the shared data structure, previously allocated by the specific driver and filled by the generic driver.
On success, a K_OK status code is returned. Otherwise, K_EFAIL is returned.
At the end of initialization time, the generic ATA driver calls the SpecAtaOps.intr_attach service routine to connect interrupt(s) for both channels (ports). At the time of this call, the PCI I/O registers and PCI device configuration space have been mapped by the generic driver and can be used. The ata_data argument is a pointer to the shared data structure, previously allocated by the specific driver and filled by the generic one. The intr_ops output argument contains a pointer to interrupt related service routines described in the following structure:
typedef struct specAtaIntrOps { /* * Mask the interrupt source. * May be called either from base level or from an interrupt handler. */ void (*mask) (SpecAtaIntrId intr_id); /* mask interrupt source */ /* * Unmask the interrupt source previously masked via mask(). * May be called either from base level or from an * interrupt handler. */ void (*unmask) (SpecAtaIntrId intr_id); /* unmask interrupt spource */ } SpecAtaIntrOps;
These methods can be called by the generic ATA driver when interrupt masking/unmasking is needed. Each routine takes as an argument the intr_id returned by the SpecAtaOps.intr_attach routine. Please note that the generic ATA driver calls the SpecAtaOps.intr_attach routine only once. This means that this routine must connect all the interrupts needed for both channels.
On success, a K_OK status code is returned. Otherwyse, K_EFAIL is returned.
Interrupts can be detached by using the SpecAtaOps.intr_detach service routine. The intr_id argument is returned by SpecAtaOps.intr_attach. Typically this is called by the generic ATA driver when a device shutdown is requested.
This routine must return the desired best chunk size, in bytes, usable by the generic ATA driver for Bus Master (DMA) operations. The maximum value must be lower or equal to 64K (SFF8038i standard). The ata_data argument is a pointer to the shared data structure, previously allocated by the specific driver and filled by the generic one.
This service routine is called by the generic ATA driver at initialization time, to set the default transfer mode, and each time a new transfer mode is requested. The ata_data argument is a pointer to the shared data structure, previously allocated by the specific driver and filled by the generic one. At the time of this call, the PCI I/O registers and PCI device configuration space have been mapped by the generic driver and can be used.
When a device shutdown is requested, the generic driver in its internal shutdown routine calls the specific ATA driver SpecAtaOps.intr_detach service routine, and as its last call, the SpecAtaOps.shutdown routine. The generic ATA driver is not allowed to use any data shared with the specific ATA driver, as they may have been freed.
The generic ATA driver can be considered as a PCI driver as it is launched by the specific ATA driver which is a PCI driver and it shares the same device node. For this reason, as well as using ATA properties, the generic ATA driver can use PCI properties.
The table below lists PCI properties which could potentially be used by a generic ATA driver.
Name | Alias | Type |
---|---|---|
"dev_num" | PCI_PROP_DEV_NUM | PciPropDevNum |
"func_num" | PCI_PROP_FUNC_NUM | PciPropFuncNum |
"io-regs" | PCI_PROP_IO_REGS | PciPropIoRegs[] |
The PCI_PROP_DEV_NUM and PCI_PROP_FUNC_NUM properties will be used to map the device's PCI configuration space. The PCI_PROP_IO_REGS could be used to map PCI I/O resources.
Read the ata(9DDI) manual page to get more information about ATA properties.
Services | Base | DKI | Interrupt | Blocking |
---|---|---|---|---|
SpecAtaOps.reset | - | + | - | - |
SpecAtaOps.intr_attach | - | + | - | + |
SpecAtaOps.intr_detach | + | + | - | + |
SpecAtaOps.bm_chunk_size | + | + | + | - |
SpecAtaOps.tune_device | + | + | + | - |
SpecAtaOps.shutdown | - | + | - | - |
See attributes(5) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
---|---|
Interface Stability | Evolving |
svDriverRegister(9DKI), svDriverEntry(9DKI), svDriverRelease(9DKI), pci(9DDI), ata(9DDI), svMemAlloc(9DKI), svMemFree(9DKI)
NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | ATTRIBUTES | SEE ALSO