X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Documentation%2FDocBook%2Flibata.tmpl;h=375ae760dc1ed1112d47874adde4de738ba5079e;hb=7e568e62e9d4674d487cdc11f369e49e56ce6703;hp=41053aed41f474544e6521876abaf3c76dbff93f;hpb=780a87f71841932db8dbb0f1eb9daf3a973a6bd6;p=linux-2.6
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index 41053aed41..375ae760dc 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -58,31 +58,24 @@
-
- Thanks
-
- The bulk of the ATA knowledge comes thanks to long conversations with
- Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA
- and SCSI specifications.
-
-
- Thanks to Alan Cox for pointing out similarities
- between SATA and SCSI, and in general for motivation to hack on
- libata.
-
-
- libata's device detection
- method, ata_pio_devchk, and in general all the early probing was
- based on extensive study of Hale Landis's probe/reset code in his
- ATADRVR driver (www.ata-atapi.com).
-
-
-
libata Driver API
+
+ struct ata_port_operations is defined for every low-level libata
+ hardware driver, and it controls how the low-level driver
+ interfaces with the ATA and SCSI layers.
+
+
+ FIS-based drivers will hook into the system with ->qc_prep() and
+ ->qc_issue() high-level hooks. Hardware which behaves in a manner
+ similar to PCI IDE hardware may utilize several generic helpers,
+ defining at a bare minimum the bus I/O addresses of the ATA shadow
+ register blocks.
+
struct ata_port_operations
+ Disable ATA port
void (*port_disable) (struct ata_port *);
@@ -91,8 +84,19 @@ void (*port_disable) (struct ata_port *);
Called from ata_bus_probe() and ata_bus_reset() error paths,
as well as when unregistering from the SCSI module (rmmod, hot
unplug).
+ This function should do whatever needs to be done to take the
+ port out of use. In most cases, ata_port_disable() can be used
+ as this hook.
+
+
+ Called from ata_bus_probe() on a failed probe.
+ Called from ata_bus_reset() on a failed bus reset.
+ Called from ata_scsi_release().
+
+
+ Post-IDENTIFY device configuration
void (*dev_config) (struct ata_port *, struct ata_device *);
@@ -102,7 +106,17 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
found. Typically used to apply device-specific fixups prior to
issue of SET FEATURES - XFER MODE, and prior to operation.
+
+ Called by ata_device_add() after ata_dev_identify() determines
+ a device is present.
+
+
+ This entry may be specified as NULL in ata_port_operations.
+
+
+
+ Set PIO/DMA mode
void (*set_piomode) (struct ata_port *, struct ata_device *);
void (*set_dmamode) (struct ata_port *, struct ata_device *);
@@ -123,6 +137,9 @@ void (*post_set_mode) (struct ata_port *ap);
->set_dma_mode() is only called if DMA is possible.
+
+
+ Taskfile read/write
void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
@@ -133,8 +150,13 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
registers / DMA buffers. ->tf_read() is called to read the
hardware registers / DMA buffers, to obtain the current set of
taskfile register values.
+ Most drivers for taskfile-based hardware (PIO or MMIO) use
+ ata_tf_load() and ata_tf_read() for these hooks.
+
+
+ ATA command execute
void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
@@ -142,8 +164,13 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
causes an ATA command, previously loaded with
->tf_load(), to be initiated in hardware.
+ Most drivers for taskfile-based hardware use ata_exec_command()
+ for this hook.
+
+
+ Per-cmd ATAPI DMA capabilities filter
int (*check_atapi_dma) (struct ata_queued_cmd *qc);
@@ -153,7 +180,14 @@ Allow low-level driver to filter ATA PACKET commands, returning a status
indicating whether or not it is OK to use DMA for the supplied PACKET
command.
+
+ This hook may be specified as NULL, in which case libata will
+ assume that atapi dma can be supported.
+
+
+
+ Read specific ATA shadow registers
u8 (*check_status)(struct ata_port *ap);
u8 (*check_altstatus)(struct ata_port *ap);
@@ -164,8 +198,19 @@ u8 (*check_err)(struct ata_port *ap);
Reads the Status/AltStatus/Error ATA shadow register from
hardware. On some hardware, reading the Status register has
the side effect of clearing the interrupt condition.
+ Most drivers for taskfile-based hardware use
+ ata_check_status() for this hook.
+
+
+ Note that because this is called from ata_device_add(), at
+ least a dummy function that clears device interrupts must be
+ provided for all drivers, even if the controller doesn't
+ actually have a taskfile status register.
+
+
+ Select ATA device on bus
void (*dev_select)(struct ata_port *ap, unsigned int device);
@@ -174,9 +219,18 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
Issues the low-level hardware command(s) that causes one of N
hardware devices to be considered 'selected' (active and
available for use) on the ATA bus. This generally has no
-meaning on FIS-based devices.
+ meaning on FIS-based devices.
+
+
+ Most drivers for taskfile-based hardware use
+ ata_std_dev_select() for this hook. Controllers which do not
+ support second drives on a port (such as SATA contollers) will
+ use ata_noop_dev_select().
+
+
+ Reset ATA bus
void (*phy_reset) (struct ata_port *ap);
@@ -187,8 +241,13 @@ void (*phy_reset) (struct ata_port *ap);
for device presence (PATA and SATA), typically a soft reset
(SRST) will be performed. Drivers typically use the helper
functions ata_bus_reset() or sata_phy_reset() for this hook.
+ Many SATA drivers use sata_phy_reset() or call it from within
+ their own phy_reset() functions.
+
+
+ Control PCI IDE BMDMA engine
void (*bmdma_setup) (struct ata_queued_cmd *qc);
void (*bmdma_start) (struct ata_queued_cmd *qc);
@@ -207,7 +266,29 @@ PCI IDE DMA Status register.
These hooks are typically either no-ops, or simply not implemented, in
FIS-based drivers.
+
+Most legacy IDE drivers use ata_bmdma_setup() for the bmdma_setup()
+hook. ata_bmdma_setup() will write the pointer to the PRD table to
+the IDE PRD Table Address register, enable DMA in the DMA Command
+register, and call exec_command() to begin the transfer.
+
+
+Most legacy IDE drivers use ata_bmdma_start() for the bmdma_start()
+hook. ata_bmdma_start() will write the ATA_DMA_START flag to the DMA
+Command register.
+
+
+Many legacy IDE drivers use ata_bmdma_stop() for the bmdma_stop()
+hook. ata_bmdma_stop() clears the ATA_DMA_START flag in the DMA
+command register.
+
+
+Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() hook.
+
+
+
+ High-level taskfile hooks
void (*qc_prep) (struct ata_queued_cmd *qc);
int (*qc_issue) (struct ata_queued_cmd *qc);
@@ -227,7 +308,14 @@ int (*qc_issue) (struct ata_queued_cmd *qc);
helper function ata_qc_issue_prot() for taskfile protocol-based
dispatch. More advanced drivers implement their own ->qc_issue.
+
+ ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and
+ ->bmdma_start() as necessary to initiate a transfer.
+
+
+
+ Timeout (error) handling
void (*eng_timeout) (struct ata_port *ap);
@@ -239,6 +327,9 @@ hardware will implement its own error handling code here. IDE BMDMA
drivers may use the helper function ata_eng_timeout().
+
+
+ Hardware interrupt handling
irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
void (*irq_clear) (struct ata_port *);
@@ -250,7 +341,25 @@ void (*irq_clear) (struct ata_port *);
before the interrupt handler is registered, to be sure hardware
is quiet.
+
+ The second argument, dev_instance, should be cast to a pointer
+ to struct ata_host_set.
+
+
+ Most legacy IDE drivers use ata_interrupt() for the
+ irq_handler hook, which scans all ports in the host_set,
+ determines which queued command was active (if any), and calls
+ ata_host_intr(ap,qc).
+
+
+ Most legacy IDE drivers use ata_bmdma_irq_clear() for the
+ irq_clear() hook, which simply clears the interrupt and error
+ flags in the DMA status register.
+
+
+
+ SATA phy read/write
u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
@@ -260,8 +369,12 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
Read and write standard SATA phy registers. Currently only used
if ->phy_reset hook called the sata_phy_reset() helper function.
+ sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE.
+
+
+ Init and shutdown
int (*port_start) (struct ata_port *ap);
void (*port_stop) (struct ata_port *ap);
@@ -272,19 +385,33 @@ void (*host_stop) (struct ata_host_set *host_set);
->port_start() is called just after the data structures for each
port are initialized. Typically this is used to alloc per-port
DMA buffers / tables / rings, enable DMA engines, and similar
- tasks.
+ tasks. Some drivers also use this entry point as a chance to
+ allocate driver-private memory for ap->private_data.
+
+
+ Many drivers use ata_port_start() as this hook or call
+ it from their own port_start() hooks. ata_port_start()
+ allocates space for a legacy IDE PRD table and returns.
->port_stop() is called after ->host_stop(). It's sole function
is to release DMA/memory resources, now that they are no longer
- actively being used.
+ actively being used. Many drivers also free driver-private
+ data from port at this time.
+
+
+ Many drivers use ata_port_stop() as this hook, which frees the
+ PRD table.
->host_stop() is called after all ->port_stop() calls
have completed. The hook must finalize hardware shutdown, release DMA
and other resources, etc.
+ This hook may be specified as NULL, in which case it is not called.
+
+
@@ -314,4 +441,24 @@ and other resources, etc.
!Idrivers/scsi/sata_sil.c
+
+ Thanks
+
+ The bulk of the ATA knowledge comes thanks to long conversations with
+ Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA
+ and SCSI specifications.
+
+
+ Thanks to Alan Cox for pointing out similarities
+ between SATA and SCSI, and in general for motivation to hack on
+ libata.
+
+
+ libata's device detection
+ method, ata_pio_devchk, and in general all the early probing was
+ based on extensive study of Hale Landis's probe/reset code in his
+ ATADRVR driver (www.ata-atapi.com).
+
+
+