Merge of 'docs' branch from
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
This commit is contained in:
commit
317604633e
|
@ -14,7 +14,7 @@
|
||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2003</year>
|
<year>2003-2005</year>
|
||||||
<holder>Jeff Garzik</holder>
|
<holder>Jeff Garzik</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
|
@ -44,30 +44,38 @@
|
||||||
|
|
||||||
<toc></toc>
|
<toc></toc>
|
||||||
|
|
||||||
<chapter id="libataThanks">
|
<chapter id="libataIntroduction">
|
||||||
<title>Thanks</title>
|
<title>Introduction</title>
|
||||||
<para>
|
<para>
|
||||||
The bulk of the ATA knowledge comes thanks to long conversations with
|
libATA is a library used inside the Linux kernel to support ATA host
|
||||||
Andre Hedrick (www.linux-ide.org).
|
controllers and devices. libATA provides an ATA driver API, class
|
||||||
|
transports for ATA and ATAPI devices, and SCSI<->ATA translation
|
||||||
|
for ATA devices according to the T10 SAT specification.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Thanks to Alan Cox for pointing out similarities
|
This Guide documents the libATA driver API, library functions, library
|
||||||
between SATA and SCSI, and in general for motivation to hack on
|
internals, and a couple sample ATA low-level drivers.
|
||||||
libata.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
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).
|
|
||||||
</para>
|
</para>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="libataDriverApi">
|
<chapter id="libataDriverApi">
|
||||||
<title>libata Driver API</title>
|
<title>libata Driver API</title>
|
||||||
|
<para>
|
||||||
|
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.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
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.
|
||||||
|
</para>
|
||||||
<sect1>
|
<sect1>
|
||||||
<title>struct ata_port_operations</title>
|
<title>struct ata_port_operations</title>
|
||||||
|
|
||||||
|
<sect2><title>Disable ATA port</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*port_disable) (struct ata_port *);
|
void (*port_disable) (struct ata_port *);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
@ -78,6 +86,9 @@ void (*port_disable) (struct ata_port *);
|
||||||
unplug).
|
unplug).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Post-IDENTIFY device configuration</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*dev_config) (struct ata_port *, struct ata_device *);
|
void (*dev_config) (struct ata_port *, struct ata_device *);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
@ -88,6 +99,9 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
|
||||||
issue of SET FEATURES - XFER MODE, and prior to operation.
|
issue of SET FEATURES - XFER MODE, and prior to operation.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Set PIO/DMA mode</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*set_piomode) (struct ata_port *, struct ata_device *);
|
void (*set_piomode) (struct ata_port *, struct ata_device *);
|
||||||
void (*set_dmamode) (struct ata_port *, struct ata_device *);
|
void (*set_dmamode) (struct ata_port *, struct ata_device *);
|
||||||
|
@ -108,6 +122,9 @@ void (*post_set_mode) (struct ata_port *ap);
|
||||||
->set_dma_mode() is only called if DMA is possible.
|
->set_dma_mode() is only called if DMA is possible.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Taskfile read/write</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
|
void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
|
||||||
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
|
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
|
||||||
|
@ -120,6 +137,9 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
|
||||||
taskfile register values.
|
taskfile register values.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>ATA command execute</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
|
void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
@ -129,17 +149,37 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
|
||||||
->tf_load(), to be initiated in hardware.
|
->tf_load(), to be initiated in hardware.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Per-cmd ATAPI DMA capabilities filter</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
u8 (*check_status)(struct ata_port *ap);
|
int (*check_atapi_dma) (struct ata_queued_cmd *qc);
|
||||||
void (*dev_select)(struct ata_port *ap, unsigned int device);
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Reads the Status ATA shadow register from hardware. On some
|
Allow low-level driver to filter ATA PACKET commands, returning a status
|
||||||
hardware, this has the side effect of clearing the interrupt
|
indicating whether or not it is OK to use DMA for the supplied PACKET
|
||||||
condition.
|
command.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Read specific ATA shadow registers</title>
|
||||||
|
<programlisting>
|
||||||
|
u8 (*check_status)(struct ata_port *ap);
|
||||||
|
u8 (*check_altstatus)(struct ata_port *ap);
|
||||||
|
u8 (*check_err)(struct ata_port *ap);
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
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.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Select ATA device on bus</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*dev_select)(struct ata_port *ap, unsigned int device);
|
void (*dev_select)(struct ata_port *ap, unsigned int device);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
@ -147,9 +187,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
|
||||||
<para>
|
<para>
|
||||||
Issues the low-level hardware command(s) that causes one of N
|
Issues the low-level hardware command(s) that causes one of N
|
||||||
hardware devices to be considered 'selected' (active and
|
hardware devices to be considered 'selected' (active and
|
||||||
available for use) on the ATA bus.
|
available for use) on the ATA bus. This generally has no
|
||||||
|
meaning on FIS-based devices.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Reset ATA bus</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*phy_reset) (struct ata_port *ap);
|
void (*phy_reset) (struct ata_port *ap);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
@ -162,17 +206,31 @@ void (*phy_reset) (struct ata_port *ap);
|
||||||
functions ata_bus_reset() or sata_phy_reset() for this hook.
|
functions ata_bus_reset() or sata_phy_reset() for this hook.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Control PCI IDE BMDMA engine</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*bmdma_setup) (struct ata_queued_cmd *qc);
|
void (*bmdma_setup) (struct ata_queued_cmd *qc);
|
||||||
void (*bmdma_start) (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);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
When setting up an IDE BMDMA transaction, these hooks arm
|
When setting up an IDE BMDMA transaction, these hooks arm
|
||||||
(->bmdma_setup) and fire (->bmdma_start) the hardware's DMA
|
(->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop)
|
||||||
engine.
|
the hardware's DMA engine. ->bmdma_status is used to read the standard
|
||||||
|
PCI IDE DMA Status register.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
These hooks are typically either no-ops, or simply not implemented, in
|
||||||
|
FIS-based drivers.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>High-level taskfile hooks</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*qc_prep) (struct ata_queued_cmd *qc);
|
void (*qc_prep) (struct ata_queued_cmd *qc);
|
||||||
int (*qc_issue) (struct ata_queued_cmd *qc);
|
int (*qc_issue) (struct ata_queued_cmd *qc);
|
||||||
|
@ -190,20 +248,26 @@ int (*qc_issue) (struct ata_queued_cmd *qc);
|
||||||
->qc_issue is used to make a command active, once the hardware
|
->qc_issue is used to make a command active, once the hardware
|
||||||
and S/G tables have been prepared. IDE BMDMA drivers use the
|
and S/G tables have been prepared. IDE BMDMA drivers use the
|
||||||
helper function ata_qc_issue_prot() for taskfile protocol-based
|
helper function ata_qc_issue_prot() for taskfile protocol-based
|
||||||
dispatch. More advanced drivers roll their own ->qc_issue
|
dispatch. More advanced drivers implement their own ->qc_issue.
|
||||||
implementation, using this as the "issue new ATA command to
|
|
||||||
hardware" hook.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Timeout (error) handling</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*eng_timeout) (struct ata_port *ap);
|
void (*eng_timeout) (struct ata_port *ap);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This is a high level error handling function, called from the
|
This is a high level error handling function, called from the
|
||||||
error handling thread, when a command times out.
|
error handling thread, when a command times out. Most newer
|
||||||
|
hardware will implement its own error handling code here. IDE BMDMA
|
||||||
|
drivers may use the helper function ata_eng_timeout().
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Hardware interrupt handling</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
|
irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
|
||||||
void (*irq_clear) (struct ata_port *);
|
void (*irq_clear) (struct ata_port *);
|
||||||
|
@ -216,6 +280,9 @@ void (*irq_clear) (struct ata_port *);
|
||||||
is quiet.
|
is quiet.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>SATA phy read/write</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
|
u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
|
||||||
void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
|
void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
|
||||||
|
@ -227,6 +294,9 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
|
||||||
if ->phy_reset hook called the sata_phy_reset() helper function.
|
if ->phy_reset hook called the sata_phy_reset() helper function.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Init and shutdown</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
int (*port_start) (struct ata_port *ap);
|
int (*port_start) (struct ata_port *ap);
|
||||||
void (*port_stop) (struct ata_port *ap);
|
void (*port_stop) (struct ata_port *ap);
|
||||||
|
@ -240,15 +310,17 @@ void (*host_stop) (struct ata_host_set *host_set);
|
||||||
tasks.
|
tasks.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
->host_stop() is called when the rmmod or hot unplug process
|
|
||||||
begins. The hook must stop all hardware interrupts, DMA
|
|
||||||
engines, etc.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
->port_stop() is called after ->host_stop(). It's sole function
|
->port_stop() is called after ->host_stop(). It's sole function
|
||||||
is to release DMA/memory resources, now that they are no longer
|
is to release DMA/memory resources, now that they are no longer
|
||||||
actively being used.
|
actively being used.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
->host_stop() is called after all ->port_stop() calls
|
||||||
|
have completed. The hook must finalize hardware shutdown, release DMA
|
||||||
|
and other resources, etc.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -279,4 +351,24 @@ void (*host_stop) (struct ata_host_set *host_set);
|
||||||
!Idrivers/scsi/sata_sil.c
|
!Idrivers/scsi/sata_sil.c
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
|
<chapter id="libataThanks">
|
||||||
|
<title>Thanks</title>
|
||||||
|
<para>
|
||||||
|
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.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Thanks to Alan Cox for pointing out similarities
|
||||||
|
between SATA and SCSI, and in general for motivation to hack on
|
||||||
|
libata.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
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).
|
||||||
|
</para>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
</book>
|
</book>
|
||||||
|
|
|
@ -665,15 +665,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
return ata_pci_init_one(pdev, port_info, n_ports);
|
return ata_pci_init_one(pdev, port_info, n_ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* piix_init -
|
|
||||||
*
|
|
||||||
* LOCKING:
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int __init piix_init(void)
|
static int __init piix_init(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -689,13 +680,6 @@ static int __init piix_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* piix_exit -
|
|
||||||
*
|
|
||||||
* LOCKING:
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void __exit piix_exit(void)
|
static void __exit piix_exit(void)
|
||||||
{
|
{
|
||||||
pci_unregister_driver(&piix_pci_driver);
|
pci_unregister_driver(&piix_pci_driver);
|
||||||
|
|
|
@ -186,6 +186,28 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
ata_wait_idle(ap);
|
ata_wait_idle(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_tf_load - send taskfile registers to host controller
|
||||||
|
* @ap: Port to which output is sent
|
||||||
|
* @tf: ATA taskfile register set
|
||||||
|
*
|
||||||
|
* Outputs ATA taskfile to standard ATA host controller using MMIO
|
||||||
|
* or PIO as indicated by the ATA_FLAG_MMIO flag.
|
||||||
|
* Writes the control, feature, nsect, lbal, lbam, and lbah registers.
|
||||||
|
* Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
|
||||||
|
* hob_lbal, hob_lbam, and hob_lbah.
|
||||||
|
*
|
||||||
|
* This function waits for idle (!BUSY and !DRQ) after writing
|
||||||
|
* registers. If the control register has a new value, this
|
||||||
|
* function also waits for idle after writing control and before
|
||||||
|
* writing the remaining registers.
|
||||||
|
*
|
||||||
|
* May be used as the tf_load() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
|
void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
{
|
{
|
||||||
if (ap->flags & ATA_FLAG_MMIO)
|
if (ap->flags & ATA_FLAG_MMIO)
|
||||||
|
@ -195,11 +217,11 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_exec_command - issue ATA command to host controller
|
* ata_exec_command_pio - issue ATA command to host controller
|
||||||
* @ap: port to which command is being issued
|
* @ap: port to which command is being issued
|
||||||
* @tf: ATA taskfile register set
|
* @tf: ATA taskfile register set
|
||||||
*
|
*
|
||||||
* Issues PIO/MMIO write to ATA command register, with proper
|
* Issues PIO write to ATA command register, with proper
|
||||||
* synchronization with interrupt handler / other threads.
|
* synchronization with interrupt handler / other threads.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
@ -235,6 +257,18 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
ata_pause(ap);
|
ata_pause(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_exec_command - issue ATA command to host controller
|
||||||
|
* @ap: port to which command is being issued
|
||||||
|
* @tf: ATA taskfile register set
|
||||||
|
*
|
||||||
|
* Issues PIO/MMIO write to ATA command register, with proper
|
||||||
|
* synchronization with interrupt handler / other threads.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*/
|
||||||
void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
|
void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
{
|
{
|
||||||
if (ap->flags & ATA_FLAG_MMIO)
|
if (ap->flags & ATA_FLAG_MMIO)
|
||||||
|
@ -305,7 +339,7 @@ void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_tf_read - input device's ATA taskfile shadow registers
|
* ata_tf_read_pio - input device's ATA taskfile shadow registers
|
||||||
* @ap: Port from which input is read
|
* @ap: Port from which input is read
|
||||||
* @tf: ATA taskfile register set for storing input
|
* @tf: ATA taskfile register set for storing input
|
||||||
*
|
*
|
||||||
|
@ -368,6 +402,23 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_tf_read - input device's ATA taskfile shadow registers
|
||||||
|
* @ap: Port from which input is read
|
||||||
|
* @tf: ATA taskfile register set for storing input
|
||||||
|
*
|
||||||
|
* Reads ATA taskfile registers for currently-selected device
|
||||||
|
* into @tf.
|
||||||
|
*
|
||||||
|
* Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48
|
||||||
|
* is set, also reads the hob registers.
|
||||||
|
*
|
||||||
|
* May be used as the tf_read() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
{
|
{
|
||||||
if (ap->flags & ATA_FLAG_MMIO)
|
if (ap->flags & ATA_FLAG_MMIO)
|
||||||
|
@ -381,7 +432,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
* @ap: port where the device is
|
* @ap: port where the device is
|
||||||
*
|
*
|
||||||
* Reads ATA taskfile status register for currently-selected device
|
* Reads ATA taskfile status register for currently-selected device
|
||||||
* and return it's value. This also clears pending interrupts
|
* and return its value. This also clears pending interrupts
|
||||||
* from this device
|
* from this device
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
@ -397,7 +448,7 @@ static u8 ata_check_status_pio(struct ata_port *ap)
|
||||||
* @ap: port where the device is
|
* @ap: port where the device is
|
||||||
*
|
*
|
||||||
* Reads ATA taskfile status register for currently-selected device
|
* Reads ATA taskfile status register for currently-selected device
|
||||||
* via MMIO and return it's value. This also clears pending interrupts
|
* via MMIO and return its value. This also clears pending interrupts
|
||||||
* from this device
|
* from this device
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
@ -408,6 +459,20 @@ static u8 ata_check_status_mmio(struct ata_port *ap)
|
||||||
return readb((void __iomem *) ap->ioaddr.status_addr);
|
return readb((void __iomem *) ap->ioaddr.status_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_check_status - Read device status reg & clear interrupt
|
||||||
|
* @ap: port where the device is
|
||||||
|
*
|
||||||
|
* Reads ATA taskfile status register for currently-selected device
|
||||||
|
* and return its value. This also clears pending interrupts
|
||||||
|
* from this device
|
||||||
|
*
|
||||||
|
* May be used as the check_status() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
u8 ata_check_status(struct ata_port *ap)
|
u8 ata_check_status(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
if (ap->flags & ATA_FLAG_MMIO)
|
if (ap->flags & ATA_FLAG_MMIO)
|
||||||
|
@ -415,6 +480,20 @@ u8 ata_check_status(struct ata_port *ap)
|
||||||
return ata_check_status_pio(ap);
|
return ata_check_status_pio(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_altstatus - Read device alternate status reg
|
||||||
|
* @ap: port where the device is
|
||||||
|
*
|
||||||
|
* Reads ATA taskfile alternate status register for
|
||||||
|
* currently-selected device and return its value.
|
||||||
|
*
|
||||||
|
* Note: may NOT be used as the check_altstatus() entry in
|
||||||
|
* ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
u8 ata_altstatus(struct ata_port *ap)
|
u8 ata_altstatus(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
if (ap->ops->check_altstatus)
|
if (ap->ops->check_altstatus)
|
||||||
|
@ -425,6 +504,20 @@ u8 ata_altstatus(struct ata_port *ap)
|
||||||
return inb(ap->ioaddr.altstatus_addr);
|
return inb(ap->ioaddr.altstatus_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_chk_err - Read device error reg
|
||||||
|
* @ap: port where the device is
|
||||||
|
*
|
||||||
|
* Reads ATA taskfile error register for
|
||||||
|
* currently-selected device and return its value.
|
||||||
|
*
|
||||||
|
* Note: may NOT be used as the check_err() entry in
|
||||||
|
* ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
u8 ata_chk_err(struct ata_port *ap)
|
u8 ata_chk_err(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
if (ap->ops->check_err)
|
if (ap->ops->check_err)
|
||||||
|
@ -873,10 +966,24 @@ void ata_dev_id_string(u16 *id, unsigned char *s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_noop_dev_select - Select device 0/1 on ATA bus
|
||||||
|
* @ap: ATA channel to manipulate
|
||||||
|
* @device: ATA device (numbered from zero) to select
|
||||||
|
*
|
||||||
|
* This function performs no actual function.
|
||||||
|
*
|
||||||
|
* May be used as the dev_select() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* caller.
|
||||||
|
*/
|
||||||
void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
|
void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_std_dev_select - Select device 0/1 on ATA bus
|
* ata_std_dev_select - Select device 0/1 on ATA bus
|
||||||
* @ap: ATA channel to manipulate
|
* @ap: ATA channel to manipulate
|
||||||
|
@ -884,7 +991,9 @@ void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
|
||||||
*
|
*
|
||||||
* Use the method defined in the ATA specification to
|
* Use the method defined in the ATA specification to
|
||||||
* make either device 0, or device 1, active on the
|
* make either device 0, or device 1, active on the
|
||||||
* ATA channel.
|
* ATA channel. Works with both PIO and MMIO.
|
||||||
|
*
|
||||||
|
* May be used as the dev_select() entry in ata_port_operations.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* caller.
|
* caller.
|
||||||
|
@ -1190,7 +1299,12 @@ err_out:
|
||||||
* ata_bus_probe - Reset and probe ATA bus
|
* ata_bus_probe - Reset and probe ATA bus
|
||||||
* @ap: Bus to probe
|
* @ap: Bus to probe
|
||||||
*
|
*
|
||||||
|
* Master ATA bus probing function. Initiates a hardware-dependent
|
||||||
|
* bus reset, then attempts to identify any devices found on
|
||||||
|
* the bus.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* Zero on success, non-zero on error.
|
* Zero on success, non-zero on error.
|
||||||
|
@ -1229,10 +1343,14 @@ err_out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_port_probe -
|
* ata_port_probe - Mark port as enabled
|
||||||
* @ap:
|
* @ap: Port for which we indicate enablement
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* Modify @ap data structure such that the system
|
||||||
|
* thinks that the entire port is enabled.
|
||||||
|
*
|
||||||
|
* LOCKING: host_set lock, or some other form of
|
||||||
|
* serialization.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ata_port_probe(struct ata_port *ap)
|
void ata_port_probe(struct ata_port *ap)
|
||||||
|
@ -1241,10 +1359,15 @@ void ata_port_probe(struct ata_port *ap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __sata_phy_reset -
|
* __sata_phy_reset - Wake/reset a low-level SATA PHY
|
||||||
* @ap:
|
* @ap: SATA port associated with target SATA PHY.
|
||||||
|
*
|
||||||
|
* This function issues commands to standard SATA Sxxx
|
||||||
|
* PHY registers, to wake up the phy (and device), and
|
||||||
|
* clear any reset condition.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void __sata_phy_reset(struct ata_port *ap)
|
void __sata_phy_reset(struct ata_port *ap)
|
||||||
|
@ -1289,10 +1412,14 @@ void __sata_phy_reset(struct ata_port *ap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __sata_phy_reset -
|
* sata_phy_reset - Reset SATA bus.
|
||||||
* @ap:
|
* @ap: SATA port associated with target SATA PHY.
|
||||||
|
*
|
||||||
|
* This function resets the SATA bus, and then probes
|
||||||
|
* the bus for devices.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void sata_phy_reset(struct ata_port *ap)
|
void sata_phy_reset(struct ata_port *ap)
|
||||||
|
@ -1304,10 +1431,16 @@ void sata_phy_reset(struct ata_port *ap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_port_disable -
|
* ata_port_disable - Disable port.
|
||||||
* @ap:
|
* @ap: Port to be disabled.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* Modify @ap data structure such that the system
|
||||||
|
* thinks that the entire port is disabled, and should
|
||||||
|
* never attempt to probe or communicate with devices
|
||||||
|
* on this port.
|
||||||
|
*
|
||||||
|
* LOCKING: host_set lock, or some other form of
|
||||||
|
* serialization.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ata_port_disable(struct ata_port *ap)
|
void ata_port_disable(struct ata_port *ap)
|
||||||
|
@ -1416,7 +1549,10 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
|
||||||
* ata_set_mode - Program timings and issue SET FEATURES - XFER
|
* ata_set_mode - Program timings and issue SET FEATURES - XFER
|
||||||
* @ap: port on which timings will be programmed
|
* @ap: port on which timings will be programmed
|
||||||
*
|
*
|
||||||
|
* Set ATA device disk transfer mode (PIO3, UDMA6, etc.).
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void ata_set_mode(struct ata_port *ap)
|
static void ata_set_mode(struct ata_port *ap)
|
||||||
|
@ -1467,7 +1603,10 @@ err_out:
|
||||||
* @tmout_pat: impatience timeout
|
* @tmout_pat: impatience timeout
|
||||||
* @tmout: overall timeout
|
* @tmout: overall timeout
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* Sleep until ATA Status register bit BSY clears,
|
||||||
|
* or a timeout occurs.
|
||||||
|
*
|
||||||
|
* LOCKING: None.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1553,10 +1692,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_bus_edd -
|
* ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
|
||||||
* @ap:
|
* @ap: Port to reset and probe
|
||||||
|
*
|
||||||
|
* Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
|
||||||
|
* probe the bus. Not often used these days.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1633,8 +1776,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
|
||||||
* the device is ATA or ATAPI.
|
* the device is ATA or ATAPI.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Inherited from caller. Some functions called by this function
|
* PCI/etc. bus probe sem.
|
||||||
* obtain the host_set lock.
|
* Obtains host_set lock.
|
||||||
*
|
*
|
||||||
* SIDE EFFECTS:
|
* SIDE EFFECTS:
|
||||||
* Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
|
* Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
|
||||||
|
@ -1876,7 +2019,11 @@ static int fgb(u32 bitmap)
|
||||||
* @xfer_mode_out: (output) SET FEATURES - XFER MODE code
|
* @xfer_mode_out: (output) SET FEATURES - XFER MODE code
|
||||||
* @xfer_shift_out: (output) bit shift that selects this mode
|
* @xfer_shift_out: (output) bit shift that selects this mode
|
||||||
*
|
*
|
||||||
|
* Based on host and device capabilities, determine the
|
||||||
|
* maximum transfer mode that is amenable to all.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* Zero on success, negative on error.
|
* Zero on success, negative on error.
|
||||||
|
@ -1909,7 +2056,11 @@ static int ata_choose_xfer_mode(struct ata_port *ap,
|
||||||
* @ap: Port associated with device @dev
|
* @ap: Port associated with device @dev
|
||||||
* @dev: Device to which command will be sent
|
* @dev: Device to which command will be sent
|
||||||
*
|
*
|
||||||
|
* Issue SET FEATURES - XFER MODE command to device @dev
|
||||||
|
* on port @ap.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
|
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
|
||||||
|
@ -1947,10 +2098,13 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_sg_clean -
|
* ata_sg_clean - Unmap DMA memory associated with command
|
||||||
* @qc:
|
* @qc: Command containing DMA memory to be released
|
||||||
|
*
|
||||||
|
* Unmap all mapped DMA memory associated with this command.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ata_sg_clean(struct ata_queued_cmd *qc)
|
static void ata_sg_clean(struct ata_queued_cmd *qc)
|
||||||
|
@ -1981,7 +2135,11 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
|
||||||
* ata_fill_sg - Fill PCI IDE PRD table
|
* ata_fill_sg - Fill PCI IDE PRD table
|
||||||
* @qc: Metadata associated with taskfile to be transferred
|
* @qc: Metadata associated with taskfile to be transferred
|
||||||
*
|
*
|
||||||
|
* Fill PCI IDE PRD (scatter-gather) table with segments
|
||||||
|
* associated with the current disk command.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void ata_fill_sg(struct ata_queued_cmd *qc)
|
static void ata_fill_sg(struct ata_queued_cmd *qc)
|
||||||
|
@ -2028,7 +2186,13 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
|
||||||
* ata_check_atapi_dma - Check whether ATAPI DMA can be supported
|
* ata_check_atapi_dma - Check whether ATAPI DMA can be supported
|
||||||
* @qc: Metadata associated with taskfile to check
|
* @qc: Metadata associated with taskfile to check
|
||||||
*
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*
|
||||||
* RETURNS: 0 when ATAPI DMA can be used
|
* RETURNS: 0 when ATAPI DMA can be used
|
||||||
* nonzero otherwise
|
* nonzero otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -2046,6 +2210,8 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
|
||||||
* ata_qc_prep - Prepare taskfile for submission
|
* ata_qc_prep - Prepare taskfile for submission
|
||||||
* @qc: Metadata associated with taskfile to be prepared
|
* @qc: Metadata associated with taskfile to be prepared
|
||||||
*
|
*
|
||||||
|
* Prepare ATA taskfile for submission.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* spin_lock_irqsave(host_set lock)
|
* spin_lock_irqsave(host_set lock)
|
||||||
*/
|
*/
|
||||||
|
@ -2057,6 +2223,32 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
|
||||||
ata_fill_sg(qc);
|
ata_fill_sg(qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_sg_init_one - Associate command with memory buffer
|
||||||
|
* @qc: Command to be associated
|
||||||
|
* @buf: Memory buffer
|
||||||
|
* @buflen: Length of memory buffer, in bytes.
|
||||||
|
*
|
||||||
|
* Initialize the data-related elements of queued_cmd @qc
|
||||||
|
* to point to a single memory buffer, @buf of byte length @buflen.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_sg_init_one - Prepare a one-entry scatter-gather list.
|
||||||
|
* @qc: Queued command
|
||||||
|
* @buf: transfer buffer
|
||||||
|
* @buflen: length of buf
|
||||||
|
*
|
||||||
|
* Builds a single-entry scatter-gather list to initiate a
|
||||||
|
* transfer utilizing the specified buffer.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
*/
|
||||||
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
|
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
|
||||||
{
|
{
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
|
@ -2074,6 +2266,32 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
|
||||||
sg->length = buflen;
|
sg->length = buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_sg_init - Associate command with scatter-gather table.
|
||||||
|
* @qc: Command to be associated
|
||||||
|
* @sg: Scatter-gather table.
|
||||||
|
* @n_elem: Number of elements in s/g table.
|
||||||
|
*
|
||||||
|
* Initialize the data-related elements of queued_cmd @qc
|
||||||
|
* to point to a scatter-gather table @sg, containing @n_elem
|
||||||
|
* elements.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_sg_init - Assign a scatter gather list to a queued command
|
||||||
|
* @qc: Queued command
|
||||||
|
* @sg: Scatter-gather list
|
||||||
|
* @n_elem: length of sg list
|
||||||
|
*
|
||||||
|
* Attaches a scatter-gather list to a queued command.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
*/
|
||||||
|
|
||||||
void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
|
void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
|
||||||
unsigned int n_elem)
|
unsigned int n_elem)
|
||||||
{
|
{
|
||||||
|
@ -2083,14 +2301,16 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_sg_setup_one -
|
* ata_sg_setup_one - DMA-map the memory buffer associated with a command.
|
||||||
* @qc:
|
* @qc: Command with memory buffer to be mapped.
|
||||||
|
*
|
||||||
|
* DMA-map the memory buffer associated with queued_cmd @qc.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* spin_lock_irqsave(host_set lock)
|
* spin_lock_irqsave(host_set lock)
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
*
|
* Zero on success, negative on error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int ata_sg_setup_one(struct ata_queued_cmd *qc)
|
static int ata_sg_setup_one(struct ata_queued_cmd *qc)
|
||||||
|
@ -2115,13 +2335,16 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_sg_setup -
|
* ata_sg_setup - DMA-map the scatter-gather table associated with a command.
|
||||||
* @qc:
|
* @qc: Command with scatter-gather table to be mapped.
|
||||||
|
*
|
||||||
|
* DMA-map the scatter-gather table associated with queued_cmd @qc.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* spin_lock_irqsave(host_set lock)
|
* spin_lock_irqsave(host_set lock)
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
|
* Zero on success, negative on error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -2151,6 +2374,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
|
||||||
* @ap:
|
* @ap:
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* None. (executing in kernel thread context)
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
*
|
*
|
||||||
|
@ -2198,6 +2422,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
|
||||||
* @ap:
|
* @ap:
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* None. (executing in kernel thread context)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ata_pio_complete (struct ata_port *ap)
|
static void ata_pio_complete (struct ata_port *ap)
|
||||||
|
@ -2240,6 +2465,18 @@ static void ata_pio_complete (struct ata_port *ap)
|
||||||
ata_qc_complete(qc, drv_stat);
|
ata_qc_complete(qc, drv_stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* swap_buf_le16 -
|
||||||
|
* @buf: Buffer to swap
|
||||||
|
* @buf_words: Number of 16-bit words in buffer.
|
||||||
|
*
|
||||||
|
* Swap halves of 16-bit words if needed to convert from
|
||||||
|
* little-endian byte order to native cpu byte order, or
|
||||||
|
* vice-versa.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
*/
|
||||||
void swap_buf_le16(u16 *buf, unsigned int buf_words)
|
void swap_buf_le16(u16 *buf, unsigned int buf_words)
|
||||||
{
|
{
|
||||||
#ifdef __BIG_ENDIAN
|
#ifdef __BIG_ENDIAN
|
||||||
|
@ -2415,6 +2652,7 @@ err_out:
|
||||||
* @ap:
|
* @ap:
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* None. (executing in kernel thread context)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ata_pio_block(struct ata_port *ap)
|
static void ata_pio_block(struct ata_port *ap)
|
||||||
|
@ -2583,6 +2821,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
|
||||||
* transaction completed successfully.
|
* transaction completed successfully.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* Inherited from SCSI layer (none, can sleep)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ata_qc_timeout(struct ata_queued_cmd *qc)
|
static void ata_qc_timeout(struct ata_queued_cmd *qc)
|
||||||
|
@ -2692,6 +2931,7 @@ out:
|
||||||
* @dev: Device from whom we request an available command structure
|
* @dev: Device from whom we request an available command structure
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* None.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
|
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
|
||||||
|
@ -2717,6 +2957,7 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
|
||||||
* @dev: Device from whom we request an available command structure
|
* @dev: Device from whom we request an available command structure
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* None.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
|
struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
|
||||||
|
@ -2781,6 +3022,7 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
|
||||||
* in case something prevents using it.
|
* in case something prevents using it.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void ata_qc_free(struct ata_queued_cmd *qc)
|
void ata_qc_free(struct ata_queued_cmd *qc)
|
||||||
|
@ -2794,9 +3036,13 @@ void ata_qc_free(struct ata_queued_cmd *qc)
|
||||||
/**
|
/**
|
||||||
* ata_qc_complete - Complete an active ATA command
|
* ata_qc_complete - Complete an active ATA command
|
||||||
* @qc: Command to complete
|
* @qc: Command to complete
|
||||||
* @drv_stat: ATA status register contents
|
* @drv_stat: ATA Status register contents
|
||||||
|
*
|
||||||
|
* Indicate to the mid and upper layers that an ATA
|
||||||
|
* command has completed, with either an ok or not-ok status.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -2892,6 +3138,7 @@ err_out:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
|
* ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
|
||||||
* @qc: command to issue to device
|
* @qc: command to issue to device
|
||||||
|
@ -2901,6 +3148,8 @@ err_out:
|
||||||
* classes called "protocols", and issuing each type of protocol
|
* classes called "protocols", and issuing each type of protocol
|
||||||
* is slightly different.
|
* is slightly different.
|
||||||
*
|
*
|
||||||
|
* May be used as the qc_issue() entry in ata_port_operations.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* spin_lock_irqsave(host_set lock)
|
* spin_lock_irqsave(host_set lock)
|
||||||
*
|
*
|
||||||
|
@ -2958,7 +3207,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_bmdma_setup - Set up PCI IDE BMDMA transaction
|
* ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
|
||||||
* @qc: Info associated with this ATA transaction.
|
* @qc: Info associated with this ATA transaction.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
@ -3065,6 +3314,18 @@ static void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
|
||||||
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
|
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_bmdma_start - Start a PCI IDE BMDMA transaction
|
||||||
|
* @qc: Info associated with this ATA transaction.
|
||||||
|
*
|
||||||
|
* Writes the ATA_DMA_START flag to the DMA command register.
|
||||||
|
*
|
||||||
|
* May be used as the bmdma_start() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*/
|
||||||
void ata_bmdma_start(struct ata_queued_cmd *qc)
|
void ata_bmdma_start(struct ata_queued_cmd *qc)
|
||||||
{
|
{
|
||||||
if (qc->ap->flags & ATA_FLAG_MMIO)
|
if (qc->ap->flags & ATA_FLAG_MMIO)
|
||||||
|
@ -3073,6 +3334,20 @@ void ata_bmdma_start(struct ata_queued_cmd *qc)
|
||||||
ata_bmdma_start_pio(qc);
|
ata_bmdma_start_pio(qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_bmdma_setup - Set up PCI IDE BMDMA transaction
|
||||||
|
* @qc: Info associated with this ATA transaction.
|
||||||
|
*
|
||||||
|
* Writes address of PRD table to device's PRD Table Address
|
||||||
|
* register, sets the DMA control register, and calls
|
||||||
|
* ops->exec_command() to start the transfer.
|
||||||
|
*
|
||||||
|
* May be used as the bmdma_setup() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*/
|
||||||
void ata_bmdma_setup(struct ata_queued_cmd *qc)
|
void ata_bmdma_setup(struct ata_queued_cmd *qc)
|
||||||
{
|
{
|
||||||
if (qc->ap->flags & ATA_FLAG_MMIO)
|
if (qc->ap->flags & ATA_FLAG_MMIO)
|
||||||
|
@ -3081,6 +3356,19 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
|
||||||
ata_bmdma_setup_pio(qc);
|
ata_bmdma_setup_pio(qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
|
||||||
|
* @ap: Port associated with this ATA transaction.
|
||||||
|
*
|
||||||
|
* Clear interrupt and error flags in DMA status register.
|
||||||
|
*
|
||||||
|
* May be used as the irq_clear() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*/
|
||||||
|
|
||||||
void ata_bmdma_irq_clear(struct ata_port *ap)
|
void ata_bmdma_irq_clear(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
if (ap->flags & ATA_FLAG_MMIO) {
|
if (ap->flags & ATA_FLAG_MMIO) {
|
||||||
|
@ -3093,6 +3381,19 @@ void ata_bmdma_irq_clear(struct ata_port *ap)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_bmdma_status - Read PCI IDE BMDMA status
|
||||||
|
* @ap: Port associated with this ATA transaction.
|
||||||
|
*
|
||||||
|
* Read and return BMDMA status register.
|
||||||
|
*
|
||||||
|
* May be used as the bmdma_status() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*/
|
||||||
|
|
||||||
u8 ata_bmdma_status(struct ata_port *ap)
|
u8 ata_bmdma_status(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
u8 host_stat;
|
u8 host_stat;
|
||||||
|
@ -3104,6 +3405,19 @@ u8 ata_bmdma_status(struct ata_port *ap)
|
||||||
return host_stat;
|
return host_stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_bmdma_stop - Stop PCI IDE BMDMA transfer
|
||||||
|
* @ap: Port associated with this ATA transaction.
|
||||||
|
*
|
||||||
|
* Clears the ATA_DMA_START flag in the dma control register
|
||||||
|
*
|
||||||
|
* May be used as the bmdma_stop() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* spin_lock_irqsave(host_set lock)
|
||||||
|
*/
|
||||||
|
|
||||||
void ata_bmdma_stop(struct ata_port *ap)
|
void ata_bmdma_stop(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
if (ap->flags & ATA_FLAG_MMIO) {
|
if (ap->flags & ATA_FLAG_MMIO) {
|
||||||
|
@ -3203,13 +3517,18 @@ idle_irq:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_interrupt - Default ATA host interrupt handler
|
* ata_interrupt - Default ATA host interrupt handler
|
||||||
* @irq: irq line
|
* @irq: irq line (unused)
|
||||||
* @dev_instance: pointer to our host information structure
|
* @dev_instance: pointer to our ata_host_set information structure
|
||||||
* @regs: unused
|
* @regs: unused
|
||||||
*
|
*
|
||||||
|
* Default interrupt handler for PCI IDE devices. Calls
|
||||||
|
* ata_host_intr() for each port that is not disabled.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* Obtains host_set lock during operation.
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
|
* IRQ_NONE or IRQ_HANDLED.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3302,6 +3621,19 @@ err_out:
|
||||||
ata_qc_complete(qc, ATA_ERR);
|
ata_qc_complete(qc, ATA_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_port_start - Set port up for dma.
|
||||||
|
* @ap: Port to initialize
|
||||||
|
*
|
||||||
|
* Called just after data structures for each port are
|
||||||
|
* initialized. Allocates space for PRD table.
|
||||||
|
*
|
||||||
|
* May be used as the port_start() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
*/
|
||||||
|
|
||||||
int ata_port_start (struct ata_port *ap)
|
int ata_port_start (struct ata_port *ap)
|
||||||
{
|
{
|
||||||
struct device *dev = ap->host_set->dev;
|
struct device *dev = ap->host_set->dev;
|
||||||
|
@ -3315,6 +3647,18 @@ int ata_port_start (struct ata_port *ap)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_port_stop - Undo ata_port_start()
|
||||||
|
* @ap: Port to shut down
|
||||||
|
*
|
||||||
|
* Frees the PRD table.
|
||||||
|
*
|
||||||
|
* May be used as the port_stop() entry in ata_port_operations.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
*/
|
||||||
|
|
||||||
void ata_port_stop (struct ata_port *ap)
|
void ata_port_stop (struct ata_port *ap)
|
||||||
{
|
{
|
||||||
struct device *dev = ap->host_set->dev;
|
struct device *dev = ap->host_set->dev;
|
||||||
|
@ -3357,7 +3701,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
|
||||||
* @ent: Probe information provided by low-level driver
|
* @ent: Probe information provided by low-level driver
|
||||||
* @port_no: Port number associated with this ata_port
|
* @port_no: Port number associated with this ata_port
|
||||||
*
|
*
|
||||||
|
* Initialize a new ata_port structure, and its associated
|
||||||
|
* scsi_host.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3412,9 +3760,13 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
|
||||||
* @host_set: Collections of ports to which we add
|
* @host_set: Collections of ports to which we add
|
||||||
* @port_no: Port number associated with this host
|
* @port_no: Port number associated with this host
|
||||||
*
|
*
|
||||||
|
* Attach low-level ATA driver to system.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
|
* New ata_port on success, for NULL on error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3447,12 +3799,22 @@ err_out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_device_add -
|
* ata_device_add - Register hardware device with ATA and SCSI layers
|
||||||
* @ent:
|
* @ent: Probe information describing hardware device to be registered
|
||||||
|
*
|
||||||
|
* This function processes the information provided in the probe
|
||||||
|
* information struct @ent, allocates the necessary ATA and SCSI
|
||||||
|
* host information structures, initializes them, and registers
|
||||||
|
* everything with requisite kernel subsystems.
|
||||||
|
*
|
||||||
|
* This function requests irqs, probes the ATA bus, and probes
|
||||||
|
* the SCSI bus.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
|
* PCI/etc. bus probe sem.
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
|
* Number of ports registered. Zero on error (no ports registered).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3604,7 +3966,15 @@ int ata_scsi_release(struct Scsi_Host *host)
|
||||||
/**
|
/**
|
||||||
* ata_std_ports - initialize ioaddr with standard port offsets.
|
* ata_std_ports - initialize ioaddr with standard port offsets.
|
||||||
* @ioaddr: IO address structure to be initialized
|
* @ioaddr: IO address structure to be initialized
|
||||||
|
*
|
||||||
|
* Utility function which initializes data_addr, error_addr,
|
||||||
|
* feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
|
||||||
|
* device_addr, status_addr, and command_addr to standard offsets
|
||||||
|
* relative to cmd_addr.
|
||||||
|
*
|
||||||
|
* Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ata_std_ports(struct ata_ioports *ioaddr)
|
void ata_std_ports(struct ata_ioports *ioaddr)
|
||||||
{
|
{
|
||||||
ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
|
ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
|
||||||
|
@ -3646,6 +4016,20 @@ ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
|
||||||
return probe_ent;
|
return probe_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_pci_init_native_mode - Initialize native-mode driver
|
||||||
|
* @pdev: pci device to be initialized
|
||||||
|
* @port: array[2] of pointers to port info structures.
|
||||||
|
*
|
||||||
|
* Utility function which allocates and initializes an
|
||||||
|
* ata_probe_ent structure for a standard dual-port
|
||||||
|
* PIO-based IDE controller. The returned ata_probe_ent
|
||||||
|
* structure can be passed to ata_device_add(). The returned
|
||||||
|
* ata_probe_ent structure should then be freed with kfree().
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
struct ata_probe_ent *
|
struct ata_probe_ent *
|
||||||
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
|
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
|
||||||
|
@ -3727,10 +4111,19 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
|
||||||
* @port_info: Information from low-level host driver
|
* @port_info: Information from low-level host driver
|
||||||
* @n_ports: Number of ports attached to host controller
|
* @n_ports: Number of ports attached to host controller
|
||||||
*
|
*
|
||||||
|
* This is a helper function which can be called from a driver's
|
||||||
|
* xxx_init_one() probe function if the hardware uses traditional
|
||||||
|
* IDE taskfile registers.
|
||||||
|
*
|
||||||
|
* This function calls pci_enable_device(), reserves its register
|
||||||
|
* regions, sets the dma mask, enables bus master mode, and calls
|
||||||
|
* ata_device_add()
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Inherited from PCI layer (may sleep).
|
* Inherited from PCI layer (may sleep).
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
|
* Zero on success, negative on errno-based value on error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3949,15 +4342,6 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits)
|
||||||
#endif /* CONFIG_PCI */
|
#endif /* CONFIG_PCI */
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ata_init -
|
|
||||||
*
|
|
||||||
* LOCKING:
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int __init ata_init(void)
|
static int __init ata_init(void)
|
||||||
{
|
{
|
||||||
ata_wq = create_workqueue("ata");
|
ata_wq = create_workqueue("ata");
|
||||||
|
|
|
@ -947,7 +947,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_scsiop_noop -
|
* ata_scsiop_noop - Command handler that simply returns success.
|
||||||
* @args: device IDENTIFY data / SCSI command of interest.
|
* @args: device IDENTIFY data / SCSI command of interest.
|
||||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||||
* @buflen: Response buffer length.
|
* @buflen: Response buffer length.
|
||||||
|
|
|
@ -467,12 +467,34 @@ static inline u8 ata_chk_status(struct ata_port *ap)
|
||||||
return ap->ops->check_status(ap);
|
return ap->ops->check_status(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_pause - Flush writes and pause 400 nanoseconds.
|
||||||
|
* @ap: Port to wait for.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
|
|
||||||
static inline void ata_pause(struct ata_port *ap)
|
static inline void ata_pause(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
ata_altstatus(ap);
|
ata_altstatus(ap);
|
||||||
ndelay(400);
|
ndelay(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_busy_wait - Wait for a port status register
|
||||||
|
* @ap: Port to wait for.
|
||||||
|
*
|
||||||
|
* Waits up to max*10 microseconds for the selected bits in the port's
|
||||||
|
* status register to be cleared.
|
||||||
|
* Returns final value of status register.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
|
|
||||||
static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
|
static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
|
||||||
unsigned int max)
|
unsigned int max)
|
||||||
{
|
{
|
||||||
|
@ -487,6 +509,18 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_wait_idle - Wait for a port to be idle.
|
||||||
|
* @ap: Port to wait for.
|
||||||
|
*
|
||||||
|
* Waits up to 10ms for port's BUSY and DRQ signals to clear.
|
||||||
|
* Returns final value of status register.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
|
|
||||||
static inline u8 ata_wait_idle(struct ata_port *ap)
|
static inline u8 ata_wait_idle(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
|
u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
|
||||||
|
@ -525,6 +559,18 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns
|
||||||
tf->device = ATA_DEVICE_OBS | ATA_DEV1;
|
tf->device = ATA_DEVICE_OBS | ATA_DEV1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_irq_on - Enable interrupts on a port.
|
||||||
|
* @ap: Port on which interrupts are enabled.
|
||||||
|
*
|
||||||
|
* Enable interrupts on a legacy IDE device using MMIO or PIO,
|
||||||
|
* wait for idle, clear any pending interrupts.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Inherited from caller.
|
||||||
|
*/
|
||||||
|
|
||||||
static inline u8 ata_irq_on(struct ata_port *ap)
|
static inline u8 ata_irq_on(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||||
|
@ -544,6 +590,18 @@ static inline u8 ata_irq_on(struct ata_port *ap)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_irq_ack - Acknowledge a device interrupt.
|
||||||
|
* @ap: Port on which interrupts are enabled.
|
||||||
|
*
|
||||||
|
* Wait up to 10 ms for legacy IDE device to become idle (BUSY
|
||||||
|
* or BUSY+DRQ clear). Obtain dma status and port status from
|
||||||
|
* device. Clear the interrupt. Return port status.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
*/
|
||||||
|
|
||||||
static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
|
static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
|
||||||
{
|
{
|
||||||
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
|
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
|
||||||
|
|
Loading…
Reference in New Issue