diff options
Diffstat (limited to 'drivers/misc/hpilo.c')
| -rw-r--r-- | drivers/misc/hpilo.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 6df0da4085e..b83e3ca12a4 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -30,7 +30,7 @@ static struct class *ilo_class; static unsigned int ilo_major; -static unsigned int max_ccb = MIN_CCB; +static unsigned int max_ccb = 16; static char ilo_hwdev[MAX_ILO_DEV]; static inline int get_entry_id(int entry) @@ -686,7 +686,7 @@ static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) pci_iounmap(pdev, hw->mmio_vaddr); } -static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) +static int ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) { int error = -ENOMEM; @@ -725,6 +725,9 @@ static void ilo_remove(struct pci_dev *pdev) int i, minor; struct ilo_hwinfo *ilo_hw = pci_get_drvdata(pdev); + if (!ilo_hw) + return; + clear_device(ilo_hw); minor = MINOR(ilo_hw->cdev.dev); @@ -736,17 +739,28 @@ static void ilo_remove(struct pci_dev *pdev) free_irq(pdev->irq, ilo_hw); ilo_unmap_device(pdev, ilo_hw); pci_release_regions(pdev); - pci_disable_device(pdev); + /* + * pci_disable_device(pdev) used to be here. But this PCI device has + * two functions with interrupt lines connected to a single pin. The + * other one is a USB host controller. So when we disable the PIN here + * e.g. by rmmod hpilo, the controller stops working. It is because + * the interrupt link is disabled in ACPI since it is not refcounted + * yet. See acpi_pci_link_free_irq called from acpi_pci_irq_disable. + */ kfree(ilo_hw); ilo_hwdev[(minor / max_ccb)] = 0; } -static int __devinit ilo_probe(struct pci_dev *pdev, +static int ilo_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int devnum, minor, start, error; + int devnum, minor, start, error = 0; struct ilo_hwinfo *ilo_hw; + /* Ignore subsystem_device = 0x1979 (set by BIOS) */ + if (pdev->subsystem_device == 0x1979) + return 0; + if (max_ccb > MAX_CCB) max_ccb = MAX_CCB; else if (max_ccb < MIN_CCB) @@ -826,7 +840,7 @@ unmap: free_regions: pci_release_regions(pdev); disable: - pci_disable_device(pdev); +/* pci_disable_device(pdev); see comment in ilo_remove */ free: kfree(ilo_hw); out: @@ -845,7 +859,7 @@ static struct pci_driver ilo_driver = { .name = ILO_NAME, .id_table = ilo_devices, .probe = ilo_probe, - .remove = __devexit_p(ilo_remove), + .remove = ilo_remove, }; static int __init ilo_init(void) @@ -885,14 +899,14 @@ static void __exit ilo_exit(void) class_destroy(ilo_class); } -MODULE_VERSION("1.3"); +MODULE_VERSION("1.4.1"); MODULE_ALIAS(ILO_NAME); MODULE_DESCRIPTION(ILO_NAME); MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); MODULE_LICENSE("GPL v2"); module_param(max_ccb, uint, 0444); -MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (8)"); +MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (16)"); module_init(ilo_init); module_exit(ilo_exit); |
