aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-sff.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2007-06-07 11:19:15 -0400
committerJeff Garzik <jeff@garzik.org>2007-06-09 22:40:28 -0400
commitd92e74d353345d19f762e9501a50b0a5f43f7ba8 (patch)
tree9a526823ddba8dd8cd07bb5d918acf7c5e820db7 /drivers/ata/libata-sff.c
parent0522b2869d89b095bf417c8cc6fa404842e91903 (diff)
libata-core/sff: Fix multiple assumptions about DMA
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> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r--drivers/ata/libata-sff.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index e35d13466c69..ce84805ba5f1 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -80,25 +80,25 @@ u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; }
80u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) 80u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
81{ 81{
82 unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; 82 unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
83 u8 host_stat, post_stat, status; 83 u8 host_stat = 0, post_stat = 0, status;
84 84
85 status = ata_busy_wait(ap, bits, 1000); 85 status = ata_busy_wait(ap, bits, 1000);
86 if (status & bits) 86 if (status & bits)
87 if (ata_msg_err(ap)) 87 if (ata_msg_err(ap))
88 printk(KERN_ERR "abnormal status 0x%X\n", status); 88 printk(KERN_ERR "abnormal status 0x%X\n", status);
89 89
90 /* get controller status; clear intr, err bits */ 90 if (ap->ioaddr.bmdma_addr) {
91 host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); 91 /* get controller status; clear intr, err bits */
92 iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, 92 host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
93 ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); 93 iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
94 94 ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
95 post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
96 95
96 post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
97 }
97 if (ata_msg_intr(ap)) 98 if (ata_msg_intr(ap))
98 printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n", 99 printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
99 __FUNCTION__, 100 __FUNCTION__,
100 host_stat, post_stat, status); 101 host_stat, post_stat, status);
101
102 return status; 102 return status;
103} 103}
104 104
@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
516 ata_bmdma_stop(qc); 516 ata_bmdma_stop(qc);
517} 517}
518 518
519/**
520 * ata_sff_port_start - Set port up for dma.
521 * @ap: Port to initialize
522 *
523 * Called just after data structures for each port are
524 * initialized. Allocates space for PRD table if the device
525 * is DMA capable SFF.
526 *
527 * May be used as the port_start() entry in ata_port_operations.
528 *
529 * LOCKING:
530 * Inherited from caller.
531 */
532
533int ata_sff_port_start(struct ata_port *ap)
534{
535 if (ap->ioaddr.bmdma_addr)
536 return ata_port_start(ap);
537 return 0;
538}
539
519#ifdef CONFIG_PCI 540#ifdef CONFIG_PCI
520 541
521static int ata_resources_present(struct pci_dev *pdev, int port) 542static int ata_resources_present(struct pci_dev *pdev, int port)