summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Dalecki <dalecki@evision-ventures.com>2002-05-28 19:17:00 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-05-28 19:17:00 -0700
commit22cd4c11916be7d4f5e3634362fc10763d60a759 (patch)
treeac51e482c07f0ba1d3f1e152e9b8f786801d5008
parenteb796b1767e2c027988e753b8a4e05e3f58aa405 (diff)
[PATCH] 2.5.18 IDE 74
- Simplify the ide-pci code further.
-rw-r--r--drivers/ide/alim15x3.c35
-rw-r--r--drivers/ide/amd74xx.c3
-rw-r--r--drivers/ide/cmd64x.c1
-rw-r--r--drivers/ide/cs5530.c2
-rw-r--r--drivers/ide/ide-pci.c276
-rw-r--r--drivers/ide/pcihost.h18
-rw-r--r--drivers/ide/serverworks.c3
7 files changed, 159 insertions, 179 deletions
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 25acceb63fed..1d99e517c5cc 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -685,20 +685,35 @@ static void __init ali15x3_init_dma(struct ata_channel *ch, unsigned long dmabas
/* module data table */
-static struct ata_pci_device chipset __initdata = {
- vendor: PCI_VENDOR_ID_AL,
- device: PCI_DEVICE_ID_AL_M5229,
- init_chipset: ali15x3_init_chipset,
- ata66_check: ali15x3_ata66_check,
- init_channel: ali15x3_init_channel,
- init_dma: ali15x3_init_dma,
- enablebits: { {0x00,0x00,0x00}, {0x00,0x00,0x00} },
- bootable: ON_BOARD
+static struct ata_pci_device chipsets[] __initdata = {
+ {
+ vendor: PCI_VENDOR_ID_AL,
+ device: PCI_DEVICE_ID_AL_M5219,
+ /* FIXME: Perhaps we should use the same init routines
+ * as below here. */
+ enablebits: { {0x00,0x00,0x00}, {0x00,0x00,0x00} },
+ bootable: ON_BOARD,
+ flags: ATA_F_SIMPLEX
+ },
+ {
+ vendor: PCI_VENDOR_ID_AL,
+ device: PCI_DEVICE_ID_AL_M5229,
+ init_chipset: ali15x3_init_chipset,
+ ata66_check: ali15x3_ata66_check,
+ init_channel: ali15x3_init_channel,
+ init_dma: ali15x3_init_dma,
+ enablebits: { {0x00,0x00,0x00}, {0x00,0x00,0x00} },
+ bootable: ON_BOARD
+ }
};
int __init init_ali15x3(void)
{
- ata_register_chipset(&chipset);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(chipsets); ++i) {
+ ata_register_chipset(&chipsets[i]);
+ }
return 0;
}
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index 3a831c27e5df..f616b6448e2e 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -443,7 +443,8 @@ static struct ata_pci_device chipsets[] __initdata = {
init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
- bootable: ON_BOARD
+ bootable: ON_BOARD,
+ flags: ATA_F_SIMPLEX
},
{
vendor: PCI_VENDOR_ID_AMD,
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 87d8abfe6fa5..85903cc67b58 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -1099,6 +1099,7 @@ static struct ata_pci_device chipsets[] __initdata = {
init_chipset: cmd64x_init_chipset,
init_channel: cmd64x_init_channel,
bootable: ON_BOARD,
+ flags: ATA_F_SIMPLEX,
},
{
vendor: PCI_VENDOR_ID_CMD,
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index 1a252f46ecce..5375be87d34c 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -374,7 +374,7 @@ static struct ata_pci_device chipset __initdata = {
init_chipset: pci_init_cs5530,
init_channel: ide_init_cs5530,
bootable: ON_BOARD,
- flags: ATA_F_DMA
+ flags: ATA_F_DMA | ATA_F_FDMA
};
int __init init_cs5530(void)
diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c
index fa7402e5db6f..66836221a64c 100644
--- a/drivers/ide/ide-pci.c
+++ b/drivers/ide/ide-pci.c
@@ -62,85 +62,68 @@ void ata_register_chipset(struct ata_pci_device *d)
}
/*
- * This allows off board ide-pci cards the enable a BIOS, verify interrupt
- * settings of split-mirror pci-config space, place chipset into init-mode,
- * and/or preserve an interrupt if the card is not native ide support.
- */
-static unsigned int __init trust_pci_irq(struct ata_pci_device *d, struct pci_dev *dev)
-{
- if (d->flags & ATA_F_IRQ)
- return dev->irq;
-
- return 0;
-}
-
-/*
* Match a PCI IDE port against an entry in ide_hwifs[],
* based on io_base port if possible.
*/
static struct ata_channel __init *lookup_channel(unsigned long io_base, int bootable, const char *name)
{
int h;
- struct ata_channel *hwif;
+ struct ata_channel *ch;
/*
- * Look for a hwif with matching io_base specified using
- * parameters to ide_setup().
+ * Look for a channel with matching io_base default value. If chipset is
+ * "ide_unknown", then claim that channel slot. Otherwise, some other
+ * chipset has already claimed it.. :(
*/
for (h = 0; h < MAX_HWIFS; ++h) {
- hwif = &ide_hwifs[h];
- if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) {
- if (hwif->chipset == ide_generic)
- return hwif; /* a perfect match */
- }
- }
- /*
- * Look for a hwif with matching io_base default value.
- * If chipset is "ide_unknown", then claim that hwif slot.
- * Otherwise, some other chipset has already claimed it.. :(
- */
- for (h = 0; h < MAX_HWIFS; ++h) {
- hwif = &ide_hwifs[h];
- if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) {
- if (hwif->chipset == ide_unknown)
- return hwif; /* match */
- printk("%s: port 0x%04lx already claimed by %s\n", name, io_base, hwif->name);
+ ch = &ide_hwifs[h];
+ if (ch->io_ports[IDE_DATA_OFFSET] == io_base) {
+ if (ch->chipset == ide_generic)
+ return ch; /* a perfect match */
+ if (ch->chipset == ide_unknown)
+ return ch; /* match */
+ printk(KERN_INFO "%s: port 0x%04lx already claimed by %s\n",
+ name, io_base, ch->name);
return NULL; /* already claimed */
}
}
+
/*
- * Okay, there is no hwif matching our io_base,
- * so we'll just claim an unassigned slot.
+ * Okay, there is no ch matching our io_base, so we'll just claim an
+ * unassigned slot.
+ *
* Give preference to claiming other slots before claiming ide0/ide1,
- * just in case there's another interface yet-to-be-scanned
- * which uses ports 1f0/170 (the ide0/ide1 defaults).
+ * just in case there's another interface yet-to-be-scanned which uses
+ * ports 1f0/170 (the ide0/ide1 defaults).
*
- * Unless there is a bootable card that does not use the standard
- * ports 1f0/170 (the ide0/ide1 defaults). The (bootable) flag.
+ * Unless there is a bootable card that does not use the standard ports
+ * 1f0/170 (the ide0/ide1 defaults). The (bootable) flag.
*/
+
if (bootable == ON_BOARD) {
for (h = 0; h < MAX_HWIFS; ++h) {
- hwif = &ide_hwifs[h];
- if (hwif->chipset == ide_unknown)
- return hwif; /* pick an unused entry */
+ ch = &ide_hwifs[h];
+ if (ch->chipset == ide_unknown)
+ return ch; /* pick an unused entry */
}
} else {
for (h = 2; h < MAX_HWIFS; ++h) {
- hwif = ide_hwifs + h;
- if (hwif->chipset == ide_unknown)
- return hwif; /* pick an unused entry */
+ ch = &ide_hwifs[h];
+ if (ch->chipset == ide_unknown)
+ return ch; /* pick an unused entry */
}
}
for (h = 0; h < 2; ++h) {
- hwif = ide_hwifs + h;
- if (hwif->chipset == ide_unknown)
- return hwif; /* pick an unused entry */
+ ch = &ide_hwifs[h];
+ if (ch->chipset == ide_unknown)
+ return ch; /* pick an unused entry */
}
- printk("%s: too many IDE interfaces, no room in table\n", name);
+ printk(KERN_INFO "%s: too many ATA interfaces.\n", name);
+
return NULL;
}
-static int __init setup_pci_baseregs (struct pci_dev *dev, const char *name)
+static int __init setup_pci_baseregs(struct pci_dev *dev, const char *name)
{
u8 reg;
u8 progif = 0;
@@ -175,110 +158,6 @@ static int __init setup_pci_baseregs (struct pci_dev *dev, const char *name)
return 0;
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
-
-/*
- * Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
- */
-static unsigned long __init get_dma_base(struct ata_channel *hwif, int extra, const char *name)
-{
- unsigned long dma_base = 0;
- struct pci_dev *dev = hwif->pci_dev;
-
- dma_base = pci_resource_start(dev, 4);
- if (!dma_base)
- return 0;
-
- /* PDC20246, PDC20262, HPT343, & HPT366 */
- if (extra) {
- request_region(dma_base + 16, extra, name);
- hwif->dma_extra = extra;
- }
-
- /* If we are on the second channel, the dma base address will be one
- * entry away from the primary interface.
- */
- if (hwif->unit == ATA_SECONDARY)
- dma_base += 8;
-
- if ((dev->vendor == PCI_VENDOR_ID_AL && dev->device == PCI_DEVICE_ID_AL_M5219) ||
- (dev->vendor == PCI_VENDOR_ID_AMD && dev->device == PCI_DEVICE_ID_AMD_VIPER_7409) ||
- (dev->vendor == PCI_VENDOR_ID_CMD && dev->device == PCI_DEVICE_ID_CMD_643) ||
- (dev->vendor == PCI_VENDOR_ID_SERVERWORKS && dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)) {
- outb(inb(dma_base + 2) & 0x60, dma_base+2);
- if (inb(dma_base + 2) & 0x80)
- printk(KERN_INFO "%s: simplex device: DMA forced\n", name);
- } else {
-
- /* 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.
- */
-
- if ((inb(dma_base + 2) & 0x80)) {
- if ((!hwif->drives[0].present && !hwif->drives[1].present) ||
- hwif->unit == ATA_SECONDARY) {
- printk("%s: simplex device: DMA disabled\n", name);
- dma_base = 0;
- }
- }
- }
-
- return dma_base;
-}
-
-/*
- * Setup DMA transfers on a channel.
- */
-static void __init setup_channel_dma(struct ata_channel *ch,
- struct pci_dev *dev,
- struct ata_pci_device *d,
- int port,
- u8 class_rev,
- int pciirq,
- int autodma,
- unsigned short *pcicmd)
-{
- unsigned long dma_base;
-
- if (d->flags & ATA_F_NOADMA)
- autodma = 0;
-
- if (autodma)
- ch->autodma = 1;
-
- if (!((d->flags & ATA_F_DMA) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))))
- return;
-
- dma_base = get_dma_base(ch, ((port == ATA_PRIMARY) && d->extra) ? d->extra : 0, dev->name);
- if (!dma_base) {
- printk("%s: %s Bus-Master DMA was disabled by BIOS\n",
- ch->name, dev->name);
-
- return;
- }
- if (!(*pcicmd & PCI_COMMAND_MASTER)) {
-
- /*
- * Set up BM-DMA capability (PnP BIOS should have done this already)
- */
- if (!(d->vendor == PCI_VENDOR_ID_CYRIX && d->device == PCI_DEVICE_ID_CYRIX_5530_IDE))
- ch->autodma = 0; /* default DMA off if we had to configure it here */
- pci_write_config_word(dev, PCI_COMMAND, *pcicmd | PCI_COMMAND_MASTER);
- if (pci_read_config_word(dev, PCI_COMMAND, pcicmd) || !(*pcicmd & PCI_COMMAND_MASTER)) {
- printk("%s: %s error updating PCICMD\n",
- ch->name, dev->name);
- dma_base = 0;
- }
- }
- if (d->init_dma)
- d->init_dma(ch, dma_base);
- else
- ata_init_dma(ch, dma_base);
-}
-#endif
-
/*
* Setup a particular port on an ATA host controller.
*
@@ -293,6 +172,7 @@ static int __init setup_host_channel(struct pci_dev *dev,
unsigned short *pcicmd)
{
unsigned long base = 0;
+ unsigned long dma_base;
unsigned long ctl = 0;
ide_pci_enablebit_t *e = &(d->enablebits[port]);
struct ata_channel *ch;
@@ -387,7 +267,79 @@ controller_ok:
}
#ifdef CONFIG_BLK_DEV_IDEDMA
- setup_channel_dma(ch, dev, d, port, class_rev, pciirq, autodma, pcicmd);
+ /*
+ * Setup DMA transfers on the channel.
+ */
+ if (d->flags & ATA_F_NOADMA)
+ autodma = 0;
+
+ if (autodma)
+ ch->autodma = 1;
+
+ if (!((d->flags & ATA_F_DMA) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))))
+ goto no_dma;
+ /*
+ * Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
+ */
+ dma_base = pci_resource_start(dev, 4);
+ if (dma_base) {
+ /* PDC20246, PDC20262, HPT343, & HPT366 */
+ if ((ch->unit == ATA_PRIMARY) && d->extra) {
+ request_region(dma_base + 16, d->extra, dev->name);
+ ch->dma_extra = d->extra;
+ }
+
+ /* If we are on the second channel, the dma base address will
+ * be one entry away from the primary interface.
+ */
+ if (ch->unit == ATA_SECONDARY)
+ dma_base += 8;
+
+ if (d->flags & ATA_F_SIMPLEX) {
+ outb(inb(dma_base + 2) & 0x60, dma_base + 2);
+ if (inb(dma_base + 2) & 0x80)
+ printk(KERN_INFO "%s: simplex device: DMA forced\n", dev->name);
+ } else {
+ /* 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.
+ */
+ if ((inb(dma_base + 2) & 0x80)) {
+ if ((!ch->drives[0].present && !ch->drives[1].present) ||
+ ch->unit == ATA_SECONDARY) {
+ printk(KERN_INFO "%s: simplex device: DMA disabled\n", dev->name);
+ dma_base = 0;
+ }
+ }
+ }
+ } else {
+ printk(KERN_INFO "%s: %s Bus-Master DMA was disabled by BIOS\n",
+ ch->name, dev->name);
+
+ goto no_dma;
+ }
+ if (!(*pcicmd & PCI_COMMAND_MASTER)) {
+ /*
+ * Set up BM-DMA capability (PnP BIOS should have done this
+ * already). Default to DMA off on the drive, if we had to
+ * configure it here. This should most propably be enabled no
+ * all chipsets which can be expected to be used on systems
+ * without a BIOS equivalent.
+ */
+ if (!(d->flags | ATA_F_FDMA))
+ ch->autodma = 0;
+ pci_write_config_word(dev, PCI_COMMAND, *pcicmd | PCI_COMMAND_MASTER);
+ if (pci_read_config_word(dev, PCI_COMMAND, pcicmd) || !(*pcicmd & PCI_COMMAND_MASTER)) {
+ printk("%s: %s error updating PCICMD\n",
+ ch->name, dev->name);
+ dma_base = 0;
+ }
+ }
+ if (d->init_dma)
+ d->init_dma(ch, dma_base);
+ else
+ ata_init_dma(ch, dma_base);
#endif
no_dma:
@@ -428,7 +380,7 @@ static void __init setup_pci_device(struct pci_dev *dev, struct ata_pci_device *
check_if_enabled:
if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) {
- printk("%s: error accessing PCI regs\n", dev->name);
+ printk(KERN_ERR "%s: error accessing PCI regs\n", dev->name);
return;
}
if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */
@@ -495,8 +447,12 @@ check_if_enabled:
*/
if (d->init_chipset)
pciirq = d->init_chipset(dev);
- else
- pciirq = trust_pci_irq(d, dev);
+ else {
+ if (d->flags & ATA_F_IRQ)
+ pciirq = dev->irq;
+ else
+ pciirq = 0;
+ }
} else if (tried_config) {
printk(KERN_INFO "ATA: will probe IRQs later\n");
pciirq = 0;
@@ -520,6 +476,10 @@ check_if_enabled:
setup_host_channel(dev, d, ATA_SECONDARY, class_rev, pciirq, autodma, &pcicmd);
}
+/*
+ * Fix crossover IRQ line setups between primary and secondary channel. Quite
+ * a common bug apparently.
+ */
static void __init pdc20270_device_order_fixup (struct pci_dev *dev, struct ata_pci_device *d)
{
struct pci_dev *dev2 = NULL;
diff --git a/drivers/ide/pcihost.h b/drivers/ide/pcihost.h
index c994b1b1ccc6..b5322cb304a3 100644
--- a/drivers/ide/pcihost.h
+++ b/drivers/ide/pcihost.h
@@ -102,14 +102,16 @@ typedef struct ide_pci_enablebit_s {
/* Flags used to untangle quirk handling.
*/
-#define ATA_F_DMA 0x01
-#define ATA_F_NODMA 0x02 /* no DMA mode supported at all */
-#define ATA_F_NOADMA 0x04 /* DMA has to be enabled explicitely */
-#define ATA_F_FIXIRQ 0x08 /* fixed irq wiring */
-#define ATA_F_SER 0x10 /* serialize on first and second channel interrupts */
-#define ATA_F_IRQ 0x20 /* trust IRQ information from config */
-#define ATA_F_PHACK 0x40 /* apply PROMISE hacks */
-#define ATA_F_HPTHACK 0x80 /* apply HPT366 hacks */
+#define ATA_F_DMA 0x001
+#define ATA_F_NODMA 0x002 /* no DMA mode supported at all */
+#define ATA_F_NOADMA 0x004 /* DMA has to be enabled explicitely */
+#define ATA_F_FDMA 0x008 /* force autodma */
+#define ATA_F_FIXIRQ 0x010 /* fixed irq wiring */
+#define ATA_F_SER 0x020 /* serialize on first and second channel interrupts */
+#define ATA_F_IRQ 0x040 /* trust IRQ information from config */
+#define ATA_F_PHACK 0x080 /* apply PROMISE hacks */
+#define ATA_F_HPTHACK 0x100 /* apply HPT366 hacks */
+#define ATA_F_SIMPLEX 0x200 /* force treatment as simple device */
struct ata_pci_device {
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index 0a0751bfb377..baf998f5b11c 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -679,7 +679,8 @@ static struct ata_pci_device chipsets[] __initdata = {
init_chipset: svwks_init_chipset,
ata66_check: svwks_ata66_check,
init_channel: ide_init_svwks,
- bootable: ON_BOARD
+ bootable: ON_BOARD,
+ flags: ATA_F_SIMPLEX
},
};