X-Git-Url: https://git.stricted.de/?a=blobdiff_plain;f=drivers%2Fscsi%2Fqla2xxx%2Fqla_os.c;h=aba1e6d480669ff6e9f932e55e6364f397d050df;hb=9b73e76f3cf63379dcf45fcd4f112f5812418d0a;hp=a8ab2d3447baf5a5fa883a247ce2af237de65980;hpb=14e660e677ddd3574247495aae4ef63eb8899072;p=GitHub%2Fmt8127%2Fandroid_kernel_alcatel_ttab.git diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a8ab2d3447ba..aba1e6d48066 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -105,13 +105,12 @@ static int qla2xxx_eh_abort(struct scsi_cmnd *); static int qla2xxx_eh_device_reset(struct scsi_cmnd *); static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); static int qla2xxx_eh_host_reset(struct scsi_cmnd *); -static int qla2x00_loop_reset(scsi_qla_host_t *ha); static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *); static int qla2x00_change_queue_depth(struct scsi_device *, int); static int qla2x00_change_queue_type(struct scsi_device *, int); -struct scsi_host_template qla2x00_driver_template = { +static struct scsi_host_template qla2x00_driver_template = { .module = THIS_MODULE, .name = QLA2XXX_DRIVER_NAME, .queuecommand = qla2x00_queuecommand, @@ -132,6 +131,7 @@ struct scsi_host_template qla2x00_driver_template = { .this_id = -1, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, + .use_sg_chaining = ENABLE_SG_CHAINING, .sg_tablesize = SG_ALL, /* @@ -163,6 +163,7 @@ struct scsi_host_template qla24xx_driver_template = { .this_id = -1, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, + .use_sg_chaining = ENABLE_SG_CHAINING, .sg_tablesize = SG_ALL, .max_sectors = 0xFFFF, @@ -177,13 +178,6 @@ struct scsi_transport_template *qla2xxx_transport_vport_template = NULL; * Timer routines */ -void qla2x00_timer(scsi_qla_host_t *); - -__inline__ void qla2x00_start_timer(scsi_qla_host_t *, - void *, unsigned long); -static __inline__ void qla2x00_restart_timer(scsi_qla_host_t *, unsigned long); -__inline__ void qla2x00_stop_timer(scsi_qla_host_t *); - __inline__ void qla2x00_start_timer(scsi_qla_host_t *ha, void *func, unsigned long interval) { @@ -201,7 +195,7 @@ qla2x00_restart_timer(scsi_qla_host_t *ha, unsigned long interval) mod_timer(&ha->timer, jiffies + interval * HZ); } -__inline__ void +static __inline__ void qla2x00_stop_timer(scsi_qla_host_t *ha) { del_timer_sync(&ha->timer); @@ -212,12 +206,11 @@ static int qla2x00_do_dpc(void *data); static void qla2x00_rst_aen(scsi_qla_host_t *); -uint8_t qla2x00_mem_alloc(scsi_qla_host_t *); -void qla2x00_mem_free(scsi_qla_host_t *ha); +static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *); +static void qla2x00_mem_free(scsi_qla_host_t *ha); static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha); static void qla2x00_free_sp_pool(scsi_qla_host_t *ha); static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *); -void qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *); /* -------------------------------------------------------------------------- */ @@ -379,7 +372,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport, static int qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); srb_t *sp; @@ -445,7 +438,7 @@ qc_fail_command: static int qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); srb_t *sp; @@ -663,7 +656,7 @@ qla2x00_block_error_handler(struct scsi_cmnd *cmnd) static int qla2xxx_eh_abort(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); srb_t *sp; int ret, i; unsigned int id, lun; @@ -803,7 +796,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) static int qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; int ret = FAILED; unsigned int id, lun; @@ -932,7 +925,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) static int qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); scsi_qla_host_t *pha = to_qla_parent(ha); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; int ret = FAILED; @@ -992,7 +985,7 @@ eh_bus_reset_done: static int qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; int ret = FAILED; unsigned int id, lun; @@ -1058,7 +1051,7 @@ eh_host_reset_lock: * Returns: * 0 = success */ -static int +int qla2x00_loop_reset(scsi_qla_host_t *ha) { int ret; @@ -1142,7 +1135,7 @@ qla2xxx_slave_alloc(struct scsi_device *sdev) static int qla2xxx_slave_configure(struct scsi_device *sdev) { - scsi_qla_host_t *ha = to_qla_host(sdev->host); + scsi_qla_host_t *ha = shost_priv(sdev->host); struct fc_rport *rport = starget_to_rport(sdev->sdev_target); if (sdev->tagged_supported) @@ -1477,15 +1470,23 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) static int qla2x00_iospace_config(scsi_qla_host_t *ha) { - unsigned long pio, pio_len, pio_flags; - unsigned long mmio, mmio_len, mmio_flags; + resource_size_t pio; + + if (pci_request_selected_regions(ha->pdev, ha->bars, + QLA2XXX_DRIVER_NAME)) { + qla_printk(KERN_WARNING, ha, + "Failed to reserve PIO/MMIO regions (%s)\n", + pci_name(ha->pdev)); + + goto iospace_error_exit; + } + if (!(ha->bars & 1)) + goto skip_pio; /* We only need PIO for Flash operations on ISP2312 v2 chips. */ pio = pci_resource_start(ha->pdev, 0); - pio_len = pci_resource_len(ha->pdev, 0); - pio_flags = pci_resource_flags(ha->pdev, 0); - if (pio_flags & IORESOURCE_IO) { - if (pio_len < MIN_IOBASE_LEN) { + if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) { + if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) { qla_printk(KERN_WARNING, ha, "Invalid PCI I/O region size (%s)...\n", pci_name(ha->pdev)); @@ -1497,36 +1498,24 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) pci_name(ha->pdev)); pio = 0; } + ha->pio_address = pio; +skip_pio: /* Use MMIO operations for all accesses. */ - mmio = pci_resource_start(ha->pdev, 1); - mmio_len = pci_resource_len(ha->pdev, 1); - mmio_flags = pci_resource_flags(ha->pdev, 1); - - if (!(mmio_flags & IORESOURCE_MEM)) { + if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) { qla_printk(KERN_ERR, ha, - "region #0 not an MMIO resource (%s), aborting\n", + "region #1 not an MMIO resource (%s), aborting\n", pci_name(ha->pdev)); goto iospace_error_exit; } - if (mmio_len < MIN_IOBASE_LEN) { + if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) { qla_printk(KERN_ERR, ha, "Invalid PCI mem region size (%s), aborting\n", pci_name(ha->pdev)); goto iospace_error_exit; } - if (pci_request_regions(ha->pdev, QLA2XXX_DRIVER_NAME)) { - qla_printk(KERN_WARNING, ha, - "Failed to reserve PIO/MMIO regions (%s)\n", - pci_name(ha->pdev)); - - goto iospace_error_exit; - } - - ha->pio_address = pio; - ha->pio_length = pio_len; - ha->iobase = ioremap(mmio, MIN_IOBASE_LEN); + ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN); if (!ha->iobase) { qla_printk(KERN_ERR, ha, "cannot remap MMIO (%s), aborting\n", pci_name(ha->pdev)); @@ -1543,7 +1532,7 @@ iospace_error_exit: static void qla2xxx_scan_start(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; + scsi_qla_host_t *ha = shost_priv(shost); set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); @@ -1553,7 +1542,7 @@ qla2xxx_scan_start(struct Scsi_Host *shost) static int qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) { - scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; + scsi_qla_host_t *ha = shost_priv(shost); if (!ha->host) return 1; @@ -1577,21 +1566,26 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) char pci_info[30]; char fw_str[30]; struct scsi_host_template *sht; + int bars; - if (pci_enable_device(pdev)) - goto probe_out; - - if (pci_find_aer_capability(pdev)) - if (pci_enable_pcie_error_reporting(pdev)) - goto probe_out; - + bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); sht = &qla2x00_driver_template; if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || - pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { + bars = pci_select_bars(pdev, IORESOURCE_MEM); sht = &qla24xx_driver_template; + } + + if (pci_enable_device_bars(pdev, bars)) + goto probe_out; + + if (pci_find_aer_capability(pdev)) + if (pci_enable_pcie_error_reporting(pdev)) + goto probe_out; + host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); if (host == NULL) { printk(KERN_WARNING @@ -1600,7 +1594,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) } /* Clear our data area */ - ha = (scsi_qla_host_t *)host->hostdata; + ha = shost_priv(host); memset(ha, 0, sizeof(scsi_qla_host_t)); ha->pdev = pdev; @@ -1608,6 +1602,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->host_no = host->host_no; sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); ha->parent = NULL; + ha->bars = bars; /* Set ISP-type information. */ qla2x00_set_isp_flags(ha); @@ -1689,9 +1684,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) /* load the F/W, read paramaters, and init the H/W */ ha->instance = num_hosts; - init_MUTEX(&ha->mbx_cmd_sem); init_MUTEX(&ha->vport_sem); - init_MUTEX_LOCKED(&ha->mbx_intr_sem); + init_completion(&ha->mbx_cmd_comp); + complete(&ha->mbx_cmd_comp); + init_completion(&ha->mbx_intr_comp); INIT_LIST_HEAD(&ha->list); INIT_LIST_HEAD(&ha->fcports); @@ -1795,6 +1791,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) qla2x00_init_host_attr(ha); + qla2x00_dfs_setup(ha); + qla_printk(KERN_INFO, ha, "\n" " QLogic Fibre Channel HBA Driver: %s\n" " QLogic %s - %s\n" @@ -1819,13 +1817,15 @@ probe_out: return ret; } -static void __devexit +static void qla2x00_remove_one(struct pci_dev *pdev) { scsi_qla_host_t *ha; ha = pci_get_drvdata(pdev); + qla2x00_dfs_remove(ha); + qla2x00_free_sysfs_attr(ha); fc_remove_host(ha->host); @@ -1859,8 +1859,11 @@ qla2x00_free_device(scsi_qla_host_t *ha) kthread_stop(t); } + if (ha->flags.fce_enabled) + qla2x00_disable_fce_trace(ha, NULL, NULL); + if (ha->eft) - qla2x00_trace_control(ha, TC_DISABLE, 0, 0); + qla2x00_disable_eft_trace(ha); ha->flags.online = 0; @@ -1878,7 +1881,7 @@ qla2x00_free_device(scsi_qla_host_t *ha) /* release io space registers */ if (ha->iobase) iounmap(ha->iobase); - pci_release_regions(ha->pdev); + pci_release_selected_regions(ha->pdev, ha->bars); } static inline void @@ -2004,7 +2007,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) * 0 = success. * 1 = failure. */ -uint8_t +static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *ha) { char name[16]; @@ -2201,7 +2204,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) * Input: * ha = adapter block pointer. */ -void +static void qla2x00_mem_free(scsi_qla_host_t *ha) { struct list_head *fcpl, *fcptemp; @@ -2216,6 +2219,10 @@ qla2x00_mem_free(scsi_qla_host_t *ha) /* free sp pool */ qla2x00_free_sp_pool(ha); + if (ha->fce) + dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, + ha->fce_dma); + if (ha->fw_dump) { if (ha->eft) dma_free_coherent(&ha->pdev->dev, @@ -2437,7 +2444,6 @@ qla2x00_do_dpc(void *data) if (atomic_read(&fcport->state) != FCS_ONLINE && fcport->login_retry) { - fcport->login_retry--; if (fcport->flags & FCF_FABRIC_DEVICE) { if (fcport->flags & FCF_TAPE_PRESENT) @@ -2453,6 +2459,7 @@ qla2x00_do_dpc(void *data) qla2x00_local_device_login( ha, fcport); + fcport->login_retry--; if (status == QLA_SUCCESS) { fcport->old_loop_id = fcport->loop_id; @@ -2470,6 +2477,8 @@ qla2x00_do_dpc(void *data) } else { fcport->login_retry = 0; } + if (fcport->login_retry == 0) + fcport->loop_id = FC_NO_LOOP_ID; } if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) break; @@ -2734,23 +2743,6 @@ qla2x00_timer(scsi_qla_host_t *ha) qla2x00_restart_timer(ha, WATCH_INTERVAL); } -/* XXX(hch): crude hack to emulate a down_timeout() */ -int -qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) -{ - const unsigned int step = 100; /* msecs */ - unsigned int iterations = jiffies_to_msecs(timeout)/100; - - do { - if (!down_trylock(sema)) - return 0; - if (msleep_interruptible(step)) - break; - } while (--iterations > 0); - - return -ETIMEDOUT; -} - /* Firmware interface routines. */ #define FW_BLOBS 6 @@ -2886,7 +2878,7 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; scsi_qla_host_t *ha = pci_get_drvdata(pdev); - if (pci_enable_device(pdev)) { + if (pci_enable_device_bars(pdev, ha->bars)) { qla_printk(KERN_WARNING, ha, "Can't re-enable PCI device after reset.\n"); @@ -2951,7 +2943,7 @@ static struct pci_driver qla2xxx_pci_driver = { }, .id_table = qla2xxx_pci_tbl, .probe = qla2x00_probe_one, - .remove = __devexit_p(qla2x00_remove_one), + .remove = qla2x00_remove_one, .err_handler = &qla2xxx_err_handler, };