ide: add IDE_HFLAG_CLEAR_SIMPLEX host flag

* 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: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 993da8f9
...@@ -775,7 +775,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev ...@@ -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; 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)) if (pci_dev_present(ati_rs100))
printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n"); 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 ...@@ -798,6 +798,9 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
d.udma_mask = ATA_UDMA6; d.udma_mask = ATA_UDMA6;
} }
if (idx == 0)
d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX;
#if defined(CONFIG_SPARC64) #if defined(CONFIG_SPARC64)
d.init_hwif = init_hwif_common_ali15x3; d.init_hwif = init_hwif_common_ali15x3;
#endif /* CONFIG_SPARC64 */ #endif /* CONFIG_SPARC64 */
...@@ -807,7 +810,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev ...@@ -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[] = { 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_M5229), 0 },
{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 0 }, { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 1 },
{ 0, }, { 0, },
}; };
MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl); MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl);
......
...@@ -295,6 +295,7 @@ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_ ...@@ -295,6 +295,7 @@ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_
if (idx == 1) { if (idx == 1) {
if (dev->revision <= 7) if (dev->revision <= 7)
d.swdma_mask = 0; d.swdma_mask = 0;
d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX;
} else if (idx == 4) { } else if (idx == 4) {
if (dev->subsystem_vendor == PCI_VENDOR_ID_AMD && if (dev->subsystem_vendor == PCI_VENDOR_ID_AMD &&
dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE)
......
...@@ -443,7 +443,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { ...@@ -443,7 +443,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
.init_chipset = init_chipset_cmd64x, .init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x, .init_hwif = init_hwif_cmd64x,
.enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, .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, .pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2, .mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* no udma */ .udma_mask = 0x00, /* no udma */
......
...@@ -104,7 +104,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = { ...@@ -104,7 +104,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
{ /* 14 */ { /* 14 */
.name = "Revolution", .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, IDE_HFLAG_OFF_BOARD,
.swdma_mask = ATA_SWDMA2, .swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2, .mwdma_mask = ATA_MWDMA2,
......
...@@ -418,7 +418,9 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device ...@@ -418,7 +418,9 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device
d = serverworks_chipsets[idx]; 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_FUNC(dev->devfn) & 1) == 0) {
if (pci_resource_start(dev, 0) != 0x01f1) if (pci_resource_start(dev, 0) != 0x01f1)
d.host_flags &= ~IDE_HFLAG_BOOTABLE; d.host_flags &= ~IDE_HFLAG_BOOTABLE;
......
...@@ -140,6 +140,16 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) ...@@ -140,6 +140,16 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
} }
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI #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 * ide_get_or_set_dma_base - setup BMIBA
* @d: IDE port info * @d: IDE port info
...@@ -154,6 +164,7 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ ...@@ -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; unsigned long dma_base = 0;
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
u8 dma_stat = 0;
if (hwif->mmio) if (hwif->mmio)
return hwif->dma_base; return hwif->dma_base;
...@@ -174,52 +185,30 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ ...@@ -174,52 +185,30 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
if (hwif->channel) if (hwif->channel)
dma_base += 8; dma_base += 8;
if ((d->host_flags & IDE_HFLAG_CS5520) == 0) { if (d->host_flags & IDE_HFLAG_CS5520)
u8 simplex_stat = 0; goto out;
switch(dev->device) { if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) {
case PCI_DEVICE_ID_AL_M5219: ide_pci_clear_simplex(dma_base, d->name);
case PCI_DEVICE_ID_AL_M5229: goto out;
case PCI_DEVICE_ID_AMD_VIPER_7409: }
case PCI_DEVICE_ID_CMD_643:
case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: /*
case PCI_DEVICE_ID_REVOLUTION: * If the device claims "simplex" DMA, this means that only one of
simplex_stat = inb(dma_base + 2); * the two interfaces can be trusted with DMA at any point in time
outb(simplex_stat & 0x60, dma_base + 2); * (so we should enable DMA only on one of the two interfaces).
simplex_stat = inb(dma_base + 2); *
if (simplex_stat & 0x80) { * FIXME: At this point we haven't probed the drives so we can't make
printk(KERN_INFO "%s: simplex device: " * the appropriate decision. Really we should defer this problem until
"DMA forced\n", * we tune the drive then try to grab DMA ownership if we want to be
d->name); * the DMA end. This has to be become dynamic to handle hot-plug.
} */
break; dma_stat = hwif->INB(dma_base + 2);
default: if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) {
/* printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name);
* If the device claims "simplex" DMA, dma_base = 0;
* 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;
}
}
}
} }
out:
return dma_base; return dma_base;
} }
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
......
...@@ -1093,6 +1093,8 @@ enum { ...@@ -1093,6 +1093,8 @@ enum {
IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26),
/* host is CY82C693 */ /* host is CY82C693 */
IDE_HFLAG_CY82C693 = (1 << 27), IDE_HFLAG_CY82C693 = (1 << 27),
/* force host out of "simplex" mode */
IDE_HFLAG_CLEAR_SIMPLEX = (1 << 28),
}; };
#ifdef CONFIG_BLK_DEV_OFFBOARD #ifdef CONFIG_BLK_DEV_OFFBOARD
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment