Commit 22cd4c11 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.18 IDE 74

- Simplify the ide-pci code further.
parent eb796b17
......@@ -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;
}
......@@ -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,
......
......@@ -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,
......
......@@ -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)
......
......@@ -61,19 +61,6 @@ void ata_register_chipset(struct ata_pci_device *d)
tmp->next = 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.
......@@ -81,66 +68,62 @@ static unsigned int __init trust_pci_irq(struct ata_pci_device *d, struct pci_de
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 @@ static int __init setup_host_channel(struct pci_dev *dev,
}
#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 @@ static void __init setup_pci_device(struct pci_dev *dev, struct ata_pci_device *
*/
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 @@ static void __init setup_pci_device(struct pci_dev *dev, struct ata_pci_device *
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;
......
......@@ -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 {
......
......@@ -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
},
};
......
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