Commit 6b46c2b1 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

libata.rst: add c function and struct cross-references

Instead of just using text for functions and structs, use
the C domain tags, in order to allow cross-referencing with
the kernel-doc markups.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 0ec88413
...@@ -18,18 +18,19 @@ internals, and a couple sample ATA low-level drivers. ...@@ -18,18 +18,19 @@ internals, and a couple sample ATA low-level drivers.
libata Driver API libata Driver API
================= =================
struct ata_port_operations is defined for every low-level libata :c:type:`struct ata_port_operations <ata_port_operations>`
is defined for every low-level libata
hardware driver, and it controls how the low-level driver interfaces hardware driver, and it controls how the low-level driver interfaces
with the ATA and SCSI layers. with the ATA and SCSI layers.
FIS-based drivers will hook into the system with ->qc_prep() and FIS-based drivers will hook into the system with ``->qc_prep()`` and
->qc_issue() high-level hooks. Hardware which behaves in a manner ``->qc_issue()`` high-level hooks. Hardware which behaves in a manner
similar to PCI IDE hardware may utilize several generic helpers, similar to PCI IDE hardware may utilize several generic helpers,
defining at a bare minimum the bus I/O addresses of the ATA shadow defining at a bare minimum the bus I/O addresses of the ATA shadow
register blocks. register blocks.
struct ata_port_operations :c:type:`struct ata_port_operations <ata_port_operations>`
---------------------------- ----------------------------------------------------------
Disable ATA port Disable ATA port
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
...@@ -39,13 +40,13 @@ Disable ATA port ...@@ -39,13 +40,13 @@ Disable ATA port
void (*port_disable) (struct ata_port *); void (*port_disable) (struct ata_port *);
Called from ata_bus_probe() error path, as well as when unregistering Called from :c:func:`ata_bus_probe` error path, as well as when unregistering
from the SCSI module (rmmod, hot unplug). This function should do 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, whatever needs to be done to take the port out of use. In most cases,
ata_port_disable() can be used as this hook. :c:func:`ata_port_disable` can be used as this hook.
Called from ata_bus_probe() on a failed probe. Called from Called from :c:func:`ata_bus_probe` on a failed probe. Called from
ata_scsi_release(). :c:func:`ata_scsi_release`.
Post-IDENTIFY device configuration Post-IDENTIFY device configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -73,22 +74,22 @@ Set PIO/DMA mode ...@@ -73,22 +74,22 @@ Set PIO/DMA mode
Hooks called prior to the issue of SET FEATURES - XFER MODE command. The Hooks called prior to the issue of SET FEATURES - XFER MODE command. The
optional ->mode_filter() hook is called when libata has built a mask of optional ``->mode_filter()`` hook is called when libata has built a mask of
the possible modes. This is passed to the ->mode_filter() function the possible modes. This is passed to the ``->mode_filter()`` function
which should return a mask of valid modes after filtering those which should return a mask of valid modes after filtering those
unsuitable due to hardware limits. It is not valid to use this interface unsuitable due to hardware limits. It is not valid to use this interface
to add modes. to add modes.
dev->pio_mode and dev->dma_mode are guaranteed to be valid when ``dev->pio_mode`` and ``dev->dma_mode`` are guaranteed to be valid when
->set_piomode() and when ->set_dmamode() is called. The timings for ``->set_piomode()`` and when ``->set_dmamode()`` is called. The timings for
any other drive sharing the cable will also be valid at this point. That any other drive sharing the cable will also be valid at this point. That
is the library records the decisions for the modes of each drive on a is the library records the decisions for the modes of each drive on a
channel before it attempts to set any of them. channel before it attempts to set any of them.
->post_set_mode() is called unconditionally, after the SET FEATURES - ``->post_set_mode()`` is called unconditionally, after the SET FEATURES -
XFER MODE command completes successfully. XFER MODE command completes successfully.
->set_piomode() is always called (if present), but ->set_dma_mode() ``->set_piomode()`` is always called (if present), but ``->set_dma_mode()``
is only called if DMA is possible. is only called if DMA is possible.
Taskfile read/write Taskfile read/write
...@@ -100,11 +101,11 @@ Taskfile read/write ...@@ -100,11 +101,11 @@ Taskfile read/write
void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf); void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
->tf_load() is called to load the given taskfile into hardware ``->tf_load()`` is called to load the given taskfile into hardware
registers / DMA buffers. ->tf_read() is called to read the hardware registers / DMA buffers. ``->tf_read()`` is called to read the hardware
registers / DMA buffers, to obtain the current set of taskfile register registers / DMA buffers, to obtain the current set of taskfile register
values. Most drivers for taskfile-based hardware (PIO or MMIO) use values. Most drivers for taskfile-based hardware (PIO or MMIO) use
ata_sff_tf_load() and ata_sff_tf_read() for these hooks. :c:func:`ata_sff_tf_load` and :c:func:`ata_sff_tf_read` for these hooks.
PIO data read/write PIO data read/write
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
...@@ -117,8 +118,8 @@ PIO data read/write ...@@ -117,8 +118,8 @@ PIO data read/write
All bmdma-style drivers must implement this hook. This is the low-level All bmdma-style drivers must implement this hook. This is the low-level
operation that actually copies the data bytes during a PIO data operation that actually copies the data bytes during a PIO data
transfer. Typically the driver will choose one of transfer. Typically the driver will choose one of
ata_sff_data_xfer_noirq(), ata_sff_data_xfer(), or :c:func:`ata_sff_data_xfer_noirq`, :c:func:`ata_sff_data_xfer`, or
ata_sff_data_xfer32(). :c:func:`ata_sff_data_xfer32`.
ATA command execute ATA command execute
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
...@@ -128,9 +129,9 @@ ATA command execute ...@@ -128,9 +129,9 @@ ATA command execute
void (*sff_exec_command)(struct ata_port *ap, struct ata_taskfile *tf); void (*sff_exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
causes an ATA command, previously loaded with ->tf_load(), to be causes an ATA command, previously loaded with ``->tf_load()``, to be
initiated in hardware. Most drivers for taskfile-based hardware use initiated in hardware. Most drivers for taskfile-based hardware use
ata_sff_exec_command() for this hook. :c:func:`ata_sff_exec_command` for this hook.
Per-cmd ATAPI DMA capabilities filter Per-cmd ATAPI DMA capabilities filter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -159,7 +160,7 @@ Read specific ATA shadow registers ...@@ -159,7 +160,7 @@ Read specific ATA shadow registers
Reads the Status/AltStatus ATA shadow register from hardware. On some Reads the Status/AltStatus ATA shadow register from hardware. On some
hardware, reading the Status register has the side effect of clearing hardware, reading the Status register has the side effect of clearing
the interrupt condition. Most drivers for taskfile-based hardware use the interrupt condition. Most drivers for taskfile-based hardware use
ata_sff_check_status() for this hook. :c:func:`ata_sff_check_status` for this hook.
Write specific ATA shadow register Write specific ATA shadow register
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -184,7 +185,7 @@ Issues the low-level hardware command(s) that causes one of N hardware ...@@ -184,7 +185,7 @@ Issues the low-level hardware command(s) that causes one of N hardware
devices to be considered 'selected' (active and available for use) on devices to be considered 'selected' (active and available for use) on
the ATA bus. This generally has no meaning on FIS-based devices. the ATA bus. This generally has no meaning on FIS-based devices.
Most drivers for taskfile-based hardware use ata_sff_dev_select() for Most drivers for taskfile-based hardware use :c:func:`ata_sff_dev_select` for
this hook. this hook.
Private tuning method Private tuning method
...@@ -222,28 +223,28 @@ Control PCI IDE BMDMA engine ...@@ -222,28 +223,28 @@ Control PCI IDE BMDMA engine
When setting up an IDE BMDMA transaction, these hooks arm When setting up an IDE BMDMA transaction, these hooks arm
(->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop) the (``->bmdma_setup``), fire (``->bmdma_start``), and halt (``->bmdma_stop``) the
hardware's DMA engine. ->bmdma_status is used to read the standard PCI hardware's DMA engine. ``->bmdma_status`` is used to read the standard PCI
IDE DMA Status register. IDE DMA Status register.
These hooks are typically either no-ops, or simply not implemented, in These hooks are typically either no-ops, or simply not implemented, in
FIS-based drivers. FIS-based drivers.
Most legacy IDE drivers use ata_bmdma_setup() for the bmdma_setup() Most legacy IDE drivers use :c:func:`ata_bmdma_setup` for the
hook. ata_bmdma_setup() will write the pointer to the PRD table to the :c:func:`bmdma_setup` hook. :c:func:`ata_bmdma_setup` will write the pointer
IDE PRD Table Address register, enable DMA in the DMA Command register, to the PRD table to the IDE PRD Table Address register, enable DMA in the DMA
and call exec_command() to begin the transfer. Command register, and call :c:func:`exec_command` to begin the transfer.
Most legacy IDE drivers use ata_bmdma_start() for the bmdma_start() Most legacy IDE drivers use :c:func:`ata_bmdma_start` for the
hook. ata_bmdma_start() will write the ATA_DMA_START flag to the DMA :c:func:`bmdma_start` hook. :c:func:`ata_bmdma_start` will write the
Command register. ATA_DMA_START flag to the DMA Command register.
Many legacy IDE drivers use ata_bmdma_stop() for the bmdma_stop() Many legacy IDE drivers use :c:func:`ata_bmdma_stop` for the
hook. ata_bmdma_stop() clears the ATA_DMA_START flag in the DMA :c:func:`bmdma_stop` hook. :c:func:`ata_bmdma_stop` clears the ATA_DMA_START
command register. flag in the DMA command register.
Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() Many legacy IDE drivers use :c:func:`ata_bmdma_status` as the
hook. :c:func:`bmdma_status` hook.
High-level taskfile hooks High-level taskfile hooks
~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -255,19 +256,19 @@ High-level taskfile hooks ...@@ -255,19 +256,19 @@ High-level taskfile hooks
Higher-level hooks, these two hooks can potentially supercede several of Higher-level hooks, these two hooks can potentially supercede several of
the above taskfile/DMA engine hooks. ->qc_prep is called after the the above taskfile/DMA engine hooks. ``->qc_prep`` is called after the
buffers have been DMA-mapped, and is typically used to populate the buffers have been DMA-mapped, and is typically used to populate the
hardware's DMA scatter-gather table. Most drivers use the standard hardware's DMA scatter-gather table. Most drivers use the standard
ata_qc_prep() helper function, but more advanced drivers roll their :c:func:`ata_qc_prep` helper function, but more advanced drivers roll their
own. own.
->qc_issue is used to make a command active, once the hardware and S/G ``->qc_issue`` is used to make a command active, once the hardware and S/G
tables have been prepared. IDE BMDMA drivers use the helper function tables have been prepared. IDE BMDMA drivers use the helper function
ata_qc_issue_prot() for taskfile protocol-based dispatch. More :c:func:`ata_qc_issue_prot` for taskfile protocol-based dispatch. More
advanced drivers implement their own ->qc_issue. advanced drivers implement their own ``->qc_issue``.
ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and :c:func:`ata_qc_issue_prot` calls ``->tf_load()``, ``->bmdma_setup()``, and
->bmdma_start() as necessary to initiate a transfer. ``->bmdma_start()`` as necessary to initiate a transfer.
Exception and probe handling (EH) Exception and probe handling (EH)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -278,7 +279,7 @@ Exception and probe handling (EH) ...@@ -278,7 +279,7 @@ Exception and probe handling (EH)
void (*phy_reset) (struct ata_port *ap); void (*phy_reset) (struct ata_port *ap);
Deprecated. Use ->error_handler() instead. Deprecated. Use ``->error_handler()`` instead.
:: ::
...@@ -286,18 +287,18 @@ Deprecated. Use ->error_handler() instead. ...@@ -286,18 +287,18 @@ Deprecated. Use ->error_handler() instead.
void (*thaw) (struct ata_port *ap); void (*thaw) (struct ata_port *ap);
ata_port_freeze() is called when HSM violations or some other :c:func:`ata_port_freeze` is called when HSM violations or some other
condition disrupts normal operation of the port. A frozen port is not condition disrupts normal operation of the port. A frozen port is not
allowed to perform any operation until the port is thawed, which usually allowed to perform any operation until the port is thawed, which usually
follows a successful reset. follows a successful reset.
The optional ->freeze() callback can be used for freezing the port The optional ``->freeze()`` callback can be used for freezing the port
hardware-wise (e.g. mask interrupt and stop DMA engine). If a port hardware-wise (e.g. mask interrupt and stop DMA engine). If a port
cannot be frozen hardware-wise, the interrupt handler must ack and clear cannot be frozen hardware-wise, the interrupt handler must ack and clear
interrupts unconditionally while the port is frozen. interrupts unconditionally while the port is frozen.
The optional ->thaw() callback is called to perform the opposite of The optional ``->thaw()`` callback is called to perform the opposite of
->freeze(): prepare the port for normal operation once again. Unmask ``->freeze()``: prepare the port for normal operation once again. Unmask
interrupts, start DMA engine, etc. interrupts, start DMA engine, etc.
:: ::
...@@ -305,10 +306,10 @@ interrupts, start DMA engine, etc. ...@@ -305,10 +306,10 @@ interrupts, start DMA engine, etc.
void (*error_handler) (struct ata_port *ap); void (*error_handler) (struct ata_port *ap);
->error_handler() is a driver's hook into probe, hotplug, and recovery ``->error_handler()`` is a driver's hook into probe, hotplug, and recovery
and other exceptional conditions. The primary responsibility of an and other exceptional conditions. The primary responsibility of an
implementation is to call ata_do_eh() or ata_bmdma_drive_eh() with implementation is to call :c:func:`ata_do_eh` or :c:func:`ata_bmdma_drive_eh`
a set of EH hooks as arguments: with a set of EH hooks as arguments:
'prereset' hook (may be NULL) is called during an EH reset, before any 'prereset' hook (may be NULL) is called during an EH reset, before any
other actions are taken. other actions are taken.
...@@ -327,7 +328,7 @@ called to perform the low-level EH reset. ...@@ -327,7 +328,7 @@ called to perform the low-level EH reset.
Perform any hardware-specific actions necessary to finish processing Perform any hardware-specific actions necessary to finish processing
after executing a probe-time or EH-time command via after executing a probe-time or EH-time command via
ata_exec_internal(). :c:func:`ata_exec_internal`.
Hardware interrupt handling Hardware interrupt handling
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -338,20 +339,20 @@ Hardware interrupt handling ...@@ -338,20 +339,20 @@ Hardware interrupt handling
void (*irq_clear) (struct ata_port *); void (*irq_clear) (struct ata_port *);
->irq_handler is the interrupt handling routine registered with the ``->irq_handler`` is the interrupt handling routine registered with the
system, by libata. ->irq_clear is called during probe just before the system, by libata. ``->irq_clear`` is called during probe just before the
interrupt handler is registered, to be sure hardware is quiet. interrupt handler is registered, to be sure hardware is quiet.
The second argument, dev_instance, should be cast to a pointer to The second argument, dev_instance, should be cast to a pointer to
struct ata_host_set. :c:type:`struct ata_host_set <ata_host_set>`.
Most legacy IDE drivers use ata_sff_interrupt() for the irq_handler Most legacy IDE drivers use :c:func:`ata_sff_interrupt` for the irq_handler
hook, which scans all ports in the host_set, determines which queued hook, which scans all ports in the host_set, determines which queued
command was active (if any), and calls ata_sff_host_intr(ap,qc). command was active (if any), and calls ata_sff_host_intr(ap,qc).
Most legacy IDE drivers use ata_sff_irq_clear() for the irq_clear() Most legacy IDE drivers use :c:func:`ata_sff_irq_clear` for the
hook, which simply clears the interrupt and error flags in the DMA :c:func:`irq_clear` hook, which simply clears the interrupt and error flags
status register. in the DMA status register.
SATA phy read/write SATA phy read/write
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
...@@ -365,8 +366,8 @@ SATA phy read/write ...@@ -365,8 +366,8 @@ SATA phy read/write
Read and write standard SATA phy registers. Currently only used if Read and write standard SATA phy registers. Currently only used if
->phy_reset hook called the sata_phy_reset() helper function. sc_reg ``->phy_reset`` hook called the :c:func:`sata_phy_reset` helper function.
is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE. sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE.
Init and shutdown Init and shutdown
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
...@@ -378,21 +379,21 @@ Init and shutdown ...@@ -378,21 +379,21 @@ Init and shutdown
void (*host_stop) (struct ata_host_set *host_set); void (*host_stop) (struct ata_host_set *host_set);
->port_start() is called just after the data structures for each port ``->port_start()`` is called just after the data structures for each port
are initialized. Typically this is used to alloc per-port DMA buffers / are initialized. Typically this is used to alloc per-port DMA buffers /
tables / rings, enable DMA engines, and similar tasks. Some drivers also tables / rings, enable DMA engines, and similar tasks. Some drivers also
use this entry point as a chance to allocate driver-private memory for use this entry point as a chance to allocate driver-private memory for
ap->private_data. ``ap->private_data``.
Many drivers use ata_port_start() as this hook or call it from their Many drivers use :c:func:`ata_port_start` as this hook or call it from their
own port_start() hooks. ata_port_start() allocates space for a legacy own :c:func:`port_start` hooks. :c:func:`ata_port_start` allocates space for
IDE PRD table and returns. a legacy IDE PRD table and returns.
->port_stop() is called after ->host_stop(). Its sole function is to ``->port_stop()`` is called after ``->host_stop()``. Its sole function is to
release DMA/memory resources, now that they are no longer actively being release DMA/memory resources, now that they are no longer actively being
used. Many drivers also free driver-private data from port at this time. used. Many drivers also free driver-private data from port at this time.
->host_stop() is called after all ->port_stop() calls have completed. ``->host_stop()`` is called after all ``->port_stop()`` calls have completed.
The hook must finalize hardware shutdown, release DMA and other The hook must finalize hardware shutdown, release DMA and other
resources, etc. This hook may be specified as NULL, in which case it is resources, etc. This hook may be specified as NULL, in which case it is
not called. not called.
...@@ -407,7 +408,8 @@ exceptions doc first. ...@@ -407,7 +408,8 @@ exceptions doc first.
Origins of commands Origins of commands
------------------- -------------------
In libata, a command is represented with struct ata_queued_cmd or qc. In libata, a command is represented with
:c:type:`struct ata_queued_cmd <ata_queued_cmd>` or qc.
qc's are preallocated during port initialization and repetitively used qc's are preallocated during port initialization and repetitively used
for command executions. Currently only one qc is allocated per port but for command executions. Currently only one qc is allocated per port but
yet-to-be-merged NCQ branch allocates one for each tag and maps each qc yet-to-be-merged NCQ branch allocates one for each tag and maps each qc
...@@ -423,17 +425,17 @@ How commands are issued ...@@ -423,17 +425,17 @@ How commands are issued
----------------------- -----------------------
Internal commands Internal commands
First, qc is allocated and initialized using ata_qc_new_init(). First, qc is allocated and initialized using :c:func:`ata_qc_new_init`.
Although ata_qc_new_init() doesn't implement any wait or retry Although :c:func:`ata_qc_new_init` doesn't implement any wait or retry
mechanism when qc is not available, internal commands are currently mechanism when qc is not available, internal commands are currently
issued only during initialization and error recovery, so no other issued only during initialization and error recovery, so no other
command is active and allocation is guaranteed to succeed. command is active and allocation is guaranteed to succeed.
Once allocated qc's taskfile is initialized for the command to be Once allocated qc's taskfile is initialized for the command to be
executed. qc currently has two mechanisms to notify completion. One executed. qc currently has two mechanisms to notify completion. One
is via qc->complete_fn() callback and the other is completion is via ``qc->complete_fn()`` callback and the other is completion
qc->waiting. qc->complete_fn() callback is the asynchronous path ``qc->waiting``. ``qc->complete_fn()`` callback is the asynchronous path
used by normal SCSI translated commands and qc->waiting is the used by normal SCSI translated commands and ``qc->waiting`` is the
synchronous (issuer sleeps in process context) path used by internal synchronous (issuer sleeps in process context) path used by internal
commands. commands.
...@@ -441,21 +443,21 @@ Internal commands ...@@ -441,21 +443,21 @@ Internal commands
qc is issued. qc is issued.
SCSI commands SCSI commands
All libata drivers use ata_scsi_queuecmd() as hostt->queuecommand All libata drivers use :c:func:`ata_scsi_queuecmd` as
callback. scmds can either be simulated or translated. No qc is ``hostt->queuecommand`` callback. scmds can either be simulated or
involved in processing a simulated scmd. The result is computed translated. No qc is involved in processing a simulated scmd. The
right away and the scmd is completed. result is computed right away and the scmd is completed.
For a translated scmd, ata_qc_new_init() is invoked to allocate a For a translated scmd, :c:func:`ata_qc_new_init` is invoked to allocate a
qc and the scmd is translated into the qc. SCSI midlayer's qc and the scmd is translated into the qc. SCSI midlayer's
completion notification function pointer is stored into completion notification function pointer is stored into
qc->scsidone. ``qc->scsidone``.
qc->complete_fn() callback is used for completion notification. ATA ``qc->complete_fn()`` callback is used for completion notification. ATA
commands use ata_scsi_qc_complete() while ATAPI commands use commands use :c:func:`ata_scsi_qc_complete` while ATAPI commands use
atapi_qc_complete(). Both functions end up calling qc->scsidone to :c:func:`atapi_qc_complete`. Both functions end up calling ``qc->scsidone``
notify upper layer when the qc is finished. After translation is to notify upper layer when the qc is finished. After translation is
completed, the qc is issued with ata_qc_issue(). completed, the qc is issued with :c:func:`ata_qc_issue`.
Note that SCSI midlayer invokes hostt->queuecommand while holding Note that SCSI midlayer invokes hostt->queuecommand while holding
host_set lock, so all above occur while holding host_set lock. host_set lock, so all above occur while holding host_set lock.
...@@ -495,34 +497,34 @@ ATAPI PIO ...@@ -495,34 +497,34 @@ ATAPI PIO
How commands are completed How commands are completed
-------------------------- --------------------------
Once issued, all qc's are either completed with ata_qc_complete() or Once issued, all qc's are either completed with :c:func:`ata_qc_complete` or
time out. For commands which are handled by interrupts, time out. For commands which are handled by interrupts,
ata_host_intr() invokes ata_qc_complete(), and, for PIO tasks, :c:func:`ata_host_intr` invokes :c:func:`ata_qc_complete`, and, for PIO tasks,
pio_task invokes ata_qc_complete(). In error cases, packet_task may pio_task invokes :c:func:`ata_qc_complete`. In error cases, packet_task may
also complete commands. also complete commands.
ata_qc_complete() does the following. :c:func:`ata_qc_complete` does the following.
1. DMA memory is unmapped. 1. DMA memory is unmapped.
2. ATA_QCFLAG_ACTIVE is cleared from qc->flags. 2. ATA_QCFLAG_ACTIVE is cleared from qc->flags.
3. qc->complete_fn() callback is invoked. If the return value of the 3. :c:func:`qc->complete_fn` callback is invoked. If the return value of the
callback is not zero. Completion is short circuited and callback is not zero. Completion is short circuited and
ata_qc_complete() returns. :c:func:`ata_qc_complete` returns.
4. __ata_qc_complete() is called, which does 4. :c:func:`__ata_qc_complete` is called, which does
1. qc->flags is cleared to zero. 1. ``qc->flags`` is cleared to zero.
2. ap->active_tag and qc->tag are poisoned. 2. ``ap->active_tag`` and ``qc->tag`` are poisoned.
3. qc->waiting is cleared & completed (in that order). 3. ``qc->waiting`` is cleared & completed (in that order).
4. qc is deallocated by clearing appropriate bit in ap->qactive. 4. qc is deallocated by clearing appropriate bit in ``ap->qactive``.
So, it basically notifies upper layer and deallocates qc. One exception So, it basically notifies upper layer and deallocates qc. One exception
is short-circuit path in #3 which is used by atapi_qc_complete(). is short-circuit path in #3 which is used by :c:func:`atapi_qc_complete`.
For all non-ATAPI commands, whether it fails or not, almost the same For all non-ATAPI commands, whether it fails or not, almost the same
code path is taken and very little error handling takes place. A qc is code path is taken and very little error handling takes place. A qc is
...@@ -531,33 +533,33 @@ otherwise. ...@@ -531,33 +533,33 @@ otherwise.
However, failed ATAPI commands require more handling as REQUEST SENSE is However, failed ATAPI commands require more handling as REQUEST SENSE is
needed to acquire sense data. If an ATAPI command fails, needed to acquire sense data. If an ATAPI command fails,
ata_qc_complete() is invoked with error status, which in turn invokes :c:func:`ata_qc_complete` is invoked with error status, which in turn invokes
atapi_qc_complete() via qc->complete_fn() callback. :c:func:`atapi_qc_complete` via ``qc->complete_fn()`` callback.
This makes atapi_qc_complete() set scmd->result to This makes :c:func:`atapi_qc_complete` set ``scmd->result`` to
SAM_STAT_CHECK_CONDITION, complete the scmd and return 1. As the SAM_STAT_CHECK_CONDITION, complete the scmd and return 1. As the
sense data is empty but scmd->result is CHECK CONDITION, SCSI midlayer sense data is empty but ``scmd->result`` is CHECK CONDITION, SCSI midlayer
will invoke EH for the scmd, and returning 1 makes ata_qc_complete() will invoke EH for the scmd, and returning 1 makes :c:func:`ata_qc_complete`
to return without deallocating the qc. This leads us to to return without deallocating the qc. This leads us to
ata_scsi_error() with partially completed qc. :c:func:`ata_scsi_error` with partially completed qc.
ata_scsi_error() :c:func:`ata_scsi_error`
------------------ ------------------------
ata_scsi_error() is the current transportt->eh_strategy_handler() :c:func:`ata_scsi_error` is the current ``transportt->eh_strategy_handler()``
for libata. As discussed above, this will be entered in two cases - for libata. As discussed above, this will be entered in two cases -
timeout and ATAPI error completion. This function calls low level libata timeout and ATAPI error completion. This function calls low level libata
driver's eng_timeout() callback, the standard callback for which is driver's :c:func:`eng_timeout` callback, the standard callback for which is
ata_eng_timeout(). It checks if a qc is active and calls :c:func:`ata_eng_timeout`. It checks if a qc is active and calls
ata_qc_timeout() on the qc if so. Actual error handling occurs in :c:func:`ata_qc_timeout` on the qc if so. Actual error handling occurs in
ata_qc_timeout(). :c:func:`ata_qc_timeout`.
If EH is invoked for timeout, ata_qc_timeout() stops BMDMA and If EH is invoked for timeout, :c:func:`ata_qc_timeout` stops BMDMA and
completes the qc. Note that as we're currently in EH, we cannot call completes the qc. Note that as we're currently in EH, we cannot call
scsi_done. As described in SCSI EH doc, a recovered scmd should be scsi_done. As described in SCSI EH doc, a recovered scmd should be
either retried with scsi_queue_insert() or finished with either retried with :c:func:`scsi_queue_insert` or finished with
scsi_finish_command(). Here, we override qc->scsidone with :c:func:`scsi_finish_command`. Here, we override ``qc->scsidone`` with
scsi_finish_command() and calls ata_qc_complete(). :c:func:`scsi_finish_command` and calls :c:func:`ata_qc_complete`.
If EH is invoked due to a failed ATAPI qc, the qc here is completed but If EH is invoked due to a failed ATAPI qc, the qc here is completed but
not deallocated. The purpose of this half-completion is to use the qc as not deallocated. The purpose of this half-completion is to use the qc as
...@@ -565,11 +567,11 @@ place holder to make EH code reach this place. This is a bit hackish, ...@@ -565,11 +567,11 @@ place holder to make EH code reach this place. This is a bit hackish,
but it works. but it works.
Once control reaches here, the qc is deallocated by invoking Once control reaches here, the qc is deallocated by invoking
__ata_qc_complete() explicitly. Then, internal qc for REQUEST SENSE :c:func:`__ata_qc_complete` explicitly. Then, internal qc for REQUEST SENSE
is issued. Once sense data is acquired, scmd is finished by directly is issued. Once sense data is acquired, scmd is finished by directly
invoking scsi_finish_command() on the scmd. Note that as we already invoking :c:func:`scsi_finish_command` on the scmd. Note that as we already
have completed and deallocated the qc which was associated with the have completed and deallocated the qc which was associated with the
scmd, we don't need to/cannot call ata_qc_complete() again. scmd, we don't need to/cannot call :c:func:`ata_qc_complete` again.
Problems with the current EH Problems with the current EH
---------------------------- ----------------------------
...@@ -583,7 +585,7 @@ Problems with the current EH ...@@ -583,7 +585,7 @@ Problems with the current EH
- When handling timeouts, no action is taken to make device forget - When handling timeouts, no action is taken to make device forget
about the timed out command and ready for new commands. about the timed out command and ready for new commands.
- EH handling via ata_scsi_error() is not properly protected from - EH handling via :c:func:`ata_scsi_error` is not properly protected from
usual command processing. On EH entrance, the device is not in usual command processing. On EH entrance, the device is not in
quiescent state. Timed out commands may succeed or fail any time. quiescent state. Timed out commands may succeed or fail any time.
pio_task and atapi_task may still be running. pio_task and atapi_task may still be running.
...@@ -622,6 +624,8 @@ libata Core Internals ...@@ -622,6 +624,8 @@ libata Core Internals
.. kernel-doc:: drivers/ata/libata-core.c .. kernel-doc:: drivers/ata/libata-core.c
:internal: :internal:
.. kernel-doc:: drivers/ata/libata-eh.c
libata SCSI translation/emulation libata SCSI translation/emulation
================================= =================================
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment