[PATCH] fix issues with loading PCI ide drivers as modules (linux2.6.0)

From: Davin McCall
Date: Fri Jan 02 2004 - 23:26:14 EST


Hi,

When loading the piix.ko module (generic IDE support is compiled in) I get error messages- the ports are already in use, the block devices are already registered.

The problems seem to be:

1) the hwif structures aren't getting marked as being used if the generic IDE layer is controlling them (->chipset is left as "ide_unknown" instead of "ide_generic")

2) if the pci module is granted control of an already initialized hwif, the drive probing etc. (including I/O port allocation) is re-run. When it fails, the drives are marked as not-present which doesn't appear to cause any problems but seems dangerous.

Patch below fixes this and allows a chipset-specific module to take over the primary IDE interface correctly. Comments welcome.

Davin



diff -urN linux-2.6.0/drivers/ide/ide-probe.c linux-2.6.0-mine/drivers/ide/ide-probe.c
--- linux-2.6.0/drivers/ide/ide-probe.c Thu Nov 27 07:44:24 2003
+++ linux-2.6.0-mine/drivers/ide/ide-probe.c Sat Jan 3 13:08:22 2004
@@ -864,6 +864,12 @@
int hwif_init (ide_hwif_t *hwif);
int probe_hwif_init (ide_hwif_t *hwif)
{
+ if( hwif->chipset == ide_pci_takeover )
+ {
+ hwif->chipset = ide_pci;
+ return 0;
+ }
+
hwif->initializing = 1;
probe_hwif(hwif);
hwif_init(hwif);
@@ -1343,6 +1349,8 @@
int unit;
if (!hwif->present)
continue;
+
+ if( hwif->chipset == ide_unknown ) hwif->chipset = ide_generic;
for (unit = 0; unit < MAX_DRIVES; ++unit)
if (hwif->drives[unit].present)
ata_attach(&hwif->drives[unit]);
diff -urN linux-2.6.0/drivers/ide/ide.c linux-2.6.0-mine/drivers/ide/ide.c
--- linux-2.6.0/drivers/ide/ide.c Thu Nov 27 07:43:29 2003
+++ linux-2.6.0-mine/drivers/ide/ide.c Sat Jan 3 11:34:11 2004
@@ -1915,7 +1915,7 @@
const char max_hwif = '0' + (MAX_HWIFS - 1);


- if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */
+ if (strncmp(s,"hd=",3) == 0 ) /* hd= is for hd.c */
return 0; /* driver and not us */

if (strncmp(s,"ide",3) &&
diff -urN linux-2.6.0/drivers/ide/setup-pci.c linux-2.6.0-mine/drivers/ide/setup-pci.c
--- linux-2.6.0/drivers/ide/setup-pci.c Thu Nov 27 07:43:39 2003
+++ linux-2.6.0-mine/drivers/ide/setup-pci.c Sat Jan 3 12:52:41 2004
@@ -449,7 +449,17 @@
} else if (hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {
goto fixup_address;
}
- hwif->chipset = ide_pci;
+
+ /*
+ * if the chipset of the returned hwif is currently ide_generic, the PCI
+ * ide driver can take over control of the hwif. We use the special
+ * ide_pci_takeover value to prevent re-probing the drives etc in
+ * probe_hwif_init.
+ */
+
+ if( hwif->chipset == ide_generic ) hwif->chipset = ide_pci_takeover;
+ else hwif->chipset = ide_pci;
+
hwif->pci_dev = dev;
hwif->cds = (struct ide_pci_device_s *) d;
hwif->channel = port;
diff -urN linux-2.6.0/include/linux/ide.h linux-2.6.0-mine/include/linux/ide.h
--- linux-2.6.0/include/linux/ide.h Thu Nov 27 07:43:36 2003
+++ linux-2.6.0-mine/include/linux/ide.h Sat Jan 3 04:55:42 2004
@@ -275,6 +275,10 @@
/*
* hwif_chipset_t is used to keep track of the specific hardware
* chipset used by each IDE interface, if known.
+ *
+ * ide_pci_takeover is a temporary state used when a chipset-specific
+ * driver is loaded as a module and has to take control of a controller
+ * previously being supervised by the generic pci driver.
*/
typedef enum { ide_unknown, ide_generic, ide_pci,
ide_cmd640, ide_dtc2278, ide_ali14xx,
@@ -282,7 +286,7 @@
ide_pdc4030, ide_rz1000, ide_trm290,
ide_cmd646, ide_cy82c693, ide_4drives,
ide_pmac, ide_etrax100, ide_acorn,
- ide_pc9800
+ ide_pc9800, ide_pci_takeover
} hwif_chipset_t;

/*



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/