Chapter 2. libata Driver API

2.1. struct ata_port_operations

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).

void (*dev_config) (struct ata_port *, struct ata_device *);
	

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.

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 *ap);
	

Hooks called prior to the issue of SET FEATURES - XFER MODE command. dev->pio_mode is guaranteed to be valid when ->set_piomode() is called, and dev->dma_mode is guaranteed to be valid when ->set_dmamode() is called. ->post_set_mode() is called unconditionally, after the SET FEATURES - XFER MODE command completes successfully.

->set_piomode() is always called (if present), but ->set_dma_mode() is only called if DMA is possible.

void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
	

->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, to obtain the current set of taskfile register values.

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.

u8   (*check_status)(struct ata_port *ap);
void (*dev_select)(struct ata_port *ap, unsigned int device);
	

Reads the Status ATA shadow register from hardware. On some hardware, this has the side effect of clearing the interrupt condition.

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.

void (*phy_reset) (struct ata_port *ap);
	

The very first step in the probe phase. Actions vary depending on the bus type, typically. After waking up the device and probing 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.

void (*bmdma_setup) (struct ata_queued_cmd *qc);
void (*bmdma_start) (struct ata_queued_cmd *qc);
	

When setting up an IDE BMDMA transaction, these hooks arm (->bmdma_setup) and fire (->bmdma_start) the hardware's DMA engine.

void (*qc_prep) (struct ata_queued_cmd *qc);
int (*qc_issue) (struct ata_queued_cmd *qc);
	

Higher-level hooks, these two hooks can potentially supercede several of the above taskfile/DMA engine hooks. ->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.

->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 roll their own ->qc_issue implementation, using this as the "issue new ATA command to hardware" hook.

void (*eng_timeout) (struct ata_port *ap);
	

This is a high level error handling function, called from the error handling thread, when a command times out.

irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
void (*irq_clear) (struct ata_port *);
	

->irq_handler is the interrupt handling routine registered with the system, by libata. ->irq_clear is called during probe just before the interrupt handler is registered, to be sure hardware is quiet.

u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
                   u32 val);
	

Read and write standard SATA phy registers. Currently only used if ->phy_reset hook called the sata_phy_reset() helper function.

int (*port_start) (struct ata_port *ap);
void (*port_stop) (struct ata_port *ap);
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.

->host_stop() is called when the rmmod or hot unplug process begins. The hook must stop all hardware interrupts, DMA engines, etc.

->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.