patch-2.3.13 linux/drivers/block/ide-pci.c

Next file: linux/drivers/block/ide-pmac.c
Previous file: linux/drivers/block/ide-floppy.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.12/linux/drivers/block/ide-pci.c linux/drivers/block/ide-pci.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide-pci.c	Version 1.03  May 1, 1999
+ *  linux/drivers/block/ide-pci.c	Version 1.04	July 27, 1999
  *
  *  Copyright (c) 1998-1999  Andre Hedrick
  *
@@ -52,6 +52,7 @@
 #define DEVID_UM8886A	((ide_pci_devid_t){PCI_VENDOR_ID_UMC,     PCI_DEVICE_ID_UMC_UM8886A})
 #define DEVID_UM8886BF	((ide_pci_devid_t){PCI_VENDOR_ID_UMC,     PCI_DEVICE_ID_UMC_UM8886BF})
 #define DEVID_HPT34X	((ide_pci_devid_t){PCI_VENDOR_ID_TTI,     PCI_DEVICE_ID_TTI_HPT343})
+#define DEVID_HPT366	((ide_pci_devid_t){PCI_VENDOR_ID_TTI,     PCI_DEVICE_ID_TTI_HPT366})
 #define DEVID_ALI15X3	((ide_pci_devid_t){PCI_VENDOR_ID_AL,      PCI_DEVICE_ID_AL_M5229})
 #define DEVID_CY82C693	((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ,  PCI_DEVICE_ID_CONTAQ_82C693})
 #define DEVID_HINT	((ide_pci_devid_t){0x3388,                0x8013})
@@ -106,11 +107,14 @@
 #endif
 
 #ifdef CONFIG_BLK_DEV_VIA82C586
+extern unsigned int pci_init_via82c568(struct pci_dev *, const char *);
 extern void ide_init_via82c586(ide_hwif_t *);
 extern void ide_dmacapable_via82c586(ide_hwif_t *, unsigned long dmabase);
+#define	PCI_VIA82C586	&pci_init_via82c568
 #define	INIT_VIA82C586	&ide_init_via82c586
 #define	DMA_VIA82C586	&ide_dmacapable_via82c586
 #else
+#define PCI_VIA82C586	NULL
 #define	INIT_VIA82C586	NULL
 #define	DMA_VIA82C586	NULL
 #endif
@@ -166,6 +170,26 @@
 #define	INIT_HPT34X	NULL
 #endif
 
+#ifdef CONFIG_BLK_DEV_HPT366
+extern unsigned int pci_init_hpt366(struct pci_dev *, const char *);
+extern void ide_init_hpt366(ide_hwif_t *);
+#define PCI_HPT366	&pci_init_hpt366
+#define INIT_HPT366	&ide_init_hpt366
+#else
+#define PCI_HPT366	NULL
+#define INIT_HPT366	IDE_IGNORE
+#endif
+
+#ifdef CONFIG_BLK_DEV_SIS5513
+extern unsigned int pci_init_sis5513(struct pci_dev *, const char *);
+extern void ide_init_sis5513(ide_hwif_t *);
+#define PCI_SIS5513	&pci_init_sis5513
+#define INIT_SIS5513	&ide_init_sis5513
+#else
+#define PCI_SIS5513	NULL
+#define INIT_SIS5513	NULL
+#endif
+
 #define INIT_SAMURAI	NULL
 #define INIT_CX5530	NULL
 
@@ -183,71 +207,85 @@
 	void			(*dma_init)(ide_hwif_t *hwif, unsigned long dmabase);
 	ide_pci_enablebit_t	enablebits[2];
 	byte			bootable;
+	byte			sixtysix;
 	unsigned int		extra;
 } ide_pci_device_t;
 
 static ide_pci_device_t ide_pci_chipsets[] __initdata = {
-	{DEVID_PIIXa,	"PIIX",		NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
-	{DEVID_PIIXb,	"PIIX",		NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
-	{DEVID_PIIX3,	"PIIX3",	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
-	{DEVID_PIIX4,	"PIIX4",	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
-	{DEVID_VIA_IDE,	"VIA_IDE",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_VP_IDE,	"VP_IDE",	NULL,		INIT_VIA82C586,	DMA_VIA82C586,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	ON_BOARD,	0 },
-	{DEVID_PDC20246,"PDC20246",	PCI_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}}, 	OFF_BOARD,	16 },
-	{DEVID_PDC20262,"PDC20262",	PCI_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}},	OFF_BOARD,	48 },
-	{DEVID_RZ1000,	"RZ1000",	NULL,		INIT_RZ1000,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_RZ1001,	"RZ1001",	NULL,		INIT_RZ1000,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_SAMURAI,	"SAMURAI",	NULL,		INIT_SAMURAI,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_CMD640,	"CMD640",	NULL,		IDE_IGNORE,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_NS87410,	"NS87410",	NULL,		NULL,		NULL,		{{0x43,0x08,0x08}, {0x47,0x08,0x08}}, 	ON_BOARD,	0 },
-	{DEVID_SIS5513,	"SIS5513",	NULL,		NULL,		NULL,		{{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, 	ON_BOARD,	0 },
-	{DEVID_CMD643,	"CMD643",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_CMD646,	"CMD646",	NULL,		INIT_CMD646,	NULL,		{{0x00,0x00,0x00}, {0x51,0x80,0x80}}, 	ON_BOARD,	0 },
-	{DEVID_HT6565,	"HT6565",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_OPTI621,	"OPTI621",	NULL,		INIT_OPTI621,	NULL,		{{0x45,0x80,0x00}, {0x40,0x08,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_OPTI621X,"OPTI621X",	NULL,		INIT_OPTI621,	NULL,		{{0x45,0x80,0x00}, {0x40,0x08,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_TRM290,	"TRM290",	NULL,		INIT_TRM290,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_NS87415,	"NS87415",	NULL,		INIT_NS87415,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_AEC6210,	"AEC6210",	PCI_AEC6210,	NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	OFF_BOARD,	0 },
-	{DEVID_W82C105,	"W82C105",	NULL,		INIT_W82C105,	NULL,		{{0x40,0x01,0x01}, {0x40,0x10,0x10}}, 	ON_BOARD,	0 },
-	{DEVID_UM8886A,	"UM8886A",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_UM8886BF,"UM8886BF",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
-	{DEVID_HPT34X,	"HPT34X",	PCI_HPT34X,	INIT_HPT34X,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	NEVER_BOARD,	16 },
-	{DEVID_ALI15X3,	"ALI15X3",	PCI_ALI15X3,	INIT_ALI15X3,	NULL,		{{0x09,0x20,0x20}, {0x09,0x10,0x10}},	ON_BOARD,	0 },
-	{DEVID_CY82C693,"CY82C693",	NULL,		INIT_CY82C693,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_HINT,	"HINT_IDE",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_CX5530,	"CX5530",	NULL,		INIT_CX5530,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{IDE_PCI_DEVID_NULL, "PCI_IDE",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 }};
+	{DEVID_PIIXa,	"PIIX",		NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0,	0 },
+	{DEVID_PIIXb,	"PIIX",		NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0,	0 },
+	{DEVID_PIIX3,	"PIIX3",	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0,	0 },
+	{DEVID_PIIX4,	"PIIX4",	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0,	0 },
+	{DEVID_VIA_IDE,	"VIA_IDE",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0,	0 },
+	{DEVID_VP_IDE,	"VP_IDE",	PCI_VIA82C586,	INIT_VIA82C586,	DMA_VIA82C586,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	ON_BOARD,	0,	0 },
+	{DEVID_PDC20246,"PDC20246",	PCI_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}}, 	OFF_BOARD,	0,	16 },
+	{DEVID_PDC20262,"PDC20262",	PCI_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}},	OFF_BOARD,	1,	48 },
+	{DEVID_RZ1000,	"RZ1000",	NULL,		INIT_RZ1000,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_RZ1001,	"RZ1001",	NULL,		INIT_RZ1000,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_SAMURAI,	"SAMURAI",	NULL,		INIT_SAMURAI,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0,	0 },
+	{DEVID_CMD640,	"CMD640",	NULL,		IDE_IGNORE,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_NS87410,	"NS87410",	NULL,		NULL,		NULL,		{{0x43,0x08,0x08}, {0x47,0x08,0x08}}, 	ON_BOARD,	0,	0 },
+	{DEVID_SIS5513,	"SIS5513",	PCI_SIS5513,	INIT_SIS5513,	NULL,		{{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, 	ON_BOARD,	1,	0 },
+	{DEVID_CMD643,	"CMD643",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0,	0 },
+	{DEVID_CMD646,	"CMD646",	NULL,		INIT_CMD646,	NULL,		{{0x00,0x00,0x00}, {0x51,0x80,0x80}}, 	ON_BOARD,	0,	0 },
+	{DEVID_HT6565,	"HT6565",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_OPTI621,	"OPTI621",	NULL,		INIT_OPTI621,	NULL,		{{0x45,0x80,0x00}, {0x40,0x08,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_OPTI621X,"OPTI621X",	NULL,		INIT_OPTI621,	NULL,		{{0x45,0x80,0x00}, {0x40,0x08,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_TRM290,	"TRM290",	NULL,		INIT_TRM290,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_NS87415,	"NS87415",	NULL,		INIT_NS87415,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_AEC6210,	"AEC6210",	PCI_AEC6210,	NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	OFF_BOARD,	0,	0 },
+	{DEVID_W82C105,	"W82C105",	NULL,		INIT_W82C105,	NULL,		{{0x40,0x01,0x01}, {0x40,0x10,0x10}}, 	ON_BOARD,	0,	0 },
+	{DEVID_UM8886A,	"UM8886A",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0,	0 },
+	{DEVID_UM8886BF,"UM8886BF",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0,	0 },
+	{DEVID_HPT34X,	"HPT34X",	PCI_HPT34X,	INIT_HPT34X,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	NEVER_BOARD,	0,	16 },
+	{DEVID_HPT366,	"HPT366",	PCI_HPT366,	INIT_HPT366,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	1,	256 },
+	{DEVID_ALI15X3,	"ALI15X3",	PCI_ALI15X3,	INIT_ALI15X3,	NULL,		{{0x09,0x20,0x20}, {0x09,0x10,0x10}},	ON_BOARD,	0,	0 },
+	{DEVID_CY82C693,"CY82C693",	NULL,		INIT_CY82C693,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0,	0 },
+	{DEVID_HINT,	"HINT_IDE",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0,	0 },
+	{DEVID_CX5530,	"CX5530",	NULL,		INIT_CX5530,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0,	0 },
+	{IDE_PCI_DEVID_NULL, "PCI_IDE",	NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0,	0 }};
+
+static byte hpt363_shared_irq = 0;
 
 /*
  * This allows offboard 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.
  */
-__initfunc(static unsigned int ide_special_settings (struct pci_dev *dev, const char *name))
+static unsigned int __init ide_special_settings (struct pci_dev *dev, const char *name)
 {
 	switch(dev->device) {
 		case PCI_DEVICE_ID_TTI_HPT343:
 			{
-				int i;
 				unsigned short pcicmd = 0;
-				unsigned long hpt34xIoBase = dev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK;
 
 				pci_write_config_byte(dev, 0x80, 0x00);
-				dev->base_address[0] = (hpt34xIoBase + 0x20);
-				dev->base_address[1] = (hpt34xIoBase + 0x34);
-				dev->base_address[2] = (hpt34xIoBase + 0x28);
-				dev->base_address[3] = (hpt34xIoBase + 0x3c);
-				for(i=0; i<4; i++)
-					dev->base_address[i] |= PCI_BASE_ADDRESS_SPACE_IO;
-
 				pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
 				if (!(pcicmd & PCI_COMMAND_MEMORY)) {
+					/*
+					 * FIXME - this is too ugly, and looks senseless.
+					 * Why not just use resource[4]?
+					 *
+					 * This was a cleaner/quicker way to get the ioports
+					 * that the are not decode do to a flaw in the chipset
+					 * design.
+					 */
+
+					int i;
+					unsigned long hpt34xIoBase = dev->resource[4].start;
+
+					dev->resource[0].start = (hpt34xIoBase + 0x20);
+					dev->resource[1].start = (hpt34xIoBase + 0x34);
+					dev->resource[2].start = (hpt34xIoBase + 0x28);
+					dev->resource[3].start = (hpt34xIoBase + 0x3c);
+					for(i=0; i<4; i++)
+						dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
 					pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
 				} else {
 					pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
 				}
 			}
+		case PCI_DEVICE_ID_TTI_HPT366:
 		case PCI_DEVICE_ID_PROMISE_20246:
 		case PCI_DEVICE_ID_PROMISE_20262:
 		case PCI_DEVICE_ID_ARTOP_ATP850UF:
@@ -262,7 +300,7 @@
  * Match a PCI IDE port against an entry in ide_hwifs[],
  * based on io_base port if possible.
  */
-__initfunc(static ide_hwif_t *ide_match_hwif (unsigned long io_base, byte bootable, const char *name))
+static ide_hwif_t __init *ide_match_hwif (unsigned long io_base, byte bootable, const char *name)
 {
 	int h;
 	ide_hwif_t *hwif;
@@ -324,7 +362,7 @@
 	return NULL;
 }
 
-__initfunc(static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name))
+static int __init ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
 {
 	byte reg, progif = 0;
 
@@ -346,11 +384,15 @@
 	/*
 	 * Setup base registers for IDE command/control spaces for each interface:
 	 */
-	for (reg = 0; reg < 4; reg++)
-		if (!dev->base_address[reg]) {
+	for (reg = 0; reg < 4; reg++) {
+		struct resource *res = dev->resource + reg;
+		if (!(res->flags & PCI_BASE_ADDRESS_SPACE_IO))
+			continue;
+		if (!res->start) {
 			printk("%s: Missing I/O address #%d\n", name, reg);
 			return 1;
 		}
+	}
 	return 0;
 }
 
@@ -364,7 +406,7 @@
  * we "know" about, this information is in the ide_pci_device_t struct;
  * for all other chipsets, we just assume both interfaces are enabled.
  */
-__initfunc(static void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d))
+static void __init ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d)
 {
 	unsigned int port, at_least_one_hwif_enabled = 0, autodma = 0, pciirq = 0;
 	unsigned short pcicmd = 0, tried_config = 0;
@@ -446,9 +488,12 @@
 		ide_pci_enablebit_t *e = &(d->enablebits[port]);
 		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val))
 			continue;	/* port not enabled */
+		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port))
+			return;
 		if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE || (dev->class & (port ? 4 : 1)) != 0) {
-			ctl  = dev->base_address[(2*port)+1] & PCI_BASE_ADDRESS_IO_MASK;
-			base = dev->base_address[2*port] & ~7;
+			/* FIXME! This really should check that it really gets the IO/MEM part right! */
+			ctl  = dev->resource[(2*port)+1].start;
+			base = dev->resource[2*port].start;
 		}
 		if ((ctl && !base) || (base && !ctl)) {
 			printk("%s: inconsistent baseregs (BIOS) for port %d, skipping\n", d->name, port);
@@ -484,13 +529,12 @@
 			hwif->irq = hwif->channel ? 15 : 14;
 			goto bypass_umc_dma;
 		}
-
+		if ((!d->sixtysix) && (hwif->udma_four))
+			hwif->udma_four = 0;
 #ifdef CONFIG_BLK_DEV_IDEDMA
 		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X))
 			autodma = 0;
-		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262))
-			hwif->udma_four = 1;
 		if (autodma)
 			hwif->autodma = 1;
 		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) ||
@@ -499,6 +543,7 @@
 #ifdef CONFIG_BLK_DEV_HPT34X
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) ||
 #endif /* CONFIG_BLK_DEV_HPT34X */
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) ||
 		    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) {
 			unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name);
@@ -534,11 +579,49 @@
 		printk("%s: neither IDE port enabled (BIOS)\n", d->name);
 }
 
+__initfunc(static void hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d))
+{
+	struct pci_dev *dev2;
+	ide_pci_device_t *d2;
+	unsigned char pin1 = 0, pin2 = 0;
+
+	d2 = d;
+	if (PCI_FUNC(dev->devfn) & 1)
+		return;
+
+	for (dev2=pci_devices; dev2; dev2=dev2->next) {
+		if ((dev2->vendor == dev->vendor) &&
+		    (dev2->device == dev->device) &&
+		    (PCI_FUNC(dev2->devfn) & 1))
+			break;
+	}
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1);
+	if (dev2) {
+		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
+		hpt363_shared_irq = (pin1 != pin2) ? 1 : 0;
+	}
+
+	if (hpt363_shared_irq) {
+		printk("%s: onboard version of chipset, pin1=%d pin2=%d\n",
+			d->name, pin1, pin2);
+	}
+
+	printk("%s: IDE controller on PCI bus %02x dev %02x\n",
+		d->name, dev->bus->number, dev->devfn);
+	ide_setup_pci_device(dev, d);
+
+	if (dev2) {
+		printk("%s: IDE controller on PCI bus %02x dev %02x\n",
+			d2->name, dev2->bus->number, dev2->devfn);
+		ide_setup_pci_device(dev2, d2);
+	}
+}
+
 /*
  * ide_scan_pcibus() gets invoked at boot time from ide.c.
  * It finds all PCI IDE controllers and calls ide_setup_pci_device for them.
  */
-__initfunc(void ide_scan_pcibus (void))
+void __init ide_scan_pcibus (void)
 {
 	struct pci_dev		*dev;
 	ide_pci_devid_t		devid;
@@ -558,6 +641,8 @@
 			continue;	/* CY82C693 is more than only a IDE controller */
 		else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1))
 			continue;	/* UM8886A/BF pair */
+		else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366))
+			hpt366_device_order_fixup(dev, d);
 		else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 			if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL))
 				printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n",

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)