diff options
Diffstat (limited to 'drivers/scsi/pmcraid.c')
| -rw-r--r-- | drivers/scsi/pmcraid.c | 139 |
1 files changed, 93 insertions, 46 deletions
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 836ddc476764..33f403e307eb 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -61,7 +61,9 @@ static atomic_t pmcraid_adapter_count = ATOMIC_INIT(0); * pmcraid_minor - minor number(s) to use */ static unsigned int pmcraid_major; -static struct class *pmcraid_class; +static const struct class pmcraid_class = { + .name = PMCRAID_DEVFILE, +}; static DECLARE_BITMAP(pmcraid_minor, PMCRAID_MAX_ADAPTERS); /* @@ -111,7 +113,7 @@ static struct pmcraid_chip_details pmcraid_chip_cfg[] = { /* * PCI device ids supported by pmcraid driver */ -static struct pci_device_id pmcraid_pci_table[] = { +static const struct pci_device_id pmcraid_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_PMC, PCI_DEVICE_ID_PMC_MAXRAID), 0, 0, (kernel_ulong_t)&pmcraid_chip_cfg[0] }, @@ -123,7 +125,7 @@ MODULE_DEVICE_TABLE(pci, pmcraid_pci_table); /** - * pmcraid_slave_alloc - Prepare for commands to a device + * pmcraid_sdev_init - Prepare for commands to a device * @scsi_dev: scsi device struct * * This function is called by mid-layer prior to sending any command to the new @@ -134,7 +136,7 @@ MODULE_DEVICE_TABLE(pci, pmcraid_pci_table); * Return value: * 0 on success / -ENXIO if device does not exist */ -static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) +static int pmcraid_sdev_init(struct scsi_device *scsi_dev) { struct pmcraid_resource_entry *temp, *res = NULL; struct pmcraid_instance *pinstance; @@ -195,8 +197,9 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) } /** - * pmcraid_slave_configure - Configures a SCSI device + * pmcraid_sdev_configure - Configures a SCSI device * @scsi_dev: scsi device struct + * @lim: queue limits * * This function is executed by SCSI mid layer just after a device is first * scanned (i.e. it has responded to an INQUIRY). For VSET resources, the @@ -207,7 +210,8 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) * Return value: * 0 on success */ -static int pmcraid_slave_configure(struct scsi_device *scsi_dev) +static int pmcraid_sdev_configure(struct scsi_device *scsi_dev, + struct queue_limits *lim) { struct pmcraid_resource_entry *res = scsi_dev->hostdata; @@ -231,8 +235,7 @@ static int pmcraid_slave_configure(struct scsi_device *scsi_dev) scsi_dev->allow_restart = 1; blk_queue_rq_timeout(scsi_dev->request_queue, PMCRAID_VSET_IO_TIMEOUT); - blk_queue_max_hw_sectors(scsi_dev->request_queue, - PMCRAID_VSET_MAX_SECTORS); + lim->max_hw_sectors = PMCRAID_VSET_MAX_SECTORS; } /* @@ -245,17 +248,17 @@ static int pmcraid_slave_configure(struct scsi_device *scsi_dev) } /** - * pmcraid_slave_destroy - Unconfigure a SCSI device before removing it + * pmcraid_sdev_destroy - Unconfigure a SCSI device before removing it * * @scsi_dev: scsi device struct * * This is called by mid-layer before removing a device. Pointer assignments - * done in pmcraid_slave_alloc will be reset to NULL here. + * done in pmcraid_sdev_init will be reset to NULL here. * * Return value * none */ -static void pmcraid_slave_destroy(struct scsi_device *scsi_dev) +static void pmcraid_sdev_destroy(struct scsi_device *scsi_dev) { struct pmcraid_resource_entry *res; @@ -492,7 +495,7 @@ static void pmcraid_clr_trans_op( } if (pinstance->reset_cmd != NULL) { - del_timer(&pinstance->reset_cmd->timer); + timer_delete(&pinstance->reset_cmd->timer); spin_lock_irqsave( pinstance->host->host_lock, lock_flags); pinstance->reset_cmd->cmd_done(pinstance->reset_cmd); @@ -541,7 +544,7 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *); */ static void pmcraid_bist_done(struct timer_list *t) { - struct pmcraid_cmd *cmd = from_timer(cmd, t, timer); + struct pmcraid_cmd *cmd = timer_container_of(cmd, t, timer); struct pmcraid_instance *pinstance = cmd->drv_inst; unsigned long lock_flags; int rc; @@ -598,7 +601,7 @@ static void pmcraid_start_bist(struct pmcraid_cmd *cmd) */ static void pmcraid_reset_alert_done(struct timer_list *t) { - struct pmcraid_cmd *cmd = from_timer(cmd, t, timer); + struct pmcraid_cmd *cmd = timer_container_of(cmd, t, timer); struct pmcraid_instance *pinstance = cmd->drv_inst; u32 status = ioread32(pinstance->ioa_status); unsigned long lock_flags; @@ -682,7 +685,7 @@ static void pmcraid_reset_alert(struct pmcraid_cmd *cmd) */ static void pmcraid_timeout_handler(struct timer_list *t) { - struct pmcraid_cmd *cmd = from_timer(cmd, t, timer); + struct pmcraid_cmd *cmd = timer_container_of(cmd, t, timer); struct pmcraid_instance *pinstance = cmd->drv_inst; unsigned long lock_flags; @@ -1943,7 +1946,7 @@ static void pmcraid_soft_reset(struct pmcraid_cmd *cmd) } iowrite32(doorbell, pinstance->int_regs.host_ioa_interrupt_reg); - ioread32(pinstance->int_regs.host_ioa_interrupt_reg), + ioread32(pinstance->int_regs.host_ioa_interrupt_reg); int_reg = ioread32(pinstance->int_regs.ioa_host_interrupt_reg); pmcraid_info("Waiting for IOA to become operational %x:%x\n", @@ -1996,7 +1999,7 @@ static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance) cpu_to_le32(PMCRAID_DRIVER_ILID); /* In case the command timer is still running */ - del_timer(&cmd->timer); + timer_delete(&cmd->timer); /* If this is an IO command, complete it by invoking scsi_done * function. If this is one of the internal commands other @@ -2679,7 +2682,7 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd) /** * pmcraid_reset_device - device reset handler functions * - * @scsi_cmd: scsi command struct + * @scsi_dev: scsi device struct * @timeout: command timeout * @modifier: reset modifier indicating the reset sequence to be performed * @@ -2691,7 +2694,7 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd) * SUCCESS / FAILED */ static int pmcraid_reset_device( - struct scsi_cmnd *scsi_cmd, + struct scsi_device *scsi_dev, unsigned long timeout, u8 modifier) { @@ -2703,11 +2706,11 @@ static int pmcraid_reset_device( u32 ioasc; pinstance = - (struct pmcraid_instance *)scsi_cmd->device->host->hostdata; - res = scsi_cmd->device->hostdata; + (struct pmcraid_instance *)scsi_dev->host->hostdata; + res = scsi_dev->hostdata; if (!res) { - sdev_printk(KERN_ERR, scsi_cmd->device, + sdev_printk(KERN_ERR, scsi_dev, "reset_device: NULL resource pointer\n"); return FAILED; } @@ -3018,27 +3021,72 @@ static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd) { scmd_printk(KERN_INFO, scmd, "resetting device due to an I/O command timeout.\n"); - return pmcraid_reset_device(scmd, + return pmcraid_reset_device(scmd->device, PMCRAID_INTERNAL_TIMEOUT, RESET_DEVICE_LUN); } static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd) { - scmd_printk(KERN_INFO, scmd, + struct Scsi_Host *host = scmd->device->host; + struct pmcraid_instance *pinstance = + (struct pmcraid_instance *)host->hostdata; + struct pmcraid_resource_entry *res = NULL; + struct pmcraid_resource_entry *temp; + struct scsi_device *sdev = NULL; + unsigned long lock_flags; + + /* + * The reset device code insists on us passing down + * a device, so grab the first device on the bus. + */ + spin_lock_irqsave(&pinstance->resource_lock, lock_flags); + list_for_each_entry(temp, &pinstance->used_res_q, queue) { + if (scmd->device->channel == PMCRAID_VSET_BUS_ID && + RES_IS_VSET(temp->cfg_entry)) { + res = temp; + break; + } else if (scmd->device->channel == PMCRAID_PHYS_BUS_ID && + RES_IS_GSCSI(temp->cfg_entry)) { + res = temp; + break; + } + } + if (res) + sdev = res->scsi_dev; + spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags); + if (!sdev) + return FAILED; + + sdev_printk(KERN_INFO, sdev, "Doing bus reset due to an I/O command timeout.\n"); - return pmcraid_reset_device(scmd, + return pmcraid_reset_device(sdev, PMCRAID_RESET_BUS_TIMEOUT, RESET_DEVICE_BUS); } static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd) { - scmd_printk(KERN_INFO, scmd, + struct Scsi_Host *shost = scmd->device->host; + struct scsi_device *scsi_dev = NULL, *tmp; + int ret; + + shost_for_each_device(tmp, shost) { + if ((tmp->channel == scmd->device->channel) && + (tmp->id == scmd->device->id)) { + scsi_dev = tmp; + break; + } + } + if (!scsi_dev) + return FAILED; + sdev_printk(KERN_INFO, scsi_dev, "Doing target reset due to an I/O command timeout.\n"); - return pmcraid_reset_device(scmd, - PMCRAID_INTERNAL_TIMEOUT, - RESET_DEVICE_TARGET); + ret = pmcraid_reset_device(scsi_dev, + PMCRAID_INTERNAL_TIMEOUT, + RESET_DEVICE_TARGET); + scsi_device_put(scsi_dev); + return ret; } /** @@ -3584,8 +3632,7 @@ static ssize_t pmcraid_show_adapter_id( struct Scsi_Host *shost = class_to_shost(dev); struct pmcraid_instance *pinstance = (struct pmcraid_instance *)shost->hostdata; - u32 adapter_id = (pinstance->pdev->bus->number << 8) | - pinstance->pdev->devfn; + u32 adapter_id = pci_dev_id(pinstance->pdev); u32 aen_group = pmcraid_event_family.id; return snprintf(buf, PAGE_SIZE, @@ -3611,7 +3658,7 @@ static struct attribute *pmcraid_host_attrs[] = { ATTRIBUTE_GROUPS(pmcraid_host); /* host template structure for pmcraid driver */ -static struct scsi_host_template pmcraid_host_template = { +static const struct scsi_host_template pmcraid_host_template = { .module = THIS_MODULE, .name = PMCRAID_DRIVER_NAME, .queuecommand = pmcraid_queuecommand, @@ -3621,9 +3668,9 @@ static struct scsi_host_template pmcraid_host_template = { .eh_device_reset_handler = pmcraid_eh_device_reset_handler, .eh_host_reset_handler = pmcraid_eh_host_reset_handler, - .slave_alloc = pmcraid_slave_alloc, - .slave_configure = pmcraid_slave_configure, - .slave_destroy = pmcraid_slave_destroy, + .sdev_init = pmcraid_sdev_init, + .sdev_configure = pmcraid_sdev_configure, + .sdev_destroy = pmcraid_sdev_destroy, .change_queue_depth = pmcraid_change_queue_depth, .can_queue = PMCRAID_MAX_IO_CMD, .this_id = -1, @@ -3935,7 +3982,7 @@ static void pmcraid_tasklet_function(unsigned long instance) list_del(&cmd->free_list); spin_unlock_irqrestore(&pinstance->pending_pool_lock, pending_lock_flags); - del_timer(&cmd->timer); + timer_delete(&cmd->timer); atomic_dec(&pinstance->outstanding_cmds); if (cmd->cmd_done == pmcraid_ioa_reset) { @@ -3962,7 +4009,7 @@ static void pmcraid_tasklet_function(unsigned long instance) * This routine un-registers registered interrupt handler and * also frees irqs/vectors. * - * Retun Value + * Return Value * None */ static @@ -3989,7 +4036,7 @@ static int pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) { struct pci_dev *pdev = pinstance->pdev; - unsigned int irq_flag = PCI_IRQ_LEGACY, flag; + unsigned int irq_flag = PCI_IRQ_INTX, flag; int num_hrrq, rc, i; irq_handler_t isr; @@ -4679,7 +4726,7 @@ static int pmcraid_setup_chrdev(struct pmcraid_instance *pinstance) if (error) pmcraid_release_minor(minor); else - device_create(pmcraid_class, NULL, MKDEV(pmcraid_major, minor), + device_create(&pmcraid_class, NULL, MKDEV(pmcraid_major, minor), NULL, "%s%u", PMCRAID_DEVFILE, minor); return error; } @@ -4695,7 +4742,7 @@ static int pmcraid_setup_chrdev(struct pmcraid_instance *pinstance) static void pmcraid_release_chrdev(struct pmcraid_instance *pinstance) { pmcraid_release_minor(MINOR(pinstance->cdev.dev)); - device_destroy(pmcraid_class, + device_destroy(&pmcraid_class, MKDEV(pmcraid_major, MINOR(pinstance->cdev.dev))); cdev_del(&pinstance->cdev); } @@ -5346,10 +5393,10 @@ static int __init pmcraid_init(void) } pmcraid_major = MAJOR(dev); - pmcraid_class = class_create(THIS_MODULE, PMCRAID_DEVFILE); - if (IS_ERR(pmcraid_class)) { - error = PTR_ERR(pmcraid_class); + error = class_register(&pmcraid_class); + + if (error) { pmcraid_err("failed to register with sysfs, error = %x\n", error); goto out_unreg_chrdev; @@ -5358,7 +5405,7 @@ static int __init pmcraid_init(void) error = pmcraid_netlink_init(); if (error) { - class_destroy(pmcraid_class); + class_unregister(&pmcraid_class); goto out_unreg_chrdev; } @@ -5369,7 +5416,7 @@ static int __init pmcraid_init(void) pmcraid_err("failed to register pmcraid driver, error = %x\n", error); - class_destroy(pmcraid_class); + class_unregister(&pmcraid_class); pmcraid_netlink_release(); out_unreg_chrdev: @@ -5388,7 +5435,7 @@ static void __exit pmcraid_exit(void) unregister_chrdev_region(MKDEV(pmcraid_major, 0), PMCRAID_MAX_ADAPTERS); pci_unregister_driver(&pmcraid_driver); - class_destroy(pmcraid_class); + class_unregister(&pmcraid_class); } module_init(pmcraid_init); |
