Messages in this thread Patch in this message | | | Date | Wed, 27 Mar 2002 23:57:35 -0800 (PST) | From | Andre Hedrick <> | Subject | LinuxATADeveloment-2.5.7.patch |
| |
Here you go ...
Anton, please try to break it :-/
Since there is no DIAG layer and I did not want to put it back in because it was taken out there are ZERO PIO checks except for the basic kernel calls.
If this is fixed, I am out of 2.5 until I can fix BLOCK to allow for in process bio walking.
Cheers,
Andre Hedrick LAD Storage Consulting Group Linux version 2.5.7 (root@athy.linux-ide.org) (gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-98)) #1 SMP Thu Mar 28 00:24:53 PST 2002 BIOS-provided physical RAM map: BIOS-e820: 0000000000000000 - 000000000009f400 (usable) BIOS-e820: 000000000009f400 - 00000000000a0000 (reserved) BIOS-e820: 00000000000e4800 - 0000000000100000 (reserved) BIOS-e820: 0000000000100000 - 000000000fff0000 (usable) BIOS-e820: 000000000fff0000 - 000000000fff6c00 (ACPI data) BIOS-e820: 000000000fff6c00 - 0000000010000000 (ACPI NVS) BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved) BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved) BIOS-e820: 00000000fff80000 - 0000000100000000 (reserved) 0MB HIGHMEM available. 255MB LOWMEM available. found SMP MP-table at 000f74d0 hm, page 000f7000 reserved twice. hm, page 000f8000 reserved twice. hm, page 0009f000 reserved twice. hm, page 000a0000 reserved twice. On node 0 totalpages: 65520 zone(0): 4096 pages. zone(1): 61424 pages. zone(2): 0 pages. Intel MultiProcessor Specification v1.4 Virtual Wire compatibility mode. OEM ID: TYAN Product ID: GUINNESS APIC at: 0xFEE00000 Processor #1 Pentium(tm) Pro APIC version 16 Processor #0 Pentium(tm) Pro APIC version 16 I/O APIC #2 Version 17 at 0xFEC00000. Processors: 2 Kernel command line: auto BOOT_IMAGE=257 ro root=302 BOOT_FILE=/boot/vmlinuz-2.5.7 Initializing CPU#0 Detected 997.468 MHz processor. Console: colour VGA+ 80x25 Calibrating delay loop... 1992.29 BogoMIPS Memory: 255020k/262080k available (1926k kernel code, 6672k reserved, 572k data, 260k init, 0k highmem) Dentry-cache hash table entries: 32768 (order: 6, 262144 bytes) Inode-cache hash table entries: 16384 (order: 5, 131072 bytes) Mount-cache hash table entries: 512 (order: 0, 4096 bytes) Buffer-cache hash table entries: 16384 (order: 4, 65536 bytes) Page-cache hash table entries: 65536 (order: 6, 262144 bytes) CPU: Before vendor init, caps: 0183fbff c1c7fbff 00000000, vendor = 2 CPU: L1 I Cache: 64K (64 bytes/line), D cache 64K (64 bytes/line) CPU: L2 Cache: 256K (64 bytes/line) CPU: After vendor init, caps: 0183fbff c1c7fbff 00000000 00000000 Intel machine check architecture supported. Intel machine check reporting enabled on CPU#0. CPU: After generic, caps: 0183fbff c1c7fbff 00000000 00000000 CPU: Common caps: 0183fbff c1c7fbff 00000000 00000000 Enabling fast FPU save and restore... done. Checking 'hlt' instruction... OK. POSIX conformance testing by UNIFIX mtrr: v1.40 (20010327) Richard Gooch (rgooch@atnf.csiro.au) mtrr: detected mtrr type: Intel CPU: Before vendor init, caps: 0183fbff c1c7fbff 00000000, vendor = 2 CPU: L1 I Cache: 64K (64 bytes/line), D cache 64K (64 bytes/line) CPU: L2 Cache: 256K (64 bytes/line) CPU: After vendor init, caps: 0183fbff c1c7fbff 00000000 00000000 Intel machine check reporting enabled on CPU#0. CPU: After generic, caps: 0183fbff c1c7fbff 00000000 00000000 CPU: Common caps: 0183fbff c1c7fbff 00000000 00000000 WARNING: This combination of AMD processors is not suitable for SMP. CPU0: AMD Athlon(tm) Processor stepping 02 per-CPU timeslice cutoff: 731.70 usecs. task migration cache decay timeout: 10 msecs. enabled ExtINT on CPU#0 ESR value before enabling vector: 00000000 ESR value after enabling vector: 00000000 Booting processor 1/0 eip 2000 Initializing CPU#1 masked ExtINT on CPU#1 ESR value before enabling vector: 00000000 ESR value after enabling vector: 00000000 Calibrating delay loop... 1992.29 BogoMIPS CPU: Before vendor init, caps: 0183fbff c1c7fbff 00000000, vendor = 2 CPU: L1 I Cache: 64K (64 bytes/line), D cache 64K (64 bytes/line) CPU: L2 Cache: 256K (64 bytes/line) CPU: After vendor init, caps: 0183fbff c1c7fbff 00000000 00000000 Intel machine check reporting enabled on CPU#1. CPU: After generic, caps: 0183fbff c1c7fbff 00000000 00000000 CPU: Common caps: 0183fbff c1c7fbff 00000000 00000000 WARNING: This combination of AMD processors is not suitable for SMP. CPU1: AMD Athlon(tm) Processor stepping 02 Total of 2 processors activated (3984.58 BogoMIPS). ENABLING IO-APIC IRQs Setting 2 in the phys_id_present_map ...changing IO-APIC physical APIC ID to 2 ... ok. init IO_APIC IRQs IO-APIC (apicid-pin) 2-0, 2-16, 2-17, 2-18, 2-19, 2-20, 2-21, 2-22, 2-23 not connected. ..TIMER: vector=0x31 pin1=2 pin2=0 number of MP IRQ sources: 16. number of IO-APIC #2 registers: 24. testing the IO APIC.......................
IO APIC #2...... .... register #00: 02000000 ....... : physical APIC id: 02 .... register #01: 00170011 ....... : max redirection entries: 0017 ....... : PRQ implemented: 0 ....... : IO APIC version: 0011 .... register #02: 00000000 ....... : arbitration: 00 .... IRQ redirection table: NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect: 00 000 00 1 0 0 0 0 0 0 00 01 003 03 0 0 0 0 0 1 1 39 02 003 03 0 0 0 0 0 1 1 31 03 003 03 0 0 0 0 0 1 1 41 04 003 03 0 0 0 0 0 1 1 49 05 003 03 1 1 0 1 0 1 1 51 06 003 03 0 0 0 0 0 1 1 59 07 003 03 0 0 0 0 0 1 1 61 08 003 03 0 0 0 0 0 1 1 69 09 003 03 0 0 0 0 0 1 1 71 0a 003 03 1 1 0 1 0 1 1 79 0b 003 03 1 1 0 1 0 1 1 81 0c 003 03 0 0 0 0 0 1 1 89 0d 003 03 0 0 0 0 0 1 1 91 0e 003 03 0 0 0 0 0 1 1 99 0f 003 03 0 0 0 0 0 1 1 A1 10 000 00 1 0 0 0 0 0 0 00 11 000 00 1 0 0 0 0 0 0 00 12 000 00 1 0 0 0 0 0 0 00 13 000 00 1 0 0 0 0 0 0 00 14 000 00 1 0 0 0 0 0 0 00 15 000 00 1 0 0 0 0 0 0 00 16 000 00 1 0 0 0 0 0 0 00 17 000 00 1 0 0 0 0 0 0 00 IRQ to pin mappings: IRQ0 -> 0:2 IRQ1 -> 0:1 IRQ3 -> 0:3 IRQ4 -> 0:4 IRQ5 -> 0:5 IRQ6 -> 0:6 IRQ7 -> 0:7 IRQ8 -> 0:8 IRQ9 -> 0:9 IRQ10 -> 0:10 IRQ11 -> 0:11 IRQ12 -> 0:12 IRQ13 -> 0:13 IRQ14 -> 0:14 IRQ15 -> 0:15 .................................... done. Using local APIC timer interrupts. calibrating APIC timer ... ..... CPU clock speed is 997.4867 MHz. ..... host bus clock speed is 265.9963 MHz. cpu: 0, clocks: 2659963, slice: 886654 CPU0<T0:2659952,T1:1773296,D:2,S:886654,C:2659963> cpu: 1, clocks: 2659963, slice: 886654 CPU1<T0:2659952,T1:886640,D:4,S:886654,C:2659963> checking TSC synchronization across CPUs: passed. mtrr: your CPUs had inconsistent fixed MTRR settings mtrr: probably your BIOS does not setup all CPUs Linux NET4.0 for Linux 2.4 Based upon Swansea University Computer Society NET3.039 Initializing RT netlink socket PCI: PCI BIOS revision 2.10 entry at 0xfd7c0, last bus=1 PCI: Using configuration type 1 PCI: Probing PCI hardware PCI: Probing PCI hardware (bus 00) Unknown bridge resource 0: assuming transparent Unknown bridge resource 1: assuming transparent Unknown bridge resource 2: assuming transparent BIOS failed to enable PCI standards compliance, fixing this error. I/O APIC: AMD Errata #22 may be present. In the event of instability try : booting with the "noapic" option. isapnp: Scanning for PnP cards... isapnp: No Plug & Play device found IA-32 Microcode Update Driver: v1.09 <tigran@veritas.com> Starting kswapd BIO: pool of 256 setup, 14Kb (56 bytes/bio) biovec: init pool 0, 1 entries, 12 bytes biovec: init pool 1, 4 entries, 48 bytes biovec: init pool 2, 16 entries, 192 bytes biovec: init pool 3, 64 entries, 768 bytes biovec: init pool 4, 128 entries, 1536 bytes biovec: init pool 5, 256 entries, 3072 bytes VFS: Diskquotas version dquot_6.4.0 initialized Journalled Block Device driver loaded devfs: v1.11 (20020129) Richard Gooch (rgooch@atnf.csiro.au) devfs: boot_options: 0x0 Installing knfsd (copyright (C) 1996 okir@monad.swb.de). udf: registering filesystem i2c-core.o: i2c core module i2c-dev.o: i2c /dev entries driver module i2c-core.o: driver i2c-dev dummy driver registered. i2c-algo-bit.o: i2c bit algorithm module i2c-algo-pcf.o: i2c pcf8584 algorithm module i2c-proc.o version 2.6.1 (20010825) pty: 256 Unix98 ptys configured Serial driver version 5.05c (2001-07-08) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled ttyS00 at 0x03f8 (irq = 4) is a 16550A kmod: failed to exec /sbin/modprobe -s -k parport_lowlevel, errno = 2 lp: driver loaded but no devices found Real Time Clock Driver v1.11 Non-volatile memory driver v1.1 Software Watchdog Timer: 0.05, timer margin: 60 sec block: 256 slots per queue, batch=32 RAMDISK driver initialized: 16 RAM disks of 64000K size 1024 blocksize loop: loaded (max 8 devices) Uniform Multi-Platform E-IDE driver ver.:7.0.0 ide: system bus speed 33MHz Advanced Micro Devices [AMD] AMD-765 [Viper] IDE: IDE controller on PCI slot 00:07.1 Advanced Micro Devices [AMD] AMD-765 [Viper] IDE: chipset revision 1 Advanced Micro Devices [AMD] AMD-765 [Viper] IDE: not 100% native mode: will probe irqs later AMD_IDE: Bios didn't set cable bits corectly. Enabling workaround. AMD_IDE: Advanced Micro Devices [AMD] AMD-765 [Viper] IDE (rev 01) UDMA100 controller on pci00:07.1 ide0: BM-DMA at 0xf000-0xf007, BIOS settings: hda:DMA, hdb:pio ide1: BM-DMA at 0xf008-0xf00f, BIOS settings: hdc:pio, hdd:pio CMD Technology Inc PCI0680: IDE controller on PCI slot 00:08.0 CMD Technology Inc PCI0680: chipset revision 1 CMD Technology Inc PCI0680: not 100% native mode: will probe irqs later ide2: BM-DMA at 0x1c50-0x1c57, BIOS settings: hde:DMA, hdf:pio ide3: BM-DMA at 0x1c58-0x1c5f, BIOS settings: hdg:DMA, hdh:pio hda: Maxtor 54610H6, ATA DISK drive hdc: CD-ROM CDU611, ATAPI CD/DVD-ROM drive hde: Maxtor 4G160J8, ATA DISK drive hdg: QUANTUM FIREBALL EX6.4A, ATA DISK drive ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 ide1 at 0x170-0x177,0x376 on irq 15 ide2 at 0x1c78-0x1c7f,0x1c72 on irq 10 ide3 at 0x1c68-0x1c6f,0x1c66 on irq 10 blk: queue c04226ac, I/O limit 4095Mb (mask 0xffffffff) hda: 90045648 sectors (46103 MB) w/2048KiB Cache, CHS=89331/16/63, UDMA(33) blk: queue c04232f4, I/O limit 4095Mb (mask 0xffffffff) hde: 320173056 sectors (163929 MB) w/2048KiB Cache, CHS=317632/255/63, UDMA(100) blk: queue c0423918, I/O limit 4095Mb (mask 0xffffffff) hdg: 12594960 sectors (6449 MB) w/418KiB Cache, CHS=13328/15/63, UDMA(33) hdc: ATAPI 10X CD-ROM drive, 256kB Cache, DMA Uniform CD-ROM driver Revision: 3.12 Partition check: /dev/ide/host0/bus0/target0/lun0: [PTBL] [5605/255/63] p1 p2 p3 p4 < p5 p6 p7 > /dev/ide/host2/bus0/target0/lun0: unknown partition table /dev/ide/host2/bus1/target0/lun0: unknown partition table SCSI subsystem driver Revision: 1.00 scsi0 : SCSI host adapter emulation for IDE ATAPI devices st: Version 20020123, bufsize 32768, wrt 30720, max init. bufs 4, s/g segs 16 NET4: Linux TCP/IP 1.0 for NET4.0 IP Protocols: ICMP, UDP, TCP IP: routing cache hash table of 1024 buckets, 16Kbytes TCP: Hash tables configured (established 8192 bind 10922) NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. RAMDISK: Compressed image found at block 0 Freeing initrd memory: 260k freed VFS: Mounted root (ext2 filesystem) readonly. Freeing unused kernel memory: 260k freed md: md driver 0.90.0 MAX_MD_DEVS=256, MD_SB_DISKS=27 diff -urN linux-2.5.7/drivers/ide/hpt34x.c linux-2.5.7.fix/drivers/ide/hpt34x.c --- linux-2.5.7/drivers/ide/hpt34x.c Mon Mar 18 12:37:05 2002 +++ linux-2.5.7.fix/drivers/ide/hpt34x.c Fri Mar 22 21:47:09 2002 @@ -334,6 +334,8 @@ drive->waiting_for_dma = 1; if (drive->type != ATA_DISK) return 0; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); return 0; diff -urN linux-2.5.7/drivers/ide/icside.c linux-2.5.7.fix/drivers/ide/icside.c --- linux-2.5.7/drivers/ide/icside.c Mon Mar 18 12:37:05 2002 +++ linux-2.5.7.fix/drivers/ide/icside.c Fri Mar 22 21:47:41 2002 @@ -444,6 +444,9 @@ if (drive->media != ide_disk) return 0; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL); OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); diff -urN linux-2.5.7/drivers/ide/ide-cd.c linux-2.5.7.fix/drivers/ide/ide-cd.c --- linux-2.5.7/drivers/ide/ide-cd.c Mon Mar 18 12:37:13 2002 +++ linux-2.5.7.fix/drivers/ide/ide-cd.c Fri Mar 22 21:50:58 2002 @@ -745,6 +745,9 @@ (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive)); if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry); OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ return ide_started; @@ -786,6 +789,9 @@ return startstop; } + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + /* Arm the interrupt handler. */ ide_set_handler (drive, handler, timeout, cdrom_timer_expiry); @@ -1005,6 +1011,9 @@ /* Done moving data! Wait for another interrupt. */ + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL); return ide_started; } @@ -1335,6 +1344,9 @@ } /* Now we wait for another interrupt. */ + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry); return ide_started; } @@ -1559,6 +1571,9 @@ } /* re-arm handler */ + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL); return ide_started; } diff -urN linux-2.5.7/drivers/ide/ide-dma.c linux-2.5.7.fix/drivers/ide/ide-dma.c --- linux-2.5.7/drivers/ide/ide-dma.c Mon Mar 18 12:37:07 2002 +++ linux-2.5.7.fix/drivers/ide/ide-dma.c Fri Mar 22 21:51:28 2002 @@ -588,6 +588,9 @@ drive->waiting_for_dma = 1; if (drive->type != ATA_DISK) return 0; + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) && (drive->addressing == 1)) { diff -urN linux-2.5.7/drivers/ide/ide-floppy.c linux-2.5.7.fix/drivers/ide/ide-floppy.c --- linux-2.5.7/drivers/ide/ide-floppy.c Mon Mar 18 12:37:08 2002 +++ linux-2.5.7.fix/drivers/ide/ide-floppy.c Fri Mar 22 21:54:53 2002 @@ -968,6 +968,9 @@ if (temp > pc->buffer_size) { printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n"); idefloppy_discard_data (drive,bcount.all); + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); return ide_started; } @@ -990,6 +993,8 @@ pc->actually_transferred+=bcount.all; /* Update the current position */ pc->current_position+=bcount.all; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ return ide_started; } @@ -1014,6 +1019,8 @@ printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n"); return ide_stopped; } + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */ atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */ return ide_started; @@ -1062,9 +1069,13 @@ * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will * not be actually used until after the packet is moved in about 50 msec. */ + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + ide_set_handler (drive, &idefloppy_pc_intr, /* service routine for packet command */ - floppy->ticks, /* wait this long before "failing" */ + floppy->ticks, /* wait this long before "failing" */ &idefloppy_transfer_pc2); /* fail == transfer_pc2 */ return ide_started; } @@ -1145,6 +1156,9 @@ } if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) { + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL); OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ return ide_started; diff -urN linux-2.5.7/drivers/ide/ide-pmac.c linux-2.5.7.fix/drivers/ide/ide-pmac.c --- linux-2.5.7/drivers/ide/ide-pmac.c Mon Mar 18 12:37:17 2002 +++ linux-2.5.7.fix/drivers/ide/ide-pmac.c Fri Mar 22 21:55:20 2002 @@ -993,6 +993,8 @@ drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA, IDE_COMMAND_REG); diff -urN linux-2.5.7/drivers/ide/ide-tape.c linux-2.5.7.fix/drivers/ide/ide-tape.c --- linux-2.5.7/drivers/ide/ide-tape.c Mon Mar 18 12:37:07 2002 +++ linux-2.5.7.fix/drivers/ide/ide-tape.c Fri Mar 22 21:57:56 2002 @@ -2155,6 +2155,9 @@ if (temp > pc->buffer_size) { printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); idetape_discard_data (drive, bcount.all); + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); return ide_started; } @@ -2181,6 +2184,9 @@ if (tape->debug_level >= 2) printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all); #endif + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */ return ide_started; } @@ -2255,6 +2261,8 @@ return ide_stopped; } tape->cmd_start_time = jiffies; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */ atapi_output_bytes (drive,pc->c,12); /* Send the actual packet */ return ide_started; @@ -2328,6 +2336,9 @@ } #endif /* CONFIG_BLK_DEV_IDEDMA */ if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); return ide_started; diff -urN linux-2.5.7/drivers/ide/ide-taskfile.c linux-2.5.7.fix/drivers/ide/ide-taskfile.c --- linux-2.5.7/drivers/ide/ide-taskfile.c Mon Mar 18 12:37:15 2002 +++ linux-2.5.7.fix/drivers/ide/ide-taskfile.c Thu Mar 28 00:17:22 2002 @@ -1,8 +1,27 @@ /* - * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> - * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> + * linux/drivers/ide/ide-taskfile.c Version 0.30 Mar 23, 2002 * - * May be copied or modified under the terms of the GNU General Public License + * Copyright (C) 2000-2002 Michael Cornwell <cornwell@acm.org> + * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> + * + * The big the bad and the ugly. + * + * Problems to be fixed because of BIO interface or the lack therefore. + * + * Fill me in stupid !!! + * + * HOST: + * General refers to the Controller and Driver "pair". + * DATA HANDLER: + * Under the context of Linux it generally refers to an interrupt handler. + * However, it correctly describes the 'HOST' + * DATA BLOCK: + * The amount of data needed to be transfered as predefined in the + * setup of the device. + * STORAGE ATOMIC: + * The 'DATA BLOCK' associated to the 'DATA HANDLER', and can be as + * small as a single sector or as large as the entire command block + * request. */ #include <linux/config.h> @@ -33,7 +52,7 @@ #define DEBUG_TASKFILE 0 /* unset when fixed */ #if DEBUG_TASKFILE -#define DTF(x...) printk(##x) +#define DTF(x...) printk(x) #else #define DTF(x...) #endif @@ -55,7 +74,7 @@ unsigned long *flags) { if (rq->bio) - bio_kunmap_irq(to, flags); + bio_kunmap_irq(to, flags); } static void bswap_data (void *buffer, int wcount) @@ -288,67 +307,96 @@ break; } } -static ide_startstop_t bio_mulout_intr(ide_drive_t *drive); /* + * FIXME before 2.6 ... DATA integrity issue upon error. + */ +/* * Handler for command write multiple * Called directly from execute_drive_cmd for the first bunch of sectors, * afterwards only by the ISR */ static ide_startstop_t task_mulout_intr(ide_drive_t *drive) { - unsigned int msect, nsect; - byte stat = GET_STAT(); - byte io_32bit = drive->io_32bit; - struct request *rq = HWGROUP(drive)->rq; - ide_hwgroup_t *hwgroup = HWGROUP(drive); - char *pBuf = NULL; + byte stat = GET_STAT(); + byte io_32bit = drive->io_32bit; + struct request *rq = HWGROUP(drive)->rq; + char *pBuf = NULL; + ide_startstop_t startstop = ide_stopped; + unsigned int msect = drive->mult_count; + unsigned int nsect; unsigned long flags; +/* + * held here as a referrence to the past. + * __ide_end_request(drive, 1, rq->hard_nr_sectors); + */ /* * (ks/hs): Handle last IRQ on multi-sector transfer, * occurs after all data was sent in this chunk */ if (rq->current_nr_sectors == 0) { - if (stat & (ERR_STAT|DRQ_STAT)) + if (stat & (ERR_STAT|DRQ_STAT)) { + printk("%s: MULTI-WRITE assume all data transfered " \ + "is bad status=0x%02x\n", + drive->name, stat); return ide_error(drive, "task_mulout_intr", stat); - - /* - * there may be more, ide_do_request will restart it if - * necessary - */ - ide_end_request(drive, 1); - - return ide_stopped; + } + if (!rq->bio) + ide_end_request(drive, 1); + return startstop; } if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { + printk("%s: MULTI-WRITE assume all data transfered " \ + "is bad status=0x%02x\n", + drive->name, stat); return ide_error(drive, "task_mulout_intr", stat); } /* no data yet, so wait for another interrupt */ - if (hwgroup->handler == NULL) + if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); return ide_started; } - /* (ks/hs): See task_mulin_intr */ - msect = drive->mult_count; - nsect = rq->current_nr_sectors; - if (nsect > msect) - nsect = msect; + if (HWGROUP(drive)->handler != NULL) { + unsigned long lflags; + spin_lock_irqsave(&ide_lock, lflags); + HWGROUP(drive)->handler = NULL; + del_timer(&HWGROUP(drive)->timer); + spin_unlock_irqrestore(&ide_lock, lflags); + } - pBuf = ide_map_rq(rq, &flags); - DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n", - pBuf, nsect, rq->current_nr_sectors); - drive->io_32bit = 0; - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - ide_unmap_rq(rq, pBuf, &flags); - drive->io_32bit = io_32bit; + do { + nsect = rq->current_nr_sectors; + if (nsect > msect) + nsect = msect; + pBuf = ide_map_rq(rq, &flags); + DTF("Multiwrite: %p, nsect: %d, msect: %d, " \ + "rq->current_nr_sectors: %ld\n", + pBuf, nsect, msect, rq->current_nr_sectors); + msect -= nsect; + drive->io_32bit = 0; +// rq->current_nr_sectors -= nsect; + taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); + ide_unmap_rq(rq, pBuf, &flags); + rq->current_nr_sectors -= nsect; + drive->io_32bit = io_32bit; + /* + * FIXME :: We really can not legally get a new page/bio + * regardless, if this is the end of our segment. + * BIO walking or segment can only be updated after we + * have a good GET_STAT(); return. + */ + if (!rq->current_nr_sectors) { + if (!ide_end_request(drive, 1)) + if (!rq->bio) + return ide_stopped; + } + } while (msect); rq->errors = 0; - /* Are we sure that this as all been already transfered? */ - rq->current_nr_sectors -= nsect; - if (hwgroup->handler == NULL) + if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); return ide_started; } @@ -361,11 +409,10 @@ byte HIHI = (drive->addressing) ? 0xE0 : 0xEF; /* (ks/hs): Moved to start, do not use for multiple out commands */ - if (task->handler != task_mulout_intr && task->handler != bio_mulout_intr) { - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ - SELECT_MASK(HWIF(drive), drive, 0); - } + /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ + SELECT_MASK(HWIF(drive), drive, 0); if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) && @@ -389,11 +436,6 @@ if (task->handler != NULL) { ide_set_handler (drive, task->handler, WAIT_CMD, NULL); OUT_BYTE(taskfile->command, IDE_COMMAND_REG); - /* - * Warning check for race between handler and prehandler for - * writing first block of data. however since we are well - * inside the boundaries of the seek, we should be okay. - */ if (task->prehandler != NULL) { return task->prehandler(drive, task->rq); } @@ -405,7 +447,12 @@ return ide_started; } -void do_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, +/* + * FIXME :: Need to merge all taskfile requests regardless of caller + * to the above do_rw_taskfile. + */ +void do_taskfile(ide_drive_t *drive, + struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, ide_handler_t *handler) { @@ -413,11 +460,10 @@ byte HIHI = (drive->addressing) ? 0xE0 : 0xEF; /* (ks/hs): Moved to start, do not use for multiple out commands */ - if (*handler != task_mulout_intr && handler != bio_mulout_intr) { - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ - SELECT_MASK(HWIF(drive), drive, 0); - } + /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ + SELECT_MASK(HWIF(drive), drive, 0); if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) && @@ -477,6 +523,8 @@ if (stat & (ERR_STAT|DRQ_STAT)) return ide_error(drive, "set_geometry_intr", stat); + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &set_geometry_intr, WAIT_CMD, NULL); return ide_started; } @@ -513,7 +561,10 @@ } /* - * Handler for command with PIO data-in phase + * Handler for command with PIO data-in phase, READ + */ +/* + * FIXME before 2.6 ... DATA integrity issue upon error. <andre@linux-ide.org> */ static ide_startstop_t task_in_intr (ide_drive_t *drive) { @@ -525,65 +576,85 @@ if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { +#if 0 + DTF("%s: READ attempting to recover last " \ + "sector counter status=0x%02x\n", + drive->name, stat); + /* + * Expect a BUG BOMB if we attempt to rewind the + * offset in the BIO aka PAGE in the current BLOCK + * segment. This is different than the HOST segment. + */ + + rq->current_nr_sectors++; +#endif return ide_error(drive, "task_in_intr", stat); } if (!(stat & BUSY_STAT)) { DTF("task_in_intr to Soon wait for next interrupt\n"); - ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); + if (HWGROUP(drive)->handler == NULL) + ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); return ide_started; } } - DTF("stat: %02x\n", stat); pBuf = ide_map_rq(rq, &flags); - DTF("Read: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); - + DTF("Read: %p, rq->current_nr_sectors: %d, stat: %02x\n", + pBuf, (int) rq->current_nr_sectors, stat); drive->io_32bit = 0; taskfile_input_data(drive, pBuf, SECTOR_WORDS); ide_unmap_rq(rq, pBuf, &flags); drive->io_32bit = io_32bit; - - if (--rq->current_nr_sectors <= 0) { - /* (hs): swapped next 2 lines */ - DTF("Request Ended stat: %02x\n", GET_STAT()); - if (ide_end_request(drive, 1)) { - ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); - return ide_started; - } - } else { + /* + * FIXME :: We really can not legally get a new page/bio + * regardless, if this is the end of our segment. + * BIO walking or segment can only be updated after we have a good + * GET_STAT(); return. + */ + if (--rq->current_nr_sectors <= 0) + if (!ide_end_request(drive, 1)) + return ide_stopped; + /* + * ERM, it is techincally legal to leave/exit here but it makes + * a mess of the code ... + */ + if (HWGROUP(drive)->handler == NULL) ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); - return ide_started; - } - return ide_stopped; + return ide_started; } +/* + * VERIFY ME before 2.6 ... unexpected race is possible based on details + * RMK with 74LS245/373/374 TTL buffer logic because of passthrough. + */ static ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) { - ide_task_t *args = rq->special; + char *pBuf = NULL; + unsigned long flags; ide_startstop_t startstop; - if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { - printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name, drive->mult_count ? "MULTWRITE" : "WRITE"); + if (ide_wait_stat(&startstop, drive, DATA_READY, + drive->bad_wstat, WAIT_DRQ)) { + printk(KERN_ERR "%s: no DRQ after issuing %s\n", + drive->name, + drive->addressing ? "WRITE_EXT" : "WRITE"); return startstop; } - - /* (ks/hs): Fixed Multi Write */ - if ((args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE) && - (args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE_EXT)) { - unsigned long flags; - char *buf = ide_map_rq(rq, &flags); - /* For Write_sectors we need to stuff the first sector */ - taskfile_output_data(drive, buf, SECTOR_WORDS); - rq->current_nr_sectors--; - ide_unmap_rq(rq, buf, &flags); - } else { - ata_poll_drive_ready(drive); - return args->handler(drive); - } + /* For Write_sectors we need to stuff the first sector */ + pBuf = ide_map_rq(rq, &flags); +// rq->current_nr_sectors--; + taskfile_output_data(drive, pBuf, SECTOR_WORDS); + /* + * WARNING :: Interrupt could happen instantly :-/ + */ + ide_unmap_rq(rq, pBuf, &flags); + rq->current_nr_sectors--; return ide_started; } /* - * Handler for command with PIO data-out phase + * Handler for command with PIO data-out phase WRITE + * + * WOOHOO this is a CORRECT STATE DIAGRAM NOW, <andre@linux-ide.org> */ static ide_startstop_t task_out_intr(ide_drive_t *drive) { @@ -593,163 +664,100 @@ char *pBuf = NULL; unsigned long flags; - if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) + if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) { + DTF("%s: WRITE attempting to recover last " \ + "sector counter status=0x%02x\n", + drive->name, stat); + rq->current_nr_sectors++; return ide_error(drive, "task_out_intr", stat); - + } + /* + * Safe to update request for partial completions. + * We have a good STATUS CHECK!!! + */ if (!rq->current_nr_sectors) if (!ide_end_request(drive, 1)) return ide_stopped; - if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) { rq = HWGROUP(drive)->rq; pBuf = ide_map_rq(rq, &flags); - DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); + DTF("write: %p, rq->current_nr_sectors: %d\n", + pBuf, (int) rq->current_nr_sectors); drive->io_32bit = 0; +// rq->current_nr_sectors--; taskfile_output_data(drive, pBuf, SECTOR_WORDS); ide_unmap_rq(rq, pBuf, &flags); drive->io_32bit = io_32bit; rq->errors = 0; rq->current_nr_sectors--; } - - ide_set_handler(drive, task_out_intr, WAIT_CMD, NULL); + if (HWGROUP(drive)->handler == NULL) + ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL); return ide_started; } -static ide_startstop_t pre_bio_out_intr(ide_drive_t *drive, struct request *rq) +static ide_startstop_t pre_task_mulout_intr(ide_drive_t *drive, struct request *rq) { ide_task_t *args = rq->special; ide_startstop_t startstop; - /* - * assign private copy for multi-write - */ - memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request)); - - if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) + if (ide_wait_stat(&startstop, drive, DATA_READY, + drive->bad_wstat, WAIT_DRQ)) { + printk(KERN_ERR "%s: no DRQ after issuing %s\n", + drive->name, + drive->addressing ? "MULTWRITE_EXT" : "MULTWRITE"); return startstop; - + } +#if 0 + if (wait_for_ready(drive, 100)) + BUG(); +#else ata_poll_drive_ready(drive); - return args->handler(drive); -} - - -static ide_startstop_t bio_mulout_intr (ide_drive_t *drive) -{ - byte stat = GET_STAT(); - byte io_32bit = drive->io_32bit; - struct request *rq = &HWGROUP(drive)->wrq; - ide_hwgroup_t *hwgroup = HWGROUP(drive); - int mcount = drive->mult_count; - ide_startstop_t startstop; - +#endif /* - * (ks/hs): Handle last IRQ on multi-sector transfer, - * occurs after all data was sent in this chunk + * WARNING :: if the drive as not acked good status we may not + * move the DATA-TRANSFER T-Bar as BSY != 0. <andre@linux-ide.org> */ - if (!rq->nr_sectors) { - if (stat & (ERR_STAT|DRQ_STAT)) { - startstop = ide_error(drive, "bio_mulout_intr", stat); - memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request)); - return startstop; - } - - __ide_end_request(drive, 1, rq->hard_nr_sectors); - HWGROUP(drive)->wrq.bio = NULL; - return ide_stopped; - } - - if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { - if (stat & (ERR_STAT | DRQ_STAT)) { - startstop = ide_error(drive, "bio_mulout_intr", stat); - memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request)); - return startstop; - } - - /* no data yet, so wait for another interrupt */ - if (hwgroup->handler == NULL) - ide_set_handler(drive, bio_mulout_intr, WAIT_CMD, NULL); - - return ide_started; - } - - do { - char *buffer; - int nsect = rq->current_nr_sectors; - unsigned long flags; - - if (nsect > mcount) - nsect = mcount; - mcount -= nsect; - - buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq); - rq->sector += nsect; - rq->nr_sectors -= nsect; - rq->current_nr_sectors -= nsect; - - /* Do we move to the next bio after this? */ - if (!rq->current_nr_sectors) { - /* remember to fix this up /jens */ - struct bio *bio = rq->bio->bi_next; - - /* end early early we ran out of requests */ - if (!bio) { - mcount = 0; - } else { - rq->bio = bio; - rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9; - } - } - - /* - * Ok, we're all setup for the interrupt - * re-entering us on the last transfer. - */ - taskfile_output_data(drive, buffer, nsect * SECTOR_WORDS); - bio_kunmap_irq(buffer, &flags); - } while (mcount); - - drive->io_32bit = io_32bit; - rq->errors = 0; - if (hwgroup->handler == NULL) - ide_set_handler(drive, bio_mulout_intr, WAIT_CMD, NULL); - - return ide_started; + return args->handler(drive); } /* * Handler for command with Read Multiple */ +/* + * FIXME before 2.6 ... DATA integrity issue upon error. <andre@linux-ide.org> + */ static ide_startstop_t task_mulin_intr(ide_drive_t *drive) { - unsigned int msect, nsect; byte stat = GET_STAT(); byte io_32bit = drive->io_32bit; struct request *rq = HWGROUP(drive)->rq; char *pBuf = NULL; + unsigned int msect = drive->mult_count; + unsigned int nsect; unsigned long flags; if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { + printk("%s: MULTI-READ assume all data transfered " \ + "is bad status=0x%02x\n", + drive->name, stat); return ide_error(drive, "task_mulin_intr", stat); } /* no data yet, so wait for another interrupt */ - ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL); + if (HWGROUP(drive)->handler == NULL) + ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL); return ide_started; } - /* (ks/hs): Fixed Multi-Sector transfer */ - msect = drive->mult_count; - do { nsect = rq->current_nr_sectors; if (nsect > msect) nsect = msect; - pBuf = ide_map_rq(rq, &flags); - - DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n", - pBuf, nsect, rq->current_nr_sectors); + DTF("Multiread: %p, nsect: %d, msect: %d, " \ + " rq->current_nr_sectors: %d\n", + pBuf, nsect, msect, rq->current_nr_sectors); drive->io_32bit = 0; taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); ide_unmap_rq(rq, pBuf, &flags); @@ -762,12 +770,8 @@ return ide_stopped; } } while (msect); - - - /* - * more data left - */ - ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL); + if (HWGROUP(drive)->handler == NULL) + ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL); return ide_started; } @@ -778,6 +782,9 @@ args->prehandler = NULL; args->handler = NULL; +#if 0 + args->posthandler = NULL; /* put this back in or BUGS will happen */ +#endif switch(args->tfRegister[IDE_COMMAND_OFFSET]) { case WIN_IDENTIFY: @@ -814,8 +821,8 @@ case CFA_WRITE_MULTI_WO_ERASE: case WIN_MULTWRITE: case WIN_MULTWRITE_EXT: - args->prehandler = pre_bio_out_intr; - args->handler = bio_mulout_intr; + args->prehandler = pre_task_mulout_intr; + args->handler = task_mulout_intr; args->command_type = IDE_DRIVE_TASK_RAW_WRITE; return; @@ -1063,6 +1070,9 @@ * * The caller has to make sure buf is never NULL! */ +/* + * FIXME before 2.6, this needs to map into at taskfile. <andre@linux-ide.org> + */ static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *argbuf) { struct request rq; @@ -1080,6 +1090,9 @@ return ide_do_drive_cmd(drive, &rq, ide_wait); } +/* + * FIXME before 2.6, this needs to map into at taskfile. <andre@linux-ide.org> + */ int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; @@ -1133,6 +1146,9 @@ return err; } +/* + * FIXME before 2.6, this needs to map into at taskfile. <andre@linux-ide.org> + */ int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; diff -urN linux-2.5.7/drivers/ide/ide.c linux-2.5.7.fix/drivers/ide/ide.c --- linux-2.5.7/drivers/ide/ide.c Mon Mar 18 12:37:14 2002 +++ linux-2.5.7.fix/drivers/ide/ide.c Sat Mar 23 01:22:41 2002 @@ -549,6 +549,8 @@ printk("%s: ATAPI reset complete\n", drive->name); } else { if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) { + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL); return ide_started; /* continue polling */ } @@ -574,6 +576,8 @@ if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) { if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) { + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL); return ide_started; /* continue polling */ } @@ -645,6 +649,8 @@ udelay (20); OUT_BYTE (WIN_SRST, IDE_COMMAND_REG); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL); __restore_flags (flags); /* local CPU only */ return ide_started; @@ -679,6 +685,8 @@ } udelay(10); /* more than enough time */ hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL); /* @@ -933,6 +941,9 @@ */ void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) { + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); + ide_set_handler (drive, handler, WAIT_CMD, NULL); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ diff -urN linux-2.5.7/drivers/ide/pdc4030.c linux-2.5.7.fix/drivers/ide/pdc4030.c --- linux-2.5.7/drivers/ide/pdc4030.c Mon Mar 18 12:37:08 2002 +++ linux-2.5.7.fix/drivers/ide/pdc4030.c Sat Mar 23 01:28:41 2002 @@ -394,6 +394,9 @@ if (GET_STAT() & BUSY_STAT) { if (time_before(jiffies, hwgroup->poll_timeout)) { + + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); return ide_started; /* continue polling... */ } @@ -476,6 +479,7 @@ if (IN_BYTE(IDE_NSECTOR_REG) != 0) { if (time_before(jiffies, hwgroup->poll_timeout)) { + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ BUG(); ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL); return ide_started; /* continue polling... */ } @@ -489,6 +493,8 @@ */ promise_multwrite(drive, 4); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); #ifdef DEBUG_WRITE printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n", @@ -523,6 +529,8 @@ if (promise_multwrite(drive, rq->nr_sectors - 4)) return ide_stopped; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL); return ide_started; } else { @@ -533,6 +541,8 @@ if (promise_multwrite(drive, rq->nr_sectors)) return ide_stopped; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); #ifdef DEBUG_WRITE printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, " @@ -554,6 +564,13 @@ unsigned long timeout; byte stat; + /* Check that it's a regular command. If not, bomb out early. */ + if (!(rq->flags & REQ_CMD)) { + blk_dump_rq_flags(rq, "pdc4030 bad flags"); + ide_end_request(drive, 0); + return ide_stopped; + } + if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ SELECT_MASK(HWIF(drive), drive, 0); @@ -568,16 +585,8 @@ OUT_BYTE(taskfile->device_head, IDE_SELECT_REG); OUT_BYTE(taskfile->command, IDE_COMMAND_REG); -/* Check that it's a regular command. If not, bomb out early. */ - if (!(rq->flags & REQ_CMD)) { - blk_dump_rq_flags(rq, "pdc4030 bad flags"); - ide_end_request(drive, 0); - return ide_stopped; - } - switch (rq_data_dir(rq)) { case READ: - OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG); /* * The card's behaviour is odd at this point. If the data is * available, DRQ will be true, and no interrupt will be @@ -600,6 +609,8 @@ printk(KERN_DEBUG "%s: read: waiting for " "interrupt\n", drive->name); #endif + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL); return ide_started; } @@ -612,7 +623,6 @@ case WRITE: { ide_startstop_t startstop; - OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG); /* * Strategy on write is: * look for the DRQ that should have been immediately asserted diff -urN linux-2.5.7/drivers/ide/trm290.c linux-2.5.7.fix/drivers/ide/trm290.c --- linux-2.5.7/drivers/ide/trm290.c Mon Mar 18 12:37:07 2002 +++ linux-2.5.7.fix/drivers/ide/trm290.c Sat Mar 23 01:29:29 2002 @@ -194,6 +194,8 @@ outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */ if (drive->type != ATA_DISK) return 0; + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); return 0;
| |