libATA Developer's Guide

Jeff Garzik

The contents of this file are subject to the Open Software License version 1.1 that can be found at and is included herein by reference.

Alternatively, the contents of this file may be used under the terms of the GNU General Public License version 2 (the "GPL") as distributed in the kernel source COPYING file, in which case the provisions of the GPL are applicable instead of the above. If you wish to allow the use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the OSL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the OSL or the GPL.

Table of Contents

1. Introduction
2. libata Driver API
struct ata_port_operations
Disable ATA port
Post-IDENTIFY device configuration
Set PIO/DMA mode
Taskfile read/write
PIO data read/write
ATA command execute
Per-cmd ATAPI DMA capabilities filter
Read specific ATA shadow registers
Select ATA device on bus
Private tuning method
Control PCI IDE BMDMA engine
High-level taskfile hooks
Exception and probe handling (EH)
Hardware interrupt handling
SATA phy read/write
Init and shutdown
3. Error handling
Origins of commands
How commands are issued
How commands are processed
How commands are completed
Problems with the current EH
4. libata Library
ata_link_next — link iteration helper
ata_dev_next — device iteration helper
atapi_cmd_type — Determine ATAPI command type from SCSI opcode
ata_tf_to_fis — Convert ATA taskfile to SATA FIS structure
ata_tf_from_fis — Convert SATA FIS to ATA taskfile
ata_pack_xfermask — Pack pio, mwdma and udma masks into xfer_mask
ata_unpack_xfermask — Unpack xfer_mask into pio, mwdma and udma masks
ata_xfer_mask2mode — Find matching XFER_* for the given xfer_mask
ata_xfer_mode2mask — Find matching xfer_mask for XFER_*
ata_xfer_mode2shift — Find matching xfer_shift for XFER_*
ata_mode_string — convert xfer_mask to string
ata_dev_classify — determine device type based on ATA-spec signature
ata_id_string — Convert IDENTIFY DEVICE page into string
ata_id_c_string — Convert IDENTIFY DEVICE page into C string
ata_id_xfermask — Compute xfermask from the given IDENTIFY data
ata_pio_queue_task — Queue port_task
ata_pio_need_iordy — check if iordy needed
ata_do_dev_read_id — default ID read method
ata_cable_40wire — return 40 wire cable type
ata_cable_80wire — return 80 wire cable type
ata_cable_unknown — return unknown PATA cable.
ata_cable_ignore — return ignored PATA cable.
ata_cable_sata — return SATA cable type
ata_port_probe — Mark port as enabled
ata_dev_pair — return other device on cable
ata_port_disable — Disable port.
sata_set_spd — set SATA spd according to spd limit
ata_timing_cycle2mode — find xfer mode for the specified cycle duration
ata_do_set_mode — Program timings and issue SET FEATURES - XFER
ata_wait_after_reset — wait for link to become ready after reset
sata_link_debounce — debounce SATA phy status
sata_link_resume — resume SATA link
ata_std_prereset — prepare for reset
sata_link_hardreset — reset link via SATA phy reset
sata_std_hardreset — COMRESET w/o waiting or classification
ata_std_postreset — standard postreset callback
ata_std_qc_defer — Check whether a qc needs to be deferred
ata_sg_init — Associate command with scatter-gather table.
ata_qc_complete — Complete an active ATA command
ata_qc_complete_multiple — Complete multiple qcs successfully
sata_scr_valid — test whether SCRs are accessible
sata_scr_read — read SCR register of the specified port
sata_scr_write — write SCR register of the specified port
sata_scr_write_flush — write SCR register of the specified port and flush
ata_link_online — test whether the given link is online
ata_link_offline — test whether the given link is offline
ata_host_suspend — suspend host
ata_host_resume — resume host
ata_port_start — Set port up for dma.
ata_host_alloc — allocate and init basic ATA host resources
ata_host_alloc_pinfo — alloc host and init with port_info array
ata_slave_link_init — initialize slave link
ata_host_start — start and freeze ports of an ATA host
ata_host_init — Initialize a host struct
ata_host_register — register initialized ATA host
ata_host_activate — start host, request IRQ and register it
ata_host_detach — Detach all ports of an ATA host
ata_pci_remove_one — PCI layer callback for device removal
ata_wait_register — wait until register value changes
5. libata Core Internals
ata_dev_phys_link — find physical link for a device
ata_force_cbl — force cable type according to libata.force
ata_force_link_limits — force link limits according to libata.force
ata_force_xfermask — force xfermask according to libata.force
ata_force_horkage — force horkage according to libata.force
ata_rwcmd_protocol — set taskfile r/w commands and protocol
ata_tf_read_block — Read block address from ATA taskfile
ata_build_rw_tf — Build ATA taskfile for given read/write request
ata_dev_enable_pm — enable SATA interface power management
ata_dev_disable_pm — disable SATA interface power management
ata_read_native_max_address — Read native max address
ata_set_max_sectors — Set max sectors
ata_hpa_resize — Resize a device with an HPA set
ata_dump_id — IDENTIFY DEVICE info debugging output
ata_port_flush_task — Flush port_task
ata_exec_internal_sg — execute libata internal command
ata_exec_internal — execute libata internal command
ata_do_simple_cmd — execute simple internal command
ata_pio_mask_no_iordy — Return the non IORDY mask
ata_dev_read_id — Read ID data from the specified device
ata_dev_configure — Configure the specified ATA/ATAPI device
ata_bus_probe — Reset and probe ATA bus
sata_print_link_status — Print SATA link status
sata_down_spd_limit — adjust SATA spd limit downward
sata_set_spd_needed — is SATA spd configuration needed
ata_down_xfermask_limit — adjust dev xfer masks downward
ata_wait_ready — wait for link to become ready
ata_dev_same_device — Determine whether new ID matches configured device
ata_dev_reread_id — Re-read IDENTIFY data
ata_dev_revalidate — Revalidate ATA device
ata_is_40wire — check drive side detection
cable_is_40wire — 40/80/SATA decider
ata_dev_xfermask — Compute supported xfermask of the given device
ata_dev_set_xfermode — Issue SET FEATURES - XFER MODE command
ata_dev_set_feature — Issue SET FEATURES - SATA FEATURES
ata_dev_init_params — Issue INIT DEV PARAMS command
ata_sg_clean — Unmap DMA memory associated with command
atapi_check_dma — Check whether ATAPI DMA can be supported
ata_sg_setup — DMA-map the scatter-gather table associated with a command.
swap_buf_le16 — swap halves of 16-bit words in place
ata_qc_new — Request an available ATA command, for queueing
ata_qc_new_init — Request an available ATA command, and initialize it
ata_qc_free — free unused ata_queued_cmd
ata_qc_issue — issue taskfile to device
ata_phys_link_online — test whether the given link is online
ata_phys_link_offline — test whether the given link is offline
ata_dev_init — Initialize an ata_device structure
ata_link_init — Initialize an ata_link structure
sata_link_init_spd — Initialize link->sata_spd_limit
ata_port_alloc — allocate and initialize basic ATA port resources
ata_finalize_port_ops — finalize ata_port_operations
ata_port_detach — Detach ATA port in prepration of device removal
6. libata SCSI translation/emulation
ata_std_bios_param — generic bios head/sector/cylinder calculator used by sd.
ata_scsi_set_capacity — adjust device capacity
ata_scsi_slave_config — Set SCSI device attributes
ata_scsi_slave_destroy — SCSI device is about to be destroyed
ata_scsi_change_queue_depth — SCSI callback for queue depth config
ata_scsi_queuecmd — Issue SCSI cdb to libata-managed device
ata_scsi_simulate — simulate SCSI command on ATA device
ata_sas_port_alloc — Allocate port for a SAS attached SATA device
ata_sas_port_start — Set port up for dma.
ata_sas_port_stop — Undo ata_sas_port_start
ata_sas_port_init — Initialize a SATA device
ata_sas_port_destroy — Destroy a SATA port allocated by ata_sas_port_alloc
ata_sas_slave_configure — Default slave_config routine for libata devices
ata_sas_queuecmd — Issue SCSI cdb to libata-managed device
ata_get_identity — Handler for HDIO_GET_IDENTITY ioctl
ata_cmd_ioctl — Handler for HDIO_DRIVE_CMD ioctl
ata_task_ioctl — Handler for HDIO_DRIVE_TASK ioctl
ata_scsi_qc_new — acquire new ata_queued_cmd reference
ata_dump_status — user friendly display of error info
ata_to_sense_error — convert ATA error to SCSI error
ata_gen_ata_sense — generate a SCSI fixed sense block
atapi_drain_needed — Check whether data transfer may overflow
ata_scsi_start_stop_xlat — Translate SCSI START STOP UNIT command
ata_scsi_flush_xlat — Translate SCSI SYNCHRONIZE CACHE command
scsi_6_lba_len — Get LBA and transfer length
scsi_10_lba_len — Get LBA and transfer length
scsi_16_lba_len — Get LBA and transfer length
ata_scsi_verify_xlat — Translate SCSI VERIFY command into an ATA one
ata_scsi_rw_xlat — Translate SCSI r/w command into an ATA one
ata_scsi_translate — Translate then issue SCSI command to ATA device
ata_scsi_rbuf_get — Map response buffer.
ata_scsi_rbuf_put — Unmap response buffer.
ata_scsi_rbuf_fill — wrapper for SCSI command simulators
ata_scsiop_inq_std — Simulate INQUIRY command
ata_scsiop_inq_00 — Simulate INQUIRY VPD page 0, list of pages
ata_scsiop_inq_80 — Simulate INQUIRY VPD page 80, device serial number
ata_scsiop_inq_83 — Simulate INQUIRY VPD page 83, device identity
ata_scsiop_inq_89 — Simulate INQUIRY VPD page 89, ATA info
ata_scsiop_noop — Command handler that simply returns success.
ata_msense_caching — Simulate MODE SENSE caching info page
ata_msense_ctl_mode — Simulate MODE SENSE control mode page
ata_msense_rw_recovery — Simulate MODE SENSE r/w error recovery page
ata_scsiop_mode_sense — Simulate MODE SENSE 6, 10 commands
ata_scsiop_read_cap — Simulate READ CAPACITY[ 16] commands
ata_scsiop_report_luns — Simulate REPORT LUNS command
atapi_xlat — Initialize PACKET taskfile
ata_scsi_find_dev — lookup ata_device from scsi_cmnd
ata_scsi_pass_thru — convert ATA pass-thru CDB to taskfile
ata_get_xlat_func — check if SCSI to ATA translation is possible
ata_scsi_dump_cdb — dump SCSI command contents to dmesg
ata_scsi_offline_dev — offline attached SCSI device
ata_scsi_remove_dev — remove attached SCSI device
ata_scsi_media_change_notify — send media change event
ata_scsi_hotplug — SCSI part of hotplug
ata_scsi_user_scan — indication for user-initiated bus scan
ata_scsi_dev_rescan — initiate scsi_rescan_device
7. ATA errors and exceptions
Exception categories
HSM violation
ATA/ATAPI device error (non-NCQ / non-CHECK CONDITION)
ATA device error (NCQ)
ATA bus error
PCI bus error
Late completion
Unknown error (timeout)
Hotplug and power management exceptions
EH recovery actions
Clearing error condition
Reconfigure transport
8. ata_piix Internals
ich_pata_cable_detect — Probe host controller cable detect info
piix_pata_prereset — prereset for PATA host controller
piix_set_piomode — Initialize host controller PATA PIO timings
do_pata_set_dmamode — Initialize host controller PATA PIO timings
piix_set_dmamode — Initialize host controller PATA DMA timings
ich_set_dmamode — Initialize host controller PATA DMA timings
piix_check_450nx_errata — Check for problem 450NX setup
piix_init_one — Register PIIX ATA PCI device with kernel services
9. sata_sil Internals
sil_set_mode — wrap set_mode functions
sil_dev_config — Apply device/host-specific errata fixups
10. Thanks