diff options
Diffstat (limited to 'drivers/misc/hpilo.c')
| -rw-r--r-- | drivers/misc/hpilo.c | 33 | 
1 files changed, 21 insertions, 12 deletions
| diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index fffc227181b0..6df0da4085e3 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | static struct class *ilo_class; | 31 | static struct class *ilo_class; | 
| 32 | static unsigned int ilo_major; | 32 | static unsigned int ilo_major; | 
| 33 | static unsigned int max_ccb = MIN_CCB; | ||
| 33 | static char ilo_hwdev[MAX_ILO_DEV]; | 34 | static char ilo_hwdev[MAX_ILO_DEV]; | 
| 34 | 35 | ||
| 35 | static inline int get_entry_id(int entry) | 36 | static inline int get_entry_id(int entry) | 
| @@ -424,7 +425,7 @@ static void ilo_set_reset(struct ilo_hwinfo *hw) | |||
| 424 | * Mapped memory is zeroed on ilo reset, so set a per ccb flag | 425 | * Mapped memory is zeroed on ilo reset, so set a per ccb flag | 
| 425 | * to indicate that this ccb needs to be closed and reopened. | 426 | * to indicate that this ccb needs to be closed and reopened. | 
| 426 | */ | 427 | */ | 
| 427 | for (slot = 0; slot < MAX_CCB; slot++) { | 428 | for (slot = 0; slot < max_ccb; slot++) { | 
| 428 | if (!hw->ccb_alloc[slot]) | 429 | if (!hw->ccb_alloc[slot]) | 
| 429 | continue; | 430 | continue; | 
| 430 | set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb); | 431 | set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb); | 
| @@ -535,7 +536,7 @@ static int ilo_close(struct inode *ip, struct file *fp) | |||
| 535 | struct ilo_hwinfo *hw; | 536 | struct ilo_hwinfo *hw; | 
| 536 | unsigned long flags; | 537 | unsigned long flags; | 
| 537 | 538 | ||
| 538 | slot = iminor(ip) % MAX_CCB; | 539 | slot = iminor(ip) % max_ccb; | 
| 539 | hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); | 540 | hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); | 
| 540 | 541 | ||
| 541 | spin_lock(&hw->open_lock); | 542 | spin_lock(&hw->open_lock); | 
| @@ -566,7 +567,7 @@ static int ilo_open(struct inode *ip, struct file *fp) | |||
| 566 | struct ilo_hwinfo *hw; | 567 | struct ilo_hwinfo *hw; | 
| 567 | unsigned long flags; | 568 | unsigned long flags; | 
| 568 | 569 | ||
| 569 | slot = iminor(ip) % MAX_CCB; | 570 | slot = iminor(ip) % max_ccb; | 
| 570 | hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); | 571 | hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); | 
| 571 | 572 | ||
| 572 | /* new ccb allocation */ | 573 | /* new ccb allocation */ | 
| @@ -663,7 +664,7 @@ static irqreturn_t ilo_isr(int irq, void *data) | |||
| 663 | ilo_set_reset(hw); | 664 | ilo_set_reset(hw); | 
| 664 | } | 665 | } | 
| 665 | 666 | ||
| 666 | for (i = 0; i < MAX_CCB; i++) { | 667 | for (i = 0; i < max_ccb; i++) { | 
| 667 | if (!hw->ccb_alloc[i]) | 668 | if (!hw->ccb_alloc[i]) | 
| 668 | continue; | 669 | continue; | 
| 669 | if (pending & (1 << i)) | 670 | if (pending & (1 << i)) | 
| @@ -697,14 +698,14 @@ static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) | |||
| 697 | } | 698 | } | 
| 698 | 699 | ||
| 699 | /* map the adapter shared memory region */ | 700 | /* map the adapter shared memory region */ | 
| 700 | hw->ram_vaddr = pci_iomap(pdev, 2, MAX_CCB * ILOHW_CCB_SZ); | 701 | hw->ram_vaddr = pci_iomap(pdev, 2, max_ccb * ILOHW_CCB_SZ); | 
| 701 | if (hw->ram_vaddr == NULL) { | 702 | if (hw->ram_vaddr == NULL) { | 
| 702 | dev_err(&pdev->dev, "Error mapping shared mem\n"); | 703 | dev_err(&pdev->dev, "Error mapping shared mem\n"); | 
| 703 | goto mmio_free; | 704 | goto mmio_free; | 
| 704 | } | 705 | } | 
| 705 | 706 | ||
| 706 | /* map the doorbell aperture */ | 707 | /* map the doorbell aperture */ | 
| 707 | hw->db_vaddr = pci_iomap(pdev, 3, MAX_CCB * ONE_DB_SIZE); | 708 | hw->db_vaddr = pci_iomap(pdev, 3, max_ccb * ONE_DB_SIZE); | 
| 708 | if (hw->db_vaddr == NULL) { | 709 | if (hw->db_vaddr == NULL) { | 
| 709 | dev_err(&pdev->dev, "Error mapping doorbell\n"); | 710 | dev_err(&pdev->dev, "Error mapping doorbell\n"); | 
| 710 | goto ram_free; | 711 | goto ram_free; | 
| @@ -727,7 +728,7 @@ static void ilo_remove(struct pci_dev *pdev) | |||
| 727 | clear_device(ilo_hw); | 728 | clear_device(ilo_hw); | 
| 728 | 729 | ||
| 729 | minor = MINOR(ilo_hw->cdev.dev); | 730 | minor = MINOR(ilo_hw->cdev.dev); | 
| 730 | for (i = minor; i < minor + MAX_CCB; i++) | 731 | for (i = minor; i < minor + max_ccb; i++) | 
| 731 | device_destroy(ilo_class, MKDEV(ilo_major, i)); | 732 | device_destroy(ilo_class, MKDEV(ilo_major, i)); | 
| 732 | 733 | ||
| 733 | cdev_del(&ilo_hw->cdev); | 734 | cdev_del(&ilo_hw->cdev); | 
| @@ -737,7 +738,7 @@ static void ilo_remove(struct pci_dev *pdev) | |||
| 737 | pci_release_regions(pdev); | 738 | pci_release_regions(pdev); | 
| 738 | pci_disable_device(pdev); | 739 | pci_disable_device(pdev); | 
| 739 | kfree(ilo_hw); | 740 | kfree(ilo_hw); | 
| 740 | ilo_hwdev[(minor / MAX_CCB)] = 0; | 741 | ilo_hwdev[(minor / max_ccb)] = 0; | 
| 741 | } | 742 | } | 
| 742 | 743 | ||
| 743 | static int __devinit ilo_probe(struct pci_dev *pdev, | 744 | static int __devinit ilo_probe(struct pci_dev *pdev, | 
| @@ -746,6 +747,11 @@ static int __devinit ilo_probe(struct pci_dev *pdev, | |||
| 746 | int devnum, minor, start, error; | 747 | int devnum, minor, start, error; | 
| 747 | struct ilo_hwinfo *ilo_hw; | 748 | struct ilo_hwinfo *ilo_hw; | 
| 748 | 749 | ||
| 750 | if (max_ccb > MAX_CCB) | ||
| 751 | max_ccb = MAX_CCB; | ||
| 752 | else if (max_ccb < MIN_CCB) | ||
| 753 | max_ccb = MIN_CCB; | ||
| 754 | |||
| 749 | /* find a free range for device files */ | 755 | /* find a free range for device files */ | 
| 750 | for (devnum = 0; devnum < MAX_ILO_DEV; devnum++) { | 756 | for (devnum = 0; devnum < MAX_ILO_DEV; devnum++) { | 
| 751 | if (ilo_hwdev[devnum] == 0) { | 757 | if (ilo_hwdev[devnum] == 0) { | 
| @@ -795,14 +801,14 @@ static int __devinit ilo_probe(struct pci_dev *pdev, | |||
| 795 | 801 | ||
| 796 | cdev_init(&ilo_hw->cdev, &ilo_fops); | 802 | cdev_init(&ilo_hw->cdev, &ilo_fops); | 
| 797 | ilo_hw->cdev.owner = THIS_MODULE; | 803 | ilo_hw->cdev.owner = THIS_MODULE; | 
| 798 | start = devnum * MAX_CCB; | 804 | start = devnum * max_ccb; | 
| 799 | error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB); | 805 | error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), max_ccb); | 
| 800 | if (error) { | 806 | if (error) { | 
| 801 | dev_err(&pdev->dev, "Could not add cdev\n"); | 807 | dev_err(&pdev->dev, "Could not add cdev\n"); | 
| 802 | goto remove_isr; | 808 | goto remove_isr; | 
| 803 | } | 809 | } | 
| 804 | 810 | ||
| 805 | for (minor = 0 ; minor < MAX_CCB; minor++) { | 811 | for (minor = 0 ; minor < max_ccb; minor++) { | 
| 806 | struct device *dev; | 812 | struct device *dev; | 
| 807 | dev = device_create(ilo_class, &pdev->dev, | 813 | dev = device_create(ilo_class, &pdev->dev, | 
| 808 | MKDEV(ilo_major, minor), NULL, | 814 | MKDEV(ilo_major, minor), NULL, | 
| @@ -879,11 +885,14 @@ static void __exit ilo_exit(void) | |||
| 879 | class_destroy(ilo_class); | 885 | class_destroy(ilo_class); | 
| 880 | } | 886 | } | 
| 881 | 887 | ||
| 882 | MODULE_VERSION("1.2"); | 888 | MODULE_VERSION("1.3"); | 
| 883 | MODULE_ALIAS(ILO_NAME); | 889 | MODULE_ALIAS(ILO_NAME); | 
| 884 | MODULE_DESCRIPTION(ILO_NAME); | 890 | MODULE_DESCRIPTION(ILO_NAME); | 
| 885 | MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); | 891 | MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); | 
| 886 | MODULE_LICENSE("GPL v2"); | 892 | MODULE_LICENSE("GPL v2"); | 
| 887 | 893 | ||
| 894 | module_param(max_ccb, uint, 0444); | ||
| 895 | MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (8)"); | ||
| 896 | |||
| 888 | module_init(ilo_init); | 897 | module_init(ilo_init); | 
| 889 | module_exit(ilo_exit); | 898 | module_exit(ilo_exit); | 
