static void intel_rng_cleanup(struct hwrng *rng) { void __iomem *mem = (void __iomem *)rng->priv; u8 hw_status; hw_status = hwstatus_get(mem); if (hw_status & INTEL_RNG_ENABLED) hwstatus_set(mem, hw_status & ~INTEL_RNG_ENABLED); else printk(KERN_WARNING PFX "unusual: RNG already disabled\n"); }
static int intel_rng_init(struct hwrng *rng) { void __iomem *mem = (void __iomem *)rng->priv; u8 hw_status; int err = -EIO; hw_status = hwstatus_get(mem); if ((hw_status & INTEL_RNG_ENABLED) == 0) hw_status = hwstatus_set(mem, hw_status | INTEL_RNG_ENABLED); if ((hw_status & INTEL_RNG_ENABLED) == 0) { printk(KERN_ERR PFX "cannot enable RNG, aborting\n"); goto out; } err = 0; out: return err; }
static int __init mod_init(void) { int err = -ENODEV; int i; struct pci_dev *dev = NULL; void __iomem *mem = mem; u8 hw_status; struct intel_rng_hw *intel_rng_hw; for (i = 0; !dev && pci_tbl[i].vendor; ++i) dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL); if (!dev) goto out; if (no_fwh_detect < 0) { pci_dev_put(dev); goto fwh_done; } intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL); if (!intel_rng_hw) { pci_dev_put(dev); goto out; } err = intel_init_hw_struct(intel_rng_hw, dev); if (err) { pci_dev_put(dev); kfree(intel_rng_hw); if (err == -ENODEV) goto fwh_done; goto out; } err = stop_machine(intel_rng_hw_init, intel_rng_hw, NULL); pci_dev_put(dev); iounmap(intel_rng_hw->mem); kfree(intel_rng_hw); if (err) goto out; fwh_done: err = -ENOMEM; mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); if (!mem) goto out; intel_rng.priv = (unsigned long)mem; err = -ENODEV; hw_status = hwstatus_get(mem); if ((hw_status & INTEL_RNG_PRESENT) == 0) { iounmap(mem); goto out; } printk(KERN_INFO "Intel 82802 RNG detected\n"); err = hwrng_register(&intel_rng); if (err) { printk(KERN_ERR PFX "RNG registering failed (%d)\n", err); iounmap(mem); } out: return err; }
static inline u8 hwstatus_set(void __iomem *mem, u8 hw_status) { writeb(hw_status, mem + INTEL_RNG_HW_STATUS); return hwstatus_get(mem); }
static int __init mod_init(void) { int err = -ENODEV; int i; struct pci_dev *dev = NULL; void __iomem *mem = mem; u8 hw_status; struct intel_rng_hw *intel_rng_hw; for (i = 0; !dev && pci_tbl[i].vendor; ++i) dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL); if (!dev) goto out; /* Device not found. */ if (no_fwh_detect < 0) { pci_dev_put(dev); goto fwh_done; } intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL); if (!intel_rng_hw) { pci_dev_put(dev); goto out; } err = intel_init_hw_struct(intel_rng_hw, dev); if (err) { pci_dev_put(dev); kfree(intel_rng_hw); if (err == -ENODEV) goto fwh_done; goto out; } /* * Since the BIOS code/data is going to disappear from its normal * location with the Read ID command, all activity on the system * must be stopped until the state is back to normal. * * Use stop_machine because IPIs can be blocked by disabling * interrupts. */ err = stop_machine(intel_rng_hw_init, intel_rng_hw, NULL); pci_dev_put(dev); iounmap(intel_rng_hw->mem); kfree(intel_rng_hw); if (err) goto out; fwh_done: err = -ENOMEM; mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); if (!mem) goto out; intel_rng.priv = (unsigned long)mem; /* Check for Random Number Generator */ err = -ENODEV; hw_status = hwstatus_get(mem); if ((hw_status & INTEL_RNG_PRESENT) == 0) { iounmap(mem); goto out; } printk(KERN_INFO "Intel 82802 RNG detected\n"); err = hwrng_register(&intel_rng); if (err) { printk(KERN_ERR PFX "RNG registering failed (%d)\n", err); iounmap(mem); } out: return err; }