patch(2.4.5): 2nd ed. Fix PCMCIA ATA/IDE + PCI IRQ sharing
Hi, this includes the last fix + now it is willing to share PCI irqs. Of course you still need CONFIG_IDEPCI_SHARE_IRQ set. Now CF is working very fine, hdparm-4.1 shows 1.27 MB/sec. (Only after treaking the source for small (i.e. <64MB) devices). Regards, Gunther --- linux245.orig/drivers/ide/ide-cs.c Fri Feb 9 20:40:02 2001 +++ linux/drivers/ide/ide-cs.c Wed Jun 27 20:19:45 2001 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -223,6 +224,15 @@ #define CFG_CHECK(fn, args...) \ if (CardServices(fn, args) != 0) goto next_entry +int idecs_register (int arg1, int arg2, int irq) +{ +hw_regs_t hw; +ide_init_hwif_ports(, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL); +hw.irq = irq; +hw.chipset = ide_pci; // this enables IRQ sharing w/ PCI irqs +return ide_register_hw(, NULL); +} + void ide_config(dev_link_t *link) { client_handle_t handle = link->handle; @@ -324,12 +334,15 @@ if (link->io.NumPorts2) release_region(link->io.BasePort2, link->io.NumPorts2); +outb(0x02, ctl_base); // Set nIEN = disable device interrupts + // else it hangs on PCI-Cardbus Add-in cards wedging irq + /* 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; --- linux245.orig/drivers/ide/ide-probe.c Sun Mar 18 18:25:02 2001 +++ linux/drivers/ide/ide-probe.c Wed Jun 27 17:31:45 2001 @@ -685,6 +685,8 @@ #else /* !CONFIG_IDEPCI_SHARE_IRQ */ int sa = (hwif->chipset == ide_pci) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT; #endif /* CONFIG_IDEPCI_SHARE_IRQ */ + + outb(0x00, hwif->io_ports[IDE_CONTROL_OFFSET]); // clear nIEN == +enable irqs if (ide_request_irq(hwif->irq, _intr, sa, hwif->name, hwgroup)) { if (!match) kfree(hwgroup); --- linux245.orig/drivers/ide/ide.c Wed May 2 01:05:00 2001 +++ linux/drivers/ide/ide.c Wed Jun 27 20:18:23 2001 @@ -2181,6 +2181,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(); --- linux245.orig/include/linux/ide.h Sat May 26 03:02:42 2001 +++ linux/include/linux/ide.h Wed Jun 27 19:01:35 2001 @@ -226,6 +226,19 @@ #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_qd6580, ide_umc8672,ide_ht6560b, +ide_pdc4030,ide_rz1000, ide_trm290, +ide_cmd646, ide_cy82c693, ide_4drives, +ide_pmac +} hwif_chipset_t; + + +/* * Structure to hold all information about the location of this port */ typedef struct hw_regs_s { @@ -234,6 +247,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; /* @@ -396,17 +410,6 @@ typedef void (ide_maskproc_t) (ide_drive_t *, int); typedef void (ide_rw_proc_t) (ide_drive_t *, ide_dma_action_t); -/* - * 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_qd6580, ide_umc8672,ide_ht6560b, - ide_pdc4030,ide_rz1000, ide_trm290, - ide_cmd646, ide_cy82c693, ide_4drives, - ide_pmac -} hwif_chipset_t; #ifdef CONFIG_BLK_DEV_IDEPCI typedef struct ide_pci_devid_s { P.S. However, my "lsata"'s heuristics shows this as ATA1 (i.e. no ATA2 features used): lsata /dev/hde ihack for pcmcia compact flash ATA Level = 1 ATAPI (Packet Interface): no ATA Device Information for Command 0xEC Conforming to 'AT Attachment for Disk Drives' ANSI X3.221-1994 X3T10 791D Revision 4c Working Draft All reserved Bits shall be zero (Chap. 8.8, p.25) Word 0 General Configuration 1 Shall be 0. Reserved for non-magnetic drives 0 Format speed tolerance gap required ? 'no' : 'yes' 0 Track Offset
patch(2.4.5): 2nd ed. Fix PCMCIA ATA/IDE + PCI IRQ sharing
Hi, this includes the last fix + now it is willing to share PCI irqs. Of course you still need CONFIG_IDEPCI_SHARE_IRQ set. Now CF is working very fine, hdparm-4.1 shows 1.27 MB/sec. (Only after treaking the source for small (i.e. 64MB) devices). Regards, Gunther --- linux245.orig/drivers/ide/ide-cs.c Fri Feb 9 20:40:02 2001 +++ linux/drivers/ide/ide-cs.c Wed Jun 27 20:19:45 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 @@ -223,6 +224,15 @@ #define CFG_CHECK(fn, args...) \ if (CardServices(fn, args) != 0) goto next_entry +int idecs_register (int arg1, int arg2, int irq) +{ +hw_regs_t hw; +ide_init_hwif_ports(hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, 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; @@ -324,12 +334,15 @@ if (link-io.NumPorts2) release_region(link-io.BasePort2, link-io.NumPorts2); +outb(0x02, ctl_base); // Set nIEN = disable device interrupts + // else it hangs on PCI-Cardbus Add-in cards wedging irq + /* 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; --- linux245.orig/drivers/ide/ide-probe.c Sun Mar 18 18:25:02 2001 +++ linux/drivers/ide/ide-probe.c Wed Jun 27 17:31:45 2001 @@ -685,6 +685,8 @@ #else /* !CONFIG_IDEPCI_SHARE_IRQ */ int sa = (hwif-chipset == ide_pci) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT; #endif /* CONFIG_IDEPCI_SHARE_IRQ */ + + outb(0x00, hwif-io_ports[IDE_CONTROL_OFFSET]); // clear nIEN == +enable irqs if (ide_request_irq(hwif-irq, ide_intr, sa, hwif-name, hwgroup)) { if (!match) kfree(hwgroup); --- linux245.orig/drivers/ide/ide.c Wed May 2 01:05:00 2001 +++ linux/drivers/ide/ide.c Wed Jun 27 20:18:23 2001 @@ -2181,6 +2181,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(); --- linux245.orig/include/linux/ide.h Sat May 26 03:02:42 2001 +++ linux/include/linux/ide.h Wed Jun 27 19:01:35 2001 @@ -226,6 +226,19 @@ #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_qd6580, ide_umc8672,ide_ht6560b, +ide_pdc4030,ide_rz1000, ide_trm290, +ide_cmd646, ide_cy82c693, ide_4drives, +ide_pmac +} hwif_chipset_t; + + +/* * Structure to hold all information about the location of this port */ typedef struct hw_regs_s { @@ -234,6 +247,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; /* @@ -396,17 +410,6 @@ typedef void (ide_maskproc_t) (ide_drive_t *, int); typedef void (ide_rw_proc_t) (ide_drive_t *, ide_dma_action_t); -/* - * 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_qd6580, ide_umc8672,ide_ht6560b, - ide_pdc4030,ide_rz1000, ide_trm290, - ide_cmd646, ide_cy82c693, ide_4drives, - ide_pmac -} hwif_chipset_t; #ifdef CONFIG_BLK_DEV_IDEPCI typedef struct ide_pci_devid_s { P.S. However, my lsata's heuristics shows this as ATA1 (i.e. no ATA2 features used): lsata /dev/hde ihack for pcmcia compact flash ATA Level = 1 ATAPI (Packet Interface): no ATA Device Information for Command 0xEC Conforming to 'AT Attachment for Disk Drives' ANSI X3.221-1994 X3T10 791D Revision 4c Working Draft All reserved Bits shall be zero (Chap. 8.8, p.25) Word 0 General Configuration 1 Shall be 0. Reserved for non-magnetic drives 0 Format speed