patch-2.4.15: Fix CompactFlash+PCMCIA+PCI system freeze (Resend)

From: Gunther Mayer (Gunther.Mayer@t-online.de)
Date: Sun Nov 25 2001 - 07:43:15 EST


Hi,

this patch is nedded to prevent system freeze on
inserting a CompactFlash (or any other ATA) card
into a PCMCIA-PCI adapter card !

The IDE maintainer (Andre) agreed with the patch but didn't submit
since the August thread .

So he must be bypassed !!!

Thanks David for integrating the minimal one-liner patch (i.e. non-freeze)
to pcmcia-cs-3.1.30. For proper working we must tell the ide subsystem
it is OK to share IRQ (which is mandatory for PCI), this takes some
trivial lines to fix the API in the ide subsystem (about "chipset"s).

Regards, Gunther

diff -ur linux-2.4.15.orig/drivers/ide/ide-cs.c linux/drivers/ide/ide-cs.c
--- linux-2.4.15.orig/drivers/ide/ide-cs.c Sun Sep 30 21:26:05 2001
+++ linux/drivers/ide/ide-cs.c Sun Nov 25 13:11:36 2001
@@ -42,6 +42,7 @@
 #include <linux/ioport.h>
 #include <linux/hdreg.h>
 #include <linux/major.h>
+#include <linux/ide.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -226,6 +227,16 @@
 #define CFG_CHECK(fn, args...) \
 if (CardServices(fn, args) != 0) goto next_entry
 
+int idecs_register (int io_base, int ctl_base, int irq)
+{
+ hw_regs_t hw;
+ ide_init_hwif_ports(&hw, (ide_ioreg_t) io_base, (ide_ioreg_t) ctl_base, NULL);
+ hw.irq = irq;
+ hw.chipset = ide_pci; // this enables IRQ sharing w/ PCI irqs
+ return ide_register_hw(&hw, NULL);
+}
+
+
 void ide_config(dev_link_t *link)
 {
     client_handle_t handle = link->handle;
@@ -327,12 +338,16 @@
     if (link->io.NumPorts2)
        release_region(link->io.BasePort2, link->io.NumPorts2);
 
+ /* disable drive interrupts during IDE probe */
+ if(ctl_base)
+ outb(0x02, ctl_base);
+
     /* retry registration in case device is still spinning up */
     for (i = 0; i < 10; i++) {
- hd = ide_register(io_base, ctl_base, link->irq.AssignedIRQ);
+ hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ);
        if (hd >= 0) break;
        if (link->io.NumPorts1 == 0x20) {
- hd = ide_register(io_base+0x10, ctl_base+0x10,
+ hd = idecs_register(io_base+0x10, ctl_base+0x10,
                              link->irq.AssignedIRQ);
            if (hd >= 0) {
                io_base += 0x10; ctl_base += 0x10;
Only in linux/drivers/ide: ide-cs.c-2415
diff -ur linux-2.4.15.orig/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.4.15.orig/drivers/ide/ide.c Thu Oct 25 22:58:35 2001
+++ linux/drivers/ide/ide.c Sun Nov 25 13:02:34 2001
@@ -2293,6 +2293,7 @@
        memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
        hwif->irq = hw->irq;
        hwif->noprobe = 0;
+ hwif->chipset = hw->chipset;
 
        if (!initializing) {
                ide_probe_module();
diff -ur linux-2.4.15.orig/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.4.15.orig/include/linux/ide.h Thu Nov 22 20:48:07 2001
+++ linux/include/linux/ide.h Sun Nov 25 13:05:57 2001
@@ -223,6 +223,23 @@
 #endif
 
 /*
+ * hwif_chipset_t is used to keep track of the specific hardware
+ * chipset used by each IDE interface, if known.
+ */
+typedef enum { ide_unknown, ide_generic, ide_pci,
+ ide_cmd640, ide_dtc2278, ide_ali14xx,
+ ide_qd65xx, ide_umc8672, ide_ht6560b,
+ ide_pdc4030, ide_rz1000, ide_trm290,
+ ide_cmd646, ide_cy82c693, ide_4drives,
+ ide_pmac, ide_etrax100
+} hwif_chipset_t;
+
+#define IDE_CHIPSET_PCI_MASK \
+ ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
+#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
+
+
+/*
  * Structure to hold all information about the location of this port
  */
 typedef struct hw_regs_s {
@@ -231,6 +248,7 @@
        int dma; /* our dma entry */
        ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
        void *priv; /* interface specific data */
+ hwif_chipset_t chipset;
 } hw_regs_t;
 
 /*
@@ -439,22 +457,6 @@
  * ide soft-power support
  */
 typedef int (ide_busproc_t) (struct hwif_s *, int);
-
-/*
- * hwif_chipset_t is used to keep track of the specific hardware
- * chipset used by each IDE interface, if known.
- */
-typedef enum { ide_unknown, ide_generic, ide_pci,
- ide_cmd640, ide_dtc2278, ide_ali14xx,
- ide_qd65xx, ide_umc8672, ide_ht6560b,
- ide_pdc4030, ide_rz1000, ide_trm290,
- ide_cmd646, ide_cy82c693, ide_4drives,
- ide_pmac, ide_etrax100
-} hwif_chipset_t;
-
-#define IDE_CHIPSET_PCI_MASK \
- ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
-#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
 typedef struct ide_pci_devid_s {


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



This archive was generated by hypermail 2b29 : Fri Nov 30 2001 - 21:00:18 EST