linux/drivers/ide
Russell King c3be57b6f3 ide: Fix Promise UDMA33 IDE driver (pdc202xx_old)
On Sun, Jan 03, 2010 at 12:23:14AM +0000, Russell King wrote:
> - with IDE
>   - locks the interrupt line, and makes the machine extremely painful -
>     about an hour to get to the point of being able to unload the
>     pdc202xx_old module.

Having manually bisected kernel versions, I've narrowed it down to some
change between 2.6.30 and 2.6.31.  There's not much which has changed
between the two kernels, but one change stands out like a sore thumb:

+static int pdc202xx_test_irq(ide_hwif_t *hwif)
+{
+       struct pci_dev *dev     = to_pci_dev(hwif->dev);
+       unsigned long high_16   = pci_resource_start(dev, 4);
+       u8 sc1d                 = inb(high_16 + 0x1d);
+
+       if (hwif->channel) {
+               /*
+                * bit 7: error, bit 6: interrupting,
+                * bit 5: FIFO full, bit 4: FIFO empty
+                */
+               return ((sc1d & 0x50) == 0x40) ? 1 : 0;
+       } else  {
+               /*
+                * bit 3: error, bit 2: interrupting,
+                * bit 1: FIFO full, bit 0: FIFO empty
+                */
+               return ((sc1d & 0x05) == 0x04) ? 1 : 0;
+       }
+}

Reading the (documented as a 32-bit) system control register when the
interface is idle gives: 0x01da110c

So, the byte at 0x1d is 0x11, which is documented as meaning that the
primary and secondary FIFOs are empty.

The code above, which is trying to see whether an IRQ is pending, checks
for the IRQ bit to be one, and the FIFO bit to be zero - or in English,
to be non-empty.

Since during a BM-DMA read, the FIFOs will naturally be drained to the
PCI bus, the chance of us getting to the interface before this happens
are extremely small - and if we don't, it means we decide not to service
the interrupt.  Hence, the screaming interrupt problem with drivers/ide.

Fix this by only indicating an interrupt is ready if both the interrupt
and FIFO empty bits are at '1'.

This bug only affects PDC20246/PDC20247 (Promise Ultra33) based cards,
and has been tested on 2.6.31 and 2.6.33-rc2.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2010-01-12 01:53:02 -08:00
..
aec62xx.c ide: fix ->init_chipset method to return 'int' value 2009-03-24 23:22:53 +01:00
ali14xx.c ide: remove useless subdirs from drivers/ide/ 2008-10-21 20:57:23 +02:00
alim15x3.c alim15x3: remove obsolete and dangerous wdc_udma parameter 2009-12-03 17:25:57 +01:00
amd74xx.c ide: fix ->init_chipset method to return 'int' value 2009-03-24 23:22:53 +01:00
at91_ide.c at91_ide: remove headers specific for at91sam9263 2009-08-15 18:55:09 -07:00
atiixp.c ahci / atiixp / pci quirks: rename AMD SB900 into Hudson-2 2009-10-16 06:21:20 -04:00
au1xxx-ide.c drivers/ide/au1xxx-ide.c: use resource_size() 2009-11-23 10:27:22 -08:00
buddha.c ide: move ack_intr() method into 'struct ide_port_ops' (take 2) 2009-06-15 18:52:58 +02:00
cmd64x.c cmd64x: remove no longer needed debugging code 2009-12-03 17:25:57 +01:00
cmd640.c cmd640: implement test_irq() method 2009-06-15 18:52:58 +02:00
cs5520.c ide cs5520: Initialize second port's interrupt number. 2009-06-24 02:36:17 -07:00
cs5530.c ide: identify data word 53 bit 1 doesn't cover words 62 and 63 (take 3) 2009-03-31 20:15:27 +02:00
cs5535.c cs5535: add pci id for AMD based CS5535 controllers 2009-12-02 14:23:01 -08:00
cs5536.c ide: do not access ide_drive_t 'drive_data' field directly 2009-06-15 22:13:44 +02:00
cy82c693.c cy82c693: remove no longer needed debugging code 2009-12-03 17:25:57 +01:00
delkin_cb.c ide: remove hw_regs_t typedef 2009-05-17 19:12:25 +02:00
dtc2278.c ide: add IDE_HFLAG_DTC2278 host flag 2009-03-27 12:46:28 +01:00
falconide.c ide: move ack_intr() method into 'struct ide_port_ops' (take 2) 2009-06-15 18:52:58 +02:00
gayle.c ide: move ack_intr() method into 'struct ide_port_ops' (take 2) 2009-06-15 18:52:58 +02:00
hpt366.c hpt366: remove dead old timing tables 2009-11-18 10:38:37 -08:00
ht6560b.c ide: do not access ide_drive_t 'drive_data' field directly 2009-06-15 22:13:44 +02:00
icside.c icside: bring back ->maskproc method 2010-01-12 01:49:23 -08:00
ide_platform.c drivers/ide/ide_platform.c: use resource_size() 2009-11-23 10:30:34 -08:00
ide-4drives.c ide: remove hw_regs_t typedef 2009-05-17 19:12:25 +02:00
ide-acpi.c ACPICA: Major update for acpi_get_object_info external interface 2009-08-27 10:17:15 -04:00
ide-atapi.c Merge branch 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6 2009-06-20 10:11:11 -07:00
ide-cd_ioctl.c ide: remove IDE_AFLAG_NO_DOORLOCKING 2008-10-17 18:09:11 +02:00
ide-cd_verbose.c
ide-cd.c const: make block_device_operations const 2009-09-22 07:17:25 -07:00
ide-cd.h ide-cd: convert to using generic sense request 2009-04-28 07:37:30 +02:00
ide-cs.c pcmcia: rework the irq_req_t typedef 2009-11-28 18:03:14 +01:00
ide-devsets.c ide: always kill the whole request on error 2009-06-25 23:57:16 -07:00
ide-disk_ioctl.c [PATCH] switch ide_disk_ops ->ioctl() to sane prototype 2008-10-21 07:47:30 -04:00
ide-disk_proc.c ide: convert to ->proc_fops 2009-09-01 17:52:57 -07:00
ide-disk.c ide: fix memory leak when flush command is issued 2009-07-21 20:23:46 -07:00
ide-disk.h [PATCH] switch ide_disk_ops ->ioctl() to sane prototype 2008-10-21 07:47:30 -04:00
ide-dma-sff.c ide: remove wmb() from ide-dma-sff.c and scc_pata.c 2009-04-08 14:12:49 +02:00
ide-dma.c ide: relax DMA info validity checking 2009-06-24 00:32:32 -07:00
ide-eh.c ide: always kill the whole request on error 2009-06-25 23:57:16 -07:00
ide-floppy_ioctl.c ide-atapi: remove pc->buf 2009-05-15 06:44:38 +02:00
ide-floppy_proc.c ide: convert to ->proc_fops 2009-09-01 17:52:57 -07:00
ide-floppy.c ide: always kill the whole request on error 2009-06-25 23:57:16 -07:00
ide-floppy.h [PATCH] switch ide_disk_ops ->ioctl() to sane prototype 2008-10-21 07:47:30 -04:00
ide-gd.c const: make block_device_operations const 2009-09-22 07:17:25 -07:00
ide-gd.h ide: move ->failed_pc to ide_drive_t 2009-03-27 12:46:34 +01:00
ide-generic.c ide: remove hw_regs_t typedef 2009-05-17 19:12:25 +02:00
ide-h8300.c ide: remove hw_regs_t typedef 2009-05-17 19:12:25 +02:00
ide-io-std.c ide: refactor tf_read() method 2009-04-08 14:13:03 +02:00
ide-io.c Revert "ide: improve handling of Power Management requests" 2009-07-06 12:39:27 -07:00
ide-ioctls.c ide: fix ioctl to pass requested transfer mode to ide_find_dma_mode instead of UDMA6 2009-11-25 15:04:54 -08:00
ide-iops.c ide: fixup for fujitsu disk 2009-09-15 01:36:25 -07:00
ide-legacy.c ide: remove hw_regs_t typedef 2009-05-17 19:12:25 +02:00
ide-lib.c Merge branch 'master' into for-2.6.31 2009-05-22 20:28:35 +02:00
ide-park.c ide: use blk_run_queue() instead of blk_start_queueing() 2009-04-28 07:37:28 +02:00
ide-pci-generic.c pata_piccolo: Driver for old Toshiba chipsets 2009-12-03 14:35:31 -05:00
ide-pio-blacklist.c
ide-pm.c ide: fix resume for CONFIG_BLK_DEV_IDEACPI=y 2009-06-29 19:20:42 -07:00
ide-pnp.c ide: remove hw_regs_t typedef 2009-05-17 19:12:25 +02:00
ide-probe.c Revert "ide: try to use PIO Mode 0 during probe if possible" 2009-11-06 04:52:50 -08:00
ide-proc.c ide: use printk_once 2009-09-22 16:29:00 -07:00
ide-scan-pci.c
ide-sysfs.c ide: move sysfs support to ide-sysfs.c 2009-01-02 16:12:48 +01:00
ide-tape.c ide-tape: remove the BKL 2009-10-29 03:09:25 -07:00
ide-taskfile.c ide: fix races in handling of user-space SET XFER commands 2009-08-07 10:43:00 -07:00
ide-timings.c ide: add support for CFA specified transfer modes (take 3) 2009-03-31 20:15:28 +02:00
ide-xfer-mode.c ide: don't enable IORDY at a probe time 2009-06-15 18:52:54 +02:00
ide.c ide: preserve Host Protected Area by default (v2) 2009-06-07 13:52:52 +02:00
it821x.c ide: add ->dma_clear method and remove ->dma_timeout one 2009-03-31 20:15:19 +02:00
it8172.c ide: IORDY handling fixes 2009-06-15 18:52:53 +02:00
it8213.c ide: IORDY handling fixes 2009-06-15 18:52:53 +02:00
jmicron.c ide: Switch to a common address 2008-11-02 21:40:08 +01:00
Kconfig ide: update Kconfig text to mark as deprecated 2009-10-29 03:09:26 -07:00
macide.c ide: move ack_intr() method into 'struct ide_port_ops' (take 2) 2009-06-15 18:52:58 +02:00
Makefile ide: merge ide_arm and ide_generic host drivers 2009-03-31 20:15:24 +02:00
ns87415.c ide: refactor tf_read() method 2009-04-08 14:13:03 +02:00
opti621.c ide: do not access ide_drive_t 'drive_data' field directly 2009-06-15 22:13:44 +02:00
palm_bk3710.c IDE: palm_bk3710: convert clock usage after clkdev conversion 2009-08-15 18:55:08 -07:00
pdc202xx_new.c ide: respect quirk_drives[] list on all controllers 2009-06-07 15:37:09 +02:00
pdc202xx_old.c ide: Fix Promise UDMA33 IDE driver (pdc202xx_old) 2010-01-12 01:53:02 -08:00
piix.c ide: IORDY handling fixes 2009-06-15 18:52:53 +02:00
pmac.c powerpc/macio: Rework hotplug media bay support 2009-12-09 17:09:14 +11:00
q40ide.c ide: move ack_intr() method into 'struct ide_port_ops' (take 2) 2009-06-15 18:52:58 +02:00
qd65xx.c ide: do not access ide_drive_t 'drive_data' field directly 2009-06-15 22:13:44 +02:00
qd65xx.h ide: do not access ide_drive_t 'drive_data' field directly 2009-06-15 22:13:44 +02:00
rapide.c ide: remove hw_regs_t typedef 2009-05-17 19:12:25 +02:00
rz1000.c rz1000: apply chipset quirks early (v2) 2008-12-29 20:27:33 +01:00
sc1200.c ide: identify data word 53 bit 1 doesn't cover words 62 and 63 (take 3) 2009-03-31 20:15:27 +02:00
scc_pata.c scc_pata: fix module unloading 2010-01-08 00:11:01 -08:00
serverworks.c ide: fix ->init_chipset method to return 'int' value 2009-03-24 23:22:53 +01:00
setup-pci.c ide: re-implement ide_pci_init_one() on top of ide_pci_init_two() 2009-06-10 14:37:21 +02:00
sgiioc4.c sgiioc4: coding style cleanup 2009-06-15 18:52:55 +02:00
siimage.c siimage: implement test_irq() method 2009-06-15 18:53:00 +02:00
sis5513.c sis5513: remove stale TODO 2009-12-03 17:25:58 +01:00
sl82c105.c sl82c105: remove no longer needed debugging code 2009-12-03 17:25:58 +01:00
slc90e66.c slc90e66: fix UDMA handling 2009-12-01 15:44:18 -08:00
tc86c001.c ide: convert to rq pos and nr_sectors accessors 2009-05-11 09:50:54 +02:00
triflex.c ide: remove HWIF() macro 2009-01-06 17:20:52 +01:00
trm290.c ide: turn selectproc() method into dev_select() method (take 5) 2009-03-31 20:15:32 +02:00
tx4938ide.c drivers/ide/tx4938ide.c: use resource_size() 2009-11-23 10:31:18 -08:00
tx4939ide.c Merge branch 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6 2009-06-12 09:29:42 -07:00
umc8672.c trivial: remove unnecessary semicolons 2009-09-21 15:14:58 +02:00
via82cxxx.c via82cxxx: Add VIA VX855 PCI Device ID 2009-05-22 16:23:39 +02:00