diff options
Diffstat (limited to 'drivers/misc/hpilo.c')
| -rw-r--r-- | drivers/misc/hpilo.c | 101 |
1 files changed, 58 insertions, 43 deletions
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 621c7a373390..04bd34c8c506 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the HP iLO management processor. * * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. - * David Altobelli <david.altobelli@hp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * David Altobelli <david.altobelli@hpe.com> */ #include <linux/kernel.h> #include <linux/types.h> @@ -28,10 +25,19 @@ #include <linux/slab.h> #include "hpilo.h" -static struct class *ilo_class; +static const struct class ilo_class = { + .name = "iLO", +}; static unsigned int ilo_major; static unsigned int max_ccb = 16; static char ilo_hwdev[MAX_ILO_DEV]; +static const struct pci_device_id ilo_blacklist[] = { + /* auxiliary iLO */ + {PCI_DEVICE_SUB(PCI_VENDOR_ID_HP, 0x3307, PCI_VENDOR_ID_HP, 0x1979)}, + /* CL */ + {PCI_DEVICE_SUB(PCI_VENDOR_ID_HP, 0x3307, PCI_VENDOR_ID_HP_3PAR, 0x0289)}, + {} +}; static inline int get_entry_id(int entry) { @@ -203,7 +209,7 @@ static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz) static inline int fifo_sz(int nr_entry) { /* size of a fifo is determined by the number of entries it contains */ - return (nr_entry * sizeof(u64)) + FIFOHANDLESIZE; + return nr_entry * sizeof(u64) + FIFOHANDLESIZE; } static void fifo_setup(void *base_addr, int nr_entry) @@ -252,7 +258,8 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) memset_io(device_ccb, 0, sizeof(struct ccb)); /* free resources used to back send/recv queues */ - pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa); + dma_free_coherent(&pdev->dev, data->dma_size, data->dma_va, + data->dma_pa); } static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) @@ -268,16 +275,14 @@ static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) 2 * desc_mem_sz(NR_QENTRY) + ILO_START_ALIGN + ILO_CACHE_SZ; - data->dma_va = pci_alloc_consistent(hw->ilo_dev, data->dma_size, - &data->dma_pa); + data->dma_va = dma_alloc_coherent(&hw->ilo_dev->dev, data->dma_size, + &data->dma_pa, GFP_ATOMIC); if (!data->dma_va) return -ENOMEM; dma_va = (char *)data->dma_va; dma_pa = data->dma_pa; - memset(dma_va, 0, data->dma_size); - dma_va = (char *)roundup((unsigned long)dma_va, ILO_START_ALIGN); dma_pa = roundup(dma_pa, ILO_START_ALIGN); @@ -389,12 +394,6 @@ static inline int is_db_reset(int db_out) return db_out & (1 << DB_RESET); } -static inline int is_device_reset(struct ilo_hwinfo *hw) -{ - /* check for global reset condition */ - return is_db_reset(get_device_outbound(hw)); -} - static inline void clear_pending_db(struct ilo_hwinfo *hw, int clr) { iowrite32(clr, &hw->mmio_vaddr[DB_OUT]); @@ -514,7 +513,7 @@ static ssize_t ilo_write(struct file *fp, const char __user *buf, return err ? -EFAULT : len; } -static unsigned int ilo_poll(struct file *fp, poll_table *wait) +static __poll_t ilo_poll(struct file *fp, poll_table *wait) { struct ccb_data *data = fp->private_data; struct ccb *driver_ccb = &data->driver_ccb; @@ -522,9 +521,9 @@ static unsigned int ilo_poll(struct file *fp, poll_table *wait) poll_wait(fp, &data->ccb_waitq, wait); if (is_channel_reset(driver_ccb)) - return POLLERR; + return EPOLLERR; else if (ilo_pkt_recv(data->ilo_hw, driver_ccb)) - return POLLIN | POLLRDNORM; + return EPOLLIN | EPOLLRDNORM; return 0; } @@ -688,7 +687,10 @@ static void ilo_unmap_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; + int bar; + unsigned long off; + u8 pci_rev_id; + int rc; /* map the memory mapped i/o registers */ hw->mmio_vaddr = pci_iomap(pdev, 1, 0); @@ -698,7 +700,21 @@ static int ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) } /* map the adapter shared memory region */ - hw->ram_vaddr = pci_iomap(pdev, 2, max_ccb * ILOHW_CCB_SZ); + rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev_id); + if (rc != 0) { + dev_err(&pdev->dev, "Error reading PCI rev id: %d\n", rc); + goto out; + } + + if (pci_rev_id >= PCI_REV_ID_NECHES) { + bar = 5; + /* Last 8k is reserved for CCBs */ + off = pci_resource_len(pdev, bar) - 0x2000; + } else { + bar = 2; + off = 0; + } + hw->ram_vaddr = pci_iomap_range(pdev, bar, off, max_ccb * ILOHW_CCB_SZ); if (hw->ram_vaddr == NULL) { dev_err(&pdev->dev, "Error mapping shared mem\n"); goto mmio_free; @@ -717,7 +733,7 @@ ram_free: mmio_free: pci_iounmap(pdev, hw->mmio_vaddr); out: - return error; + return -ENOMEM; } static void ilo_remove(struct pci_dev *pdev) @@ -732,7 +748,7 @@ static void ilo_remove(struct pci_dev *pdev) minor = MINOR(ilo_hw->cdev.dev); for (i = minor; i < minor + max_ccb; i++) - device_destroy(ilo_class, MKDEV(ilo_major, i)); + device_destroy(&ilo_class, MKDEV(ilo_major, i)); cdev_del(&ilo_hw->cdev); ilo_disable_interrupts(ilo_hw); @@ -754,12 +770,13 @@ static void ilo_remove(struct pci_dev *pdev) static int ilo_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int devnum, minor, start, error = 0; + int devnum, slot, start, error = 0; struct ilo_hwinfo *ilo_hw; - /* Ignore subsystem_device = 0x1979 (set by BIOS) */ - if (pdev->subsystem_device == 0x1979) - goto out; + if (pci_match_id(ilo_blacklist, pdev)) { + dev_dbg(&pdev->dev, "Not supported on this device\n"); + return -ENODEV; + } if (max_ccb > MAX_CCB) max_ccb = MAX_CCB; @@ -822,11 +839,11 @@ static int ilo_probe(struct pci_dev *pdev, goto remove_isr; } - for (minor = 0 ; minor < max_ccb; minor++) { + for (slot = 0; slot < max_ccb; slot++) { struct device *dev; - dev = device_create(ilo_class, &pdev->dev, - MKDEV(ilo_major, minor), NULL, - "hpilo!d%dccb%d", devnum, minor); + dev = device_create(&ilo_class, &pdev->dev, + MKDEV(ilo_major, start + slot), NULL, + "hpilo!d%dccb%d", devnum, slot); if (IS_ERR(dev)) dev_err(&pdev->dev, "Could not create files\n"); } @@ -848,7 +865,7 @@ out: return error; } -static struct pci_device_id ilo_devices[] = { +static const struct pci_device_id ilo_devices[] = { { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) }, { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) }, { } @@ -867,11 +884,9 @@ static int __init ilo_init(void) int error; dev_t dev; - ilo_class = class_create(THIS_MODULE, "iLO"); - if (IS_ERR(ilo_class)) { - error = PTR_ERR(ilo_class); + error = class_register(&ilo_class); + if (error) goto out; - } error = alloc_chrdev_region(&dev, 0, MAX_OPEN, ILO_NAME); if (error) @@ -887,7 +902,7 @@ static int __init ilo_init(void) chr_remove: unregister_chrdev_region(dev, MAX_OPEN); class_destroy: - class_destroy(ilo_class); + class_unregister(&ilo_class); out: return error; } @@ -896,17 +911,17 @@ static void __exit ilo_exit(void) { pci_unregister_driver(&ilo_driver); unregister_chrdev_region(MKDEV(ilo_major, 0), MAX_OPEN); - class_destroy(ilo_class); + class_unregister(&ilo_class); } -MODULE_VERSION("1.4"); +MODULE_VERSION("1.5.0"); MODULE_ALIAS(ILO_NAME); MODULE_DESCRIPTION(ILO_NAME); -MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); +MODULE_AUTHOR("David Altobelli <david.altobelli@hpe.com>"); MODULE_LICENSE("GPL v2"); module_param(max_ccb, uint, 0444); -MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (16)"); +MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (8-24)(default=16)"); module_init(ilo_init); module_exit(ilo_exit); |
