From 9863be598ed068613996af8da71d9fd976a0ab2d Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 10 Jan 2007 23:15:41 -0800 Subject: [PATCH] intel-rng workarounds Add a load option to intel-rng to allow skipping the FWH detection, necessary in case the BIOS has locked read-only the firmware hub space. Also prevent any attempt to write to firmware space if it cannot be write enabled (apparently caused hangs on some systems not having an FWH and thus also not having a respective RNG). Signed-off-by: Jan Beulich Signed-off-by: Michael Buesch Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hw_random/intel-rng.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'drivers/char/hw_random') diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 8efbc9c0e545..154ce3e6b3c9 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c @@ -143,6 +143,11 @@ static const struct pci_device_id pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, pci_tbl); +static __initdata int no_fwh_detect; +module_param(no_fwh_detect, int, 0); +MODULE_PARM_DESC(no_fwh_detect, "Skip FWH detection:\n" + " positive value - skip if FWH space locked read-only\n" + " negative value - skip always"); static inline u8 hwstatus_get(void __iomem *mem) { @@ -240,6 +245,11 @@ static int __init mod_init(void) if (!dev) goto out; /* Device not found. */ + if (no_fwh_detect < 0) { + pci_dev_put(dev); + goto fwh_done; + } + /* Check for Intel 82802 */ if (dev->device < 0x2640) { fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD; @@ -252,6 +262,23 @@ static int __init mod_init(void) pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val); pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val); + if ((bios_cntl_val & + (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) + == BIOS_CNTL_LOCK_ENABLE_MASK) { + static __initdata /*const*/ char warning[] = + KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n" + KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n" + KERN_WARNING PFX "you are certain that your system has a functional\n" + KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n"; + + pci_dev_put(dev); + if (no_fwh_detect) + goto fwh_done; + printk(warning); + err = -EBUSY; + goto out; + } + mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); if (mem == NULL) { pci_dev_put(dev); @@ -280,8 +307,7 @@ static int __init mod_init(void) pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val | FWH_F8_EN_MASK); - if (!(bios_cntl_val & - (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))) + if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK)) pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK); @@ -315,6 +341,8 @@ static int __init mod_init(void) goto out; } +fwh_done: + err = -ENOMEM; mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); if (!mem) -- cgit v1.2.3 From 56fb5fe9f16f630e3ee663c47c5aff26ac424d05 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Wed, 10 Jan 2007 23:15:43 -0800 Subject: [PATCH] Fix HWRNG built-in initcalls priority This changes all HWRNG driver initcalls to module_init(). We must probe the RNGs after the major kernel subsystems are already up and running (like PCI). This fixes Bug 7730. http://bugzilla.kernel.org/show_bug.cgi?id=7730 Signed-off-by: Michael Buesch Cc: Jan Beulich Cc: Jeff Garzik Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hw_random/amd-rng.c | 2 +- drivers/char/hw_random/geode-rng.c | 2 +- drivers/char/hw_random/intel-rng.c | 2 +- drivers/char/hw_random/ixp4xx-rng.c | 2 +- drivers/char/hw_random/via-rng.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/char/hw_random') diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c index 71e4e0f3fd54..556fd81fa815 100644 --- a/drivers/char/hw_random/amd-rng.c +++ b/drivers/char/hw_random/amd-rng.c @@ -144,7 +144,7 @@ static void __exit mod_exit(void) hwrng_unregister(&amd_rng); } -subsys_initcall(mod_init); +module_init(mod_init); module_exit(mod_exit); MODULE_AUTHOR("The Linux Kernel team"); diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c index d37ced0d132b..8e8658dcd2e3 100644 --- a/drivers/char/hw_random/geode-rng.c +++ b/drivers/char/hw_random/geode-rng.c @@ -125,7 +125,7 @@ static void __exit mod_exit(void) iounmap(mem); } -subsys_initcall(mod_init); +module_init(mod_init); module_exit(mod_exit); MODULE_DESCRIPTION("H/W RNG driver for AMD Geode LX CPUs"); diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 154ce3e6b3c9..f22e78e3c70f 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c @@ -378,7 +378,7 @@ static void __exit mod_exit(void) iounmap(mem); } -subsys_initcall(mod_init); +module_init(mod_init); module_exit(mod_exit); MODULE_DESCRIPTION("H/W RNG driver for Intel chipsets"); diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c index c9caff57db85..bab43ca32ac1 100644 --- a/drivers/char/hw_random/ixp4xx-rng.c +++ b/drivers/char/hw_random/ixp4xx-rng.c @@ -64,7 +64,7 @@ static void __exit ixp4xx_rng_exit(void) iounmap(rng_base); } -subsys_initcall(ixp4xx_rng_init); +module_init(ixp4xx_rng_init); module_exit(ixp4xx_rng_exit); MODULE_AUTHOR("Deepak Saxena "); diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index 0e786b617bb8..9ebf84d18655 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c @@ -176,7 +176,7 @@ static void __exit mod_exit(void) hwrng_unregister(&via_rng); } -subsys_initcall(mod_init); +module_init(mod_init); module_exit(mod_exit); MODULE_DESCRIPTION("H/W RNG driver for VIA chipsets"); -- cgit v1.2.3