Sophie

Sophie

distrib > CentOS > 6 > i386 > by-pkgid > cf93d8a8acdcc6fe2225039da0502495 > files > 2272

kernel-doc-2.6.32-131.17.1.el6.centos.plus.noarch.rpm

<?xml version="1.0" encoding="ANSI_X3.4-1968" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968" /><title>Chapter&#160;2.&#160;libata Driver API</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><link rel="home" href="index.html" title="libATA Developer's Guide" /><link rel="up" href="index.html" title="libATA Developer's Guide" /><link rel="prev" href="ch01.html" title="Chapter&#160;1.&#160;Introduction" /><link rel="next" href="ch03.html" title="Chapter&#160;3.&#160;Error handling" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter&#160;2.&#160;libata Driver API</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch01.html">Prev</a>&#160;</td><th width="60%" align="center">&#160;</th><td width="20%" align="right">&#160;<a accesskey="n" href="ch03.html">Next</a></td></tr></table><hr /></div><div class="chapter" title="Chapter&#160;2.&#160;libata Driver API"><div class="titlepage"><div><div><h2 class="title"><a id="libataDriverApi"></a>Chapter&#160;2.&#160;libata Driver API</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="ch02.html#id2849705">struct ata_port_operations</a></span></dt><dd><dl><dt><span class="sect2"><a href="ch02.html#id2849711">Disable ATA port</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2849737">Post-IDENTIFY device configuration</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810465">Set PIO/DMA mode</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810509">Taskfile read/write</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810532">PIO data read/write</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810552">ATA command execute</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810571">Per-cmd ATAPI DMA capabilities filter</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810594">Read specific ATA shadow registers</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810621">Select ATA device on bus</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810647">Private tuning method</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810680">Control PCI IDE BMDMA engine</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810730">High-level taskfile hooks</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2815095">Exception and probe handling (EH)</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2815183">Hardware interrupt handling</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2815220">SATA phy read/write</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2815241">Init and shutdown</a></span></dt></dl></dd></dl></div><p>
     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.
     </p><p>
     FIS-based drivers will hook into the system with -&gt;qc_prep() and
     -&gt;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.
     </p><div class="sect1" title="struct ata_port_operations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id2849705"></a>struct ata_port_operations</h2></div></div></div><div class="toc"><dl><dt><span class="sect2"><a href="ch02.html#id2849711">Disable ATA port</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2849737">Post-IDENTIFY device configuration</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810465">Set PIO/DMA mode</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810509">Taskfile read/write</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810532">PIO data read/write</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810552">ATA command execute</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810571">Per-cmd ATAPI DMA capabilities filter</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810594">Read specific ATA shadow registers</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810621">Select ATA device on bus</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810647">Private tuning method</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810680">Control PCI IDE BMDMA engine</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2810730">High-level taskfile hooks</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2815095">Exception and probe handling (EH)</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2815183">Hardware interrupt handling</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2815220">SATA phy read/write</a></span></dt><dt><span class="sect2"><a href="ch02.html#id2815241">Init and shutdown</a></span></dt></dl></div><div class="sect2" title="Disable ATA port"><div class="titlepage"><div><div><h3 class="title"><a id="id2849711"></a>Disable ATA port</h3></div></div></div><pre class="programlisting">
void (*port_disable) (struct ata_port *);
	</pre><p>
	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.
	</p><p>
	Called from ata_bus_probe() on a failed probe.
	Called from ata_bus_reset() on a failed bus reset.
	Called from ata_scsi_release().
	</p></div><div class="sect2" title="Post-IDENTIFY device configuration"><div class="titlepage"><div><div><h3 class="title"><a id="id2849737"></a>Post-IDENTIFY device configuration</h3></div></div></div><pre class="programlisting">
void (*dev_config) (struct ata_port *, struct ata_device *);
	</pre><p>
	Called after IDENTIFY [PACKET] DEVICE is issued to each device
	found.  Typically used to apply device-specific fixups prior to
	issue of SET FEATURES - XFER MODE, and prior to operation.
	</p><p>
	Called by ata_device_add() after ata_dev_identify() determines
	a device is present.
	</p><p>
	This entry may be specified as NULL in ata_port_operations.
	</p></div><div class="sect2" title="Set PIO/DMA mode"><div class="titlepage"><div><div><h3 class="title"><a id="id2810465"></a>Set PIO/DMA mode</h3></div></div></div><pre class="programlisting">
void (*set_piomode) (struct ata_port *, struct ata_device *);
void (*set_dmamode) (struct ata_port *, struct ata_device *);
void (*post_set_mode) (struct ata_port *);
unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned int);
	</pre><p>
	Hooks called prior to the issue of SET FEATURES - XFER MODE
	command.  The optional -&gt;mode_filter() hook is called when libata
	has built a mask of the possible modes. This is passed to the 
	-&gt;mode_filter() function which should return a mask of valid modes
	after filtering those unsuitable due to hardware limits. It is not
	valid to use this interface to add modes.
	</p><p>
	dev-&gt;pio_mode and dev-&gt;dma_mode are guaranteed to be valid when
	-&gt;set_piomode() and when -&gt;set_dmamode() is called. The timings for
	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 channel before it attempts to set any of them.
	</p><p>
	-&gt;post_set_mode() is
	called unconditionally, after the SET FEATURES - XFER MODE
	command completes successfully.
	</p><p>
	-&gt;set_piomode() is always called (if present), but
	-&gt;set_dma_mode() is only called if DMA is possible.
	</p></div><div class="sect2" title="Taskfile read/write"><div class="titlepage"><div><div><h3 class="title"><a id="id2810509"></a>Taskfile read/write</h3></div></div></div><pre class="programlisting">
void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
	</pre><p>
	-&gt;tf_load() is called to load the given taskfile into hardware
	registers / DMA buffers.  -&gt;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.
	</p></div><div class="sect2" title="PIO data read/write"><div class="titlepage"><div><div><h3 class="title"><a id="id2810532"></a>PIO data read/write</h3></div></div></div><pre class="programlisting">
void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
	</pre><p>
All bmdma-style drivers must implement this hook.  This is the low-level
operation that actually copies the data bytes during a PIO data
transfer.
Typically the driver
will choose one of ata_pio_data_xfer_noirq(), ata_pio_data_xfer(), or
ata_mmio_data_xfer().
	</p></div><div class="sect2" title="ATA command execute"><div class="titlepage"><div><div><h3 class="title"><a id="id2810552"></a>ATA command execute</h3></div></div></div><pre class="programlisting">
void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
	</pre><p>
	causes an ATA command, previously loaded with
	-&gt;tf_load(), to be initiated in hardware.
	Most drivers for taskfile-based hardware use ata_exec_command()
	for this hook.
	</p></div><div class="sect2" title="Per-cmd ATAPI DMA capabilities filter"><div class="titlepage"><div><div><h3 class="title"><a id="id2810571"></a>Per-cmd ATAPI DMA capabilities filter</h3></div></div></div><pre class="programlisting">
int (*check_atapi_dma) (struct ata_queued_cmd *qc);
	</pre><p>
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.
	</p><p>
	This hook may be specified as NULL, in which case libata will
	assume that atapi dma can be supported.
	</p></div><div class="sect2" title="Read specific ATA shadow registers"><div class="titlepage"><div><div><h3 class="title"><a id="id2810594"></a>Read specific ATA shadow registers</h3></div></div></div><pre class="programlisting">
u8   (*check_status)(struct ata_port *ap);
u8   (*check_altstatus)(struct ata_port *ap);
	</pre><p>
	Reads the Status/AltStatus 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.
	</p><p>
	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.
	</p></div><div class="sect2" title="Select ATA device on bus"><div class="titlepage"><div><div><h3 class="title"><a id="id2810621"></a>Select ATA device on bus</h3></div></div></div><pre class="programlisting">
void (*dev_select)(struct ata_port *ap, unsigned int device);
	</pre><p>
	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.
	</p><p>
	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().
	</p></div><div class="sect2" title="Private tuning method"><div class="titlepage"><div><div><h3 class="title"><a id="id2810647"></a>Private tuning method</h3></div></div></div><pre class="programlisting">
void (*set_mode) (struct ata_port *ap);
	</pre><p>
	By default libata performs drive and controller tuning in
	accordance with the ATA timing rules and also applies blacklists
	and cable limits. Some controllers need special handling and have
	custom tuning rules, typically raid controllers that use ATA
	commands but do not actually do drive timing.
	</p><div class="warning" title="Warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3><p>
	This hook should not be used to replace the standard controller
	tuning logic when a controller has quirks. Replacing the default
	tuning logic in that case would bypass handling for drive and
	bridge quirks that may be important to data reliability. If a
	controller needs to filter the mode selection it should use the
	mode_filter hook instead.
	</p></div></div><div class="sect2" title="Control PCI IDE BMDMA engine"><div class="titlepage"><div><div><h3 class="title"><a id="id2810680"></a>Control PCI IDE BMDMA engine</h3></div></div></div><pre class="programlisting">
void (*bmdma_setup) (struct ata_queued_cmd *qc);
void (*bmdma_start) (struct ata_queued_cmd *qc);
void (*bmdma_stop) (struct ata_port *ap);
u8   (*bmdma_status) (struct ata_port *ap);
	</pre><p>
When setting up an IDE BMDMA transaction, these hooks arm
(-&gt;bmdma_setup), fire (-&gt;bmdma_start), and halt (-&gt;bmdma_stop)
the hardware's DMA engine.  -&gt;bmdma_status is used to read the standard
PCI IDE DMA Status register.
	</p><p>
These hooks are typically either no-ops, or simply not implemented, in
FIS-based drivers.
	</p><p>
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.
	</p><p>
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.
	</p><p>
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.
	</p><p>
Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() hook.
	</p></div><div class="sect2" title="High-level taskfile hooks"><div class="titlepage"><div><div><h3 class="title"><a id="id2810730"></a>High-level taskfile hooks</h3></div></div></div><pre class="programlisting">
void (*qc_prep) (struct ata_queued_cmd *qc);
int (*qc_issue) (struct ata_queued_cmd *qc);
	</pre><p>
	Higher-level hooks, these two hooks can potentially supercede
	several of the above taskfile/DMA engine hooks.  -&gt;qc_prep is
	called after the buffers have been DMA-mapped, and is typically
	used to populate the hardware's DMA scatter-gather table.
	Most drivers use the standard ata_qc_prep() helper function, but
	more advanced drivers roll their own.
	</p><p>
	-&gt;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 ata_qc_issue_prot() for taskfile protocol-based
	dispatch.  More advanced drivers implement their own -&gt;qc_issue.
	</p><p>
	ata_qc_issue_prot() calls -&gt;tf_load(), -&gt;bmdma_setup(), and
	-&gt;bmdma_start() as necessary to initiate a transfer.
	</p></div><div class="sect2" title="Exception and probe handling (EH)"><div class="titlepage"><div><div><h3 class="title"><a id="id2815095"></a>Exception and probe handling (EH)</h3></div></div></div><pre class="programlisting">
void (*eng_timeout) (struct ata_port *ap);
void (*phy_reset) (struct ata_port *ap);
	</pre><p>
Deprecated.  Use -&gt;error_handler() instead.
	</p><pre class="programlisting">
void (*freeze) (struct ata_port *ap);
void (*thaw) (struct ata_port *ap);
	</pre><p>
ata_port_freeze() is called when HSM violations or some other
condition disrupts normal operation of the port.  A frozen port
is not allowed to perform any operation until the port is
thawed, which usually follows a successful reset.
	</p><p>
The optional -&gt;freeze() callback can be used for freezing the 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 interrupts unconditionally while the port
is frozen.
	</p><p>
The optional -&gt;thaw() callback is called to perform the opposite of -&gt;freeze():
prepare the port for normal operation once again.  Unmask interrupts,
start DMA engine, etc.
	</p><pre class="programlisting">
void (*error_handler) (struct ata_port *ap);
	</pre><p>
-&gt;error_handler() is a driver's hook into probe, hotplug, and recovery
and other exceptional conditions.  The primary responsibility of an
implementation is to call ata_do_eh() or ata_bmdma_drive_eh() with a set
of EH hooks as arguments:
	</p><p>
'prereset' hook (may be NULL) is called during an EH reset, before any other actions
are taken.
	</p><p>
'postreset' hook (may be NULL) is called after the EH reset is performed.  Based on
existing conditions, severity of the problem, and hardware capabilities,
	</p><p>
Either 'softreset' (may be NULL) or 'hardreset' (may be NULL) will be
called to perform the low-level EH reset.
	</p><pre class="programlisting">
void (*post_internal_cmd) (struct ata_queued_cmd *qc);
	</pre><p>
Perform any hardware-specific actions necessary to finish processing
after executing a probe-time or EH-time command via ata_exec_internal().
	</p></div><div class="sect2" title="Hardware interrupt handling"><div class="titlepage"><div><div><h3 class="title"><a id="id2815183"></a>Hardware interrupt handling</h3></div></div></div><pre class="programlisting">
irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
void (*irq_clear) (struct ata_port *);
	</pre><p>
	-&gt;irq_handler is the interrupt handling routine registered with
	the system, by libata.  -&gt;irq_clear is called during probe just
	before the interrupt handler is registered, to be sure hardware
	is quiet.
	</p><p>
	The second argument, dev_instance, should be cast to a pointer
	to struct ata_host_set.
	</p><p>
	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).
	</p><p>
	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.
	</p></div><div class="sect2" title="SATA phy read/write"><div class="titlepage"><div><div><h3 class="title"><a id="id2815220"></a>SATA phy read/write</h3></div></div></div><pre class="programlisting">
int (*scr_read) (struct ata_port *ap, unsigned int sc_reg,
		 u32 *val);
int (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
                   u32 val);
	</pre><p>
	Read and write standard SATA phy registers.  Currently only used
	if -&gt;phy_reset hook called the sata_phy_reset() helper function.
	sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE.
	</p></div><div class="sect2" title="Init and shutdown"><div class="titlepage"><div><div><h3 class="title"><a id="id2815241"></a>Init and shutdown</h3></div></div></div><pre class="programlisting">
int (*port_start) (struct ata_port *ap);
void (*port_stop) (struct ata_port *ap);
void (*host_stop) (struct ata_host_set *host_set);
	</pre><p>
	-&gt;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.  Some drivers also use this entry point as a chance to
	allocate driver-private memory for ap-&gt;private_data.
	</p><p>
	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.
	</p><p>
	-&gt;port_stop() is called after -&gt;host_stop().  It's sole function
	is to 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.
	</p><p>
	Many drivers use ata_port_stop() as this hook, which frees the
	PRD table.
	</p><p>
	-&gt;host_stop() is called after all -&gt;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.
	</p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch01.html">Prev</a>&#160;</td><td width="20%" align="center">&#160;</td><td width="40%" align="right">&#160;<a accesskey="n" href="ch03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&#160;1.&#160;Introduction&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Chapter&#160;3.&#160;Error handling</td></tr></table></div></body></html>