Thread (44 messages) 44 messages, 5 authors, 2008-08-08
STALE6548d

[PATCH] ide-generic: handle probing of legacy io-ports v5 (was: Re: [PATCH 1/2] pata_legacy: export functionality to ide)

From: Borislav Petkov <hidden>
Date: 2008-08-07 04:38:27
Also in: lkml
Subsystem: the rest · Maintainer: Linus Torvalds

On Thu, Aug 07, 2008 at 12:04:19AM +0400, Sergei Shtylyov wrote:

[.. ]
quoted
quoted
quoted
quoted
Would have been probably enough to test only BAR0/2, don't you think?
quoted
quoted
quoted
I assume you're referring to the legacy ioports fixup in
drivers/pci/probe.c:pci_setup_device().
quoted
quoted
  And to the fact that the value 0x1f0 should only be ever seen in 
BAR0 and 0x170 in BAR2 even if they would have been read off the 
chips (some chips have these values reading back even in legacy mode, 
and even could malfunction if other values are written there), not 
fixed up there, and certainly not in BAR1 or BAR3, so it's quite 
pointless to look in these BARs too.
quoted
So the comment in there saying that in some cases BAR0-3 could contain junk is a
bogus?
   Don't know. The PCI IDE spec. said that those should be 0 in 
compatibility mode but I know that some controllers require the standard 
values of 0x1[f7]0 to be in BAR0/2 in compatibility mode. If my memory 
serves, NatSemi PC8741x were ones of those...
quoted
In other words, can we assume that one will always read 0x1f0 from BAR0
and 0x170 from BAR2 in compatibility mode.
   Certainly not. We can only rely on the workaround putting 0x1[f7]0 in 
the resources 0/2.
quoted
If so, the check is even simpler:
quoted
	if (pci_resource_start(p, 0) == 0x1f0)
		*primary = 1;
	if (pci_resource_start(p, 2) == 0x170)
		*secondary = 1;
   Yes, I think that should be enough...
Here's v5:

---
From: Borislav Petkov <redacted>
Date: Sun, 3 Aug 2008 18:46:35 +0200
Subject: [PATCH] ide-generic: handle probing of legacy io-ports v5

Avoid probing the io-ports in case an IDE PCI controller is present and it
uses the legacy iobases. If we still want to enforce the probing, we do

ide_generic.probe_mask=0x3f

on the kernel command line. The iobase checking code is
adapted from drivers/ata/pata_legacy.c after converting hex
pci ids into their corresponding macros in <linux/pci_ids.h>.

Also, check only BAR0/2 resources since those are guaranteed
by the workaround in drivers/pci/probe.c:pci_setup_device().

CC: Sergei Shtylyov <redacted>
Signed-off-by: Borislav Petkov <redacted>
---
 drivers/ide/ide-generic.c |   56 +++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 8fe8b5b..608f353 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/ide.h>
+#include <linux/pci_ids.h>
 
 /* FIXME: convert m32r to use ide_platform host driver */
 #ifdef CONFIG_M32R
@@ -27,7 +28,7 @@
 
 #define DRV_NAME	"ide_generic"
 
-static int probe_mask = 0x03;
+static int probe_mask;
 module_param(probe_mask, int, 0);
 MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
 
@@ -100,19 +101,66 @@ static const u16 legacy_bases[] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 };
 static const int legacy_irqs[]  = { 14, 15, 11, 10, 8, 12 };
 #endif
 
+static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
+{
+	struct pci_dev *p = NULL;
+	u16 val;
+
+	for_each_pci_dev(p) {
+
+		if (pci_resource_start(p, 0) == 0x1f0)
+			*primary = 1;
+		if (pci_resource_start(p, 2) == 0x170)
+			*secondary = 1;
+
+		/* Cyrix CS55{1,2}0 pre SFF MWDMA ATA on the bridge */
+		if (p->vendor == PCI_VENDOR_ID_CYRIX &&
+		    (p->device == PCI_DEVICE_ID_CYRIX_5510 ||
+		     p->device == PCI_DEVICE_ID_CYRIX_5520))
+			*primary = *secondary = 1;
+
+		/* Intel MPIIX - PIO ATA on non PCI side of bridge */
+		if (p->vendor == PCI_VENDOR_ID_INTEL &&
+		    p->device == PCI_DEVICE_ID_INTEL_82371MX) {
+
+			pci_read_config_word(p, 0x6C, &val);
+			if (val & 0x8000) {
+				/* ATA port enabled */
+				if (val & 0x4000)
+					*secondary = 1;
+				else
+					*primary = 1;
+			}
+		}
+	}
+}
+
 static int __init ide_generic_init(void)
 {
 	hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS];
 	struct ide_host *host;
 	unsigned long io_addr;
-	int i, rc;
+	int i, rc, primary = 0, secondary = 0;
 
 #ifdef CONFIG_MIPS
 	if (!ide_probe_legacy())
 		return -ENODEV;
 #endif
-	printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module "
-			 "parameter for probing all legacy ISA IDE ports\n");
+	ide_generic_check_pci_legacy_iobases(&primary, &secondary);
+
+	if (!probe_mask) {
+		printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" "
+		     "module parameter for probing all legacy ISA IDE ports\n");
+
+		if (primary == 0)
+			probe_mask |= 0x1;
+
+		if (secondary == 0)
+			probe_mask |= 0x2;
+	} else {
+		printk(KERN_WARNING "%s: enforcing probing of io ports upon "
+			"user request.\n", DRV_NAME);
+	}
 
 	memset(hws, 0, sizeof(hw_regs_t *) * MAX_HWIFS);
 
-- 
1.5.5.4

-- 
Regards/Gruss,
    Boris.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help