Last modified: 2023-08-05 10:33
The EIDE4030plus is a caching VLB super-I/O card with two different PATA controllers on it. One of them drives the two 32-bit "VESA IDE" headers that support HDDs up to 8.4 GB with caching but not ATAPI. The other drives the ATAPI-ready 16-bit "ISA IDE" header that was included primarily to support CD-ROMs, but which can also support HDDs.
The VESA IDE channel works fine for DOS. However, in Linux, libata would not detect the hard drive. The old ide driver (/dev/hda) detected it after timing out on a lost interrupt, but proceeded to print lots more warnings and errors and then trashed the disk. The potentially applicable CONFIG_BLK_DEV_4DRIVES driver (four drives on an IDE port instead of the standard two) just caused a kernel panic during boot-up every time it was enabled.
I decided to focus my debugging efforts on libata. The result was a kludgy patch that allows error-free detection and read-only access to a disk on the VESA IDE channel. Unfortunately, writing to the disk from Linux still trashes it.
The following sections step through the debugging process to show where the trouble spots are and maybe enable someone with more knowledge of libata to finally fix the problems.
The system under test is DFI486 booted from CD-RW using Smart BootManager. The CD-RW contains a modified Slackware 14.1 boot environment with custom kernel and copy-on-write root filesystem instead of a large initrd in order to function with 32 GiB of RAM.
Kernel | 3.13.2 from kernel.org CONFIG_ATA=y CONFIG_ATA_SFF=y CONFIG_PATA_LEGACY=y |
Controller card | Promise EIDE4030plus VLB Firmware V4.4 BIOS V1.00 All default jumpers for PATA channels |
Motherboard | DFI 486-CCV Rev. A Contaq 82C596 A chipset AMI BIOS 1992 CONTAQ/3-H |
VESA IDE master (J1) | ST36421A 6 GiB HDD |
ISA IDE master (J3) | JLMS XJ-HD166S DVD-ROM |
The kernel detects the DVD-ROM on the ISA IDE channel but not the HDD on the primary VESA IDE channel.
PDC20230-C/20630 VLB ATA controller detected. scsi0 : pata_legacy ata1: PATA max PIO2 cmd 0x1f0 ctl 0x3f6 irq 14 scsi1 : pata_legacy ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15 ata2.00: ATAPI: JLMS XJ-HD166S, DS18, max UDMA/33 ata2.00: configured for PIO scsi 1:0:0:0: CD-ROM JLMS XJ-HD166S DS18 PQ: 0 ANSI: 5 sr0: scsi3-mmc drive: 20x/48x cd/rw xa/form2 cdda tray cdrom: Uniform CD-ROM driver Revision: 3.20 sr 1:0:0:0: Attached scsi CD-ROM sr0 sr 1:0:0:0: Attached scsi generic sg0 type 5 scsi2 : pata_legacy ata3: PATA max PIO4 cmd 0x1e8 ctl 0x3ee irq 11 scsi3 : pata_legacy ata4: PATA max PIO4 cmd 0x168 ctl 0x36e irq 10 scsi4 : pata_legacy ata5: PATA max PIO4 cmd 0x1e0 ctl 0x3e6 irq 8 scsi5 : pata_legacy ata6: PATA max PIO4 cmd 0x160 ctl 0x366 irq 12
Alarmingly, the speculative probing for four additional IDE interfaces results in all of the mentioned resources being grabbed despite no devices being found there. That's a lot of IRQs to tie up for no reason.
Interrupts | I/O ports |
---|---|
CPU0 0: 88783 XT-PIC-XT-PIC timer 1: 309 XT-PIC-XT-PIC i8042 2: 0 XT-PIC-XT-PIC cascade 6: 23 XT-PIC-XT-PIC floppy 8: 0 XT-PIC-XT-PIC platform 10: 0 XT-PIC-XT-PIC platform 11: 0 XT-PIC-XT-PIC platform 12: 0 XT-PIC-XT-PIC platform 14: 0 XT-PIC-XT-PIC platform 15: 2861 XT-PIC-XT-PIC platform NMI: 0 Non-maskable interrupts MCE: 0 Machine check exceptions MCP: 0 Machine check polls ERR: 0 | 0000-001f : dma1 0020-0021 : pic1 0040-0043 : timer0 0050-0053 : timer1 0060-0060 : keyboard 0064-0064 : keyboard 0070-0071 : rtc_cmos 0080-008f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : fpu 0160-0167 : pata_legacy 0168-016f : pata_legacy 0170-0177 : pata_legacy 01e0-01e7 : pata_legacy 01e8-01ef : pata_legacy 01f0-01f7 : pata_legacy 0366-0366 : pata_legacy 036e-036e : pata_legacy 0376-0376 : pata_legacy 03c0-03df : vga+ 03e6-03e6 : pata_legacy 03ee-03ee : pata_legacy 03f2-03f2 : floppy 03f4-03f5 : floppy 03f6-03f6 : pata_legacy 03f7-03f7 : floppy 03f8-03ff : serial |
Since there is no nice way to stop the speculative probes on a system that has no PCI bus, delete the offending code block from function legacy_init in pata_legacy.c.
--- drivers/ata/pata_legacy.c.orig 2014-01-19 21:40:07.000000000 -0500 +++ drivers/ata/pata_legacy.c 2014-02-09 14:29:07.908798493 -0500 @@ -1217,14 +1217,6 @@ if (secondary == 0 || all) legacy_probe_add(0x170, 15, UNKNOWN, 0); - if (probe_all || !pci_present) { - /* ISA/VLB extra ports */ - legacy_probe_add(0x1E8, 11, UNKNOWN, 0); - legacy_probe_add(0x168, 10, UNKNOWN, 0); - legacy_probe_add(0x1E0, 8, UNKNOWN, 0); - legacy_probe_add(0x160, 12, UNKNOWN, 0); - } - if (opti82c46x) probe_opti_vlb(); if (qdi)
This clears up that problem but does nothing about the HDD detection.
PDC20230-C/20630 VLB ATA controller detected. scsi0 : pata_legacy ata1: PATA max PIO2 cmd 0x1f0 ctl 0x3f6 irq 14 scsi1 : pata_legacy ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15 ata2.00: ATAPI: JLMS XJ-HD166S, DS18, max UDMA/33 ata2.00: configured for PIO scsi 1:0:0:0: CD-ROM JLMS XJ-HD166S DS18 PQ: 0 ANSI: 5 sr0: scsi3-mmc drive: 20x/48x cd/rw xa/form2 cdda tray cdrom: Uniform CD-ROM driver Revision: 3.20 sr 1:0:0:0: Attached scsi CD-ROM sr0 sr 1:0:0:0: Attached scsi generic sg0 type 5
Interrupts | I/O ports |
---|---|
CPU0 0: 18416 XT-PIC-XT-PIC timer 1: 245 XT-PIC-XT-PIC i8042 2: 0 XT-PIC-XT-PIC cascade 6: 15 XT-PIC-XT-PIC floppy 8: 0 XT-PIC-XT-PIC rtc0 14: 0 XT-PIC-XT-PIC platform 15: 2296 XT-PIC-XT-PIC platform NMI: 0 Non-maskable interrupts MCE: 0 Machine check exceptions MCP: 0 Machine check polls ERR: 0 | 0000-001f : dma1 0020-0021 : pic1 0040-0043 : timer0 0050-0053 : timer1 0060-0060 : keyboard 0064-0064 : keyboard 0070-0071 : rtc_cmos 0070-0071 : rtc0 0080-008f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : fpu 0170-0177 : pata_legacy 01f0-01f7 : pata_legacy 0376-0376 : pata_legacy 03c0-03df : vga+ 03f2-03f2 : floppy 03f4-03f5 : floppy 03f6-03f6 : pata_legacy 03f7-03f7 : floppy 03f8-03ff : serial |
libata has a force parameter to disable a drive that is detected but there is no parameter to force the detection and enablement of a missing drive.
The point of failure for the detection of the HDD is function ata_dev_classify in libata-core.c. A PATA hard drive is supposed to show up here with a signature of 0/0. Instead, the HDD on the VESA IDE channel shows up with a variety of signatures. Worse, whatever the HDD's signature is at any given time, the non-existent slave device always has the same signature.
--- drivers/ata/libata-core.c.orig 2014-02-09 12:54:25.028802855 -0500 +++ drivers/ata/libata-core.c 2014-02-09 21:49:23.668778215 -0500 @@ -1068,7 +1068,10 @@ * SEMB signature. This is worked around in * ata_dev_read_id(). */ - if ((tf->lbam == 0) && (tf->lbah == 0)) { + printk(KERN_INFO "ata_dev_classify device signature 0x%x/0x%x\n", tf->lbam, tf->lbah); + if ((((tf->lbam == 7 || tf->lbam == 0)) && (tf->lbah == 0)) || + ((tf->lbam == 7 || tf->lbam == 0x10) && (tf->lbah == 0x34)) || + ((tf->lbam == 0x30) && (tf->lbah == 0x36))) { DPRINTK("found ATA device by sig\n"); return ATA_DEV_ATA; }
Now the HDD is detected, but the PDC20230 driver has a different failure (failed to set xfermode) and disables the device. Furthermore, the resulting attempts to initialize the non-existent slave device are a slowdown nuisance that is NOT avoided by supplying the kernel parameter libata.force=1.1:disable.
PDC20230-C/20630 VLB ATA controller detected. scsi0 : pata_legacy ata1: PATA max PIO2 cmd 0x1f0 ctl 0x3f6 irq 14 ata_dev_classify device signature 0x7/0x34 ata_dev_classify device signature 0x7/0x34 ata1.01: qc timeout (cmd 0xec) ata1.01: failed to IDENTIFY (I/O error, err_mask=0x4) ata1: link is slow to respond, please be patient (ready=0) ata1: device not ready (errno=-16), forcing hardreset ata_dev_classify device signature 0x0/0x0 ata_dev_classify device signature 0x0/0x0 ata1.01: qc timeout (cmd 0xec) ata1.01: failed to IDENTIFY (I/O error, err_mask=0x4) ata1: link is slow to respond, please be patient (ready=0) ata1: device not ready (errno=-16), forcing hardreset ata_dev_classify device signature 0x0/0x0 ata_dev_classify device signature 0x0/0x0 ata1.01: qc timeout (cmd 0xec) ata1.01: failed to IDENTIFY (I/O error, err_mask=0x4) ata1: link is slow to respond, please be patient (ready=0) ata1: device not ready (errno=-16), forcing hardreset ata_dev_classify device signature 0x0/0x0 ata_dev_classify device signature 0x0/0x0 ata1.00: qc timeout (cmd 0xf8) ata1.00: failed to read native max address (err_mask=0x4) ata1.00: HPA support seems broken, skipping HPA handling ata_dev_classify device signature 0x7/0x0 ata_dev_classify device signature 0x7/0x0 ata1.00: ATA-4: ST36421A, 6.01, max UDMA/33 ata1.00: 12596850 sectors, multi 0: LBA ata1.00: failed to set xfermode (err_mask=0x1) ata1.00: limiting speed to PIO1 ata_dev_classify device signature 0x7/0x0 ata_dev_classify device signature 0x7/0x0 ata1.00: failed to set xfermode (err_mask=0x1) ata1.00: disabled scsi1 : pata_legacy ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15 ata_dev_classify device signature 0x14/0xeb ata_dev_classify device signature 0x7f/0x7f ata2.00: ATAPI: JLMS XJ-HD166S, DS18, max UDMA/33 ata2.00: configured for PIO scsi 1:0:0:0: CD-ROM JLMS XJ-HD166S DS18 PQ: 0 ANSI: 5 sr0: scsi3-mmc drive: 20x/48x cd/rw xa/form2 cdda tray cdrom: Uniform CD-ROM driver Revision: 3.20 sr 1:0:0:0: Attached scsi CD-ROM sr0 sr 1:0:0:0: Attached scsi generic sg0 type 5
This change occurs in function probe_chip_type of pata_legacy.c.
--- drivers/ata/pata_legacy.c.1 2014-02-09 14:29:07.908798493 -0500 +++ drivers/ata/pata_legacy.c 2014-02-09 17:30:07.378790157 -0500 @@ -905,7 +905,7 @@ udelay(100); inb(0x1F5); local_irq_restore(flags); - return PDC20230; + return BIOS; } else { outb(0x55, 0x1F2); inb(0x1F2);
At last, the disk is detected and enabled. The pio_mask for the BIOS driver is PIO4 while for PDC20230 it was only PIO2, but it seems unlikely that this has any impact. Comments for function legacy_set_mode in pata_legacy.c say: "The BIOS configured everything. Our job is not to fiddle. Just use whatever PIO the hardware is using and leave it at that."
PDC20230-C/20630 VLB ATA controller detected. scsi0 : pata_legacy ata1: PATA max PIO4 cmd 0x1f0 ctl 0x3f6 irq 14 ata_dev_classify device signature 0x10/0x34 ata_dev_classify device signature 0x10/0x34 ata1.01: qc timeout (cmd 0xec) ata1.01: failed to IDENTIFY (I/O error, err_mask=0x4) ata1: link is slow to respond, please be patient (ready=0) ata1: device not ready (errno=-16), forcing hardreset ata_dev_classify device signature 0x0/0x0 ata_dev_classify device signature 0x0/0x0 ata1.01: qc timeout (cmd 0xec) ata1.01: failed to IDENTIFY (I/O error, err_mask=0x4) ata1: link is slow to respond, please be patient (ready=0) ata1: device not ready (errno=-16), forcing hardreset ata_dev_classify device signature 0x0/0x0 ata_dev_classify device signature 0x0/0x0 ata1.01: qc timeout (cmd 0xec) ata1.01: failed to IDENTIFY (I/O error, err_mask=0x4) ata1: link is slow to respond, please be patient (ready=0) ata1: device not ready (errno=-16), forcing hardreset ata_dev_classify device signature 0x0/0x0 ata_dev_classify device signature 0x0/0x0 ata1.00: qc timeout (cmd 0xf8) ata1.00: failed to read native max address (err_mask=0x4) ata1.00: HPA support seems broken, skipping HPA handling ata_dev_classify device signature 0x0/0x0 ata_dev_classify device signature 0x0/0x0 ata1.00: ATA-4: ST36421A, 6.01, max UDMA/33 ata1.00: 12596850 sectors, multi 0: LBA ata1.00: configured for PIO scsi 0:0:0:0: Direct-Access ATA ST36421A 6.01 PQ: 0 ANSI: 5 sd 0:0:0:0: [sda] 12596850 512-byte logical blocks: (6.44 GB/6.00 GiB) sd 0:0:0:0: Attached scsi generic sg0 type 0 sd 0:0:0:0: [sda] Write Protect is off sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00 sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA sda: sda1 sd 0:0:0:0: [sda] Attached SCSI disk scsi1 : pata_legacy ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15 ata_dev_classify device signature 0x14/0xeb ata_dev_classify device signature 0x7f/0x7f ata2.00: ATAPI: JLMS XJ-HD166S, DS18, max UDMA/33 ata2.00: configured for PIO scsi 1:0:0:0: CD-ROM JLMS XJ-HD166S DS18 PQ: 0 ANSI: 5 sr0: scsi3-mmc drive: 20x/48x cd/rw xa/form2 cdda tray cdrom: Uniform CD-ROM driver Revision: 3.20 sr 1:0:0:0: Attached scsi CD-ROM sr0 sr 1:0:0:0: Attached scsi generic sg1 type 5
Unfortunately, though at first it appeared to be working, I was unable to create an ext4 file system on a hard drive connected to the VESA IDE channel without it becoming corrupt immediately. So much for that.
A hard drive connected to the (Winbond W83758P) 16-bit ISA IDE channel works without a problem in Linux, but there are additional complications.
So, being forced to allow the Linux-incompatible VESA IDE channel to have the first hard drive, I left the 6 GiB drive there for DOS and put a 12 GiB drive on the ISA IDE channel for Linux. To boot Linux with no BIOS access to the second hard drive I had to copy the kernel binary to the DOS partition and install LILO on a boot floppy.
The complete patch applicable to kernel 3.13.2 is here.
libata-core.c | 239 ++-------------------------------------------------------- pata_legacy.c | 69 ---------------- 2 files changed, 10 insertions(+), 298 deletions(-)
It includes the following final speed-ups and clean-ups:
scsi0 : pata_legacy ata1: PATA max PIO4 cmd 0x1f0 ctl 0x3f6 irq 14 ata: ATA device, sig 0x00/0x00 ata: non-existent device, sig 0x00/0x00 ata1.00: ATA-4: ST36421A, 6.01, max UDMA/33 ata1.00: 12596850 sectors, multi 0: LBA ata1.00: configured for PIO scsi 0:0:0:0: Direct-Access ATA ST36421A 6.01 PQ: 0 ANSI: 5 sd 0:0:0:0: [sda] 12596850 512-byte logical blocks: (6.44 GB/6.00 GiB) sd 0:0:0:0: [sda] Write Protect is off sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00 sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA sd 0:0:0:0: Attached scsi generic sg0 type 0 sda: sda1 sd 0:0:0:0: [sda] Attached SCSI disk scsi1 : pata_legacy ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15 ata: ATA device, sig 0x00/0x00 ata: ATAPI device, sig 0x14/0xeb ata2.00: ATA-4: WDC AC313000R, 15.01J55, max UDMA/33 ata2.00: 25429824 sectors, multi 0: LBA ata2.01: ATAPI: JLMS XJ-HD166S, DS18, max UDMA/33 ata2.00: configured for PIO ata2.01: configured for PIO scsi 1:0:0:0: Direct-Access ATA WDC AC313000R 15.0 PQ: 0 ANSI: 5 sd 1:0:0:0: [sdb] 25429824 512-byte logical blocks: (13.0 GB/12.1 GiB) sd 1:0:0:0: [sdb] Write Protect is off sd 1:0:0:0: [sdb] Mode Sense: 00 3a 00 00 sd 1:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA sd 1:0:0:0: Attached scsi generic sg1 type 0 scsi 1:0:1:0: CD-ROM JLMS XJ-HD166S DS18 PQ: 0 ANSI: 5 sr0: scsi3-mmc drive: 20x/48x cd/rw xa/form2 cdda tray cdrom: Uniform CD-ROM driver Revision: 3.20 sr 1:0:1:0: Attached scsi CD-ROM sr0 sdb: sdb1 sdb2 sdb3 sr 1:0:1:0: Attached scsi generic sg2 type 5 sd 1:0:0:0: [sdb] Attached SCSI disk
Final resource allocation with network and sound drivers loaded:
Interrupts | I/O ports | DMA |
---|---|---|
CPU0 0: 39059 XT-PIC-XT-PIC timer 1: 385 XT-PIC-XT-PIC i8042 2: 0 XT-PIC-XT-PIC cascade 4: 123 XT-PIC-XT-PIC serial 5: 0 XT-PIC-XT-PIC * 6: 3 XT-PIC-XT-PIC floppy 8: 0 XT-PIC-XT-PIC rtc0 9: 1 XT-PIC-XT-PIC WSS 10: 122 XT-PIC-XT-PIC NE2000 14: 2665 XT-PIC-XT-PIC platform 15: 96297 XT-PIC-XT-PIC platform NMI: 0 Non-maskable interrupts MCE: 0 Machine check exceptions MCP: 0 Machine check polls ERR: 0 * Undeclared grab by Aztech sound card, probably for Sound Blaster emulation but possibly MPU-401. | 0000-001f : dma1 0020-0021 : pic1 0040-0043 : timer0 0050-0053 : timer1 0060-0060 : keyboard 0064-0064 : keyboard 0070-0071 : rtc_cmos 0070-0071 : rtc0 0080-008f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : fpu 0170-0177 : pata_legacy 01f0-01f7 : pata_legacy 0200-0207 : ns558-isa 0213-0213 : ISAPnP 0220-022f : AZT1605 0240-025f : ne 0330-0331 : MPU401 UART 0376-0376 : pata_legacy 0388-0389 : OPL2/3 (left) 038a-038b : OPL2/3 (right) 03c0-03df : vga+ 03f2-03f2 : floppy 03f4-03f5 : floppy 03f6-03f6 : pata_legacy 03f7-03f7 : floppy 03f8-03ff : serial 0530-0533 : AZT1605 0534-0537 : WSS 0620-062f : AZT1605 0a79-0a79 : isapnp write | 1: WSS - 1 2: floppy 4: cascade |
A game port, parallel port, and COM2 are disabled by jumpers on the Promise card. The Aztech sound card apparently hooks IRQ 5 though the ALSA module has no such resource declared. An MPU-401 IRQ and a second DMA might also be in stealth use by the sound card, pending investigation.
The PDC20230 driver might be made to work with a tweak to function ata_dev_set_mode in libata-core.c, which already notes in commentary that "Some very old devices and some bad newer ones fail any kind of SET_XFERMODE request but support PIO0-2 timings and no IORDY." No idea if using this driver would avoid the disk corruption problem that is occurring with the BIOS.
Maybe the type 1 settings in the mainboard's BIOS were involved in the failures with the ISA IDE channel set to primary. Maybe when ISA IDE is primary the main BIOS settings have to be real. But then what do you do about the DVD-ROM? Or maybe that's what hung it.