[libata] Move some bmdma-specific code to libata-bmdma.c
[safe/jmp/linux-2.6] / drivers / scsi / libata-core.c
index 8c86ae8..f3c115b 100644 (file)
@@ -1221,13 +1221,6 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
         * common ATA, ATAPI feature tests
         */
 
-       /* we require DMA support (bits 8 of word 49) */
-       if (!ata_id_has_dma(id)) {
-               printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
-               rc = -EINVAL;
-               goto err_out_nosup;
-       }
-
        /* find max transfer mode; for printk only */
        xfer_mask = ata_id_xfermask(id);
 
@@ -1739,7 +1732,7 @@ static int ata_host_set_pio(struct ata_port *ap)
                        continue;
 
                if (!dev->pio_mode) {
-                       printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
+                       printk(KERN_WARNING "ata%u: no PIO support for device %d.\n", ap->id, i);
                        return -1;
                }
 
@@ -2001,9 +1994,19 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
         * status is checked.  Because waiting for "a while" before
         * checking status is fine, post SRST, we perform this magic
         * delay here as well.
+        *
+        * Old drivers/ide uses the 2mS rule and then waits for ready
         */
        msleep(150);
 
+       
+       /* Before we perform post reset processing we want to see if 
+          the bus shows 0xFF because the odd clown forgets the D7 pulldown
+          resistor */
+       
+       if (ata_check_status(ap) == 0xFF)
+               return 1;       /* Positive is failure for some reason */
+
        ata_bus_post_reset(ap, devmask);
 
        return 0;
@@ -2553,48 +2556,72 @@ int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
 }
 
 static const char * const ata_dma_blacklist [] = {
-       "WDC AC11000H",
-       "WDC AC22100H",
-       "WDC AC32500H",
-       "WDC AC33100H",
-       "WDC AC31600H",
-       "WDC AC32100H",
-       "WDC AC23200L",
-       "Compaq CRD-8241B",
-       "CRD-8400B",
-       "CRD-8480B",
-       "CRD-8482B",
-       "CRD-84",
-       "SanDisk SDP3B",
-       "SanDisk SDP3B-64",
-       "SANYO CD-ROM CRD",
-       "HITACHI CDR-8",
-       "HITACHI CDR-8335",
-       "HITACHI CDR-8435",
-       "Toshiba CD-ROM XM-6202B",
-       "TOSHIBA CD-ROM XM-1702BC",
-       "CD-532E-A",
-       "E-IDE CD-ROM CR-840",
-       "CD-ROM Drive/F5A",
-       "WPI CDD-820",
-       "SAMSUNG CD-ROM SC-148C",
-       "SAMSUNG CD-ROM SC",
-       "SanDisk SDP3B-64",
-       "ATAPI CD-ROM DRIVE 40X MAXIMUM",
-       "_NEC DV5800A",
+       "WDC AC11000H", NULL,
+       "WDC AC22100H", NULL,
+       "WDC AC32500H", NULL,
+       "WDC AC33100H", NULL,
+       "WDC AC31600H", NULL,
+       "WDC AC32100H", "24.09P07",
+       "WDC AC23200L", "21.10N21",
+       "Compaq CRD-8241B",  NULL,
+       "CRD-8400B", NULL,
+       "CRD-8480B", NULL,
+       "CRD-8482B", NULL,
+       "CRD-84", NULL,
+       "SanDisk SDP3B", NULL,
+       "SanDisk SDP3B-64", NULL,
+       "SANYO CD-ROM CRD", NULL,
+       "HITACHI CDR-8", NULL,
+       "HITACHI CDR-8335", NULL, 
+       "HITACHI CDR-8435", NULL,
+       "Toshiba CD-ROM XM-6202B", NULL, 
+       "TOSHIBA CD-ROM XM-1702BC", NULL, 
+       "CD-532E-A", NULL, 
+       "E-IDE CD-ROM CR-840", NULL, 
+       "CD-ROM Drive/F5A", NULL, 
+       "WPI CDD-820", NULL, 
+       "SAMSUNG CD-ROM SC-148C", NULL,
+       "SAMSUNG CD-ROM SC", NULL, 
+       "SanDisk SDP3B-64", NULL,
+       "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,
+       "_NEC DV5800A", NULL,
+       "SAMSUNG CD-ROM SN-124", "N001"
 };
+static int ata_strim(char *s, size_t len)
+{
+       len = strnlen(s, len);
+
+       /* ATAPI specifies that empty space is blank-filled; remove blanks */
+       while ((len > 0) && (s[len - 1] == ' ')) {
+               len--;
+               s[len] = 0;
+       }
+       return len;
+}
 
 static int ata_dma_blacklisted(const struct ata_device *dev)
 {
-       unsigned char model_num[41];
+       unsigned char model_num[40];
+       unsigned char model_rev[16];
+       unsigned int nlen, rlen;
        int i;
 
-       ata_id_c_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
-
-       for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++)
-               if (!strcmp(ata_dma_blacklist[i], model_num))
-                       return 1;
+       ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
+                         sizeof(model_num));
+       ata_id_string(dev->id, model_rev, ATA_ID_FW_REV_OFS,
+                         sizeof(model_rev));
+       nlen = ata_strim(model_num, sizeof(model_num));
+       rlen = ata_strim(model_rev, sizeof(model_rev));
 
+       for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) {
+               if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) {
+                       if (ata_dma_blacklist[i+1] == NULL)
+                               return 1;
+                       if (!strncmp(ata_dma_blacklist[i], model_rev, rlen))
+                               return 1;
+               }
+       }
        return 0;
 }
 
@@ -4038,237 +4065,6 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
 }
 
 /**
- *     ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
- *     @qc: Info associated with this ATA transaction.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
- */
-
-static 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);
-       u8 dmactl;
-       void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-
-       /* load PRD table addr. */
-       mb();   /* make sure PRD table writes are visible to controller */
-       writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
-
-       /* specify data direction, triple-check start bit is clear */
-       dmactl = readb(mmio + ATA_DMA_CMD);
-       dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
-       if (!rw)
-               dmactl |= ATA_DMA_WR;
-       writeb(dmactl, mmio + ATA_DMA_CMD);
-
-       /* issue r/w command */
-       ap->ops->exec_command(ap, &qc->tf);
-}
-
-/**
- *     ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction
- *     @qc: Info associated with this ATA transaction.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
- */
-
-static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       void __iomem *mmio = (void __iomem *) 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
-        * flush the mmio write.  However, control also passes
-        * to the hardware at this point, and it will interrupt
-        * us when we are to resume control.  So, in effect,
-        * we don't care when the mmio write flushes.
-        * Further, a read of the DMA status register _immediately_
-        * following the write may not be what certain flaky hardware
-        * is expected, so I think it is best to not add a readb()
-        * without first all the MMIO ATA cards/mobos.
-        * Or maybe I'm just being paranoid.
-        */
-}
-
-/**
- *     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)
- */
-
-static 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);
-       u8 dmactl;
-
-       /* load PRD table addr. */
-       outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
-
-       /* specify data direction, triple-check start bit is clear */
-       dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-       dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
-       if (!rw)
-               dmactl |= ATA_DMA_WR;
-       outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
-       /* 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)
- */
-
-static 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);
-}
-
-
-/**
- *     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)
-{
-       if (qc->ap->flags & ATA_FLAG_MMIO)
-               ata_bmdma_start_mmio(qc);
-       else
-               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)
-{
-       if (qc->ap->flags & ATA_FLAG_MMIO)
-               ata_bmdma_setup_mmio(qc);
-       else
-               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)
-{
-    if (ap->flags & ATA_FLAG_MMIO) {
-        void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
-        writeb(readb(mmio), mmio);
-    } else {
-        unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
-        outb(inb(addr), addr);
-    }
-
-}
-
-
-/**
- *     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 host_stat;
-       if (ap->flags & ATA_FLAG_MMIO) {
-               void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-               host_stat = readb(mmio + ATA_DMA_STATUS);
-       } else
-               host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-       return host_stat;
-}
-
-
-/**
- *     ata_bmdma_stop - Stop PCI IDE BMDMA transfer
- *     @qc: Command we are ending DMA for
- *
- *     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_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       if (ap->flags & ATA_FLAG_MMIO) {
-               void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-
-               /* clear start/stop bit */
-               writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
-                       mmio + ATA_DMA_CMD);
-       } else {
-               /* clear start/stop bit */
-               outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
-                       ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-       }
-
-       /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-       ata_altstatus(ap);        /* dummy read */
-}
-
-/**
  *     ata_host_intr - Handle host interrupt for given (port, task)
  *     @ap: Port on which interrupt arrived (possibly...)
  *     @qc: Taskfile currently active in engine
@@ -4340,9 +4136,9 @@ idle_irq:
 
 #ifdef ATA_IRQ_TRAP
        if ((ap->stats.idle_irq % 1000) == 0) {
-               handled = 1;
                ata_irq_ack(ap, 0); /* debug trap */
                printk(KERN_WARNING "ata%d: irq trap\n", ap->id);
+               return 1;
        }
 #endif
        return 0;       /* irq not handled */
@@ -4656,6 +4452,8 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
        if (!host)
                return NULL;
 
+       host->transportt = &ata_scsi_transport_template;
+
        ap = (struct ata_port *) &host->hostdata[0];
 
        ata_host_init(ap, host, host_set, ent, port_no);
@@ -5088,7 +4886,6 @@ EXPORT_SYMBOL_GPL(ata_busy_sleep);
 EXPORT_SYMBOL_GPL(ata_port_queue_task);
 EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
 EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
-EXPORT_SYMBOL_GPL(ata_scsi_timed_out);
 EXPORT_SYMBOL_GPL(ata_scsi_error);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 EXPORT_SYMBOL_GPL(ata_scsi_release);
@@ -5112,6 +4909,8 @@ EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
 EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
 EXPORT_SYMBOL_GPL(ata_pci_device_resume);
+EXPORT_SYMBOL_GPL(ata_pci_default_filter);
+EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
 #endif /* CONFIG_PCI */
 
 EXPORT_SYMBOL_GPL(ata_device_suspend);