summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@redhat.com>2004-05-13 12:35:48 -0400
committerJeff Garzik <jgarzik@redhat.com>2004-05-13 12:35:48 -0400
commit8fdb45f52c108cf1c02078681b87209a3bf10656 (patch)
treedfd840b5cb399dce4f28bdce31463fa046783d40
parent141baf80514374935d084c12f2f1e426e9cea5a0 (diff)
[libata] add new ->bmdma_setup hook
In order to support some new taskfile protocols, particularly ATAPI, the setup-and-start-DMA hook needs to be split into its component pieces, 'setup' and 'start'. For PCI IDE-style controllers, most of the code is moved into the 'setup' portion, with the 'start' portion only flipping a single bit in hardware.
-rw-r--r--drivers/scsi/ata_piix.c2
-rw-r--r--drivers/scsi/libata-core.c46
-rw-r--r--drivers/scsi/sata_promise.c8
-rw-r--r--drivers/scsi/sata_sil.c1
-rw-r--r--drivers/scsi/sata_sis.c1
-rw-r--r--drivers/scsi/sata_svw.c1
-rw-r--r--drivers/scsi/sata_sx4.c8
-rw-r--r--drivers/scsi/sata_via.c1
-rw-r--r--drivers/scsi/sata_vsc.c1
-rw-r--r--include/linux/libata.h3
10 files changed, 66 insertions, 6 deletions
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 0d99b2bb26ae..140ae2b93f1e 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -136,6 +136,7 @@ static struct ata_port_operations piix_pata_ops = {
.phy_reset = piix_pata_phy_reset,
+ .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
@@ -158,6 +159,7 @@ static struct ata_port_operations piix_sata_ops = {
.phy_reset = piix_sata_phy_reset,
+ .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index c60d6903c5aa..6524b3159bf6 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2445,6 +2445,7 @@ static int ata_qc_issue_prot(struct ata_queued_cmd *qc)
case ATA_PROT_DMA:
ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
+ ap->ops->bmdma_setup(qc); /* initiate bmdma */
ap->ops->bmdma_start(qc); /* initiate bmdma */
break;
@@ -2465,14 +2466,14 @@ static int ata_qc_issue_prot(struct ata_queued_cmd *qc)
}
/**
- * ata_bmdma_start_mmio -
- * @qc:
+ * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction (MMIO)
+ * @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
+void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
@@ -2496,8 +2497,24 @@ void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
/* issue r/w command */
ap->ops->exec_command(ap, &qc->tf);
+}
+
+/**
+ * ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction (MMIO)
+ * @qc: Info associated with this ATA transaction.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+
+void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void *mmio = (void *) ap->ioaddr.bmdma_addr;
+ u8 dmactl;
/* start host DMA transaction */
+ dmactl = readb(mmio + ATA_DMA_CMD);
writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);
/* Strictly, one may wish to issue a readb() here, to
@@ -2514,14 +2531,14 @@ void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
}
/**
- * ata_bmdma_start_pio -
- * @qc:
+ * ata_bmdma_setup_pio - Set up PCI IDE BMDMA transaction (PIO)
+ * @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
+void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
@@ -2544,8 +2561,23 @@ void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
/* issue r/w command */
ap->ops->exec_command(ap, &qc->tf);
+}
+
+/**
+ * ata_bmdma_start_pio - Start a PCI IDE BMDMA transaction (PIO)
+ * @qc: Info associated with this ATA transaction.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+
+void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ u8 dmactl;
/* start host DMA transaction */
+ dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
outb(dmactl | ATA_DMA_START,
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
@@ -3475,7 +3507,9 @@ EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_port_stop);
EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_fill_sg);
+EXPORT_SYMBOL_GPL(ata_bmdma_setup_pio);
EXPORT_SYMBOL_GPL(ata_bmdma_start_pio);
+EXPORT_SYMBOL_GPL(ata_bmdma_setup_mmio);
EXPORT_SYMBOL_GPL(ata_bmdma_start_mmio);
EXPORT_SYMBOL_GPL(ata_port_probe);
EXPORT_SYMBOL_GPL(sata_phy_reset);
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index c31b85ec6840..2b41bdbcfbc9 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -74,6 +74,7 @@ struct pdc_port_priv {
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static void pdc_dma_setup(struct ata_queued_cmd *qc);
static void pdc_dma_start(struct ata_queued_cmd *qc);
static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static void pdc_eng_timeout(struct ata_port *ap);
@@ -111,6 +112,7 @@ static struct ata_port_operations pdc_sata_ops = {
.check_status = ata_check_status_mmio,
.exec_command = pdc_exec_command_mmio,
.phy_reset = pdc_phy_reset,
+ .bmdma_setup = pdc_dma_setup,
.bmdma_start = pdc_dma_start,
.fill_sg = pdc_fill_sg,
.eng_timeout = pdc_eng_timeout,
@@ -431,6 +433,12 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
return IRQ_RETVAL(handled);
}
+static void pdc_dma_setup(struct ata_queued_cmd *qc)
+{
+ /* nothing for now. later, we will call standard
+ * code in libata-core for ATAPI here */
+}
+
static void pdc_dma_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 45a579cde6b5..f21d3aa00629 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -129,6 +129,7 @@ static struct ata_port_operations sil_ops = {
.exec_command = ata_exec_command_mmio,
.phy_reset = sata_phy_reset,
.post_set_mode = sil_post_set_mode,
+ .bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 92f1d51c9306..d60c5443091c 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -98,6 +98,7 @@ static struct ata_port_operations sis_ops = {
.check_status = ata_check_status_pio,
.exec_command = ata_exec_command_pio,
.phy_reset = sata_phy_reset,
+ .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index c7237e1669f3..4dac5f67dc22 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -231,6 +231,7 @@ static struct ata_port_operations k2_sata_ops = {
.check_status = k2_stat_check_status,
.exec_command = ata_exec_command_mmio,
.phy_reset = sata_phy_reset,
+ .bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 24e18a18c6b8..a93c571fe323 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -146,6 +146,7 @@ struct pdc_host_priv {
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static void pdc20621_dma_setup(struct ata_queued_cmd *qc);
static void pdc20621_dma_start(struct ata_queued_cmd *qc);
static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static void pdc_eng_timeout(struct ata_port *ap);
@@ -197,6 +198,7 @@ static struct ata_port_operations pdc_20621_ops = {
.check_status = ata_check_status_mmio,
.exec_command = pdc_exec_command_mmio,
.phy_reset = pdc_20621_phy_reset,
+ .bmdma_setup = pdc20621_dma_setup,
.bmdma_start = pdc20621_dma_start,
.fill_sg = pdc20621_fill_sg,
.eng_timeout = pdc_eng_timeout,
@@ -568,6 +570,12 @@ static void pdc20621_dump_hdma(struct ata_queued_cmd *qc)
static inline void pdc20621_dump_hdma(struct ata_queued_cmd *qc) { }
#endif /* ATA_VERBOSE_DEBUG */
+static void pdc20621_dma_setup(struct ata_queued_cmd *qc)
+{
+ /* nothing for now. later, we will call standard
+ * code in libata-core for ATAPI here */
+}
+
static void pdc20621_dma_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index e282e388294f..c4385bc01c29 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -106,6 +106,7 @@ static struct ata_port_operations svia_sata_ops = {
.phy_reset = sata_phy_reset,
+ .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index 71e3f8b1faf6..93344b7010b3 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -213,6 +213,7 @@ static struct ata_port_operations vsc_sata_ops = {
.exec_command = ata_exec_command_mmio,
.check_status = ata_check_status_mmio,
.phy_reset = sata_phy_reset,
+ .bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
diff --git a/include/linux/libata.h b/include/linux/libata.h
index efcc745effae..cf2a784a8850 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -335,6 +335,7 @@ struct ata_port_operations {
void (*phy_reset) (struct ata_port *ap);
void (*post_set_mode) (struct ata_port *ap);
+ void (*bmdma_setup) (struct ata_queued_cmd *qc);
void (*bmdma_start) (struct ata_queued_cmd *qc);
void (*fill_sg) (struct ata_queued_cmd *qc);
void (*eng_timeout) (struct ata_port *ap);
@@ -397,7 +398,9 @@ extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap);
extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
extern void ata_fill_sg(struct ata_queued_cmd *qc);
+extern void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc);
extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc);
+extern void ata_bmdma_setup_pio (struct ata_queued_cmd *qc);
extern void ata_bmdma_start_pio (struct ata_queued_cmd *qc);
extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat, unsigned int done_late);