ide: add IDE_HFLAG_CLEAR_SIMPLEX host flag
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Fri, 1 Feb 2008 22:09:30 +0000 (23:09 +0100)
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Fri, 1 Feb 2008 22:09:30 +0000 (23:09 +0100)
* Rename 'simplex_stat' variable to 'dma_stat' in ide_get_or_set_dma_base().

* Factor out code for forcing host out of "simplex" mode from
  ide_get_or_set_dma_base() to ide_pci_clear_simplex() helper.

* Add IDE_HFLAG_CLEAR_SIMPLEX host flag and set it in alim15x3 (for M5229),
  amd74xx (for AMD 7409), cmd64x (for CMD643), generic (for Netcell) and
  serverworks (for CSB5) host drivers.

* Make ide_get_or_set_dma_base() test for IDE_HFLAG_CLEAR_SIMPLEX host flag
  instead of checking dev->device (BTW the code was buggy because it didn't
  check for dev->vendor, luckily none of these PCI Device IDs was used by
  some other vendor for PCI IDE controller).

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
drivers/ide/pci/alim15x3.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/generic.c
drivers/ide/pci/serverworks.c
drivers/ide/setup-pci.c
include/linux/ide.h

index 9dd7cb4..0b65a2c 100644 (file)
@@ -775,7 +775,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
        };
 
        struct ide_port_info d = ali15x3_chipset;
-       u8 rev = dev->revision;
+       u8 rev = dev->revision, idx = id->driver_data;
 
        if (pci_dev_present(ati_rs100))
                printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
@@ -798,6 +798,9 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
                        d.udma_mask = ATA_UDMA6;
        }
 
+       if (idx == 0)
+               d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX;
+
 #if defined(CONFIG_SPARC64)
        d.init_hwif = init_hwif_common_ali15x3;
 #endif /* CONFIG_SPARC64 */
@@ -807,7 +810,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
 
 static const struct pci_device_id alim15x3_pci_tbl[] = {
        { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 },
-       { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 0 },
+       { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 1 },
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl);
index 13c9f67..2e8cbca 100644 (file)
@@ -295,6 +295,7 @@ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_
        if (idx == 1) {
                if (dev->revision <= 7)
                        d.swdma_mask = 0;
+               d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX;
        } else if (idx == 4) {
                if (dev->subsystem_vendor == PCI_VENDOR_ID_AMD &&
                    dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE)
index cd4eb9d..effd79a 100644 (file)
@@ -443,7 +443,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
                .init_chipset   = init_chipset_cmd64x,
                .init_hwif      = init_hwif_cmd64x,
                .enablebits     = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
-               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+               .host_flags     = IDE_HFLAG_CLEAR_SIMPLEX |
+                                 IDE_HFLAG_ABUSE_PREFETCH |
+                                 IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO5,
                .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = 0x00, /* no udma */
index 0688569..22ef348 100644 (file)
@@ -104,7 +104,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
 
        {       /* 14 */
                .name           = "Revolution",
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+               .host_flags     = IDE_HFLAG_CLEAR_SIMPLEX |
+                                 IDE_HFLAG_TRUST_BIOS_FOR_DMA |
                                  IDE_HFLAG_OFF_BOARD,
                .swdma_mask     = ATA_SWDMA2,
                .mwdma_mask     = ATA_MWDMA2,
index 877c09b..bf01c38 100644 (file)
@@ -418,7 +418,9 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device
 
        d = serverworks_chipsets[idx];
 
-       if (idx == 2 || idx == 3) {
+       if (idx == 1)
+               d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX;
+       else if (idx == 2 || idx == 3) {
                if ((PCI_FUNC(dev->devfn) & 1) == 0) {
                        if (pci_resource_start(dev, 0) != 0x01f1)
                                d.host_flags &= ~IDE_HFLAG_BOOTABLE;
index c473f45..0a4b3a6 100644 (file)
@@ -140,6 +140,16 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+static void ide_pci_clear_simplex(unsigned long dma_base, const char *name)
+{
+       u8 dma_stat = inb(dma_base + 2);
+
+       outb(dma_stat & 0x60, dma_base + 2);
+       dma_stat = inb(dma_base + 2);
+       if (dma_stat & 0x80)
+               printk(KERN_INFO "%s: simplex device: DMA forced\n", name);
+}
+
 /**
  *     ide_get_or_set_dma_base         -       setup BMIBA
  *     @d: IDE port info
@@ -154,6 +164,7 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
 {
        unsigned long   dma_base = 0;
        struct pci_dev  *dev = hwif->pci_dev;
+       u8 dma_stat = 0;
 
        if (hwif->mmio)
                return hwif->dma_base;
@@ -174,52 +185,30 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
        if (hwif->channel)
                dma_base += 8;
 
-       if ((d->host_flags & IDE_HFLAG_CS5520) == 0) {
-               u8 simplex_stat = 0;
-
-               switch(dev->device) {
-                       case PCI_DEVICE_ID_AL_M5219:
-                       case PCI_DEVICE_ID_AL_M5229:
-                       case PCI_DEVICE_ID_AMD_VIPER_7409:
-                       case PCI_DEVICE_ID_CMD_643:
-                       case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
-                       case PCI_DEVICE_ID_REVOLUTION:
-                               simplex_stat = inb(dma_base + 2);
-                               outb(simplex_stat & 0x60, dma_base + 2);
-                               simplex_stat = inb(dma_base + 2);
-                               if (simplex_stat & 0x80) {
-                                       printk(KERN_INFO "%s: simplex device: "
-                                                        "DMA forced\n",
-                                                        d->name);
-                               }
-                               break;
-                       default:
-                               /*
-                                * If the device claims "simplex" DMA,
-                                * this means only one of the two interfaces
-                                * can be trusted with DMA at any point in time.
-                                * So we should enable DMA only on one of the
-                                * two interfaces.
-                                */
-                               simplex_stat = hwif->INB(dma_base + 2);
-                               if (simplex_stat & 0x80) {
-                                       /* simplex device? */
-/*
- *     At this point we haven't probed the drives so we can't make the
- *     appropriate decision. Really we should defer this problem
- *     until we tune the drive then try to grab DMA ownership if we want
- *     to be the DMA end. This has to be become dynamic to handle hot
- *     plug.
- */
-                                       if (hwif->mate && hwif->mate->dma_base) {
-                                               printk(KERN_INFO "%s: simplex device: "
-                                                                "DMA disabled\n",
-                                                                d->name);
-                                               dma_base = 0;
-                                       }
-                               }
-               }
+       if (d->host_flags & IDE_HFLAG_CS5520)
+               goto out;
+
+       if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) {
+               ide_pci_clear_simplex(dma_base, d->name);
+               goto out;
+       }
+
+       /*
+        * If the device claims "simplex" DMA, this means that only one of
+        * the two interfaces can be trusted with DMA at any point in time
+        * (so we should enable DMA only on one of the two interfaces).
+        *
+        * FIXME: At this point we haven't probed the drives so we can't make
+        * the appropriate decision.  Really we should defer this problem until
+        * we tune the drive then try to grab DMA ownership if we want to be
+        * the DMA end.  This has to be become dynamic to handle hot-plug.
+        */
+       dma_stat = hwif->INB(dma_base + 2);
+       if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) {
+               printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name);
+               dma_base = 0;
        }
+out:
        return dma_base;
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
index f1a10c8..1b31597 100644 (file)
@@ -1093,6 +1093,8 @@ enum {
        IDE_HFLAG_ABUSE_SET_DMA_MODE    = (1 << 26),
        /* host is CY82C693 */
        IDE_HFLAG_CY82C693              = (1 << 27),
+       /* force host out of "simplex" mode */
+       IDE_HFLAG_CLEAR_SIMPLEX         = (1 << 28),
 };
 
 #ifdef CONFIG_BLK_DEV_OFFBOARD