All of lore.kernel.org
 help / color / mirror / Atom feed
* Bug#679545: [RFC/PATCH] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-16 16:39 ` Stephan Schreiber
  0 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-16 16:39 UTC (permalink / raw)
  To: linux-ia64; +Cc: alan, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

Hello,
please could you add some comments about the problem or review the  
proposed patch?

Kernel 3.2.23 with Debian patches (Debian Wheezy, testing)
Debian bug#679545 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679545)

Machine: Dell PowerEdge 3250 (equivalent with Intel SR870BH2)
Processor: 2x Itanium Madison 1.5GHz 6M
Memory: 4GB

Intel ICH4 (82801DB), IDE host adapter. The ata_piix module fails to  
initialize.

A snippet from dmesg:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Mon Jul 23 09:01:02 UTC 2012
...
[    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
...
[    1.640965] libata version 3.00 loaded.
[    1.641656] ata_piix 0000:00:1f.1: version 2.13
[    1.641671] ata_piix 0000:00:1f.1: device not available (can't  
reserve [mem 0x00000000-0x000003ff])
[    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
...

lspci -vvxxx reports:

00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller  
(rev 02) (prog-if 8a [Master SecP PriP])
	Subsystem: Intel Corporation Device 3404
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-  
Stepping- SERR- FastB2B- DisINTx-
	Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-  
<TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 0
	Region 0: I/O ports at 01f0 [size=8]
	Region 1: I/O ports at 03f4 [size=1]
	Region 2: I/O ports at 0170 [size=8]
	Region 3: I/O ports at 0374 [size=1]
	Region 4: I/O ports at 1000 [size=16]
00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
40: 03 a3 00 80 00 00 00 00 01 00 02 00 00 00 00 00
50: 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00
60: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 60 0f 00 00 00 00 00 00


You can read in the "Intel 82801DB I/O Controller Hub 4 (ICH4)" datasheet
(http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82801db-io-controller-hub-4-datasheet.pdf)
about the EXBAR register at offset 0x24 (4 bytes):
"EXBAR register
This is a memory mapped BAR that requires 1 KB of DWord-aligned memory  
that is Intel reserved
for future functionality. BIOS needs to program the base address for a  
1-KB memory space."

The dump shows that EXBAR is 0x0000, equal to the default value after  
reset; EFI doesn't initialize it.

ata_piix uses pcim_enable_device() which enables this along with the  
I/O BARs. In systems based on the Intel SR870 platform the firmware  
does not initialize the EXBAR and pcim_enable_device() fails because  
the memory region 0x0-0x3FF cannot be allocated.

The proposed patch adds ia64 arch-specific 'pci quirk' code.
Since the patched Kernel doesn't see any memory resource of IDE  
hostadapter, it doesn't set the PCI_COMMAND_MEMORY bit in the CMD  
register; the EXBAR resource is *not* visible in the memeory space at  
all.

A snippet of the dmesg output on the patched Kernel:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Sun Sep 16 15:16:55 CEST 2012
...
[    0.065491] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065505] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065516] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065527] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065537] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065548] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065559] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
[    0.065574] pci 0000:00:1f.1: SR870 EFI bug workaround; hide EXBAR  
memory resource.
...
[    1.391942] libata version 3.00 loaded.
[    1.392567] ata_piix 0000:00:1f.1: version 2.13
[    1.392807] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
[    1.399383] scsi0 : ata_piix
[    1.402505] scsi1 : ata_piix
[    1.402609] ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x1000 irq 34
[    1.402658] ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x1008 irq 33
[    1.565703] ata1.00: ATAPI: HL-DT-ST DVDRAM GSA-T40N, JR03, max UDMA/33
[    1.581571] ata1.00: configured for UDMA/33
[    1.587075] scsi 0:0:0:0: CD-ROM            HL-DT-ST DVDRAM  
GSA-T40N  JR03 PQ: 0 ANSI: 5
[    1.598796] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw  
xa/form2 cdda tray
[    1.598863] cdrom: Uniform CD-ROM driver Revision: 3.20
[    1.599263] sr 0:0:0:0: Attached scsi CD-ROM sr0
[    1.601972] sr 0:0:0:0: Attached scsi generic sg0 type 5
...


(Note: The patch of this posting differs slightly from the one which I  
have posted on Debian bug#679545 - just cosmetic improvements.)

Kind regards,
Stephan Schreiber



--- linux-3.2.23/arch/ia64/pci/fixup.c.orig	2012-09-16  
11:23:30.000000000 +0200
+++ linux-3.2.23/arch/ia64/pci/fixup.c	2012-09-16 11:52:13.000000000 +0200
@@ -67,3 +67,40 @@ static void __devinit pci_fixup_video(st
  	}
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
+
+
+/*
+ * Fixup the EFI bug of Intel's SR870 platform
+ *
+ * The EFI of Intel's SR870BH2 and SR870BN4 including their OEM  
equivalents by
+ * Fujitsu and Dell doesn't initialize the memory resource of the ICH4 IDE
+ * hostadapter. The memory resource has the default after reset: 0x0-0x3FF.
+ * The ata_piix driver uses pcim_enable_device() which attempts to  
enable this
+ * along with the I/O BARs and pcim_enable_device() fails because the memory
+ * region 0x0-0x3FF cannot be allocated.
+ * The memory resource is the 6th resource of the ICH4 IDE hostadapter;
+ * Intel's datasheet "Intel 82801DB I/O Controller Hub 4 (ICH4)" (Document
+ * Number: 290744-001) states in section "10.1.15 EXBAR - Expansion Base
+ * Address Register (IDE-D31:F1)" on page 389:
+ * "This is a memory mapped BAR ... that is Intel reserved for future
+ * functionality. BIOS needs to program the base address for a 1-KB memory
+ * space."
+ * Since nothing uses the EXBAR, we hide it so that only the I/O BARs will be
+ * enabled.
+ */
+
+static void __devinit pci_fixup_sr870_ich4(struct pci_dev *dev)
+{
+	struct resource *r;
+
+	r = &dev->resource[5];
+	if ((r->flags & IORESOURCE_MEM)
+	&& r->start == 0 && r->end != 0) {
+		dev_info(&dev->dev,
+			"SR870 EFI bug workaround; hide EXBAR memory resource.\n");
+		r->flags = 0;
+		r->end = 0;
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11,
+						pci_fixup_sr870_ich4);

Signed-off-by: Stephan Schreiber <info@fs-driver.org>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC/PATCH] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-16 16:39 ` Stephan Schreiber
  0 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-16 16:39 UTC (permalink / raw)
  To: linux-ia64; +Cc: alan, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

Hello,
please could you add some comments about the problem or review the  
proposed patch?

Kernel 3.2.23 with Debian patches (Debian Wheezy, testing)
Debian bug#679545 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679545)

Machine: Dell PowerEdge 3250 (equivalent with Intel SR870BH2)
Processor: 2x Itanium Madison 1.5GHz 6M
Memory: 4GB

Intel ICH4 (82801DB), IDE host adapter. The ata_piix module fails to  
initialize.

A snippet from dmesg:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Mon Jul 23 09:01:02 UTC 2012
...
[    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
...
[    1.640965] libata version 3.00 loaded.
[    1.641656] ata_piix 0000:00:1f.1: version 2.13
[    1.641671] ata_piix 0000:00:1f.1: device not available (can't  
reserve [mem 0x00000000-0x000003ff])
[    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
...

lspci -vvxxx reports:

00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller  
(rev 02) (prog-if 8a [Master SecP PriP])
	Subsystem: Intel Corporation Device 3404
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-  
Stepping- SERR- FastB2B- DisINTx-
	Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-  
<TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 0
	Region 0: I/O ports at 01f0 [size=8]
	Region 1: I/O ports at 03f4 [size=1]
	Region 2: I/O ports at 0170 [size=8]
	Region 3: I/O ports at 0374 [size=1]
	Region 4: I/O ports at 1000 [size=16]
00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
40: 03 a3 00 80 00 00 00 00 01 00 02 00 00 00 00 00
50: 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00
60: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 60 0f 00 00 00 00 00 00


You can read in the "Intel 82801DB I/O Controller Hub 4 (ICH4)" datasheet
(http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82801db-io-controller-hub-4-datasheet.pdf)
about the EXBAR register at offset 0x24 (4 bytes):
"EXBAR register
This is a memory mapped BAR that requires 1 KB of DWord-aligned memory  
that is Intel reserved
for future functionality. BIOS needs to program the base address for a  
1-KB memory space."

The dump shows that EXBAR is 0x0000, equal to the default value after  
reset; EFI doesn't initialize it.

ata_piix uses pcim_enable_device() which enables this along with the  
I/O BARs. In systems based on the Intel SR870 platform the firmware  
does not initialize the EXBAR and pcim_enable_device() fails because  
the memory region 0x0-0x3FF cannot be allocated.

The proposed patch adds ia64 arch-specific 'pci quirk' code.
Since the patched Kernel doesn't see any memory resource of IDE  
hostadapter, it doesn't set the PCI_COMMAND_MEMORY bit in the CMD  
register; the EXBAR resource is *not* visible in the memeory space at  
all.

A snippet of the dmesg output on the patched Kernel:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Sun Sep 16 15:16:55 CEST 2012
...
[    0.065491] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065505] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065516] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065527] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065537] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065548] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065559] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
[    0.065574] pci 0000:00:1f.1: SR870 EFI bug workaround; hide EXBAR  
memory resource.
...
[    1.391942] libata version 3.00 loaded.
[    1.392567] ata_piix 0000:00:1f.1: version 2.13
[    1.392807] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
[    1.399383] scsi0 : ata_piix
[    1.402505] scsi1 : ata_piix
[    1.402609] ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x1000 irq 34
[    1.402658] ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x1008 irq 33
[    1.565703] ata1.00: ATAPI: HL-DT-ST DVDRAM GSA-T40N, JR03, max UDMA/33
[    1.581571] ata1.00: configured for UDMA/33
[    1.587075] scsi 0:0:0:0: CD-ROM            HL-DT-ST DVDRAM  
GSA-T40N  JR03 PQ: 0 ANSI: 5
[    1.598796] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw  
xa/form2 cdda tray
[    1.598863] cdrom: Uniform CD-ROM driver Revision: 3.20
[    1.599263] sr 0:0:0:0: Attached scsi CD-ROM sr0
[    1.601972] sr 0:0:0:0: Attached scsi generic sg0 type 5
...


(Note: The patch of this posting differs slightly from the one which I  
have posted on Debian bug#679545 - just cosmetic improvements.)

Kind regards,
Stephan Schreiber



--- linux-3.2.23/arch/ia64/pci/fixup.c.orig	2012-09-16  
11:23:30.000000000 +0200
+++ linux-3.2.23/arch/ia64/pci/fixup.c	2012-09-16 11:52:13.000000000 +0200
@@ -67,3 +67,40 @@ static void __devinit pci_fixup_video(st
  	}
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
+
+
+/*
+ * Fixup the EFI bug of Intel's SR870 platform
+ *
+ * The EFI of Intel's SR870BH2 and SR870BN4 including their OEM  
equivalents by
+ * Fujitsu and Dell doesn't initialize the memory resource of the ICH4 IDE
+ * hostadapter. The memory resource has the default after reset: 0x0-0x3FF.
+ * The ata_piix driver uses pcim_enable_device() which attempts to  
enable this
+ * along with the I/O BARs and pcim_enable_device() fails because the memory
+ * region 0x0-0x3FF cannot be allocated.
+ * The memory resource is the 6th resource of the ICH4 IDE hostadapter;
+ * Intel's datasheet "Intel 82801DB I/O Controller Hub 4 (ICH4)" (Document
+ * Number: 290744-001) states in section "10.1.15 EXBAR - Expansion Base
+ * Address Register (IDE-D31:F1)" on page 389:
+ * "This is a memory mapped BAR ... that is Intel reserved for future
+ * functionality. BIOS needs to program the base address for a 1-KB memory
+ * space."
+ * Since nothing uses the EXBAR, we hide it so that only the I/O BARs will be
+ * enabled.
+ */
+
+static void __devinit pci_fixup_sr870_ich4(struct pci_dev *dev)
+{
+	struct resource *r;
+
+	r = &dev->resource[5];
+	if ((r->flags & IORESOURCE_MEM)
+	&& r->start == 0 && r->end != 0) {
+		dev_info(&dev->dev,
+			"SR870 EFI bug workaround; hide EXBAR memory resource.\n");
+		r->flags = 0;
+		r->end = 0;
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11,
+						pci_fixup_sr870_ich4);

Signed-off-by: Stephan Schreiber <info@fs-driver.org>



^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC/PATCH] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-16 16:39 ` Stephan Schreiber
  0 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-16 16:39 UTC (permalink / raw)
  To: linux-ia64; +Cc: alan, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

Hello,
please could you add some comments about the problem or review the  
proposed patch?

Kernel 3.2.23 with Debian patches (Debian Wheezy, testing)
Debian bug#679545 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bugg9545)

Machine: Dell PowerEdge 3250 (equivalent with Intel SR870BH2)
Processor: 2x Itanium Madison 1.5GHz 6M
Memory: 4GB

Intel ICH4 (82801DB), IDE host adapter. The ata_piix module fails to  
initialize.

A snippet from dmesg:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Mon Jul 23 09:01:02 UTC 2012
...
[    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
...
[    1.640965] libata version 3.00 loaded.
[    1.641656] ata_piix 0000:00:1f.1: version 2.13
[    1.641671] ata_piix 0000:00:1f.1: device not available (can't  
reserve [mem 0x00000000-0x000003ff])
[    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
...

lspci -vvxxx reports:

00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller  
(rev 02) (prog-if 8a [Master SecP PriP])
	Subsystem: Intel Corporation Device 3404
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-  
Stepping- SERR- FastB2B- DisINTx-
	Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-  
<TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 0
	Region 0: I/O ports at 01f0 [size=8]
	Region 1: I/O ports at 03f4 [size=1]
	Region 2: I/O ports at 0170 [size=8]
	Region 3: I/O ports at 0374 [size=1]
	Region 4: I/O ports at 1000 [size\x16]
00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
40: 03 a3 00 80 00 00 00 00 01 00 02 00 00 00 00 00
50: 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00
60: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 60 0f 00 00 00 00 00 00


You can read in the "Intel 82801DB I/O Controller Hub 4 (ICH4)" datasheet
(http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82801db-io-controller-hub-4-datasheet.pdf)
about the EXBAR register at offset 0x24 (4 bytes):
"EXBAR register
This is a memory mapped BAR that requires 1 KB of DWord-aligned memory  
that is Intel reserved
for future functionality. BIOS needs to program the base address for a  
1-KB memory space."

The dump shows that EXBAR is 0x0000, equal to the default value after  
reset; EFI doesn't initialize it.

ata_piix uses pcim_enable_device() which enables this along with the  
I/O BARs. In systems based on the Intel SR870 platform the firmware  
does not initialize the EXBAR and pcim_enable_device() fails because  
the memory region 0x0-0x3FF cannot be allocated.

The proposed patch adds ia64 arch-specific 'pci quirk' code.
Since the patched Kernel doesn't see any memory resource of IDE  
hostadapter, it doesn't set the PCI_COMMAND_MEMORY bit in the CMD  
register; the EXBAR resource is *not* visible in the memeory space at  
all.

A snippet of the dmesg output on the patched Kernel:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Sun Sep 16 15:16:55 CEST 2012
...
[    0.065491] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065505] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065516] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065527] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065537] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065548] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065559] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
[    0.065574] pci 0000:00:1f.1: SR870 EFI bug workaround; hide EXBAR  
memory resource.
...
[    1.391942] libata version 3.00 loaded.
[    1.392567] ata_piix 0000:00:1f.1: version 2.13
[    1.392807] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
[    1.399383] scsi0 : ata_piix
[    1.402505] scsi1 : ata_piix
[    1.402609] ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x1000 irq 34
[    1.402658] ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x1008 irq 33
[    1.565703] ata1.00: ATAPI: HL-DT-ST DVDRAM GSA-T40N, JR03, max UDMA/33
[    1.581571] ata1.00: configured for UDMA/33
[    1.587075] scsi 0:0:0:0: CD-ROM            HL-DT-ST DVDRAM  
GSA-T40N  JR03 PQ: 0 ANSI: 5
[    1.598796] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw  
xa/form2 cdda tray
[    1.598863] cdrom: Uniform CD-ROM driver Revision: 3.20
[    1.599263] sr 0:0:0:0: Attached scsi CD-ROM sr0
[    1.601972] sr 0:0:0:0: Attached scsi generic sg0 type 5
...


(Note: The patch of this posting differs slightly from the one which I  
have posted on Debian bug#679545 - just cosmetic improvements.)

Kind regards,
Stephan Schreiber



--- linux-3.2.23/arch/ia64/pci/fixup.c.orig	2012-09-16  
11:23:30.000000000 +0200
+++ linux-3.2.23/arch/ia64/pci/fixup.c	2012-09-16 11:52:13.000000000 +0200
@@ -67,3 +67,40 @@ static void __devinit pci_fixup_video(st
  	}
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
+
+
+/*
+ * Fixup the EFI bug of Intel's SR870 platform
+ *
+ * The EFI of Intel's SR870BH2 and SR870BN4 including their OEM  
equivalents by
+ * Fujitsu and Dell doesn't initialize the memory resource of the ICH4 IDE
+ * hostadapter. The memory resource has the default after reset: 0x0-0x3FF.
+ * The ata_piix driver uses pcim_enable_device() which attempts to  
enable this
+ * along with the I/O BARs and pcim_enable_device() fails because the memory
+ * region 0x0-0x3FF cannot be allocated.
+ * The memory resource is the 6th resource of the ICH4 IDE hostadapter;
+ * Intel's datasheet "Intel 82801DB I/O Controller Hub 4 (ICH4)" (Document
+ * Number: 290744-001) states in section "10.1.15 EXBAR - Expansion Base
+ * Address Register (IDE-D31:F1)" on page 389:
+ * "This is a memory mapped BAR ... that is Intel reserved for future
+ * functionality. BIOS needs to program the base address for a 1-KB memory
+ * space."
+ * Since nothing uses the EXBAR, we hide it so that only the I/O BARs will be
+ * enabled.
+ */
+
+static void __devinit pci_fixup_sr870_ich4(struct pci_dev *dev)
+{
+	struct resource *r;
+
+	r = &dev->resource[5];
+	if ((r->flags & IORESOURCE_MEM)
+	&& r->start = 0 && r->end != 0) {
+		dev_info(&dev->dev,
+			"SR870 EFI bug workaround; hide EXBAR memory resource.\n");
+		r->flags = 0;
+		r->end = 0;
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11,
+						pci_fixup_sr870_ich4);

Signed-off-by: Stephan Schreiber <info@fs-driver.org>



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-09-16 16:39 ` Stephan Schreiber
@ 2012-09-17 10:56   ` Alan Cox
  -1 siblings, 0 replies; 22+ messages in thread
From: Alan Cox @ 2012-09-17 10:56 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: linux-ia64, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

My only disagreement here would be putting it in the ia64 paths. If
someone does the same for x86-32 (and this is EFI so it'll presumbly
smell the same on all platforms) then we'll want the same.

Better I think to generically catch the 0/0 case.

Alan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-17 10:56   ` Alan Cox
  0 siblings, 0 replies; 22+ messages in thread
From: Alan Cox @ 2012-09-17 10:56 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: linux-ia64, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

My only disagreement here would be putting it in the ia64 paths. If
someone does the same for x86-32 (and this is EFI so it'll presumbly
smell the same on all platforms) then we'll want the same.

Better I think to generically catch the 0/0 case.

Alan


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-09-16 16:39 ` Stephan Schreiber
@ 2012-09-17 21:41   ` Bjorn Helgaas
  -1 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2012-09-17 21:41 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: linux-ia64, alan, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

On Sun, Sep 16, 2012 at 10:39 AM, Stephan Schreiber <info@fs-driver.org> wrote:

> [    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
> [    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
> [    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
> [    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
> [    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
> [    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
> [    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
> ...
> [    1.640965] libata version 3.00 loaded.
> [    1.641656] ata_piix 0000:00:1f.1: version 2.13
> [    1.641671] ata_piix 0000:00:1f.1: device not available (can't reserve
> [mem 0x00000000-0x000003ff])
> [    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
> ...
>
> lspci -vvxxx reports:
>
> 00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller (rev
> 02) (prog-if 8a [Master SecP PriP])
>         Subsystem: Intel Corporation Device 3404
>         Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
> Stepping- SERR- FastB2B- DisINTx-
>         Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
> <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0
>         Interrupt: pin A routed to IRQ 0
>         Region 0: I/O ports at 01f0 [size=8]
>         Region 1: I/O ports at 03f4 [size=1]
>         Region 2: I/O ports at 0170 [size=8]
>         Region 3: I/O ports at 0374 [size=1]
>         Region 4: I/O ports at 1000 [size=16]
> 00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
> 10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
> 20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
> 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00

I agree that we should have a generic way to do this rather than an
ia64-specific way.  In this case you have EFI, but the same thing
could happen with BIOS.

The firmware left the memory BAR at 0x24 cleared (0x00000000), but it
also left the MEM bit in the command register disabled.  So it seems
like a Linux bug that we're trying to use that zero address from the
BAR.  If the firmware left the MEM or IO decode enable bit cleared,
why would we assume it put anything useful in the corresponding BARs?

What would break if we paid attention to the command register enables
in the PCI core and just cleared the resource flags for MEM BARs if
the MEM-decode bit was off, and those for IO BARs if the IO-decode bit
was off?

I don't know much of the ancient history here, so maybe there's a good
reason why this works the way it currently does.

Bjorn

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-17 21:41   ` Bjorn Helgaas
  0 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2012-09-17 21:41 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: linux-ia64, alan, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

On Sun, Sep 16, 2012 at 10:39 AM, Stephan Schreiber <info@fs-driver.org> wrote:

> [    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
> [    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
> [    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
> [    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
> [    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
> [    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
> [    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
> ...
> [    1.640965] libata version 3.00 loaded.
> [    1.641656] ata_piix 0000:00:1f.1: version 2.13
> [    1.641671] ata_piix 0000:00:1f.1: device not available (can't reserve
> [mem 0x00000000-0x000003ff])
> [    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
> ...
>
> lspci -vvxxx reports:
>
> 00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller (rev
> 02) (prog-if 8a [Master SecP PriP])
>         Subsystem: Intel Corporation Device 3404
>         Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
> Stepping- SERR- FastB2B- DisINTx-
>         Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
> <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0
>         Interrupt: pin A routed to IRQ 0
>         Region 0: I/O ports at 01f0 [size=8]
>         Region 1: I/O ports at 03f4 [size=1]
>         Region 2: I/O ports at 0170 [size=8]
>         Region 3: I/O ports at 0374 [size=1]
>         Region 4: I/O ports at 1000 [size\x16]
> 00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
> 10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
> 20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
> 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00

I agree that we should have a generic way to do this rather than an
ia64-specific way.  In this case you have EFI, but the same thing
could happen with BIOS.

The firmware left the memory BAR at 0x24 cleared (0x00000000), but it
also left the MEM bit in the command register disabled.  So it seems
like a Linux bug that we're trying to use that zero address from the
BAR.  If the firmware left the MEM or IO decode enable bit cleared,
why would we assume it put anything useful in the corresponding BARs?

What would break if we paid attention to the command register enables
in the PCI core and just cleared the resource flags for MEM BARs if
the MEM-decode bit was off, and those for IO BARs if the IO-decode bit
was off?

I don't know much of the ancient history here, so maybe there's a good
reason why this works the way it currently does.

Bjorn

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Bug#679545: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-09-17 10:56   ` Alan Cox
  (?)
@ 2012-09-20 14:16     ` Stephan Schreiber
  -1 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-20 14:16 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-ia64, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

description of the symptoms which you have already read on the initial  
RFC/PATCH======>

Kernel 3.2.23 with Debian patches (Debian Wheezy, testing)
Debian bug#679545 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679545)

Machine: Dell PowerEdge 3250 (equivalent with Intel SR870BH2)
Processor: 2x Itanium Madison 1.5GHz 6M
Memory: 4GB

Intel ICH4 (82801DB), IDE host adapter. The ata_piix module fails to  
initialize.

A snippet from dmesg:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Mon Jul 23 09:01:02 UTC 2012
...
[    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
...
[    1.640965] libata version 3.00 loaded.
[    1.641656] ata_piix 0000:00:1f.1: version 2.13
[    1.641671] ata_piix 0000:00:1f.1: device not available (can't  
reserve [mem 0x00000000-0x000003ff])
[    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
...

lspci -vvxxx reports:

00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller  
(rev 02) (prog-if 8a [Master SecP PriP])
	Subsystem: Intel Corporation Device 3404
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-  
Stepping- SERR- FastB2B- DisINTx-
	Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-  
<TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 0
	Region 0: I/O ports at 01f0 [size=8]
	Region 1: I/O ports at 03f4 [size=1]
	Region 2: I/O ports at 0170 [size=8]
	Region 3: I/O ports at 0374 [size=1]
	Region 4: I/O ports at 1000 [size=16]
00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
40: 03 a3 00 80 00 00 00 00 01 00 02 00 00 00 00 00
50: 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00
60: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 60 0f 00 00 00 00 00 00


You can read in the "Intel 82801DB I/O Controller Hub 4 (ICH4)" datasheet
(http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82801db-io-controller-hub-4-datasheet.pdf)
about the EXBAR register at offset 0x24 (4 bytes):
"EXBAR register
This is a memory mapped BAR that requires 1 KB of DWord-aligned memory  
that is Intel reserved
for future functionality. BIOS needs to program the base address for a  
1-KB memory space."

The dump shows that EXBAR is 0x0000, equal to the default value after  
reset; EFI doesn't initialize it.

ata_piix uses pcim_enable_device() which enables this along with the  
I/O BARs. In systems based on the Intel SR870 platform the firmware  
does not initialize the EXBAR and pcim_enable_device() fails because  
the memory region 0x0-0x3FF cannot be allocated.

<=====description of the symptoms which you have already read on the  
initial RFC/PATCH



> My only disagreement here would be putting it in the ia64 paths. If
> someone does the same for x86-32 (and this is EFI so it'll presumbly
> smell the same on all platforms) then we'll want the same.
>
> Better I think to generically catch the 0/0 case.
>
> Alan


Here is a new patch. It extends some existing code in  
pci_setup_device() which maintains some hard-coded io regions on ide  
controllers in legacy mode.
The idea is hiding an uninitialized EXBAR just as on the initial patch.
The patch is defensive; it does nothing if
- the controller isn't in legacy mode,
- BAR5 (EXBAR) isn't a memory resource, or
- BAR5 is already initialized.

The patch is generic because it works on both x86-32 and ia64 and also  
for other ICH4 variants than my rare 82801DB_11 ICH4.
Even the added 'if' statement of this patch is also executed on IDE  
controllers of other vendors than Intel or on other Intel ICHs, I  
believe that it won't break anything.

Stephan



--- linux-3.2.23/drivers/pci/probe.c.orig	2012-07-12 05:32:21.000000000 +0200
+++ linux-3.2.23/drivers/pci/probe.c	2012-09-19 20:52:24.000000000 +0200
@@ -898,146 +898,158 @@ int pci_setup_device(struct pci_dev *dev
  {
  	u32 class;
  	u8 hdr_type;
  	struct pci_slot *slot;
  	int pos = 0;

  	if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
  		return -EIO;

  	dev->sysdata = dev->bus->sysdata;
  	dev->dev.parent = dev->bus->bridge;
  	dev->dev.bus = &pci_bus_type;
  	dev->hdr_type = hdr_type & 0x7f;
  	dev->multifunction = !!(hdr_type & 0x80);
  	dev->error_state = pci_channel_io_normal;
  	set_pcie_port_type(dev);

  	list_for_each_entry(slot, &dev->bus->slots, list)
  		if (PCI_SLOT(dev->devfn) == slot->number)
  			dev->slot = slot;

  	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
  	   set this higher, assuming the system even supports it.  */
  	dev->dma_mask = 0xffffffff;

  	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
  		     dev->bus->number, PCI_SLOT(dev->devfn),
  		     PCI_FUNC(dev->devfn));

  	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
  	dev->revision = class & 0xff;
  	class >>= 8;				    /* upper 3 bytes */
  	dev->class = class;
  	class >>= 8;

  	dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %d class %#08x\n",
  		   dev->vendor, dev->device, dev->hdr_type, class);

  	/* need to have dev->class ready */
  	dev->cfg_size = pci_cfg_space_size(dev);

  	/* "Unknown power state" */
  	dev->current_state = PCI_UNKNOWN;

  	/* Early fixups, before probing the BARs */
  	pci_fixup_device(pci_fixup_early, dev);
  	/* device class may be changed after fixup */
  	class = dev->class >> 8;

  	switch (dev->hdr_type) {		    /* header type */
  	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
  		if (class == PCI_CLASS_BRIDGE_PCI)
  			goto bad;
  		pci_read_irq(dev);
  		pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
  		pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
  		pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);

  		/*
  		 *	Do the ugly legacy mode stuff here rather than broken chip
  		 *	quirk code. Legacy mode ATA controllers have fixed
  		 *	addresses. These are not always echoed in BAR0-3, and
  		 *	BAR0-3 in a few cases contain junk!
+		 *	BAR5 is a memory resource on Intel ICH4 which isn't
+		 *	functional at all. Some BIOS or EFI don't initialize
+		 *	it and would break ata_piix. If the controller is in
+		 *	legacy mode and BAR5 is an uninitialized memory
+		 *	resource, hide it.
  		 */
  		if (class == PCI_CLASS_STORAGE_IDE) {
  			u8 progif;
  			pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
  			if ((progif & 1) == 0) {
  				dev->resource[0].start = 0x1F0;
  				dev->resource[0].end = 0x1F7;
  				dev->resource[0].flags = LEGACY_IO_RESOURCE;
  				dev->resource[1].start = 0x3F6;
  				dev->resource[1].end = 0x3F6;
  				dev->resource[1].flags = LEGACY_IO_RESOURCE;
  			}
  			if ((progif & 4) == 0) {
  				dev->resource[2].start = 0x170;
  				dev->resource[2].end = 0x177;
  				dev->resource[2].flags = LEGACY_IO_RESOURCE;
  				dev->resource[3].start = 0x376;
  				dev->resource[3].end = 0x376;
  				dev->resource[3].flags = LEGACY_IO_RESOURCE;
  			}
+			if ((progif & 5) == 0
+			    && (dev->resource[5].flags & IORESOURCE_MEM)
+			    && dev->resource[5].start == 0
+			    && dev->resource[5].end != 0) {
+				dev->resource[5].flags = 0;
+				dev->resource[5].end = 0;
+			}
  		}
  		break;

  	case PCI_HEADER_TYPE_BRIDGE:		    /* bridge header */
  		if (class != PCI_CLASS_BRIDGE_PCI)
  			goto bad;
  		/* The PCI-to-PCI bridge spec requires that subtractive
  		   decoding (i.e. transparent) bridge must have programming
  		   interface code of 0x01. */
  		pci_read_irq(dev);
  		dev->transparent = ((dev->class & 0xff) == 1);
  		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
  		set_pcie_hotplug_bridge(dev);
  		pos = pci_find_capability(dev, PCI_CAP_ID_SSVID);
  		if (pos) {
  			pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID,  
&dev->subsystem_vendor);
  			pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID,  
&dev->subsystem_device);
  		}
  		break;

  	case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
  		if (class != PCI_CLASS_BRIDGE_CARDBUS)
  			goto bad;
  		pci_read_irq(dev);
  		pci_read_bases(dev, 1, 0);
  		pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID,  
&dev->subsystem_vendor);
  		pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
  		break;

  	default:				    /* unknown header */
  		dev_err(&dev->dev, "unknown header type %02x, "
  			"ignoring device\n", dev->hdr_type);
  		return -EIO;

  	bad:
  		dev_err(&dev->dev, "ignoring class %02x (doesn't match header "
  			"type %02x)\n", class, dev->hdr_type);
  		dev->class = PCI_CLASS_NOT_DEFINED;
  	}

  	/* We found a fine healthy device, go go go... */
  	return 0;
  }

  static void pci_release_capabilities(struct pci_dev *dev)
  {
  	pci_vpd_release(dev);
  	pci_iov_release(dev);
  }

  /**
   * pci_release_dev - free a pci device structure when all users of  
it are finished.
   * @dev: device that's been disconnected
   *
   * Will be called only by the device core when all users of this pci  
device are
   * done.
   */
  static void pci_release_dev(struct device *dev)
  {
  	struct pci_dev *pci_dev;

  	pci_dev = to_pci_dev(dev);
  	pci_release_capabilities(pci_dev);



Signed-off-by: Stephan Schreiber <info@fs-driver.org>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-20 14:16     ` Stephan Schreiber
  0 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-20 14:16 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-ia64, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

description of the symptoms which you have already read on the initial  
RFC/PATCH======>

Kernel 3.2.23 with Debian patches (Debian Wheezy, testing)
Debian bug#679545 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679545)

Machine: Dell PowerEdge 3250 (equivalent with Intel SR870BH2)
Processor: 2x Itanium Madison 1.5GHz 6M
Memory: 4GB

Intel ICH4 (82801DB), IDE host adapter. The ata_piix module fails to  
initialize.

A snippet from dmesg:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Mon Jul 23 09:01:02 UTC 2012
...
[    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
...
[    1.640965] libata version 3.00 loaded.
[    1.641656] ata_piix 0000:00:1f.1: version 2.13
[    1.641671] ata_piix 0000:00:1f.1: device not available (can't  
reserve [mem 0x00000000-0x000003ff])
[    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
...

lspci -vvxxx reports:

00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller  
(rev 02) (prog-if 8a [Master SecP PriP])
	Subsystem: Intel Corporation Device 3404
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-  
Stepping- SERR- FastB2B- DisINTx-
	Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-  
<TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 0
	Region 0: I/O ports at 01f0 [size=8]
	Region 1: I/O ports at 03f4 [size=1]
	Region 2: I/O ports at 0170 [size=8]
	Region 3: I/O ports at 0374 [size=1]
	Region 4: I/O ports at 1000 [size=16]
00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
40: 03 a3 00 80 00 00 00 00 01 00 02 00 00 00 00 00
50: 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00
60: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 60 0f 00 00 00 00 00 00


You can read in the "Intel 82801DB I/O Controller Hub 4 (ICH4)" datasheet
(http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82801db-io-controller-hub-4-datasheet.pdf)
about the EXBAR register at offset 0x24 (4 bytes):
"EXBAR register
This is a memory mapped BAR that requires 1 KB of DWord-aligned memory  
that is Intel reserved
for future functionality. BIOS needs to program the base address for a  
1-KB memory space."

The dump shows that EXBAR is 0x0000, equal to the default value after  
reset; EFI doesn't initialize it.

ata_piix uses pcim_enable_device() which enables this along with the  
I/O BARs. In systems based on the Intel SR870 platform the firmware  
does not initialize the EXBAR and pcim_enable_device() fails because  
the memory region 0x0-0x3FF cannot be allocated.

<=====description of the symptoms which you have already read on the  
initial RFC/PATCH



> My only disagreement here would be putting it in the ia64 paths. If
> someone does the same for x86-32 (and this is EFI so it'll presumbly
> smell the same on all platforms) then we'll want the same.
>
> Better I think to generically catch the 0/0 case.
>
> Alan


Here is a new patch. It extends some existing code in  
pci_setup_device() which maintains some hard-coded io regions on ide  
controllers in legacy mode.
The idea is hiding an uninitialized EXBAR just as on the initial patch.
The patch is defensive; it does nothing if
- the controller isn't in legacy mode,
- BAR5 (EXBAR) isn't a memory resource, or
- BAR5 is already initialized.

The patch is generic because it works on both x86-32 and ia64 and also  
for other ICH4 variants than my rare 82801DB_11 ICH4.
Even the added 'if' statement of this patch is also executed on IDE  
controllers of other vendors than Intel or on other Intel ICHs, I  
believe that it won't break anything.

Stephan



--- linux-3.2.23/drivers/pci/probe.c.orig	2012-07-12 05:32:21.000000000 +0200
+++ linux-3.2.23/drivers/pci/probe.c	2012-09-19 20:52:24.000000000 +0200
@@ -898,146 +898,158 @@ int pci_setup_device(struct pci_dev *dev
  {
  	u32 class;
  	u8 hdr_type;
  	struct pci_slot *slot;
  	int pos = 0;

  	if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
  		return -EIO;

  	dev->sysdata = dev->bus->sysdata;
  	dev->dev.parent = dev->bus->bridge;
  	dev->dev.bus = &pci_bus_type;
  	dev->hdr_type = hdr_type & 0x7f;
  	dev->multifunction = !!(hdr_type & 0x80);
  	dev->error_state = pci_channel_io_normal;
  	set_pcie_port_type(dev);

  	list_for_each_entry(slot, &dev->bus->slots, list)
  		if (PCI_SLOT(dev->devfn) == slot->number)
  			dev->slot = slot;

  	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
  	   set this higher, assuming the system even supports it.  */
  	dev->dma_mask = 0xffffffff;

  	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
  		     dev->bus->number, PCI_SLOT(dev->devfn),
  		     PCI_FUNC(dev->devfn));

  	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
  	dev->revision = class & 0xff;
  	class >>= 8;				    /* upper 3 bytes */
  	dev->class = class;
  	class >>= 8;

  	dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %d class %#08x\n",
  		   dev->vendor, dev->device, dev->hdr_type, class);

  	/* need to have dev->class ready */
  	dev->cfg_size = pci_cfg_space_size(dev);

  	/* "Unknown power state" */
  	dev->current_state = PCI_UNKNOWN;

  	/* Early fixups, before probing the BARs */
  	pci_fixup_device(pci_fixup_early, dev);
  	/* device class may be changed after fixup */
  	class = dev->class >> 8;

  	switch (dev->hdr_type) {		    /* header type */
  	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
  		if (class == PCI_CLASS_BRIDGE_PCI)
  			goto bad;
  		pci_read_irq(dev);
  		pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
  		pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
  		pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);

  		/*
  		 *	Do the ugly legacy mode stuff here rather than broken chip
  		 *	quirk code. Legacy mode ATA controllers have fixed
  		 *	addresses. These are not always echoed in BAR0-3, and
  		 *	BAR0-3 in a few cases contain junk!
+		 *	BAR5 is a memory resource on Intel ICH4 which isn't
+		 *	functional at all. Some BIOS or EFI don't initialize
+		 *	it and would break ata_piix. If the controller is in
+		 *	legacy mode and BAR5 is an uninitialized memory
+		 *	resource, hide it.
  		 */
  		if (class == PCI_CLASS_STORAGE_IDE) {
  			u8 progif;
  			pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
  			if ((progif & 1) == 0) {
  				dev->resource[0].start = 0x1F0;
  				dev->resource[0].end = 0x1F7;
  				dev->resource[0].flags = LEGACY_IO_RESOURCE;
  				dev->resource[1].start = 0x3F6;
  				dev->resource[1].end = 0x3F6;
  				dev->resource[1].flags = LEGACY_IO_RESOURCE;
  			}
  			if ((progif & 4) == 0) {
  				dev->resource[2].start = 0x170;
  				dev->resource[2].end = 0x177;
  				dev->resource[2].flags = LEGACY_IO_RESOURCE;
  				dev->resource[3].start = 0x376;
  				dev->resource[3].end = 0x376;
  				dev->resource[3].flags = LEGACY_IO_RESOURCE;
  			}
+			if ((progif & 5) == 0
+			    && (dev->resource[5].flags & IORESOURCE_MEM)
+			    && dev->resource[5].start == 0
+			    && dev->resource[5].end != 0) {
+				dev->resource[5].flags = 0;
+				dev->resource[5].end = 0;
+			}
  		}
  		break;

  	case PCI_HEADER_TYPE_BRIDGE:		    /* bridge header */
  		if (class != PCI_CLASS_BRIDGE_PCI)
  			goto bad;
  		/* The PCI-to-PCI bridge spec requires that subtractive
  		   decoding (i.e. transparent) bridge must have programming
  		   interface code of 0x01. */
  		pci_read_irq(dev);
  		dev->transparent = ((dev->class & 0xff) == 1);
  		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
  		set_pcie_hotplug_bridge(dev);
  		pos = pci_find_capability(dev, PCI_CAP_ID_SSVID);
  		if (pos) {
  			pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID,  
&dev->subsystem_vendor);
  			pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID,  
&dev->subsystem_device);
  		}
  		break;

  	case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
  		if (class != PCI_CLASS_BRIDGE_CARDBUS)
  			goto bad;
  		pci_read_irq(dev);
  		pci_read_bases(dev, 1, 0);
  		pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID,  
&dev->subsystem_vendor);
  		pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
  		break;

  	default:				    /* unknown header */
  		dev_err(&dev->dev, "unknown header type %02x, "
  			"ignoring device\n", dev->hdr_type);
  		return -EIO;

  	bad:
  		dev_err(&dev->dev, "ignoring class %02x (doesn't match header "
  			"type %02x)\n", class, dev->hdr_type);
  		dev->class = PCI_CLASS_NOT_DEFINED;
  	}

  	/* We found a fine healthy device, go go go... */
  	return 0;
  }

  static void pci_release_capabilities(struct pci_dev *dev)
  {
  	pci_vpd_release(dev);
  	pci_iov_release(dev);
  }

  /**
   * pci_release_dev - free a pci device structure when all users of  
it are finished.
   * @dev: device that's been disconnected
   *
   * Will be called only by the device core when all users of this pci  
device are
   * done.
   */
  static void pci_release_dev(struct device *dev)
  {
  	struct pci_dev *pci_dev;

  	pci_dev = to_pci_dev(dev);
  	pci_release_capabilities(pci_dev);



Signed-off-by: Stephan Schreiber <info@fs-driver.org>





^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-20 14:16     ` Stephan Schreiber
  0 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-20 14:16 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-ia64, linux-pci, linux-ide, linux-kernel, 679545, jrnieder

description of the symptoms which you have already read on the initial  
RFC/PATCH===>

Kernel 3.2.23 with Debian patches (Debian Wheezy, testing)
Debian bug#679545 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bugg9545)

Machine: Dell PowerEdge 3250 (equivalent with Intel SR870BH2)
Processor: 2x Itanium Madison 1.5GHz 6M
Memory: 4GB

Intel ICH4 (82801DB), IDE host adapter. The ata_piix module fails to  
initialize.

A snippet from dmesg:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Mon Jul 23 09:01:02 UTC 2012
...
[    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
...
[    1.640965] libata version 3.00 loaded.
[    1.641656] ata_piix 0000:00:1f.1: version 2.13
[    1.641671] ata_piix 0000:00:1f.1: device not available (can't  
reserve [mem 0x00000000-0x000003ff])
[    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
...

lspci -vvxxx reports:

00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller  
(rev 02) (prog-if 8a [Master SecP PriP])
	Subsystem: Intel Corporation Device 3404
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-  
Stepping- SERR- FastB2B- DisINTx-
	Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-  
<TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 0
	Region 0: I/O ports at 01f0 [size=8]
	Region 1: I/O ports at 03f4 [size=1]
	Region 2: I/O ports at 0170 [size=8]
	Region 3: I/O ports at 0374 [size=1]
	Region 4: I/O ports at 1000 [size\x16]
00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
40: 03 a3 00 80 00 00 00 00 01 00 02 00 00 00 00 00
50: 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00
60: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 60 0f 00 00 00 00 00 00


You can read in the "Intel 82801DB I/O Controller Hub 4 (ICH4)" datasheet
(http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82801db-io-controller-hub-4-datasheet.pdf)
about the EXBAR register at offset 0x24 (4 bytes):
"EXBAR register
This is a memory mapped BAR that requires 1 KB of DWord-aligned memory  
that is Intel reserved
for future functionality. BIOS needs to program the base address for a  
1-KB memory space."

The dump shows that EXBAR is 0x0000, equal to the default value after  
reset; EFI doesn't initialize it.

ata_piix uses pcim_enable_device() which enables this along with the  
I/O BARs. In systems based on the Intel SR870 platform the firmware  
does not initialize the EXBAR and pcim_enable_device() fails because  
the memory region 0x0-0x3FF cannot be allocated.

<==Þscription of the symptoms which you have already read on the  
initial RFC/PATCH



> My only disagreement here would be putting it in the ia64 paths. If
> someone does the same for x86-32 (and this is EFI so it'll presumbly
> smell the same on all platforms) then we'll want the same.
>
> Better I think to generically catch the 0/0 case.
>
> Alan


Here is a new patch. It extends some existing code in  
pci_setup_device() which maintains some hard-coded io regions on ide  
controllers in legacy mode.
The idea is hiding an uninitialized EXBAR just as on the initial patch.
The patch is defensive; it does nothing if
- the controller isn't in legacy mode,
- BAR5 (EXBAR) isn't a memory resource, or
- BAR5 is already initialized.

The patch is generic because it works on both x86-32 and ia64 and also  
for other ICH4 variants than my rare 82801DB_11 ICH4.
Even the added 'if' statement of this patch is also executed on IDE  
controllers of other vendors than Intel or on other Intel ICHs, I  
believe that it won't break anything.

Stephan



--- linux-3.2.23/drivers/pci/probe.c.orig	2012-07-12 05:32:21.000000000 +0200
+++ linux-3.2.23/drivers/pci/probe.c	2012-09-19 20:52:24.000000000 +0200
@@ -898,146 +898,158 @@ int pci_setup_device(struct pci_dev *dev
  {
  	u32 class;
  	u8 hdr_type;
  	struct pci_slot *slot;
  	int pos = 0;

  	if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
  		return -EIO;

  	dev->sysdata = dev->bus->sysdata;
  	dev->dev.parent = dev->bus->bridge;
  	dev->dev.bus = &pci_bus_type;
  	dev->hdr_type = hdr_type & 0x7f;
  	dev->multifunction = !!(hdr_type & 0x80);
  	dev->error_state = pci_channel_io_normal;
  	set_pcie_port_type(dev);

  	list_for_each_entry(slot, &dev->bus->slots, list)
  		if (PCI_SLOT(dev->devfn) = slot->number)
  			dev->slot = slot;

  	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
  	   set this higher, assuming the system even supports it.  */
  	dev->dma_mask = 0xffffffff;

  	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
  		     dev->bus->number, PCI_SLOT(dev->devfn),
  		     PCI_FUNC(dev->devfn));

  	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
  	dev->revision = class & 0xff;
  	class >>= 8;				    /* upper 3 bytes */
  	dev->class = class;
  	class >>= 8;

  	dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %d class %#08x\n",
  		   dev->vendor, dev->device, dev->hdr_type, class);

  	/* need to have dev->class ready */
  	dev->cfg_size = pci_cfg_space_size(dev);

  	/* "Unknown power state" */
  	dev->current_state = PCI_UNKNOWN;

  	/* Early fixups, before probing the BARs */
  	pci_fixup_device(pci_fixup_early, dev);
  	/* device class may be changed after fixup */
  	class = dev->class >> 8;

  	switch (dev->hdr_type) {		    /* header type */
  	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
  		if (class = PCI_CLASS_BRIDGE_PCI)
  			goto bad;
  		pci_read_irq(dev);
  		pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
  		pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
  		pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);

  		/*
  		 *	Do the ugly legacy mode stuff here rather than broken chip
  		 *	quirk code. Legacy mode ATA controllers have fixed
  		 *	addresses. These are not always echoed in BAR0-3, and
  		 *	BAR0-3 in a few cases contain junk!
+		 *	BAR5 is a memory resource on Intel ICH4 which isn't
+		 *	functional at all. Some BIOS or EFI don't initialize
+		 *	it and would break ata_piix. If the controller is in
+		 *	legacy mode and BAR5 is an uninitialized memory
+		 *	resource, hide it.
  		 */
  		if (class = PCI_CLASS_STORAGE_IDE) {
  			u8 progif;
  			pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
  			if ((progif & 1) = 0) {
  				dev->resource[0].start = 0x1F0;
  				dev->resource[0].end = 0x1F7;
  				dev->resource[0].flags = LEGACY_IO_RESOURCE;
  				dev->resource[1].start = 0x3F6;
  				dev->resource[1].end = 0x3F6;
  				dev->resource[1].flags = LEGACY_IO_RESOURCE;
  			}
  			if ((progif & 4) = 0) {
  				dev->resource[2].start = 0x170;
  				dev->resource[2].end = 0x177;
  				dev->resource[2].flags = LEGACY_IO_RESOURCE;
  				dev->resource[3].start = 0x376;
  				dev->resource[3].end = 0x376;
  				dev->resource[3].flags = LEGACY_IO_RESOURCE;
  			}
+			if ((progif & 5) = 0
+			    && (dev->resource[5].flags & IORESOURCE_MEM)
+			    && dev->resource[5].start = 0
+			    && dev->resource[5].end != 0) {
+				dev->resource[5].flags = 0;
+				dev->resource[5].end = 0;
+			}
  		}
  		break;

  	case PCI_HEADER_TYPE_BRIDGE:		    /* bridge header */
  		if (class != PCI_CLASS_BRIDGE_PCI)
  			goto bad;
  		/* The PCI-to-PCI bridge spec requires that subtractive
  		   decoding (i.e. transparent) bridge must have programming
  		   interface code of 0x01. */
  		pci_read_irq(dev);
  		dev->transparent = ((dev->class & 0xff) = 1);
  		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
  		set_pcie_hotplug_bridge(dev);
  		pos = pci_find_capability(dev, PCI_CAP_ID_SSVID);
  		if (pos) {
  			pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID,  
&dev->subsystem_vendor);
  			pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID,  
&dev->subsystem_device);
  		}
  		break;

  	case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
  		if (class != PCI_CLASS_BRIDGE_CARDBUS)
  			goto bad;
  		pci_read_irq(dev);
  		pci_read_bases(dev, 1, 0);
  		pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID,  
&dev->subsystem_vendor);
  		pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
  		break;

  	default:				    /* unknown header */
  		dev_err(&dev->dev, "unknown header type %02x, "
  			"ignoring device\n", dev->hdr_type);
  		return -EIO;

  	bad:
  		dev_err(&dev->dev, "ignoring class %02x (doesn't match header "
  			"type %02x)\n", class, dev->hdr_type);
  		dev->class = PCI_CLASS_NOT_DEFINED;
  	}

  	/* We found a fine healthy device, go go go... */
  	return 0;
  }

  static void pci_release_capabilities(struct pci_dev *dev)
  {
  	pci_vpd_release(dev);
  	pci_iov_release(dev);
  }

  /**
   * pci_release_dev - free a pci device structure when all users of  
it are finished.
   * @dev: device that's been disconnected
   *
   * Will be called only by the device core when all users of this pci  
device are
   * done.
   */
  static void pci_release_dev(struct device *dev)
  {
  	struct pci_dev *pci_dev;

  	pci_dev = to_pci_dev(dev);
  	pci_release_capabilities(pci_dev);



Signed-off-by: Stephan Schreiber <info@fs-driver.org>





^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-09-20 14:16     ` Stephan Schreiber
@ 2012-09-20 16:02       ` Bjorn Helgaas
  -1 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2012-09-20 16:02 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

On Thu, Sep 20, 2012 at 8:16 AM, Stephan Schreiber <info@fs-driver.org> wrote:
> description of the symptoms which you have already read on the initial
> RFC/PATCH======>
>
>
> Kernel 3.2.23 with Debian patches (Debian Wheezy, testing)
> Debian bug#679545 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679545)
>
> Machine: Dell PowerEdge 3250 (equivalent with Intel SR870BH2)
> Processor: 2x Itanium Madison 1.5GHz 6M
> Memory: 4GB
>
> Intel ICH4 (82801DB), IDE host adapter. The ata_piix module fails to
> initialize.
>
> A snippet from dmesg:
> [    0.000000] Initializing cgroup subsys cpuset
> [    0.000000] Initializing cgroup subsys cpu
> [    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)
> (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) ) #1
> SMP Mon Jul 23 09:01:02 UTC 2012
> ...
> [    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
> [    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
> [    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
> [    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
> [    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
> [    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
> [    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
> ...
> [    1.640965] libata version 3.00 loaded.
> [    1.641656] ata_piix 0000:00:1f.1: version 2.13
> [    1.641671] ata_piix 0000:00:1f.1: device not available (can't reserve
> [mem 0x00000000-0x000003ff])
> [    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
> ...
>
> lspci -vvxxx reports:
>
> 00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller (rev
> 02) (prog-if 8a [Master SecP PriP])
>         Subsystem: Intel Corporation Device 3404
>         Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
> Stepping- SERR- FastB2B- DisINTx-
>         Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
> <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0
>         Interrupt: pin A routed to IRQ 0
>         Region 0: I/O ports at 01f0 [size=8]
>         Region 1: I/O ports at 03f4 [size=1]
>         Region 2: I/O ports at 0170 [size=8]
>         Region 3: I/O ports at 0374 [size=1]
>         Region 4: I/O ports at 1000 [size=16]
> 00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
> 10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
> 20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
> 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
> 40: 03 a3 00 80 00 00 00 00 01 00 02 00 00 00 00 00
> 50: 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00
> 60: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
> 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> f0: 00 00 00 00 00 00 00 00 60 0f 00 00 00 00 00 00
>
>
> You can read in the "Intel 82801DB I/O Controller Hub 4 (ICH4)" datasheet
> (http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82801db-io-controller-hub-4-datasheet.pdf)
> about the EXBAR register at offset 0x24 (4 bytes):
> "EXBAR register
> This is a memory mapped BAR that requires 1 KB of DWord-aligned memory that
> is Intel reserved
> for future functionality. BIOS needs to program the base address for a 1-KB
> memory space."
>
> The dump shows that EXBAR is 0x0000, equal to the default value after reset;
> EFI doesn't initialize it.
>
> ata_piix uses pcim_enable_device() which enables this along with the I/O
> BARs. In systems based on the Intel SR870 platform the firmware does not
> initialize the EXBAR and pcim_enable_device() fails because the memory
> region 0x0-0x3FF cannot be allocated.
>
> <=====description of the symptoms which you have already read on the initial
> RFC/PATCH
>
>
>
>
>> My only disagreement here would be putting it in the ia64 paths. If
>> someone does the same for x86-32 (and this is EFI so it'll presumbly
>> smell the same on all platforms) then we'll want the same.
>>
>> Better I think to generically catch the 0/0 case.
>>
>> Alan
>
>
>
> Here is a new patch. It extends some existing code in pci_setup_device()
> which maintains some hard-coded io regions on ide controllers in legacy
> mode.
> The idea is hiding an uninitialized EXBAR just as on the initial patch.
> The patch is defensive; it does nothing if
> - the controller isn't in legacy mode,
> - BAR5 (EXBAR) isn't a memory resource, or
> - BAR5 is already initialized.
>
> The patch is generic because it works on both x86-32 and ia64 and also for
> other ICH4 variants than my rare 82801DB_11 ICH4.
> Even the added 'if' statement of this patch is also executed on IDE
> controllers of other vendors than Intel or on other Intel ICHs, I believe
> that it won't break anything.

This still isn't very generic.  It only looks at BAR 5 and only for
IDE controllers, so it fixes the problem for this device and this
BIOS, but there's no reason the same problem couldn't happen on other
devices and other BARs.

My proposal was basically:

    pci_read_config_word(dev, PCI_COMMAND, &cmd);
    for (i = 0; i < 6; i++) {
        /* read BAR i here */
        r = dev->resource[i];
        if (((r->flags & IORESOURCE_MEM) && (cmd & PCI_COMMAND_MEMORY)) ||
            ((r->flags & IORESOURCE_IO) && (cmd & PCI_COMMAND_IO))) {
            /* treat resource as valid */
        } else {
            /* treat resource as unassigned; try to assign it later */
        }
    }

(This is just to show the idea; the actual Linux code isn't structured
like this.)

> --- linux-3.2.23/drivers/pci/probe.c.orig       2012-07-12
> 05:32:21.000000000 +0200
> +++ linux-3.2.23/drivers/pci/probe.c    2012-09-19 20:52:24.000000000 +0200
> @@ -898,146 +898,158 @@ int pci_setup_device(struct pci_dev *dev
>  {
>         u32 class;
>         u8 hdr_type;
>         struct pci_slot *slot;
>         int pos = 0;
>
>         if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
>                 return -EIO;
>
>         dev->sysdata = dev->bus->sysdata;
>         dev->dev.parent = dev->bus->bridge;
>         dev->dev.bus = &pci_bus_type;
>         dev->hdr_type = hdr_type & 0x7f;
>         dev->multifunction = !!(hdr_type & 0x80);
>         dev->error_state = pci_channel_io_normal;
>         set_pcie_port_type(dev);
>
>         list_for_each_entry(slot, &dev->bus->slots, list)
>                 if (PCI_SLOT(dev->devfn) == slot->number)
>                         dev->slot = slot;
>
>         /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
>            set this higher, assuming the system even supports it.  */
>         dev->dma_mask = 0xffffffff;
>
>         dev_set_name(&dev->dev, "%04x:%02x:%02x.%d",
> pci_domain_nr(dev->bus),
>                      dev->bus->number, PCI_SLOT(dev->devfn),
>                      PCI_FUNC(dev->devfn));
>
>         pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
>         dev->revision = class & 0xff;
>         class >>= 8;                                /* upper 3 bytes */
>         dev->class = class;
>         class >>= 8;
>
>         dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %d class
> %#08x\n",
>                    dev->vendor, dev->device, dev->hdr_type, class);
>
>         /* need to have dev->class ready */
>         dev->cfg_size = pci_cfg_space_size(dev);
>
>         /* "Unknown power state" */
>         dev->current_state = PCI_UNKNOWN;
>
>         /* Early fixups, before probing the BARs */
>         pci_fixup_device(pci_fixup_early, dev);
>         /* device class may be changed after fixup */
>         class = dev->class >> 8;
>
>         switch (dev->hdr_type) {                    /* header type */
>         case PCI_HEADER_TYPE_NORMAL:                /* standard header */
>                 if (class == PCI_CLASS_BRIDGE_PCI)
>                         goto bad;
>                 pci_read_irq(dev);
>                 pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
>                 pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID,
> &dev->subsystem_vendor);
>                 pci_read_config_word(dev, PCI_SUBSYSTEM_ID,
> &dev->subsystem_device);
>
>                 /*
>                  *      Do the ugly legacy mode stuff here rather than
> broken chip
>                  *      quirk code. Legacy mode ATA controllers have fixed
>                  *      addresses. These are not always echoed in BAR0-3,
> and
>                  *      BAR0-3 in a few cases contain junk!
> +                *      BAR5 is a memory resource on Intel ICH4 which isn't
> +                *      functional at all. Some BIOS or EFI don't initialize
> +                *      it and would break ata_piix. If the controller is in
> +                *      legacy mode and BAR5 is an uninitialized memory
> +                *      resource, hide it.
>                  */
>                 if (class == PCI_CLASS_STORAGE_IDE) {
>                         u8 progif;
>                         pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
>                         if ((progif & 1) == 0) {
>                                 dev->resource[0].start = 0x1F0;
>                                 dev->resource[0].end = 0x1F7;
>                                 dev->resource[0].flags = LEGACY_IO_RESOURCE;
>                                 dev->resource[1].start = 0x3F6;
>                                 dev->resource[1].end = 0x3F6;
>                                 dev->resource[1].flags = LEGACY_IO_RESOURCE;
>                         }
>                         if ((progif & 4) == 0) {
>                                 dev->resource[2].start = 0x170;
>                                 dev->resource[2].end = 0x177;
>                                 dev->resource[2].flags = LEGACY_IO_RESOURCE;
>                                 dev->resource[3].start = 0x376;
>                                 dev->resource[3].end = 0x376;
>                                 dev->resource[3].flags = LEGACY_IO_RESOURCE;
>                         }
> +                       if ((progif & 5) == 0
> +                           && (dev->resource[5].flags & IORESOURCE_MEM)
> +                           && dev->resource[5].start == 0
> +                           && dev->resource[5].end != 0) {
> +                               dev->resource[5].flags = 0;
> +                               dev->resource[5].end = 0;
> +                       }
>                 }
>                 break;
>
>         case PCI_HEADER_TYPE_BRIDGE:                /* bridge header */
>                 if (class != PCI_CLASS_BRIDGE_PCI)
>                         goto bad;
>                 /* The PCI-to-PCI bridge spec requires that subtractive
>                    decoding (i.e. transparent) bridge must have programming
>                    interface code of 0x01. */
>                 pci_read_irq(dev);
>                 dev->transparent = ((dev->class & 0xff) == 1);
>                 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
>                 set_pcie_hotplug_bridge(dev);
>                 pos = pci_find_capability(dev, PCI_CAP_ID_SSVID);
>                 if (pos) {
>                         pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID,
> &dev->subsystem_vendor);
>                         pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID,
> &dev->subsystem_device);
>                 }
>                 break;
>
>         case PCI_HEADER_TYPE_CARDBUS:               /* CardBus bridge header
> */
>                 if (class != PCI_CLASS_BRIDGE_CARDBUS)
>                         goto bad;
>                 pci_read_irq(dev);
>                 pci_read_bases(dev, 1, 0);
>                 pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID,
> &dev->subsystem_vendor);
>                 pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID,
> &dev->subsystem_device);
>                 break;
>
>         default:                                    /* unknown header */
>                 dev_err(&dev->dev, "unknown header type %02x, "
>                         "ignoring device\n", dev->hdr_type);
>                 return -EIO;
>
>         bad:
>                 dev_err(&dev->dev, "ignoring class %02x (doesn't match
> header "
>                         "type %02x)\n", class, dev->hdr_type);
>                 dev->class = PCI_CLASS_NOT_DEFINED;
>         }
>
>         /* We found a fine healthy device, go go go... */
>         return 0;
>  }
>
>  static void pci_release_capabilities(struct pci_dev *dev)
>  {
>         pci_vpd_release(dev);
>         pci_iov_release(dev);
>  }
>
>  /**
>   * pci_release_dev - free a pci device structure when all users of it are
> finished.
>   * @dev: device that's been disconnected
>   *
>   * Will be called only by the device core when all users of this pci device
> are
>   * done.
>   */
>  static void pci_release_dev(struct device *dev)
>  {
>         struct pci_dev *pci_dev;
>
>         pci_dev = to_pci_dev(dev);
>         pci_release_capabilities(pci_dev);
>
>
>
> Signed-off-by: Stephan Schreiber <info@fs-driver.org>
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-20 16:02       ` Bjorn Helgaas
  0 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2012-09-20 16:02 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

On Thu, Sep 20, 2012 at 8:16 AM, Stephan Schreiber <info@fs-driver.org> wrote:
> description of the symptoms which you have already read on the initial
> RFC/PATCH===>
>
>
> Kernel 3.2.23 with Debian patches (Debian Wheezy, testing)
> Debian bug#679545 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bugg9545)
>
> Machine: Dell PowerEdge 3250 (equivalent with Intel SR870BH2)
> Processor: 2x Itanium Madison 1.5GHz 6M
> Memory: 4GB
>
> Intel ICH4 (82801DB), IDE host adapter. The ata_piix module fails to
> initialize.
>
> A snippet from dmesg:
> [    0.000000] Initializing cgroup subsys cpuset
> [    0.000000] Initializing cgroup subsys cpu
> [    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)
> (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) ) #1
> SMP Mon Jul 23 09:01:02 UTC 2012
> ...
> [    0.065516] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
> [    0.065530] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
> [    0.065541] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
> [    0.065552] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
> [    0.065563] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
> [    0.065574] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
> [    0.065585] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff]
> ...
> [    1.640965] libata version 3.00 loaded.
> [    1.641656] ata_piix 0000:00:1f.1: version 2.13
> [    1.641671] ata_piix 0000:00:1f.1: device not available (can't reserve
> [mem 0x00000000-0x000003ff])
> [    1.641747] ata_piix: probe of 0000:00:1f.1 failed with error -22
> ...
>
> lspci -vvxxx reports:
>
> 00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller (rev
> 02) (prog-if 8a [Master SecP PriP])
>         Subsystem: Intel Corporation Device 3404
>         Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
> Stepping- SERR- FastB2B- DisINTx-
>         Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
> <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0
>         Interrupt: pin A routed to IRQ 0
>         Region 0: I/O ports at 01f0 [size=8]
>         Region 1: I/O ports at 03f4 [size=1]
>         Region 2: I/O ports at 0170 [size=8]
>         Region 3: I/O ports at 0374 [size=1]
>         Region 4: I/O ports at 1000 [size\x16]
> 00: 86 80 cb 24 05 00 80 02 02 8a 01 01 00 00 00 00
> 10: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
> 20: 01 10 00 00 00 00 00 00 00 00 00 00 86 80 04 34
> 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
> 40: 03 a3 00 80 00 00 00 00 01 00 02 00 00 00 00 00
> 50: 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00
> 60: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
> 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> f0: 00 00 00 00 00 00 00 00 60 0f 00 00 00 00 00 00
>
>
> You can read in the "Intel 82801DB I/O Controller Hub 4 (ICH4)" datasheet
> (http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82801db-io-controller-hub-4-datasheet.pdf)
> about the EXBAR register at offset 0x24 (4 bytes):
> "EXBAR register
> This is a memory mapped BAR that requires 1 KB of DWord-aligned memory that
> is Intel reserved
> for future functionality. BIOS needs to program the base address for a 1-KB
> memory space."
>
> The dump shows that EXBAR is 0x0000, equal to the default value after reset;
> EFI doesn't initialize it.
>
> ata_piix uses pcim_enable_device() which enables this along with the I/O
> BARs. In systems based on the Intel SR870 platform the firmware does not
> initialize the EXBAR and pcim_enable_device() fails because the memory
> region 0x0-0x3FF cannot be allocated.
>
> <==Þscription of the symptoms which you have already read on the initial
> RFC/PATCH
>
>
>
>
>> My only disagreement here would be putting it in the ia64 paths. If
>> someone does the same for x86-32 (and this is EFI so it'll presumbly
>> smell the same on all platforms) then we'll want the same.
>>
>> Better I think to generically catch the 0/0 case.
>>
>> Alan
>
>
>
> Here is a new patch. It extends some existing code in pci_setup_device()
> which maintains some hard-coded io regions on ide controllers in legacy
> mode.
> The idea is hiding an uninitialized EXBAR just as on the initial patch.
> The patch is defensive; it does nothing if
> - the controller isn't in legacy mode,
> - BAR5 (EXBAR) isn't a memory resource, or
> - BAR5 is already initialized.
>
> The patch is generic because it works on both x86-32 and ia64 and also for
> other ICH4 variants than my rare 82801DB_11 ICH4.
> Even the added 'if' statement of this patch is also executed on IDE
> controllers of other vendors than Intel or on other Intel ICHs, I believe
> that it won't break anything.

This still isn't very generic.  It only looks at BAR 5 and only for
IDE controllers, so it fixes the problem for this device and this
BIOS, but there's no reason the same problem couldn't happen on other
devices and other BARs.

My proposal was basically:

    pci_read_config_word(dev, PCI_COMMAND, &cmd);
    for (i = 0; i < 6; i++) {
        /* read BAR i here */
        r = dev->resource[i];
        if (((r->flags & IORESOURCE_MEM) && (cmd & PCI_COMMAND_MEMORY)) ||
            ((r->flags & IORESOURCE_IO) && (cmd & PCI_COMMAND_IO))) {
            /* treat resource as valid */
        } else {
            /* treat resource as unassigned; try to assign it later */
        }
    }

(This is just to show the idea; the actual Linux code isn't structured
like this.)

> --- linux-3.2.23/drivers/pci/probe.c.orig       2012-07-12
> 05:32:21.000000000 +0200
> +++ linux-3.2.23/drivers/pci/probe.c    2012-09-19 20:52:24.000000000 +0200
> @@ -898,146 +898,158 @@ int pci_setup_device(struct pci_dev *dev
>  {
>         u32 class;
>         u8 hdr_type;
>         struct pci_slot *slot;
>         int pos = 0;
>
>         if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
>                 return -EIO;
>
>         dev->sysdata = dev->bus->sysdata;
>         dev->dev.parent = dev->bus->bridge;
>         dev->dev.bus = &pci_bus_type;
>         dev->hdr_type = hdr_type & 0x7f;
>         dev->multifunction = !!(hdr_type & 0x80);
>         dev->error_state = pci_channel_io_normal;
>         set_pcie_port_type(dev);
>
>         list_for_each_entry(slot, &dev->bus->slots, list)
>                 if (PCI_SLOT(dev->devfn) = slot->number)
>                         dev->slot = slot;
>
>         /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
>            set this higher, assuming the system even supports it.  */
>         dev->dma_mask = 0xffffffff;
>
>         dev_set_name(&dev->dev, "%04x:%02x:%02x.%d",
> pci_domain_nr(dev->bus),
>                      dev->bus->number, PCI_SLOT(dev->devfn),
>                      PCI_FUNC(dev->devfn));
>
>         pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
>         dev->revision = class & 0xff;
>         class >>= 8;                                /* upper 3 bytes */
>         dev->class = class;
>         class >>= 8;
>
>         dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %d class
> %#08x\n",
>                    dev->vendor, dev->device, dev->hdr_type, class);
>
>         /* need to have dev->class ready */
>         dev->cfg_size = pci_cfg_space_size(dev);
>
>         /* "Unknown power state" */
>         dev->current_state = PCI_UNKNOWN;
>
>         /* Early fixups, before probing the BARs */
>         pci_fixup_device(pci_fixup_early, dev);
>         /* device class may be changed after fixup */
>         class = dev->class >> 8;
>
>         switch (dev->hdr_type) {                    /* header type */
>         case PCI_HEADER_TYPE_NORMAL:                /* standard header */
>                 if (class = PCI_CLASS_BRIDGE_PCI)
>                         goto bad;
>                 pci_read_irq(dev);
>                 pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
>                 pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID,
> &dev->subsystem_vendor);
>                 pci_read_config_word(dev, PCI_SUBSYSTEM_ID,
> &dev->subsystem_device);
>
>                 /*
>                  *      Do the ugly legacy mode stuff here rather than
> broken chip
>                  *      quirk code. Legacy mode ATA controllers have fixed
>                  *      addresses. These are not always echoed in BAR0-3,
> and
>                  *      BAR0-3 in a few cases contain junk!
> +                *      BAR5 is a memory resource on Intel ICH4 which isn't
> +                *      functional at all. Some BIOS or EFI don't initialize
> +                *      it and would break ata_piix. If the controller is in
> +                *      legacy mode and BAR5 is an uninitialized memory
> +                *      resource, hide it.
>                  */
>                 if (class = PCI_CLASS_STORAGE_IDE) {
>                         u8 progif;
>                         pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
>                         if ((progif & 1) = 0) {
>                                 dev->resource[0].start = 0x1F0;
>                                 dev->resource[0].end = 0x1F7;
>                                 dev->resource[0].flags = LEGACY_IO_RESOURCE;
>                                 dev->resource[1].start = 0x3F6;
>                                 dev->resource[1].end = 0x3F6;
>                                 dev->resource[1].flags = LEGACY_IO_RESOURCE;
>                         }
>                         if ((progif & 4) = 0) {
>                                 dev->resource[2].start = 0x170;
>                                 dev->resource[2].end = 0x177;
>                                 dev->resource[2].flags = LEGACY_IO_RESOURCE;
>                                 dev->resource[3].start = 0x376;
>                                 dev->resource[3].end = 0x376;
>                                 dev->resource[3].flags = LEGACY_IO_RESOURCE;
>                         }
> +                       if ((progif & 5) = 0
> +                           && (dev->resource[5].flags & IORESOURCE_MEM)
> +                           && dev->resource[5].start = 0
> +                           && dev->resource[5].end != 0) {
> +                               dev->resource[5].flags = 0;
> +                               dev->resource[5].end = 0;
> +                       }
>                 }
>                 break;
>
>         case PCI_HEADER_TYPE_BRIDGE:                /* bridge header */
>                 if (class != PCI_CLASS_BRIDGE_PCI)
>                         goto bad;
>                 /* The PCI-to-PCI bridge spec requires that subtractive
>                    decoding (i.e. transparent) bridge must have programming
>                    interface code of 0x01. */
>                 pci_read_irq(dev);
>                 dev->transparent = ((dev->class & 0xff) = 1);
>                 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
>                 set_pcie_hotplug_bridge(dev);
>                 pos = pci_find_capability(dev, PCI_CAP_ID_SSVID);
>                 if (pos) {
>                         pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID,
> &dev->subsystem_vendor);
>                         pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID,
> &dev->subsystem_device);
>                 }
>                 break;
>
>         case PCI_HEADER_TYPE_CARDBUS:               /* CardBus bridge header
> */
>                 if (class != PCI_CLASS_BRIDGE_CARDBUS)
>                         goto bad;
>                 pci_read_irq(dev);
>                 pci_read_bases(dev, 1, 0);
>                 pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID,
> &dev->subsystem_vendor);
>                 pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID,
> &dev->subsystem_device);
>                 break;
>
>         default:                                    /* unknown header */
>                 dev_err(&dev->dev, "unknown header type %02x, "
>                         "ignoring device\n", dev->hdr_type);
>                 return -EIO;
>
>         bad:
>                 dev_err(&dev->dev, "ignoring class %02x (doesn't match
> header "
>                         "type %02x)\n", class, dev->hdr_type);
>                 dev->class = PCI_CLASS_NOT_DEFINED;
>         }
>
>         /* We found a fine healthy device, go go go... */
>         return 0;
>  }
>
>  static void pci_release_capabilities(struct pci_dev *dev)
>  {
>         pci_vpd_release(dev);
>         pci_iov_release(dev);
>  }
>
>  /**
>   * pci_release_dev - free a pci device structure when all users of it are
> finished.
>   * @dev: device that's been disconnected
>   *
>   * Will be called only by the device core when all users of this pci device
> are
>   * done.
>   */
>  static void pci_release_dev(struct device *dev)
>  {
>         struct pci_dev *pci_dev;
>
>         pci_dev = to_pci_dev(dev);
>         pci_release_capabilities(pci_dev);
>
>
>
> Signed-off-by: Stephan Schreiber <info@fs-driver.org>
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-09-20 16:02       ` Bjorn Helgaas
@ 2012-09-24 17:09         ` Stephan Schreiber
  -1 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-24 17:09 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

Mpfff, there aren't many replies; seems I didn't satisfy what you want  
to have...

At first I want to mention that I just want to help the Debian project  
and started testing Debian Wheezy my old ia64 box.
Since these are my first messages on the kernel lists, I really don't  
feel me in a position to tell you what's right or wrong for the Kernel  
- I guess you have much more Linux Kernel knowledge than me.


> The firmware left the memory BAR at 0x24 cleared (0x00000000), but it
> also left the MEM bit in the command register disabled.  So it seems
> like a Linux bug that we're trying to use that zero address from the
> BAR.  If the firmware left the MEM or IO decode enable bit cleared,
> why would we assume it put anything useful in the corresponding BARs?

Your idea would be a fundamental change in the Kernel; I just want to  
fix the ata_piix problem in Debian Wheezy.

I can't tell you whether the developer of the EFI thought this. Maybe  
it is simply a bug.
If you would evaluate the command registers, which the BIOS or EFI has  
initialized, you would work around some wrong BARs. You might run into  
trouble due to wrong command register values instead.
Are you sure that any BIOS or EFI sets the command registers correctly?

Currently the Linux Kernel sets and clears the IORESOURCE_MEM and  
IORESOURCE_IO bits in the command registers as needed.
Windows reconfigures any PCI device. The settings of the BIOS or EFI  
do not matter at all; the user doesn't experience any BIOS bug at all.





> This still isn't very generic.  It only looks at BAR 5 and only for
> IDE controllers, so it fixes the problem for this device and this
> BIOS, but there's no reason the same problem couldn't happen on other
> devices and other BARs.
>
> My proposal was basically:
>
>     pci_read_config_word(dev, PCI_COMMAND, &cmd);
>     for (i = 0; i < 6; i++) {
>         /* read BAR i here */
>         r = dev->resource[i];
>         if (((r->flags & IORESOURCE_MEM) && (cmd & PCI_COMMAND_MEMORY)) ||
>             ((r->flags & IORESOURCE_IO) && (cmd & PCI_COMMAND_IO))) {
>             /* treat resource as valid */
>         } else {
>             /* treat resource as unassigned; try to assign it later */
>         }
>     }

Both of my two patches hide the BAR5 when we know that BAR5 is not functional.
The first patch makes sure that the PCI device id matches; the second  
one checks whether it is an ide controller in legacy mode. The  
associated ide/piix or ata/ata_piix doesn't need the BAR5 memory  
resource at all.
The other BARs are functional and needed.

I don't know what regression can occur when you hide *any*  
uninitialized BAR of *any* pci device. Some drivers might be screwed  
up when a needed mem resource is absend - after pci_enable_device() or  
pcim_enable_device() returned success.



Ben Hutchings of the Debian project pointed to some interesting detail  
about ide/piix:
"By the way, the reason the old IDE driver worked is that
drivers/ide/setup-pci.c has a fallback for this:

	if (pci_enable_device(dev)) {
		ret = pci_enable_device_io(dev);

It was added almost exactly 10 years ago without any specific comment."


Debian had both ide/piix and ata/ata_piix in the past. When ata_piix  
didn't initialize, ide/piix took over the device. The user didn't  
experience any problem.
The old ide/piix has been removed with recent Debian versions (due to  
problems with shared interrupts). Thus, the ICH4 problem is on the  
table again.


Since you don't want to take my patches, I need some new ideas. The  
patch shouldn't be a fundamental, experimental change with the risk of  
regression because it is intended for a *stable* Debian release.

Suggestions or comments are appreciated.

Stephan



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-24 17:09         ` Stephan Schreiber
  0 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-24 17:09 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

Mpfff, there aren't many replies; seems I didn't satisfy what you want  
to have...

At first I want to mention that I just want to help the Debian project  
and started testing Debian Wheezy my old ia64 box.
Since these are my first messages on the kernel lists, I really don't  
feel me in a position to tell you what's right or wrong for the Kernel  
- I guess you have much more Linux Kernel knowledge than me.


> The firmware left the memory BAR at 0x24 cleared (0x00000000), but it
> also left the MEM bit in the command register disabled.  So it seems
> like a Linux bug that we're trying to use that zero address from the
> BAR.  If the firmware left the MEM or IO decode enable bit cleared,
> why would we assume it put anything useful in the corresponding BARs?

Your idea would be a fundamental change in the Kernel; I just want to  
fix the ata_piix problem in Debian Wheezy.

I can't tell you whether the developer of the EFI thought this. Maybe  
it is simply a bug.
If you would evaluate the command registers, which the BIOS or EFI has  
initialized, you would work around some wrong BARs. You might run into  
trouble due to wrong command register values instead.
Are you sure that any BIOS or EFI sets the command registers correctly?

Currently the Linux Kernel sets and clears the IORESOURCE_MEM and  
IORESOURCE_IO bits in the command registers as needed.
Windows reconfigures any PCI device. The settings of the BIOS or EFI  
do not matter at all; the user doesn't experience any BIOS bug at all.





> This still isn't very generic.  It only looks at BAR 5 and only for
> IDE controllers, so it fixes the problem for this device and this
> BIOS, but there's no reason the same problem couldn't happen on other
> devices and other BARs.
>
> My proposal was basically:
>
>     pci_read_config_word(dev, PCI_COMMAND, &cmd);
>     for (i = 0; i < 6; i++) {
>         /* read BAR i here */
>         r = dev->resource[i];
>         if (((r->flags & IORESOURCE_MEM) && (cmd & PCI_COMMAND_MEMORY)) ||
>             ((r->flags & IORESOURCE_IO) && (cmd & PCI_COMMAND_IO))) {
>             /* treat resource as valid */
>         } else {
>             /* treat resource as unassigned; try to assign it later */
>         }
>     }

Both of my two patches hide the BAR5 when we know that BAR5 is not functional.
The first patch makes sure that the PCI device id matches; the second  
one checks whether it is an ide controller in legacy mode. The  
associated ide/piix or ata/ata_piix doesn't need the BAR5 memory  
resource at all.
The other BARs are functional and needed.

I don't know what regression can occur when you hide *any*  
uninitialized BAR of *any* pci device. Some drivers might be screwed  
up when a needed mem resource is absend - after pci_enable_device() or  
pcim_enable_device() returned success.



Ben Hutchings of the Debian project pointed to some interesting detail  
about ide/piix:
"By the way, the reason the old IDE driver worked is that
drivers/ide/setup-pci.c has a fallback for this:

	if (pci_enable_device(dev)) {
		ret = pci_enable_device_io(dev);

It was added almost exactly 10 years ago without any specific comment."


Debian had both ide/piix and ata/ata_piix in the past. When ata_piix  
didn't initialize, ide/piix took over the device. The user didn't  
experience any problem.
The old ide/piix has been removed with recent Debian versions (due to  
problems with shared interrupts). Thus, the ICH4 problem is on the  
table again.


Since you don't want to take my patches, I need some new ideas. The  
patch shouldn't be a fundamental, experimental change with the risk of  
regression because it is intended for a *stable* Debian release.

Suggestions or comments are appreciated.

Stephan



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-09-24 17:09         ` Stephan Schreiber
@ 2012-09-24 23:54           ` Bjorn Helgaas
  -1 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2012-09-24 23:54 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

On Mon, Sep 24, 2012 at 07:09:12PM +0200, Stephan Schreiber wrote:
> Mpfff, there aren't many replies; seems I didn't satisfy what you
> want to have...
> 
> At first I want to mention that I just want to help the Debian
> project and started testing Debian Wheezy my old ia64 box.

Thanks, I really appreciate that, and you've done a huge amount of
debugging and testing already.  It's very normal to iterate on the
resolution as we're doing now.

> >The firmware left the memory BAR at 0x24 cleared (0x00000000), but it
> >also left the MEM bit in the command register disabled.  So it seems
> >like a Linux bug that we're trying to use that zero address from the
> >BAR.  If the firmware left the MEM or IO decode enable bit cleared,
> >why would we assume it put anything useful in the corresponding BARs?
> 
> Your idea would be a fundamental change in the Kernel; I just want
> to fix the ata_piix problem in Debian Wheezy.

Right.  I think you've tripped over a rather fundamental issue, and
I'm hoping we can fix that.  If we can, that will help many users,
not just the handful who have this ia64 box.

> If you would evaluate the command registers, which the BIOS or EFI
> has initialized, you would work around some wrong BARs. You might
> run into trouble due to wrong command register values instead.
> Are you sure that any BIOS or EFI sets the command registers correctly?

We can't be 100% sure about things like that, of course.  But we do
know that if the MEM or IO bits are set in the command register, the
device will claim transactions that match whatever is in the BARs.
So setting the MEM or IO bit is a pretty strong statement that the
BAR contains a valid address.  If the BIOS leaves those bits clear,
we really can't conclude anything about the BAR contents.

> Currently the Linux Kernel sets and clears the IORESOURCE_MEM and
> IORESOURCE_IO bits in the command registers as needed.
> Windows reconfigures any PCI device. The settings of the BIOS or EFI
> do not matter at all; the user doesn't experience any BIOS bug at
> all.

On x86, Windows normally doesn't reconfigure PCI devices unless it
finds a problem with the configuration done by the BIOS.  I suspect
it works similarly on ia64.  I would guess that Windows noticed that
the MEM bit was not set, and therefore ignored the MEM BAR contents.

Can you try the following patch?  It's based on 3.6-rc5+, but I think
it will apply to your 3.2.23 kernel with minor conflicts that shouldn't
be too hard to resolve.

It's not quite right because we really shouldn't turn on the MEM or IO
decode bit unless *all* of the corresponding BARs have been set, but
in your case, I think there is only one MEM BAR that is an issue.

Bjorn




commit 9038dd3b3c4c9e4c7ca0118c8df398c4c646ab58
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Mon Sep 24 17:16:28 2012 -0600

    vsprintf: Add support for IORESOURCE_UNSET in %pR

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 0e33754..b6ceeee 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -600,7 +600,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
 	 * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
 #define RSRC_BUF_SIZE		((2 * sizeof(resource_size_t)) + 4)
 #define FLAG_BUF_SIZE		(2 * sizeof(res->flags))
-#define DECODED_BUF_SIZE	sizeof("[mem - 64bit pref window disabled]")
+#define DECODED_BUF_SIZE	sizeof("[mem - 64bit pref window unset disabled]")
 #define RAW_BUF_SIZE		sizeof("[mem - flags 0x]")
 	char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
 		     2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
@@ -642,6 +642,8 @@ char *resource_string(char *buf, char *end, struct resource *res,
 			p = string(p, pend, " pref", str_spec);
 		if (res->flags & IORESOURCE_WINDOW)
 			p = string(p, pend, " window", str_spec);
+		if (res->flags & IORESOURCE_UNSET)
+			p = string(p, pend, " unset", str_spec);
 		if (res->flags & IORESOURCE_DISABLED)
 			p = string(p, pend, " disabled", str_spec);
 	} else {

commit f4795a79dc370b6f4106768b16a4a9edba4df933
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Mon Sep 24 17:15:30 2012 -0600

    PCI: Ignore BAR contents when firmware left decoding disabled

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2396111..6926dcb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -175,9 +175,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 
 	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
+	pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);
+
 	/* No printks while decoding is disabled! */
 	if (!dev->mmio_always_on) {
-		pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);
 		pci_write_config_word(dev, PCI_COMMAND,
 			orig_cmd & ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
 	}
@@ -211,9 +212,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		if (res->flags & IORESOURCE_IO) {
 			l &= PCI_BASE_ADDRESS_IO_MASK;
 			mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT;
+			if (!(orig_cmd & PCI_COMMAND_IO))
+				res->flags |= IORESOURCE_UNSET;
 		} else {
 			l &= PCI_BASE_ADDRESS_MEM_MASK;
 			mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
+			if (!(orig_cmd & PCI_COMMAND_MEM))
+				res->flags |= IORESOURCE_UNSET;
 		}
 	} else {
 		res->flags |= (l & IORESOURCE_ROM_ENABLE);
@@ -248,6 +253,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			/* Address above 32-bit boundary; disable the BAR */
 			pci_write_config_dword(dev, pos, 0);
 			pci_write_config_dword(dev, pos + 4, 0);
+			res->flags |= IORESOURCE_UNSET;
 			region.start = 0;
 			region.end = sz64;
 			pcibios_bus_to_resource(dev, res, &region);

commit f90b82ab54efa462681d5dd99fd926f2563f7a93
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Mon Sep 24 17:28:21 2012 -0600

    PCI: Don't claim BARs that haven't been assigned

diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 81b88bd..9f9e31a 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -113,6 +113,9 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
 	struct resource *res = &dev->resource[resource];
 	struct resource *root, *conflict;
 
+	if (res->flags & IORESOURCE_UNSET)
+		return 0;
+
 	root = pci_find_parent_resource(dev, res);
 	if (!root) {
 		dev_info(&dev->dev, "no compatible bridge window for %pR\n",
@@ -334,6 +337,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
 
 		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
 			continue;
+		if (r->flags & IORESOURCE_UNSET)
+			continue;
 		if ((i == PCI_ROM_RESOURCE) &&
 				(!(r->flags & IORESOURCE_ROM_ENABLE)))
 			continue;

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-24 23:54           ` Bjorn Helgaas
  0 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2012-09-24 23:54 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

On Mon, Sep 24, 2012 at 07:09:12PM +0200, Stephan Schreiber wrote:
> Mpfff, there aren't many replies; seems I didn't satisfy what you
> want to have...
> 
> At first I want to mention that I just want to help the Debian
> project and started testing Debian Wheezy my old ia64 box.

Thanks, I really appreciate that, and you've done a huge amount of
debugging and testing already.  It's very normal to iterate on the
resolution as we're doing now.

> >The firmware left the memory BAR at 0x24 cleared (0x00000000), but it
> >also left the MEM bit in the command register disabled.  So it seems
> >like a Linux bug that we're trying to use that zero address from the
> >BAR.  If the firmware left the MEM or IO decode enable bit cleared,
> >why would we assume it put anything useful in the corresponding BARs?
> 
> Your idea would be a fundamental change in the Kernel; I just want
> to fix the ata_piix problem in Debian Wheezy.

Right.  I think you've tripped over a rather fundamental issue, and
I'm hoping we can fix that.  If we can, that will help many users,
not just the handful who have this ia64 box.

> If you would evaluate the command registers, which the BIOS or EFI
> has initialized, you would work around some wrong BARs. You might
> run into trouble due to wrong command register values instead.
> Are you sure that any BIOS or EFI sets the command registers correctly?

We can't be 100% sure about things like that, of course.  But we do
know that if the MEM or IO bits are set in the command register, the
device will claim transactions that match whatever is in the BARs.
So setting the MEM or IO bit is a pretty strong statement that the
BAR contains a valid address.  If the BIOS leaves those bits clear,
we really can't conclude anything about the BAR contents.

> Currently the Linux Kernel sets and clears the IORESOURCE_MEM and
> IORESOURCE_IO bits in the command registers as needed.
> Windows reconfigures any PCI device. The settings of the BIOS or EFI
> do not matter at all; the user doesn't experience any BIOS bug at
> all.

On x86, Windows normally doesn't reconfigure PCI devices unless it
finds a problem with the configuration done by the BIOS.  I suspect
it works similarly on ia64.  I would guess that Windows noticed that
the MEM bit was not set, and therefore ignored the MEM BAR contents.

Can you try the following patch?  It's based on 3.6-rc5+, but I think
it will apply to your 3.2.23 kernel with minor conflicts that shouldn't
be too hard to resolve.

It's not quite right because we really shouldn't turn on the MEM or IO
decode bit unless *all* of the corresponding BARs have been set, but
in your case, I think there is only one MEM BAR that is an issue.

Bjorn




commit 9038dd3b3c4c9e4c7ca0118c8df398c4c646ab58
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Mon Sep 24 17:16:28 2012 -0600

    vsprintf: Add support for IORESOURCE_UNSET in %pR

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 0e33754..b6ceeee 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -600,7 +600,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
 	 * 64-bit res (sizeof=8): 20 chars in dec, 18 in hex ("0x" + 16) */
 #define RSRC_BUF_SIZE		((2 * sizeof(resource_size_t)) + 4)
 #define FLAG_BUF_SIZE		(2 * sizeof(res->flags))
-#define DECODED_BUF_SIZE	sizeof("[mem - 64bit pref window disabled]")
+#define DECODED_BUF_SIZE	sizeof("[mem - 64bit pref window unset disabled]")
 #define RAW_BUF_SIZE		sizeof("[mem - flags 0x]")
 	char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
 		     2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
@@ -642,6 +642,8 @@ char *resource_string(char *buf, char *end, struct resource *res,
 			p = string(p, pend, " pref", str_spec);
 		if (res->flags & IORESOURCE_WINDOW)
 			p = string(p, pend, " window", str_spec);
+		if (res->flags & IORESOURCE_UNSET)
+			p = string(p, pend, " unset", str_spec);
 		if (res->flags & IORESOURCE_DISABLED)
 			p = string(p, pend, " disabled", str_spec);
 	} else {

commit f4795a79dc370b6f4106768b16a4a9edba4df933
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Mon Sep 24 17:15:30 2012 -0600

    PCI: Ignore BAR contents when firmware left decoding disabled

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2396111..6926dcb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -175,9 +175,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 
 	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
+	pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);
+
 	/* No printks while decoding is disabled! */
 	if (!dev->mmio_always_on) {
-		pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);
 		pci_write_config_word(dev, PCI_COMMAND,
 			orig_cmd & ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
 	}
@@ -211,9 +212,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		if (res->flags & IORESOURCE_IO) {
 			l &= PCI_BASE_ADDRESS_IO_MASK;
 			mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT;
+			if (!(orig_cmd & PCI_COMMAND_IO))
+				res->flags |= IORESOURCE_UNSET;
 		} else {
 			l &= PCI_BASE_ADDRESS_MEM_MASK;
 			mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
+			if (!(orig_cmd & PCI_COMMAND_MEM))
+				res->flags |= IORESOURCE_UNSET;
 		}
 	} else {
 		res->flags |= (l & IORESOURCE_ROM_ENABLE);
@@ -248,6 +253,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			/* Address above 32-bit boundary; disable the BAR */
 			pci_write_config_dword(dev, pos, 0);
 			pci_write_config_dword(dev, pos + 4, 0);
+			res->flags |= IORESOURCE_UNSET;
 			region.start = 0;
 			region.end = sz64;
 			pcibios_bus_to_resource(dev, res, &region);

commit f90b82ab54efa462681d5dd99fd926f2563f7a93
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Mon Sep 24 17:28:21 2012 -0600

    PCI: Don't claim BARs that haven't been assigned

diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 81b88bd..9f9e31a 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -113,6 +113,9 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
 	struct resource *res = &dev->resource[resource];
 	struct resource *root, *conflict;
 
+	if (res->flags & IORESOURCE_UNSET)
+		return 0;
+
 	root = pci_find_parent_resource(dev, res);
 	if (!root) {
 		dev_info(&dev->dev, "no compatible bridge window for %pR\n",
@@ -334,6 +337,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
 
 		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
 			continue;
+		if (r->flags & IORESOURCE_UNSET)
+			continue;
 		if ((i = PCI_ROM_RESOURCE) &&
 				(!(r->flags & IORESOURCE_ROM_ENABLE)))
 			continue;

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-09-24 23:54           ` Bjorn Helgaas
@ 2012-09-29 22:09             ` Stephan Schreiber
  -1 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-29 22:09 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

Hello Bjorn,
thank you very much for the patch.
I tested it; it works.

(typing mistake: it must read PCI_COMMAND_MEMORY instead of  
PCI_COMMAND_MEM at one location;
some hunks of the patch couldn't be applied automatically on Kernel  
3.2.23 because some comments in the contexts are different)

The dmesg output:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Fri Sep 28 21:57:11 CEST 2012
...
[    0.065510] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065524] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065535] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065546] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065556] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065567] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065578] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff unset]
...
[    1.391380] libata version 3.00 loaded.
[    1.391922] ata_piix 0000:00:1f.1: version 2.13
[    1.391938] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
[    1.392493] scsi0 : ata_piix
[    1.392886] scsi1 : ata_piix
[    1.393018] ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x1000 irq 34
[    1.393066] ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x1008 irq 33
[    1.557756] ata1.00: ATAPI: HL-DT-ST DVDRAM GSA-T40N, JR03, max UDMA/33
[    1.573616] ata1.00: configured for UDMA/33
[    1.579147] scsi 0:0:0:0: CD-ROM            HL-DT-ST DVDRAM  
GSA-T40N  JR03 PQ: 0 ANSI: 5
[    1.590806] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw  
xa/form2 cdda tray
[    1.590872] cdrom: Uniform CD-ROM driver Revision: 3.20
[    1.591272] sr 0:0:0:0: Attached scsi CD-ROM sr0
[    1.593910] sr 0:0:0:0: Attached scsi generic sg0 type 5
...


How is the chance to get this patch or a similar one into linux-next?



> On x86, Windows normally doesn't reconfigure PCI devices unless it
> finds a problem with the configuration done by the BIOS.  I suspect
> it works similarly on ia64.  I would guess that Windows noticed that
> the MEM bit was not set, and therefore ignored the MEM BAR contents.

Since I have the four Windows versions 'for Itanium Based Systems' on  
that box as well (XP, Server 2003, 2008, 2008 R2), I can tell you more:
The Device Manager shows a memory range FFBFFC00-FFBFFFFF for the  
"Intel 82801DB Ultra ATA Storage Controller-24CB" - on any of these  
Windows versions.


Stephan




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-09-29 22:09             ` Stephan Schreiber
  0 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-09-29 22:09 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

Hello Bjorn,
thank you very much for the patch.
I tested it; it works.

(typing mistake: it must read PCI_COMMAND_MEMORY instead of  
PCI_COMMAND_MEM at one location;
some hunks of the patch couldn't be applied automatically on Kernel  
3.2.23 because some comments in the contexts are different)

The dmesg output:
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)  
(debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) )  
#1 SMP Fri Sep 28 21:57:11 CEST 2012
...
[    0.065510] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065524] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065535] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065546] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065556] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065567] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065578] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff unset]
...
[    1.391380] libata version 3.00 loaded.
[    1.391922] ata_piix 0000:00:1f.1: version 2.13
[    1.391938] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
[    1.392493] scsi0 : ata_piix
[    1.392886] scsi1 : ata_piix
[    1.393018] ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x1000 irq 34
[    1.393066] ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x1008 irq 33
[    1.557756] ata1.00: ATAPI: HL-DT-ST DVDRAM GSA-T40N, JR03, max UDMA/33
[    1.573616] ata1.00: configured for UDMA/33
[    1.579147] scsi 0:0:0:0: CD-ROM            HL-DT-ST DVDRAM  
GSA-T40N  JR03 PQ: 0 ANSI: 5
[    1.590806] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw  
xa/form2 cdda tray
[    1.590872] cdrom: Uniform CD-ROM driver Revision: 3.20
[    1.591272] sr 0:0:0:0: Attached scsi CD-ROM sr0
[    1.593910] sr 0:0:0:0: Attached scsi generic sg0 type 5
...


How is the chance to get this patch or a similar one into linux-next?



> On x86, Windows normally doesn't reconfigure PCI devices unless it
> finds a problem with the configuration done by the BIOS.  I suspect
> it works similarly on ia64.  I would guess that Windows noticed that
> the MEM bit was not set, and therefore ignored the MEM BAR contents.

Since I have the four Windows versions 'for Itanium Based Systems' on  
that box as well (XP, Server 2003, 2008, 2008 R2), I can tell you more:
The Device Manager shows a memory range FFBFFC00-FFBFFFFF for the  
"Intel 82801DB Ultra ATA Storage Controller-24CB" - on any of these  
Windows versions.


Stephan




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-09-29 22:09             ` Stephan Schreiber
@ 2012-10-01 16:28               ` Bjorn Helgaas
  -1 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2012-10-01 16:28 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

On Sat, Sep 29, 2012 at 4:09 PM, Stephan Schreiber <info@fs-driver.org> wrote:
> Hello Bjorn,
> thank you very much for the patch.
> I tested it; it works.
>
> (typing mistake: it must read PCI_COMMAND_MEMORY instead of PCI_COMMAND_MEM
> at one location;
> some hunks of the patch couldn't be applied automatically on Kernel 3.2.23
> because some comments in the contexts are different)

Thanks a lot for testing this!  I'll fix up this typo and work on
getting something like this merged.

> The dmesg output:
>
> [    0.000000] Initializing cgroup subsys cpuset
> [    0.000000] Initializing cgroup subsys cpu
> [    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)
> (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) ) #1
> SMP Fri Sep 28 21:57:11 CEST 2012
> ...
> [    0.065510] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
> [    0.065524] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
> [    0.065535] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
> [    0.065546] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
> [    0.065556] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
> [    0.065567] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
> [    0.065578] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff unset]
> ...
> [    1.391380] libata version 3.00 loaded.
> [    1.391922] ata_piix 0000:00:1f.1: version 2.13
> [    1.391938] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
> [    1.392493] scsi0 : ata_piix
> [    1.392886] scsi1 : ata_piix
> [    1.393018] ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x1000 irq
> 34
> [    1.393066] ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x1008 irq
> 33
> [    1.557756] ata1.00: ATAPI: HL-DT-ST DVDRAM GSA-T40N, JR03, max UDMA/33
> [    1.573616] ata1.00: configured for UDMA/33
> [    1.579147] scsi 0:0:0:0: CD-ROM            HL-DT-ST DVDRAM GSA-T40N
> JR03 PQ: 0 ANSI: 5
> [    1.590806] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw xa/form2
> cdda tray
> [    1.590872] cdrom: Uniform CD-ROM driver Revision: 3.20
> [    1.591272] sr 0:0:0:0: Attached scsi CD-ROM sr0
> [    1.593910] sr 0:0:0:0: Attached scsi generic sg0 type 5
> ...

>> On x86, Windows normally doesn't reconfigure PCI devices unless it
>> finds a problem with the configuration done by the BIOS.  I suspect
>> it works similarly on ia64.  I would guess that Windows noticed that
>> the MEM bit was not set, and therefore ignored the MEM BAR contents.
>
>
> Since I have the four Windows versions 'for Itanium Based Systems' on that
> box as well (XP, Server 2003, 2008, 2008 R2), I can tell you more:
> The Device Manager shows a memory range FFBFFC00-FFBFFFFF for the "Intel
> 82801DB Ultra ATA Storage Controller-24CB" - on any of these Windows
> versions.

Oh, that's good data, thanks!  It looks like Windows noticed that the
BAR was invalid and assigned a valid resource to it.  That's in the
third aperture below:

ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-01])
pci_root PNP0A03:00: host bridge window [mem 0x000a0000-0x000fffff]
pci_root PNP0A03:00: host bridge window [mem 0xfa000000-0xfbffffff]
pci_root PNP0A03:00: host bridge window [mem 0xff000000-0xffffffff]
pci_root PNP0A03:00: host bridge window [mem 0xfec00000-0xfec0ffff]

Linux *should* probably do the same (though at a different actual
address because we assign bottom-up instead of top-down as Windows
does).  I don't know off the top of my head whether we actually do in
this case or not.

What's the output of "dmesg | grep 0000:00:1f.1; lspci -vs00:1f.1"?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-10-01 16:28               ` Bjorn Helgaas
  0 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2012-10-01 16:28 UTC (permalink / raw)
  To: Stephan Schreiber
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

On Sat, Sep 29, 2012 at 4:09 PM, Stephan Schreiber <info@fs-driver.org> wrote:
> Hello Bjorn,
> thank you very much for the patch.
> I tested it; it works.
>
> (typing mistake: it must read PCI_COMMAND_MEMORY instead of PCI_COMMAND_MEM
> at one location;
> some hunks of the patch couldn't be applied automatically on Kernel 3.2.23
> because some comments in the contexts are different)

Thanks a lot for testing this!  I'll fix up this typo and work on
getting something like this merged.

> The dmesg output:
>
> [    0.000000] Initializing cgroup subsys cpuset
> [    0.000000] Initializing cgroup subsys cpu
> [    0.000000] Linux version 3.2.0-3-mckinley (Debian 3.2.23-1)
> (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) ) #1
> SMP Fri Sep 28 21:57:11 CEST 2012
> ...
> [    0.065510] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
> [    0.065524] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
> [    0.065535] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
> [    0.065546] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
> [    0.065556] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
> [    0.065567] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
> [    0.065578] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff unset]
> ...
> [    1.391380] libata version 3.00 loaded.
> [    1.391922] ata_piix 0000:00:1f.1: version 2.13
> [    1.391938] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
> [    1.392493] scsi0 : ata_piix
> [    1.392886] scsi1 : ata_piix
> [    1.393018] ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x1000 irq
> 34
> [    1.393066] ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x1008 irq
> 33
> [    1.557756] ata1.00: ATAPI: HL-DT-ST DVDRAM GSA-T40N, JR03, max UDMA/33
> [    1.573616] ata1.00: configured for UDMA/33
> [    1.579147] scsi 0:0:0:0: CD-ROM            HL-DT-ST DVDRAM GSA-T40N
> JR03 PQ: 0 ANSI: 5
> [    1.590806] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw xa/form2
> cdda tray
> [    1.590872] cdrom: Uniform CD-ROM driver Revision: 3.20
> [    1.591272] sr 0:0:0:0: Attached scsi CD-ROM sr0
> [    1.593910] sr 0:0:0:0: Attached scsi generic sg0 type 5
> ...

>> On x86, Windows normally doesn't reconfigure PCI devices unless it
>> finds a problem with the configuration done by the BIOS.  I suspect
>> it works similarly on ia64.  I would guess that Windows noticed that
>> the MEM bit was not set, and therefore ignored the MEM BAR contents.
>
>
> Since I have the four Windows versions 'for Itanium Based Systems' on that
> box as well (XP, Server 2003, 2008, 2008 R2), I can tell you more:
> The Device Manager shows a memory range FFBFFC00-FFBFFFFF for the "Intel
> 82801DB Ultra ATA Storage Controller-24CB" - on any of these Windows
> versions.

Oh, that's good data, thanks!  It looks like Windows noticed that the
BAR was invalid and assigned a valid resource to it.  That's in the
third aperture below:

ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-01])
pci_root PNP0A03:00: host bridge window [mem 0x000a0000-0x000fffff]
pci_root PNP0A03:00: host bridge window [mem 0xfa000000-0xfbffffff]
pci_root PNP0A03:00: host bridge window [mem 0xff000000-0xffffffff]
pci_root PNP0A03:00: host bridge window [mem 0xfec00000-0xfec0ffff]

Linux *should* probably do the same (though at a different actual
address because we assign bottom-up instead of top-down as Windows
does).  I don't know off the top of my head whether we actually do in
this case or not.

What's the output of "dmesg | grep 0000:00:1f.1; lspci -vs00:1f.1"?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
  2012-10-01 16:28               ` Bjorn Helgaas
@ 2012-10-02 19:48                 ` Stephan Schreiber
  -1 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-10-02 19:48 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

> Thanks a lot for testing this!  I'll fix up this typo and work on
> getting something like this merged.

Thank you very much!
If you want me to test anything, don't hesitate to contact me.


> What's the output of "dmesg | grep 0000:00:1f.1; lspci -vs00:1f.1"?

[    0.065506] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065520] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065531] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065542] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065553] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065564] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065575] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff unset]
[    1.415250] ata_piix 0000:00:1f.1: version 2.13
[    1.415276] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller  
(rev 02) (prog-if 8a [Master SecP PriP])
	Subsystem: Intel Corporation Device 3404
	Flags: bus master, medium devsel, latency 0
	I/O ports at 01f0 [size=8]
	I/O ports at 03f4 [size=1]
	I/O ports at 0170 [size=8]
	I/O ports at 0374 [size=1]
	I/O ports at 1000 [size=16]
	Kernel driver in use: ata_piix




Stephan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC/PATCH v2] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource
@ 2012-10-02 19:48                 ` Stephan Schreiber
  0 siblings, 0 replies; 22+ messages in thread
From: Stephan Schreiber @ 2012-10-02 19:48 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Alan Cox, linux-ia64, linux-pci, linux-ide, linux-kernel, 679545,
	jrnieder

> Thanks a lot for testing this!  I'll fix up this typo and work on
> getting something like this merged.

Thank you very much!
If you want me to test anything, don't hesitate to contact me.


> What's the output of "dmesg | grep 0000:00:1f.1; lspci -vs00:1f.1"?

[    0.065506] pci 0000:00:1f.1: [8086:24cb] type 0 class 0x000101
[    0.065520] pci 0000:00:1f.1: reg 10: [io  0x0000-0x0007]
[    0.065531] pci 0000:00:1f.1: reg 14: [io  0x0000-0x0003]
[    0.065542] pci 0000:00:1f.1: reg 18: [io  0x0000-0x0007]
[    0.065553] pci 0000:00:1f.1: reg 1c: [io  0x0000-0x0003]
[    0.065564] pci 0000:00:1f.1: reg 20: [io  0x1000-0x100f]
[    0.065575] pci 0000:00:1f.1: reg 24: [mem 0x00000000-0x000003ff unset]
[    1.415250] ata_piix 0000:00:1f.1: version 2.13
[    1.415276] ata_piix 0000:00:1f.1: can't derive routing for PCI INT A
00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller  
(rev 02) (prog-if 8a [Master SecP PriP])
	Subsystem: Intel Corporation Device 3404
	Flags: bus master, medium devsel, latency 0
	I/O ports at 01f0 [size=8]
	I/O ports at 03f4 [size=1]
	I/O ports at 0170 [size=8]
	I/O ports at 0374 [size=1]
	I/O ports at 1000 [size\x16]
	Kernel driver in use: ata_piix




Stephan





^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2012-10-02 19:48 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-16 16:39 Bug#679545: [RFC/PATCH] ia64, SR870, EFI bug breaks ata_piix, uninitialized ICH4 IDE EXBAR mem resource Stephan Schreiber
2012-09-16 16:39 ` Stephan Schreiber
2012-09-16 16:39 ` Stephan Schreiber
2012-09-17 10:56 ` Alan Cox
2012-09-17 10:56   ` Alan Cox
2012-09-20 14:16   ` Bug#679545: [RFC/PATCH v2] " Stephan Schreiber
2012-09-20 14:16     ` Stephan Schreiber
2012-09-20 14:16     ` Stephan Schreiber
2012-09-20 16:02     ` Bjorn Helgaas
2012-09-20 16:02       ` Bjorn Helgaas
2012-09-24 17:09       ` Stephan Schreiber
2012-09-24 17:09         ` Stephan Schreiber
2012-09-24 23:54         ` Bjorn Helgaas
2012-09-24 23:54           ` Bjorn Helgaas
2012-09-29 22:09           ` Stephan Schreiber
2012-09-29 22:09             ` Stephan Schreiber
2012-10-01 16:28             ` Bjorn Helgaas
2012-10-01 16:28               ` Bjorn Helgaas
2012-10-02 19:48               ` Stephan Schreiber
2012-10-02 19:48                 ` Stephan Schreiber
2012-09-17 21:41 ` [RFC/PATCH] " Bjorn Helgaas
2012-09-17 21:41   ` Bjorn Helgaas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.