Promise EIDE4030PLUS meets libata

Last modified: Mon Feb 17 21:22:43 EST 2014

Introduction

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.

Starting configuration

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

1. Baseline (unmodified 3.13.2 kernel)

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.

InterruptsI/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

2. Stop resource grabs for non-existent IDE interfaces

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

InterruptsI/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

3. Accept spurious ATA device signatures

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

4. Force use of BIOS instead of non-working PDC20230 driver

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

Configuration change

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.

5. Final speed-ups and clean-ups

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:

  1. Function ata_dev_classify in libata-core.c:  Forget about the device signatures and just hard-code the device classes based on inferred channel and device number.  Keep the info message that reports the signatures received but make it more conformant.  Delete superfluous code.
  2. Function probe_chip_type in pata_legacy.c:  Reduce to one line of code; just return BIOS.
  3. Function ata_hpa_resize in libata-core.c:  Stub out the function to skip the failing attempt to detect an HPA.  Delete two other functions that the compiler then complained were unused.

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:

InterruptsI/O portsDMA
           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.

Postscript

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.


DFI486
KB
Home