* [PATCH] libata-core/sff: Fix multiple assumptions about DMA
@ 2007-06-07 15:19 Alan Cox
2007-06-10 2:43 ` Jeff Garzik
0 siblings, 1 reply; 2+ messages in thread
From: Alan Cox @ 2007-06-07 15:19 UTC (permalink / raw)
To: akpm, linux-ide, jeff
The ata IRQ ack functions are only used when debugging. Unfortunately
almost every controller that calls them can cause crashes in some
configurations as there are missing checks for bmdma presence.
In addition ata_port_start insists of installing DMA buffers and pad
buffers for controllers regardless. The SFF controllers actually need to
make that decision dynamically at controller setup time and all need the
same helper - so we add ata_sff_port_start. Future patches will switch
the SFF drivers to use this.
Signed-off-by: Alan Cox <alan@redhat.com>
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.22-rc4-mm2/drivers/ata/libata-core.c linux-2.6.22-rc4-mm2/drivers/ata/libata-core.c
--- linux.vanilla-2.6.22-rc4-mm2/drivers/ata/libata-core.c 2007-06-07 14:26:08.000000000 +0100
+++ linux-2.6.22-rc4-mm2/drivers/ata/libata-core.c 2007-06-07 14:45:37.000000000 +0100
@@ -6888,6 +6946,7 @@
EXPORT_SYMBOL_GPL(ata_altstatus);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
+EXPORT_SYMBOL_GPL(ata_sff_port_start);
EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_data_xfer);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.22-rc4-mm2/drivers/ata/libata-sff.c linux-2.6.22-rc4-mm2/drivers/ata/libata-sff.c
--- linux.vanilla-2.6.22-rc4-mm2/drivers/ata/libata-sff.c 2007-06-07 14:25:57.000000000 +0100
+++ linux-2.6.22-rc4-mm2/drivers/ata/libata-sff.c 2007-06-07 14:31:24.000000000 +0100
@@ -80,25 +80,25 @@
u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
{
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
- u8 host_stat, post_stat, status;
+ u8 host_stat = 0, post_stat = 0, status;
status = ata_busy_wait(ap, bits, 1000);
if (status & bits)
if (ata_msg_err(ap))
printk(KERN_ERR "abnormal status 0x%X\n", status);
- /* get controller status; clear intr, err bits */
- host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
- ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-
- post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ if (ap->ioaddr.bmdma_addr) {
+ /* get controller status; clear intr, err bits */
+ host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+ ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ }
if (ata_msg_intr(ap))
printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
__FUNCTION__,
host_stat, post_stat, status);
-
return status;
}
@@ -516,6 +516,27 @@
ata_bmdma_stop(qc);
}
+/**
+ * ata_sff_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 if the device
+ * is DMA capable SFF.
+ *
+ * May be used as the port_start() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+
+int ata_sff_port_start(struct ata_port *ap)
+{
+ if (ap->ioaddr.bmdma_addr)
+ return ata_port_start(ap);
+ return 0;
+}
+
#ifdef CONFIG_PCI
static int ata_resources_present(struct pci_dev *pdev, int port)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.22-rc4-mm2/include/linux/libata.h linux-2.6.22-rc4-mm2/include/linux/libata.h
--- linux.vanilla-2.6.22-rc4-mm2/include/linux/libata.h 2007-06-07 14:26:10.000000000 +0100
+++ linux-2.6.22-rc4-mm2/include/linux/libata.h 2007-06-07 14:38:07.000000000 +0100
@@ -783,6 +786,7 @@
extern u8 ata_altstatus(struct ata_port *ap);
extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
extern int ata_port_start (struct ata_port *ap);
+extern int ata_sff_port_start (struct ata_port *ap);
extern irqreturn_t ata_interrupt (int irq, void *dev_instance);
extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
unsigned int buflen, int write_data);
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] libata-core/sff: Fix multiple assumptions about DMA
2007-06-07 15:19 [PATCH] libata-core/sff: Fix multiple assumptions about DMA Alan Cox
@ 2007-06-10 2:43 ` Jeff Garzik
0 siblings, 0 replies; 2+ messages in thread
From: Jeff Garzik @ 2007-06-10 2:43 UTC (permalink / raw)
To: Alan Cox; +Cc: akpm, linux-ide
Alan Cox wrote:
> The ata IRQ ack functions are only used when debugging. Unfortunately
> almost every controller that calls them can cause crashes in some
> configurations as there are missing checks for bmdma presence.
>
> In addition ata_port_start insists of installing DMA buffers and pad
> buffers for controllers regardless. The SFF controllers actually need to
> make that decision dynamically at controller setup time and all need the
> same helper - so we add ata_sff_port_start. Future patches will switch
> the SFF drivers to use this.
>
> Signed-off-by: Alan Cox <alan@redhat.com>
applied to #upstream-fixes
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-06-10 2:43 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-07 15:19 [PATCH] libata-core/sff: Fix multiple assumptions about DMA Alan Cox
2007-06-10 2:43 ` Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).