From 20df429dd6671804999493baf2952f82582869fa Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 10 Oct 2008 22:39:35 +0200 Subject: 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 . Also, check only BAR0/2 resources since those are guaranteed by the workaround in drivers/pci/probe.c:pci_setup_device(). Signed-off-by: Borislav Petkov Acked-by: Sergei Shtylyov Cc: Alan Cox [bart: trivial printk() fixups] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-generic.c | 55 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) (limited to 'drivers/ide/ide-generic.c') diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 8fe8b5b9cf7d..0a3cb0c33ae5 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c @@ -19,6 +19,7 @@ #include #include #include +#include /* 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,65 @@ 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_INFO DRV_NAME ": enforcing probing of I/O ports " + "upon user request\n"); memset(hws, 0, sizeof(hw_regs_t *) * MAX_HWIFS); -- cgit v1.2.3 From 6ccc6d7ecbb427580d045699e434bc5c6f45e227 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:42 +0200 Subject: ide-generic: no need to probe all ports at once Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-generic.c | 47 ++++++++++++----------------------------------- 1 file changed, 12 insertions(+), 35 deletions(-) (limited to 'drivers/ide/ide-generic.c') diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 0a3cb0c33ae5..3104dc8d5b61 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c @@ -137,10 +137,9 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary) static int __init ide_generic_init(void) { - hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS]; - struct ide_host *host; + hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; unsigned long io_addr; - int i, rc, primary = 0, secondary = 0; + int i, rc = 0, primary = 0, secondary = 0; #ifdef CONFIG_MIPS if (!ide_probe_legacy()) @@ -161,13 +160,9 @@ static int __init ide_generic_init(void) printk(KERN_INFO DRV_NAME ": enforcing probing of I/O ports " "upon user request\n"); - memset(hws, 0, sizeof(hw_regs_t *) * MAX_HWIFS); - for (i = 0; i < ARRAY_SIZE(legacy_bases); i++) { io_addr = legacy_bases[i]; - hws[i] = NULL; - if ((probe_mask & (1 << i)) && io_addr) { if (!request_region(io_addr, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX " @@ -184,45 +179,27 @@ static int __init ide_generic_init(void) continue; } - memset(&hw[i], 0, sizeof(hw[i])); - ide_std_init_ports(&hw[i], io_addr, io_addr + 0x206); + memset(&hw, 0, sizeof(hw)); + ide_std_init_ports(&hw, io_addr, io_addr + 0x206); #ifdef CONFIG_IA64 - hw[i].irq = isa_irq_to_vector(legacy_irqs[i]); + hw.irq = isa_irq_to_vector(legacy_irqs[i]); #else - hw[i].irq = legacy_irqs[i]; + hw.irq = legacy_irqs[i]; #endif - hw[i].chipset = ide_generic; + hw.chipset = ide_generic; - hws[i] = &hw[i]; + rc = ide_host_add(NULL, hws, NULL); + if (rc) { + release_region(io_addr + 0x206, 1); + release_region(io_addr, 8); + } } } - host = ide_host_alloc_all(NULL, hws); - if (host == NULL) { - rc = -ENOMEM; - goto err; - } - - rc = ide_host_register(host, NULL, hws); - if (rc) - goto err_free; - if (ide_generic_sysfs_init()) printk(KERN_ERR DRV_NAME ": failed to create ide_generic " "class\n"); - return 0; -err_free: - ide_host_free(host); -err: - for (i = 0; i < MAX_HWIFS; i++) { - if (hws[i] == NULL) - continue; - - io_addr = hws[i]->io_ports.data_addr; - release_region(io_addr + 0x206, 1); - release_region(io_addr, 8); - } return rc; } -- cgit v1.2.3 From cf4049103be931fca133f66b3181490284a521c6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:42 +0200 Subject: ide-generic: remove no longer needed ide_probe_legacy() There is now a generic solution [ide_generic_check_pci_legacy_iobases()] so MIPS-specific ide_probe_legacy() is no longer necessary. Cc: Ralf Baechle Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-generic.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/ide/ide-generic.c') diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 3104dc8d5b61..81a5282ce1eb 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c @@ -141,10 +141,6 @@ static int __init ide_generic_init(void) unsigned long io_addr; int i, rc = 0, primary = 0, secondary = 0; -#ifdef CONFIG_MIPS - if (!ide_probe_legacy()) - return -ENODEV; -#endif ide_generic_check_pci_legacy_iobases(&primary, &secondary); if (!probe_mask) { -- cgit v1.2.3