diff options
| -rw-r--r-- | drivers/scsi/cxgb3i/cxgb3i_offload.c | 34 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 4 | ||||
| -rwxr-xr-x | drivers/scsi/lpfc/lpfc_hbadisc.c | 25 | ||||
| -rwxr-xr-x[-rw-r--r--] | drivers/scsi/lpfc/lpfc_hw4.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 14 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 48 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_version.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/pmcraid.c | 8 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 32 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 9 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 22 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 9 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 64 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 90 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/stex.c | 5 |
21 files changed, 322 insertions, 60 deletions
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index 26ffdcd5a437..15a00e8b7122 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c | |||
| @@ -1440,6 +1440,10 @@ void cxgb3i_c3cn_release(struct s3_conn *c3cn) | |||
| 1440 | static int is_cxgb3_dev(struct net_device *dev) | 1440 | static int is_cxgb3_dev(struct net_device *dev) |
| 1441 | { | 1441 | { |
| 1442 | struct cxgb3i_sdev_data *cdata; | 1442 | struct cxgb3i_sdev_data *cdata; |
| 1443 | struct net_device *ndev = dev; | ||
| 1444 | |||
| 1445 | if (dev->priv_flags & IFF_802_1Q_VLAN) | ||
| 1446 | ndev = vlan_dev_real_dev(dev); | ||
| 1443 | 1447 | ||
| 1444 | write_lock(&cdata_rwlock); | 1448 | write_lock(&cdata_rwlock); |
| 1445 | list_for_each_entry(cdata, &cdata_list, list) { | 1449 | list_for_each_entry(cdata, &cdata_list, list) { |
| @@ -1447,7 +1451,7 @@ static int is_cxgb3_dev(struct net_device *dev) | |||
| 1447 | int i; | 1451 | int i; |
| 1448 | 1452 | ||
| 1449 | for (i = 0; i < ports->nports; i++) | 1453 | for (i = 0; i < ports->nports; i++) |
| 1450 | if (dev == ports->lldevs[i]) { | 1454 | if (ndev == ports->lldevs[i]) { |
| 1451 | write_unlock(&cdata_rwlock); | 1455 | write_unlock(&cdata_rwlock); |
| 1452 | return 1; | 1456 | return 1; |
| 1453 | } | 1457 | } |
| @@ -1566,6 +1570,26 @@ out_err: | |||
| 1566 | return -EINVAL; | 1570 | return -EINVAL; |
| 1567 | } | 1571 | } |
| 1568 | 1572 | ||
| 1573 | /** | ||
| 1574 | * cxgb3i_find_dev - find the interface associated with the given address | ||
| 1575 | * @ipaddr: ip address | ||
| 1576 | */ | ||
| 1577 | static struct net_device * | ||
| 1578 | cxgb3i_find_dev(struct net_device *dev, __be32 ipaddr) | ||
| 1579 | { | ||
| 1580 | struct flowi fl; | ||
| 1581 | int err; | ||
| 1582 | struct rtable *rt; | ||
| 1583 | |||
| 1584 | memset(&fl, 0, sizeof(fl)); | ||
| 1585 | fl.nl_u.ip4_u.daddr = ipaddr; | ||
| 1586 | |||
| 1587 | err = ip_route_output_key(dev ? dev_net(dev) : &init_net, &rt, &fl); | ||
| 1588 | if (!err) | ||
| 1589 | return (&rt->u.dst)->dev; | ||
| 1590 | |||
| 1591 | return NULL; | ||
| 1592 | } | ||
| 1569 | 1593 | ||
| 1570 | /** | 1594 | /** |
| 1571 | * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address | 1595 | * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address |
| @@ -1581,6 +1605,7 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, | |||
| 1581 | struct cxgb3i_sdev_data *cdata; | 1605 | struct cxgb3i_sdev_data *cdata; |
| 1582 | struct t3cdev *cdev; | 1606 | struct t3cdev *cdev; |
| 1583 | __be32 sipv4; | 1607 | __be32 sipv4; |
| 1608 | struct net_device *dstdev; | ||
| 1584 | int err; | 1609 | int err; |
| 1585 | 1610 | ||
| 1586 | c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); | 1611 | c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); |
| @@ -1591,6 +1616,13 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, | |||
| 1591 | c3cn->daddr.sin_port = usin->sin_port; | 1616 | c3cn->daddr.sin_port = usin->sin_port; |
| 1592 | c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; | 1617 | c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; |
| 1593 | 1618 | ||
| 1619 | dstdev = cxgb3i_find_dev(dev, usin->sin_addr.s_addr); | ||
| 1620 | if (!dstdev || !is_cxgb3_dev(dstdev)) | ||
| 1621 | return -ENETUNREACH; | ||
| 1622 | |||
| 1623 | if (dstdev->priv_flags & IFF_802_1Q_VLAN) | ||
| 1624 | dev = dstdev; | ||
| 1625 | |||
| 1594 | rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, | 1626 | rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, |
| 1595 | c3cn->daddr.sin_addr.s_addr, | 1627 | c3cn->daddr.sin_addr.s_addr, |
| 1596 | c3cn->saddr.sin_port, | 1628 | c3cn->saddr.sin_port, |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index ce522702a6c1..2cc39684ce97 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
| @@ -4142,8 +4142,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
| 4142 | spin_lock_irq(shost->host_lock); | 4142 | spin_lock_irq(shost->host_lock); |
| 4143 | if (vport->fc_rscn_flush) { | 4143 | if (vport->fc_rscn_flush) { |
| 4144 | /* Another thread is walking fc_rscn_id_list on this vport */ | 4144 | /* Another thread is walking fc_rscn_id_list on this vport */ |
| 4145 | spin_unlock_irq(shost->host_lock); | ||
| 4146 | vport->fc_flag |= FC_RSCN_DISCOVERY; | 4145 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
| 4146 | spin_unlock_irq(shost->host_lock); | ||
| 4147 | /* Send back ACC */ | 4147 | /* Send back ACC */ |
| 4148 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | 4148 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); |
| 4149 | return 0; | 4149 | return 0; |
| @@ -5948,8 +5948,8 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
| 5948 | lpfc_initial_fdisc(vport); | 5948 | lpfc_initial_fdisc(vport); |
| 5949 | break; | 5949 | break; |
| 5950 | } | 5950 | } |
| 5951 | |||
| 5952 | } else { | 5951 | } else { |
| 5952 | vport->vpi_state |= LPFC_VPI_REGISTERED; | ||
| 5953 | if (vport == phba->pport) | 5953 | if (vport == phba->pport) |
| 5954 | if (phba->sli_rev < LPFC_SLI_REV4) | 5954 | if (phba->sli_rev < LPFC_SLI_REV4) |
| 5955 | lpfc_issue_fabric_reglogin(vport); | 5955 | lpfc_issue_fabric_reglogin(vport); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 3b9424427652..2445e399fd60 100755 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
| @@ -747,6 +747,10 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
| 747 | 747 | ||
| 748 | if (phba->link_state == LPFC_LINK_DOWN) | 748 | if (phba->link_state == LPFC_LINK_DOWN) |
| 749 | return 0; | 749 | return 0; |
| 750 | |||
| 751 | /* Block all SCSI stack I/Os */ | ||
| 752 | lpfc_scsi_dev_block(phba); | ||
| 753 | |||
| 750 | spin_lock_irq(&phba->hbalock); | 754 | spin_lock_irq(&phba->hbalock); |
| 751 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | 755 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); |
| 752 | if (phba->link_state > LPFC_LINK_DOWN) { | 756 | if (phba->link_state > LPFC_LINK_DOWN) { |
| @@ -1555,10 +1559,16 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1555 | * to book keeping the FCFIs can be used. | 1559 | * to book keeping the FCFIs can be used. |
| 1556 | */ | 1560 | */ |
| 1557 | if (shdr_status || shdr_add_status) { | 1561 | if (shdr_status || shdr_add_status) { |
| 1558 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1562 | if (shdr_status == STATUS_FCF_TABLE_EMPTY) { |
| 1559 | "2521 READ_FCF_RECORD mailbox failed " | 1563 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 1560 | "with status x%x add_status x%x, mbx\n", | 1564 | "2726 READ_FCF_RECORD Indicates empty " |
| 1561 | shdr_status, shdr_add_status); | 1565 | "FCF table.\n"); |
| 1566 | } else { | ||
| 1567 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 1568 | "2521 READ_FCF_RECORD mailbox failed " | ||
| 1569 | "with status x%x add_status x%x, mbx\n", | ||
| 1570 | shdr_status, shdr_add_status); | ||
| 1571 | } | ||
| 1562 | goto out; | 1572 | goto out; |
| 1563 | } | 1573 | } |
| 1564 | /* Interpreting the returned information of FCF records */ | 1574 | /* Interpreting the returned information of FCF records */ |
| @@ -1698,7 +1708,9 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 1698 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 1708 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
| 1699 | return; | 1709 | return; |
| 1700 | } | 1710 | } |
| 1711 | spin_lock_irq(&phba->hbalock); | ||
| 1701 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; | 1712 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; |
| 1713 | spin_unlock_irq(&phba->hbalock); | ||
| 1702 | 1714 | ||
| 1703 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1715 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
| 1704 | lpfc_initial_fdisc(vport); | 1716 | lpfc_initial_fdisc(vport); |
| @@ -2259,7 +2271,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
| 2259 | mb->mbxStatus); | 2271 | mb->mbxStatus); |
| 2260 | break; | 2272 | break; |
| 2261 | } | 2273 | } |
| 2274 | spin_lock_irq(&phba->hbalock); | ||
| 2262 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; | 2275 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; |
| 2276 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | ||
| 2277 | spin_unlock_irq(&phba->hbalock); | ||
| 2263 | vport->unreg_vpi_cmpl = VPORT_OK; | 2278 | vport->unreg_vpi_cmpl = VPORT_OK; |
| 2264 | mempool_free(pmb, phba->mbox_mem_pool); | 2279 | mempool_free(pmb, phba->mbox_mem_pool); |
| 2265 | /* | 2280 | /* |
| @@ -4475,8 +4490,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | |||
| 4475 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | 4490 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) |
| 4476 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 4491 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
| 4477 | lpfc_mbx_unreg_vpi(vports[i]); | 4492 | lpfc_mbx_unreg_vpi(vports[i]); |
| 4493 | spin_lock_irq(&phba->hbalock); | ||
| 4478 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 4494 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; |
| 4479 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; | 4495 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; |
| 4496 | spin_unlock_irq(&phba->hbalock); | ||
| 4480 | } | 4497 | } |
| 4481 | lpfc_destroy_vport_work_array(phba, vports); | 4498 | lpfc_destroy_vport_work_array(phba, vports); |
| 4482 | 4499 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 1585148a17e5..8a2a1c5935c6 100644..100755 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
| @@ -1013,7 +1013,7 @@ struct lpfc_mbx_wq_destroy { | |||
| 1013 | }; | 1013 | }; |
| 1014 | 1014 | ||
| 1015 | #define LPFC_HDR_BUF_SIZE 128 | 1015 | #define LPFC_HDR_BUF_SIZE 128 |
| 1016 | #define LPFC_DATA_BUF_SIZE 4096 | 1016 | #define LPFC_DATA_BUF_SIZE 2048 |
| 1017 | struct rq_context { | 1017 | struct rq_context { |
| 1018 | uint32_t word0; | 1018 | uint32_t word0; |
| 1019 | #define lpfc_rq_context_rq_size_SHIFT 16 | 1019 | #define lpfc_rq_context_rq_size_SHIFT 16 |
| @@ -1371,6 +1371,7 @@ struct lpfc_mbx_query_fw_cfg { | |||
| 1371 | #define STATUS_ERROR_ACITMAIN 0x2a | 1371 | #define STATUS_ERROR_ACITMAIN 0x2a |
| 1372 | #define STATUS_REBOOT_REQUIRED 0x2c | 1372 | #define STATUS_REBOOT_REQUIRED 0x2c |
| 1373 | #define STATUS_FCF_IN_USE 0x3a | 1373 | #define STATUS_FCF_IN_USE 0x3a |
| 1374 | #define STATUS_FCF_TABLE_EMPTY 0x43 | ||
| 1374 | 1375 | ||
| 1375 | struct lpfc_mbx_sli4_config { | 1376 | struct lpfc_mbx_sli4_config { |
| 1376 | struct mbox_header header; | 1377 | struct mbox_header header; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d4da6bdd0e73..b8eb1b6e5e77 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
| @@ -3006,6 +3006,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
| 3006 | struct lpfc_vport *vport; | 3006 | struct lpfc_vport *vport; |
| 3007 | struct lpfc_nodelist *ndlp; | 3007 | struct lpfc_nodelist *ndlp; |
| 3008 | struct Scsi_Host *shost; | 3008 | struct Scsi_Host *shost; |
| 3009 | uint32_t link_state; | ||
| 3009 | 3010 | ||
| 3010 | phba->fc_eventTag = acqe_fcoe->event_tag; | 3011 | phba->fc_eventTag = acqe_fcoe->event_tag; |
| 3011 | phba->fcoe_eventtag = acqe_fcoe->event_tag; | 3012 | phba->fcoe_eventtag = acqe_fcoe->event_tag; |
| @@ -3052,9 +3053,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
| 3052 | break; | 3053 | break; |
| 3053 | /* | 3054 | /* |
| 3054 | * Currently, driver support only one FCF - so treat this as | 3055 | * Currently, driver support only one FCF - so treat this as |
| 3055 | * a link down. | 3056 | * a link down, but save the link state because we don't want |
| 3057 | * it to be changed to Link Down unless it is already down. | ||
| 3056 | */ | 3058 | */ |
| 3059 | link_state = phba->link_state; | ||
| 3057 | lpfc_linkdown(phba); | 3060 | lpfc_linkdown(phba); |
| 3061 | phba->link_state = link_state; | ||
| 3058 | /* Unregister FCF if no devices connected to it */ | 3062 | /* Unregister FCF if no devices connected to it */ |
| 3059 | lpfc_unregister_unused_fcf(phba); | 3063 | lpfc_unregister_unused_fcf(phba); |
| 3060 | break; | 3064 | break; |
| @@ -7226,8 +7230,6 @@ lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba) | |||
| 7226 | { | 7230 | { |
| 7227 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7231 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 7228 | "2711 PCI channel permanent disable for failure\n"); | 7232 | "2711 PCI channel permanent disable for failure\n"); |
| 7229 | /* Block all SCSI devices' I/Os on the host */ | ||
| 7230 | lpfc_scsi_dev_block(phba); | ||
| 7231 | /* Clean up all driver's outstanding SCSI I/Os */ | 7233 | /* Clean up all driver's outstanding SCSI I/Os */ |
| 7232 | lpfc_sli_flush_fcp_rings(phba); | 7234 | lpfc_sli_flush_fcp_rings(phba); |
| 7233 | } | 7235 | } |
| @@ -7256,6 +7258,9 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) | |||
| 7256 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 7258 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
| 7257 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 7259 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
| 7258 | 7260 | ||
| 7261 | /* Block all SCSI devices' I/Os on the host */ | ||
| 7262 | lpfc_scsi_dev_block(phba); | ||
| 7263 | |||
| 7259 | switch (state) { | 7264 | switch (state) { |
| 7260 | case pci_channel_io_normal: | 7265 | case pci_channel_io_normal: |
| 7261 | /* Non-fatal error, prepare for recovery */ | 7266 | /* Non-fatal error, prepare for recovery */ |
| @@ -7507,6 +7512,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
| 7507 | error = -ENODEV; | 7512 | error = -ENODEV; |
| 7508 | goto out_free_sysfs_attr; | 7513 | goto out_free_sysfs_attr; |
| 7509 | } | 7514 | } |
| 7515 | /* Default to single FCP EQ for non-MSI-X */ | ||
| 7516 | if (phba->intr_type != MSIX) | ||
| 7517 | phba->cfg_fcp_eq_count = 1; | ||
| 7510 | /* Set up SLI-4 HBA */ | 7518 | /* Set up SLI-4 HBA */ |
| 7511 | if (lpfc_sli4_hba_setup(phba)) { | 7519 | if (lpfc_sli4_hba_setup(phba)) { |
| 7512 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7520 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 7935667b81a5..589549b2bf0e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
| @@ -1383,7 +1383,7 @@ lpfc_sli_hbq_to_firmware_s4(struct lpfc_hba *phba, uint32_t hbqno, | |||
| 1383 | /* HBQ for ELS and CT traffic. */ | 1383 | /* HBQ for ELS and CT traffic. */ |
| 1384 | static struct lpfc_hbq_init lpfc_els_hbq = { | 1384 | static struct lpfc_hbq_init lpfc_els_hbq = { |
| 1385 | .rn = 1, | 1385 | .rn = 1, |
| 1386 | .entry_count = 200, | 1386 | .entry_count = 256, |
| 1387 | .mask_count = 0, | 1387 | .mask_count = 0, |
| 1388 | .profile = 0, | 1388 | .profile = 0, |
| 1389 | .ring_mask = (1 << LPFC_ELS_RING), | 1389 | .ring_mask = (1 << LPFC_ELS_RING), |
| @@ -1482,8 +1482,11 @@ err: | |||
| 1482 | int | 1482 | int |
| 1483 | lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) | 1483 | lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) |
| 1484 | { | 1484 | { |
| 1485 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | 1485 | if (phba->sli_rev == LPFC_SLI_REV4) |
| 1486 | lpfc_hbq_defs[qno]->add_count)); | 1486 | return 0; |
| 1487 | else | ||
| 1488 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | ||
| 1489 | lpfc_hbq_defs[qno]->add_count); | ||
| 1487 | } | 1490 | } |
| 1488 | 1491 | ||
| 1489 | /** | 1492 | /** |
| @@ -1498,8 +1501,12 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) | |||
| 1498 | static int | 1501 | static int |
| 1499 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) | 1502 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) |
| 1500 | { | 1503 | { |
| 1501 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | 1504 | if (phba->sli_rev == LPFC_SLI_REV4) |
| 1502 | lpfc_hbq_defs[qno]->init_count)); | 1505 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, |
| 1506 | lpfc_hbq_defs[qno]->entry_count); | ||
| 1507 | else | ||
| 1508 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | ||
| 1509 | lpfc_hbq_defs[qno]->init_count); | ||
| 1503 | } | 1510 | } |
| 1504 | 1511 | ||
| 1505 | /** | 1512 | /** |
| @@ -4110,6 +4117,7 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
| 4110 | if (rc) { | 4117 | if (rc) { |
| 4111 | dma_free_coherent(&phba->pcidev->dev, dma_size, | 4118 | dma_free_coherent(&phba->pcidev->dev, dma_size, |
| 4112 | dmabuf->virt, dmabuf->phys); | 4119 | dmabuf->virt, dmabuf->phys); |
| 4120 | kfree(dmabuf); | ||
| 4113 | return -EIO; | 4121 | return -EIO; |
| 4114 | } | 4122 | } |
| 4115 | 4123 | ||
| @@ -5848,7 +5856,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 5848 | iocbq->iocb.un.ulpWord[3]); | 5856 | iocbq->iocb.un.ulpWord[3]); |
| 5849 | wqe->generic.word3 = 0; | 5857 | wqe->generic.word3 = 0; |
| 5850 | bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext); | 5858 | bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext); |
| 5851 | bf_set(wqe_xc, &wqe->generic, 1); | ||
| 5852 | /* The entire sequence is transmitted for this IOCB */ | 5859 | /* The entire sequence is transmitted for this IOCB */ |
| 5853 | xmit_len = total_len; | 5860 | xmit_len = total_len; |
| 5854 | cmnd = CMD_XMIT_SEQUENCE64_CR; | 5861 | cmnd = CMD_XMIT_SEQUENCE64_CR; |
| @@ -10944,7 +10951,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
| 10944 | return dmabuf; | 10951 | return dmabuf; |
| 10945 | } | 10952 | } |
| 10946 | temp_hdr = seq_dmabuf->hbuf.virt; | 10953 | temp_hdr = seq_dmabuf->hbuf.virt; |
| 10947 | if (new_hdr->fh_seq_cnt < temp_hdr->fh_seq_cnt) { | 10954 | if (be16_to_cpu(new_hdr->fh_seq_cnt) < |
| 10955 | be16_to_cpu(temp_hdr->fh_seq_cnt)) { | ||
| 10948 | list_del_init(&seq_dmabuf->hbuf.list); | 10956 | list_del_init(&seq_dmabuf->hbuf.list); |
| 10949 | list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list); | 10957 | list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list); |
| 10950 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); | 10958 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); |
| @@ -10955,6 +10963,11 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
| 10955 | list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list); | 10963 | list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list); |
| 10956 | seq_dmabuf->time_stamp = jiffies; | 10964 | seq_dmabuf->time_stamp = jiffies; |
| 10957 | lpfc_update_rcv_time_stamp(vport); | 10965 | lpfc_update_rcv_time_stamp(vport); |
| 10966 | if (list_empty(&seq_dmabuf->dbuf.list)) { | ||
| 10967 | temp_hdr = dmabuf->hbuf.virt; | ||
| 10968 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); | ||
| 10969 | return seq_dmabuf; | ||
| 10970 | } | ||
| 10958 | /* find the correct place in the sequence to insert this frame */ | 10971 | /* find the correct place in the sequence to insert this frame */ |
| 10959 | list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { | 10972 | list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { |
| 10960 | temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 10973 | temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
| @@ -10963,7 +10976,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
| 10963 | * If the frame's sequence count is greater than the frame on | 10976 | * If the frame's sequence count is greater than the frame on |
| 10964 | * the list then insert the frame right after this frame | 10977 | * the list then insert the frame right after this frame |
| 10965 | */ | 10978 | */ |
| 10966 | if (new_hdr->fh_seq_cnt > temp_hdr->fh_seq_cnt) { | 10979 | if (be16_to_cpu(new_hdr->fh_seq_cnt) > |
| 10980 | be16_to_cpu(temp_hdr->fh_seq_cnt)) { | ||
| 10967 | list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); | 10981 | list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); |
| 10968 | return seq_dmabuf; | 10982 | return seq_dmabuf; |
| 10969 | } | 10983 | } |
| @@ -11210,7 +11224,7 @@ lpfc_seq_complete(struct hbq_dmabuf *dmabuf) | |||
| 11210 | seq_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 11224 | seq_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
| 11211 | hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; | 11225 | hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; |
| 11212 | /* If there is a hole in the sequence count then fail. */ | 11226 | /* If there is a hole in the sequence count then fail. */ |
| 11213 | if (++seq_count != hdr->fh_seq_cnt) | 11227 | if (++seq_count != be16_to_cpu(hdr->fh_seq_cnt)) |
| 11214 | return 0; | 11228 | return 0; |
| 11215 | fctl = (hdr->fh_f_ctl[0] << 16 | | 11229 | fctl = (hdr->fh_f_ctl[0] << 16 | |
| 11216 | hdr->fh_f_ctl[1] << 8 | | 11230 | hdr->fh_f_ctl[1] << 8 | |
| @@ -11242,6 +11256,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
| 11242 | struct lpfc_iocbq *first_iocbq, *iocbq; | 11256 | struct lpfc_iocbq *first_iocbq, *iocbq; |
| 11243 | struct fc_frame_header *fc_hdr; | 11257 | struct fc_frame_header *fc_hdr; |
| 11244 | uint32_t sid; | 11258 | uint32_t sid; |
| 11259 | struct ulp_bde64 *pbde; | ||
| 11245 | 11260 | ||
| 11246 | fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; | 11261 | fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; |
| 11247 | /* remove from receive buffer list */ | 11262 | /* remove from receive buffer list */ |
| @@ -11283,8 +11298,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
| 11283 | if (!iocbq->context3) { | 11298 | if (!iocbq->context3) { |
| 11284 | iocbq->context3 = d_buf; | 11299 | iocbq->context3 = d_buf; |
| 11285 | iocbq->iocb.ulpBdeCount++; | 11300 | iocbq->iocb.ulpBdeCount++; |
| 11286 | iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize = | 11301 | pbde = (struct ulp_bde64 *) |
| 11287 | LPFC_DATA_BUF_SIZE; | 11302 | &iocbq->iocb.unsli3.sli3Words[4]; |
| 11303 | pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE; | ||
| 11288 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | 11304 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += |
| 11289 | bf_get(lpfc_rcqe_length, | 11305 | bf_get(lpfc_rcqe_length, |
| 11290 | &seq_dmabuf->cq_event.cqe.rcqe_cmpl); | 11306 | &seq_dmabuf->cq_event.cqe.rcqe_cmpl); |
| @@ -11401,15 +11417,9 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, | |||
| 11401 | return; | 11417 | return; |
| 11402 | } | 11418 | } |
| 11403 | /* If not last frame in sequence continue processing frames. */ | 11419 | /* If not last frame in sequence continue processing frames. */ |
| 11404 | if (!lpfc_seq_complete(seq_dmabuf)) { | 11420 | if (!lpfc_seq_complete(seq_dmabuf)) |
| 11405 | /* | ||
| 11406 | * When saving off frames post a new one and mark this | ||
| 11407 | * frame to be freed when it is finished. | ||
| 11408 | **/ | ||
| 11409 | lpfc_sli_hbqbuf_fill_hbqs(phba, LPFC_ELS_HBQ, 1); | ||
| 11410 | dmabuf->tag = -1; | ||
| 11411 | return; | 11421 | return; |
| 11412 | } | 11422 | |
| 11413 | /* Send the complete sequence to the upper layer protocol */ | 11423 | /* Send the complete sequence to the upper layer protocol */ |
| 11414 | lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf); | 11424 | lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf); |
| 11415 | } | 11425 | } |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 25d66d070cf8..44e5f574236b 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | /* Multi-queue arrangement for fast-path FCP work queues */ | 28 | /* Multi-queue arrangement for fast-path FCP work queues */ |
| 29 | #define LPFC_FN_EQN_MAX 8 | 29 | #define LPFC_FN_EQN_MAX 8 |
| 30 | #define LPFC_SP_EQN_DEF 1 | 30 | #define LPFC_SP_EQN_DEF 1 |
| 31 | #define LPFC_FP_EQN_DEF 1 | 31 | #define LPFC_FP_EQN_DEF 4 |
| 32 | #define LPFC_FP_EQN_MIN 1 | 32 | #define LPFC_FP_EQN_MIN 1 |
| 33 | #define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF) | 33 | #define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF) |
| 34 | 34 | ||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index c7f3aed2aab8..792f72263f1a 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | * included with this package. * | 18 | * included with this package. * |
| 19 | *******************************************************************/ | 19 | *******************************************************************/ |
| 20 | 20 | ||
| 21 | #define LPFC_DRIVER_VERSION "8.3.6" | 21 | #define LPFC_DRIVER_VERSION "8.3.7" |
| 22 | #define LPFC_DRIVER_NAME "lpfc" | 22 | #define LPFC_DRIVER_NAME "lpfc" |
| 23 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" | 23 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" |
| 24 | #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" | 24 | #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" |
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 7d6dd83d3592..e3c7fa642306 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
| @@ -512,8 +512,10 @@ enable_vport(struct fc_vport *fc_vport) | |||
| 512 | return VPORT_OK; | 512 | return VPORT_OK; |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | spin_lock_irq(&phba->hbalock); | ||
| 515 | vport->load_flag |= FC_LOADING; | 516 | vport->load_flag |= FC_LOADING; |
| 516 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 517 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
| 518 | spin_unlock_irq(&phba->hbalock); | ||
| 517 | 519 | ||
| 518 | /* Use the Physical nodes Fabric NDLP to determine if the link is | 520 | /* Use the Physical nodes Fabric NDLP to determine if the link is |
| 519 | * up and ready to FDISC. | 521 | * up and ready to FDISC. |
| @@ -700,7 +702,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
| 700 | } | 702 | } |
| 701 | spin_unlock_irq(&phba->ndlp_lock); | 703 | spin_unlock_irq(&phba->ndlp_lock); |
| 702 | } | 704 | } |
| 703 | if (vport->vpi_state != LPFC_VPI_REGISTERED) | 705 | if (!(vport->vpi_state & LPFC_VPI_REGISTERED)) |
| 704 | goto skip_logo; | 706 | goto skip_logo; |
| 705 | vport->unreg_vpi_cmpl = VPORT_INVAL; | 707 | vport->unreg_vpi_cmpl = VPORT_INVAL; |
| 706 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 708 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index e7d2688fbeba..b6f1ef954af1 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
| @@ -2483,14 +2483,12 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd) | |||
| 2483 | sense_copied = 1; | 2483 | sense_copied = 1; |
| 2484 | } | 2484 | } |
| 2485 | 2485 | ||
| 2486 | if (RES_IS_GSCSI(res->cfg_entry)) { | 2486 | if (RES_IS_GSCSI(res->cfg_entry)) |
| 2487 | pmcraid_cancel_all(cmd, sense_copied); | 2487 | pmcraid_cancel_all(cmd, sense_copied); |
| 2488 | } else if (sense_copied) { | 2488 | else if (sense_copied) |
| 2489 | pmcraid_erp_done(cmd); | 2489 | pmcraid_erp_done(cmd); |
| 2490 | return 0; | 2490 | else |
| 2491 | } else { | ||
| 2492 | pmcraid_request_sense(cmd); | 2491 | pmcraid_request_sense(cmd); |
| 2493 | } | ||
| 2494 | 2492 | ||
| 2495 | return 1; | 2493 | return 1; |
| 2496 | 2494 | ||
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 21e2bc4d7401..3a9f5b288aee 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
| @@ -232,6 +232,9 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
| 232 | if (off) | 232 | if (off) |
| 233 | return 0; | 233 | return 0; |
| 234 | 234 | ||
| 235 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
| 236 | return 0; | ||
| 237 | |||
| 235 | if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) | 238 | if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) |
| 236 | return -EINVAL; | 239 | return -EINVAL; |
| 237 | if (start > ha->optrom_size) | 240 | if (start > ha->optrom_size) |
| @@ -379,6 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, | |||
| 379 | struct device, kobj))); | 382 | struct device, kobj))); |
| 380 | struct qla_hw_data *ha = vha->hw; | 383 | struct qla_hw_data *ha = vha->hw; |
| 381 | 384 | ||
| 385 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
| 386 | return 0; | ||
| 387 | |||
| 382 | if (!capable(CAP_SYS_ADMIN)) | 388 | if (!capable(CAP_SYS_ADMIN)) |
| 383 | return 0; | 389 | return 0; |
| 384 | 390 | ||
| @@ -398,6 +404,9 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, | |||
| 398 | struct qla_hw_data *ha = vha->hw; | 404 | struct qla_hw_data *ha = vha->hw; |
| 399 | uint8_t *tmp_data; | 405 | uint8_t *tmp_data; |
| 400 | 406 | ||
| 407 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
| 408 | return 0; | ||
| 409 | |||
| 401 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || | 410 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || |
| 402 | !ha->isp_ops->write_nvram) | 411 | !ha->isp_ops->write_nvram) |
| 403 | return 0; | 412 | return 0; |
| @@ -1238,10 +1247,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr, | |||
| 1238 | char *buf) | 1247 | char *buf) |
| 1239 | { | 1248 | { |
| 1240 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1249 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
| 1241 | int rval; | 1250 | int rval = QLA_FUNCTION_FAILED; |
| 1242 | uint16_t state[5]; | 1251 | uint16_t state[5]; |
| 1243 | 1252 | ||
| 1244 | rval = qla2x00_get_firmware_state(vha, state); | 1253 | if (!vha->hw->flags.eeh_busy) |
| 1254 | rval = qla2x00_get_firmware_state(vha, state); | ||
| 1245 | if (rval != QLA_SUCCESS) | 1255 | if (rval != QLA_SUCCESS) |
| 1246 | memset(state, -1, sizeof(state)); | 1256 | memset(state, -1, sizeof(state)); |
| 1247 | 1257 | ||
| @@ -1452,10 +1462,13 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
| 1452 | if (!fcport) | 1462 | if (!fcport) |
| 1453 | return; | 1463 | return; |
| 1454 | 1464 | ||
| 1455 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) | 1465 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) |
| 1466 | return; | ||
| 1467 | |||
| 1468 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { | ||
| 1456 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); | 1469 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); |
| 1457 | else | 1470 | return; |
| 1458 | qla2x00_abort_fcport_cmds(fcport); | 1471 | } |
| 1459 | 1472 | ||
| 1460 | /* | 1473 | /* |
| 1461 | * Transport has effectively 'deleted' the rport, clear | 1474 | * Transport has effectively 'deleted' the rport, clear |
| @@ -1475,6 +1488,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) | |||
| 1475 | if (!fcport) | 1488 | if (!fcport) |
| 1476 | return; | 1489 | return; |
| 1477 | 1490 | ||
| 1491 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) | ||
| 1492 | return; | ||
| 1493 | |||
| 1478 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { | 1494 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { |
| 1479 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); | 1495 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); |
| 1480 | return; | 1496 | return; |
| @@ -1515,6 +1531,12 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
| 1515 | pfc_host_stat = &ha->fc_host_stat; | 1531 | pfc_host_stat = &ha->fc_host_stat; |
| 1516 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); | 1532 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); |
| 1517 | 1533 | ||
| 1534 | if (test_bit(UNLOADING, &vha->dpc_flags)) | ||
| 1535 | goto done; | ||
| 1536 | |||
| 1537 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
| 1538 | goto done; | ||
| 1539 | |||
| 1518 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); | 1540 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); |
| 1519 | if (stats == NULL) { | 1541 | if (stats == NULL) { |
| 1520 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", | 1542 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index f660dd70b72e..d6d9c86cb058 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ | 26 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ |
| 27 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ | 27 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ |
| 28 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ | 28 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ |
| 29 | /* #define QL_DEBUG_LEVEL_17 */ /* Output MULTI-Q trace messages */ | 29 | /* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */ |
| 30 | 30 | ||
| 31 | /* | 31 | /* |
| 32 | * Macros use for debugging the driver. | 32 | * Macros use for debugging the driver. |
| @@ -132,6 +132,13 @@ | |||
| 132 | #else | 132 | #else |
| 133 | #define DEBUG16(x) do {} while (0) | 133 | #define DEBUG16(x) do {} while (0) |
| 134 | #endif | 134 | #endif |
| 135 | |||
| 136 | #if defined(QL_DEBUG_LEVEL_17) | ||
| 137 | #define DEBUG17(x) do {x;} while (0) | ||
| 138 | #else | ||
| 139 | #define DEBUG17(x) do {} while (0) | ||
| 140 | #endif | ||
| 141 | |||
| 135 | /* | 142 | /* |
| 136 | * Firmware Dump structure definition | 143 | * Firmware Dump structure definition |
| 137 | */ | 144 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 384afda7dbe9..608e675f68c8 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -2256,11 +2256,13 @@ struct qla_hw_data { | |||
| 2256 | uint32_t disable_serdes :1; | 2256 | uint32_t disable_serdes :1; |
| 2257 | uint32_t gpsc_supported :1; | 2257 | uint32_t gpsc_supported :1; |
| 2258 | uint32_t npiv_supported :1; | 2258 | uint32_t npiv_supported :1; |
| 2259 | uint32_t pci_channel_io_perm_failure :1; | ||
| 2259 | uint32_t fce_enabled :1; | 2260 | uint32_t fce_enabled :1; |
| 2260 | uint32_t fac_supported :1; | 2261 | uint32_t fac_supported :1; |
| 2261 | uint32_t chip_reset_done :1; | 2262 | uint32_t chip_reset_done :1; |
| 2262 | uint32_t port0 :1; | 2263 | uint32_t port0 :1; |
| 2263 | uint32_t running_gold_fw :1; | 2264 | uint32_t running_gold_fw :1; |
| 2265 | uint32_t eeh_busy :1; | ||
| 2264 | uint32_t cpu_affinity_enabled :1; | 2266 | uint32_t cpu_affinity_enabled :1; |
| 2265 | uint32_t disable_msix_handshake :1; | 2267 | uint32_t disable_msix_handshake :1; |
| 2266 | } flags; | 2268 | } flags; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 0b6801fc6389..f61fb8d01330 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
| @@ -324,6 +324,7 @@ qla2x00_read_ram_word(scsi_qla_host_t *, uint32_t, uint32_t *); | |||
| 324 | extern int | 324 | extern int |
| 325 | qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); | 325 | qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); |
| 326 | 326 | ||
| 327 | extern int qla2x00_get_data_rate(scsi_qla_host_t *); | ||
| 327 | /* | 328 | /* |
| 328 | * Global Function Prototypes in qla_isr.c source file. | 329 | * Global Function Prototypes in qla_isr.c source file. |
| 329 | */ | 330 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 73a793539d45..b4a0eac8f96d 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -269,6 +269,8 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
| 269 | vha->flags.online = 0; | 269 | vha->flags.online = 0; |
| 270 | ha->flags.chip_reset_done = 0; | 270 | ha->flags.chip_reset_done = 0; |
| 271 | vha->flags.reset_active = 0; | 271 | vha->flags.reset_active = 0; |
| 272 | ha->flags.pci_channel_io_perm_failure = 0; | ||
| 273 | ha->flags.eeh_busy = 0; | ||
| 272 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); | 274 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
| 273 | atomic_set(&vha->loop_state, LOOP_DOWN); | 275 | atomic_set(&vha->loop_state, LOOP_DOWN); |
| 274 | vha->device_flags = DFLG_NO_CABLE; | 276 | vha->device_flags = DFLG_NO_CABLE; |
| @@ -581,6 +583,9 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) | |||
| 581 | uint32_t cnt; | 583 | uint32_t cnt; |
| 582 | uint16_t cmd; | 584 | uint16_t cmd; |
| 583 | 585 | ||
| 586 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
| 587 | return; | ||
| 588 | |||
| 584 | ha->isp_ops->disable_intrs(ha); | 589 | ha->isp_ops->disable_intrs(ha); |
| 585 | 590 | ||
| 586 | spin_lock_irqsave(&ha->hardware_lock, flags); | 591 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| @@ -786,6 +791,12 @@ void | |||
| 786 | qla24xx_reset_chip(scsi_qla_host_t *vha) | 791 | qla24xx_reset_chip(scsi_qla_host_t *vha) |
| 787 | { | 792 | { |
| 788 | struct qla_hw_data *ha = vha->hw; | 793 | struct qla_hw_data *ha = vha->hw; |
| 794 | |||
| 795 | if (pci_channel_offline(ha->pdev) && | ||
| 796 | ha->flags.pci_channel_io_perm_failure) { | ||
| 797 | return; | ||
| 798 | } | ||
| 799 | |||
| 789 | ha->isp_ops->disable_intrs(ha); | 800 | ha->isp_ops->disable_intrs(ha); |
| 790 | 801 | ||
| 791 | /* Perform RISC reset. */ | 802 | /* Perform RISC reset. */ |
| @@ -2266,6 +2277,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
| 2266 | clear_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | 2277 | clear_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
| 2267 | clear_bit(RSCN_UPDATE, &vha->dpc_flags); | 2278 | clear_bit(RSCN_UPDATE, &vha->dpc_flags); |
| 2268 | 2279 | ||
| 2280 | qla2x00_get_data_rate(vha); | ||
| 2281 | |||
| 2269 | /* Determine what we need to do */ | 2282 | /* Determine what we need to do */ |
| 2270 | if (ha->current_topology == ISP_CFG_FL && | 2283 | if (ha->current_topology == ISP_CFG_FL && |
| 2271 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { | 2284 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { |
| @@ -3560,6 +3573,13 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) | |||
| 3560 | /* Requeue all commands in outstanding command list. */ | 3573 | /* Requeue all commands in outstanding command list. */ |
| 3561 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); | 3574 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); |
| 3562 | 3575 | ||
| 3576 | if (unlikely(pci_channel_offline(ha->pdev) && | ||
| 3577 | ha->flags.pci_channel_io_perm_failure)) { | ||
| 3578 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); | ||
| 3579 | status = 0; | ||
| 3580 | return status; | ||
| 3581 | } | ||
| 3582 | |||
| 3563 | ha->isp_ops->get_flash_version(vha, req->ring); | 3583 | ha->isp_ops->get_flash_version(vha, req->ring); |
| 3564 | 3584 | ||
| 3565 | ha->isp_ops->nvram_config(vha); | 3585 | ha->isp_ops->nvram_config(vha); |
| @@ -4458,6 +4478,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha) | |||
| 4458 | int ret, retries; | 4478 | int ret, retries; |
| 4459 | struct qla_hw_data *ha = vha->hw; | 4479 | struct qla_hw_data *ha = vha->hw; |
| 4460 | 4480 | ||
| 4481 | if (ha->flags.pci_channel_io_perm_failure) | ||
| 4482 | return; | ||
| 4461 | if (!IS_FWI2_CAPABLE(ha)) | 4483 | if (!IS_FWI2_CAPABLE(ha)) |
| 4462 | return; | 4484 | return; |
| 4463 | if (!ha->fw_major_version) | 4485 | if (!ha->fw_major_version) |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1692a883f4de..ffd0efdff40e 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
| @@ -152,7 +152,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
| 152 | for (iter = 50; iter--; ) { | 152 | for (iter = 50; iter--; ) { |
| 153 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 153 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
| 154 | if (stat & HSR_RISC_PAUSED) { | 154 | if (stat & HSR_RISC_PAUSED) { |
| 155 | if (pci_channel_offline(ha->pdev)) | 155 | if (unlikely(pci_channel_offline(ha->pdev))) |
| 156 | break; | 156 | break; |
| 157 | 157 | ||
| 158 | hccr = RD_REG_WORD(®->hccr); | 158 | hccr = RD_REG_WORD(®->hccr); |
| @@ -1846,12 +1846,15 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
| 1846 | reg = &ha->iobase->isp24; | 1846 | reg = &ha->iobase->isp24; |
| 1847 | status = 0; | 1847 | status = 0; |
| 1848 | 1848 | ||
| 1849 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
| 1850 | return IRQ_HANDLED; | ||
| 1851 | |||
| 1849 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1852 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| 1850 | vha = pci_get_drvdata(ha->pdev); | 1853 | vha = pci_get_drvdata(ha->pdev); |
| 1851 | for (iter = 50; iter--; ) { | 1854 | for (iter = 50; iter--; ) { |
| 1852 | stat = RD_REG_DWORD(®->host_status); | 1855 | stat = RD_REG_DWORD(®->host_status); |
| 1853 | if (stat & HSRX_RISC_PAUSED) { | 1856 | if (stat & HSRX_RISC_PAUSED) { |
| 1854 | if (pci_channel_offline(ha->pdev)) | 1857 | if (unlikely(pci_channel_offline(ha->pdev))) |
| 1855 | break; | 1858 | break; |
| 1856 | 1859 | ||
| 1857 | hccr = RD_REG_DWORD(®->hccr); | 1860 | hccr = RD_REG_DWORD(®->hccr); |
| @@ -1992,7 +1995,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
| 1992 | do { | 1995 | do { |
| 1993 | stat = RD_REG_DWORD(®->host_status); | 1996 | stat = RD_REG_DWORD(®->host_status); |
| 1994 | if (stat & HSRX_RISC_PAUSED) { | 1997 | if (stat & HSRX_RISC_PAUSED) { |
| 1995 | if (pci_channel_offline(ha->pdev)) | 1998 | if (unlikely(pci_channel_offline(ha->pdev))) |
| 1996 | break; | 1999 | break; |
| 1997 | 2000 | ||
| 1998 | hccr = RD_REG_DWORD(®->hccr); | 2001 | hccr = RD_REG_DWORD(®->hccr); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 05d595d9a7ef..056e4d4505f3 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
| @@ -56,6 +56,12 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
| 56 | 56 | ||
| 57 | DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); | 57 | DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); |
| 58 | 58 | ||
| 59 | if (ha->flags.pci_channel_io_perm_failure) { | ||
| 60 | DEBUG(printk("%s(%ld): Perm failure on EEH, timeout MBX " | ||
| 61 | "Exiting.\n", __func__, vha->host_no)); | ||
| 62 | return QLA_FUNCTION_TIMEOUT; | ||
| 63 | } | ||
| 64 | |||
| 59 | /* | 65 | /* |
| 60 | * Wait for active mailbox commands to finish by waiting at most tov | 66 | * Wait for active mailbox commands to finish by waiting at most tov |
| 61 | * seconds. This is to serialize actual issuing of mailbox cmds during | 67 | * seconds. This is to serialize actual issuing of mailbox cmds during |
| @@ -154,10 +160,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
| 154 | /* Check for pending interrupts. */ | 160 | /* Check for pending interrupts. */ |
| 155 | qla2x00_poll(ha->rsp_q_map[0]); | 161 | qla2x00_poll(ha->rsp_q_map[0]); |
| 156 | 162 | ||
| 157 | if (command != MBC_LOAD_RISC_RAM_EXTENDED && | 163 | if (!ha->flags.mbox_int && |
| 158 | !ha->flags.mbox_int) | 164 | !(IS_QLA2200(ha) && |
| 165 | command == MBC_LOAD_RISC_RAM_EXTENDED)) | ||
| 159 | msleep(10); | 166 | msleep(10); |
| 160 | } /* while */ | 167 | } /* while */ |
| 168 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
| 169 | "Waited %d sec\n", | ||
| 170 | (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ))); | ||
| 161 | } | 171 | } |
| 162 | 172 | ||
| 163 | /* Check whether we timed out */ | 173 | /* Check whether we timed out */ |
| @@ -227,7 +237,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
| 227 | 237 | ||
| 228 | if (rval == QLA_FUNCTION_TIMEOUT && | 238 | if (rval == QLA_FUNCTION_TIMEOUT && |
| 229 | mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { | 239 | mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { |
| 230 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { | 240 | if (!io_lock_on || (mcp->flags & IOCTL_CMD) || |
| 241 | ha->flags.eeh_busy) { | ||
| 231 | /* not in dpc. schedule it for dpc to take over. */ | 242 | /* not in dpc. schedule it for dpc to take over. */ |
| 232 | DEBUG(printk("%s(%ld): timeout schedule " | 243 | DEBUG(printk("%s(%ld): timeout schedule " |
| 233 | "isp_abort_needed.\n", __func__, | 244 | "isp_abort_needed.\n", __func__, |
| @@ -237,7 +248,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
| 237 | base_vha->host_no)); | 248 | base_vha->host_no)); |
| 238 | qla_printk(KERN_WARNING, ha, | 249 | qla_printk(KERN_WARNING, ha, |
| 239 | "Mailbox command timeout occurred. Scheduling ISP " | 250 | "Mailbox command timeout occurred. Scheduling ISP " |
| 240 | "abort.\n"); | 251 | "abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy); |
| 241 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | 252 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); |
| 242 | qla2xxx_wake_dpc(vha); | 253 | qla2xxx_wake_dpc(vha); |
| 243 | } else if (!abort_active) { | 254 | } else if (!abort_active) { |
| @@ -2530,6 +2541,9 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, | |||
| 2530 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2541 | if (!IS_FWI2_CAPABLE(vha->hw)) |
| 2531 | return QLA_FUNCTION_FAILED; | 2542 | return QLA_FUNCTION_FAILED; |
| 2532 | 2543 | ||
| 2544 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
| 2545 | return QLA_FUNCTION_FAILED; | ||
| 2546 | |||
| 2533 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2547 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
| 2534 | 2548 | ||
| 2535 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2549 | mcp->mb[0] = MBC_TRACE_CONTROL; |
| @@ -2565,6 +2579,9 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *vha) | |||
| 2565 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2579 | if (!IS_FWI2_CAPABLE(vha->hw)) |
| 2566 | return QLA_FUNCTION_FAILED; | 2580 | return QLA_FUNCTION_FAILED; |
| 2567 | 2581 | ||
| 2582 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
| 2583 | return QLA_FUNCTION_FAILED; | ||
| 2584 | |||
| 2568 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2585 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
| 2569 | 2586 | ||
| 2570 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2587 | mcp->mb[0] = MBC_TRACE_CONTROL; |
| @@ -2595,6 +2612,9 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, | |||
| 2595 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) | 2612 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) |
| 2596 | return QLA_FUNCTION_FAILED; | 2613 | return QLA_FUNCTION_FAILED; |
| 2597 | 2614 | ||
| 2615 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
| 2616 | return QLA_FUNCTION_FAILED; | ||
| 2617 | |||
| 2598 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2618 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
| 2599 | 2619 | ||
| 2600 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2620 | mcp->mb[0] = MBC_TRACE_CONTROL; |
| @@ -2639,6 +2659,9 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) | |||
| 2639 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2659 | if (!IS_FWI2_CAPABLE(vha->hw)) |
| 2640 | return QLA_FUNCTION_FAILED; | 2660 | return QLA_FUNCTION_FAILED; |
| 2641 | 2661 | ||
| 2662 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
| 2663 | return QLA_FUNCTION_FAILED; | ||
| 2664 | |||
| 2642 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2665 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
| 2643 | 2666 | ||
| 2644 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2667 | mcp->mb[0] = MBC_TRACE_CONTROL; |
| @@ -3643,3 +3666,36 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) | |||
| 3643 | 3666 | ||
| 3644 | return rval; | 3667 | return rval; |
| 3645 | } | 3668 | } |
| 3669 | |||
| 3670 | int | ||
| 3671 | qla2x00_get_data_rate(scsi_qla_host_t *vha) | ||
| 3672 | { | ||
| 3673 | int rval; | ||
| 3674 | mbx_cmd_t mc; | ||
| 3675 | mbx_cmd_t *mcp = &mc; | ||
| 3676 | struct qla_hw_data *ha = vha->hw; | ||
| 3677 | |||
| 3678 | if (!IS_FWI2_CAPABLE(ha)) | ||
| 3679 | return QLA_FUNCTION_FAILED; | ||
| 3680 | |||
| 3681 | DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, vha->host_no)); | ||
| 3682 | |||
| 3683 | mcp->mb[0] = MBC_DATA_RATE; | ||
| 3684 | mcp->mb[1] = 0; | ||
| 3685 | mcp->out_mb = MBX_1|MBX_0; | ||
| 3686 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | ||
| 3687 | mcp->tov = MBX_TOV_SECONDS; | ||
| 3688 | mcp->flags = 0; | ||
| 3689 | rval = qla2x00_mailbox_command(vha, mcp); | ||
| 3690 | if (rval != QLA_SUCCESS) { | ||
| 3691 | DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n", | ||
| 3692 | __func__, vha->host_no, rval, mcp->mb[0])); | ||
| 3693 | } else { | ||
| 3694 | DEBUG11(printk(KERN_INFO | ||
| 3695 | "%s(%ld): done.\n", __func__, vha->host_no)); | ||
| 3696 | if (mcp->mb[1] != 0x7) | ||
| 3697 | ha->link_data_rate = mcp->mb[1]; | ||
| 3698 | } | ||
| 3699 | |||
| 3700 | return rval; | ||
| 3701 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 2a4c7f4e7b69..b901aa267e7d 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
| @@ -639,8 +639,10 @@ static void qla_do_work(struct work_struct *work) | |||
| 639 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); | 639 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); |
| 640 | struct scsi_qla_host *vha; | 640 | struct scsi_qla_host *vha; |
| 641 | 641 | ||
| 642 | spin_lock_irq(&rsp->hw->hardware_lock); | ||
| 642 | vha = qla25xx_get_host(rsp); | 643 | vha = qla25xx_get_host(rsp); |
| 643 | qla24xx_process_response_queue(vha, rsp); | 644 | qla24xx_process_response_queue(vha, rsp); |
| 645 | spin_unlock_irq(&rsp->hw->hardware_lock); | ||
| 644 | } | 646 | } |
| 645 | 647 | ||
| 646 | /* create response queue */ | 648 | /* create response queue */ |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 2f873d237325..209f50e788a1 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -475,11 +475,11 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
| 475 | srb_t *sp; | 475 | srb_t *sp; |
| 476 | int rval; | 476 | int rval; |
| 477 | 477 | ||
| 478 | if (unlikely(pci_channel_offline(ha->pdev))) { | 478 | if (ha->flags.eeh_busy) { |
| 479 | if (ha->pdev->error_state == pci_channel_io_frozen) | 479 | if (ha->flags.pci_channel_io_perm_failure) |
| 480 | cmd->result = DID_REQUEUE << 16; | ||
| 481 | else | ||
| 482 | cmd->result = DID_NO_CONNECT << 16; | 480 | cmd->result = DID_NO_CONNECT << 16; |
| 481 | else | ||
| 482 | cmd->result = DID_REQUEUE << 16; | ||
| 483 | goto qc24_fail_command; | 483 | goto qc24_fail_command; |
| 484 | } | 484 | } |
| 485 | 485 | ||
| @@ -552,8 +552,15 @@ qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) | |||
| 552 | #define ABORT_POLLING_PERIOD 1000 | 552 | #define ABORT_POLLING_PERIOD 1000 |
| 553 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) | 553 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) |
| 554 | unsigned long wait_iter = ABORT_WAIT_ITER; | 554 | unsigned long wait_iter = ABORT_WAIT_ITER; |
| 555 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | ||
| 556 | struct qla_hw_data *ha = vha->hw; | ||
| 555 | int ret = QLA_SUCCESS; | 557 | int ret = QLA_SUCCESS; |
| 556 | 558 | ||
| 559 | if (unlikely(pci_channel_offline(ha->pdev)) || ha->flags.eeh_busy) { | ||
| 560 | DEBUG17(qla_printk(KERN_WARNING, ha, "return:eh_wait\n")); | ||
| 561 | return ret; | ||
| 562 | } | ||
| 563 | |||
| 557 | while (CMD_SP(cmd) && wait_iter--) { | 564 | while (CMD_SP(cmd) && wait_iter--) { |
| 558 | msleep(ABORT_POLLING_PERIOD); | 565 | msleep(ABORT_POLLING_PERIOD); |
| 559 | } | 566 | } |
| @@ -1810,6 +1817,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1810 | 1817 | ||
| 1811 | /* Set ISP-type information. */ | 1818 | /* Set ISP-type information. */ |
| 1812 | qla2x00_set_isp_flags(ha); | 1819 | qla2x00_set_isp_flags(ha); |
| 1820 | |||
| 1821 | /* Set EEH reset type to fundamental if required by hba */ | ||
| 1822 | if ( IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) { | ||
| 1823 | pdev->needs_freset = 1; | ||
| 1824 | pci_save_state(pdev); | ||
| 1825 | } | ||
| 1826 | |||
| 1813 | /* Configure PCI I/O space */ | 1827 | /* Configure PCI I/O space */ |
| 1814 | ret = qla2x00_iospace_config(ha); | 1828 | ret = qla2x00_iospace_config(ha); |
| 1815 | if (ret) | 1829 | if (ret) |
| @@ -2174,6 +2188,24 @@ qla2x00_free_device(scsi_qla_host_t *vha) | |||
| 2174 | { | 2188 | { |
| 2175 | struct qla_hw_data *ha = vha->hw; | 2189 | struct qla_hw_data *ha = vha->hw; |
| 2176 | 2190 | ||
| 2191 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); | ||
| 2192 | |||
| 2193 | /* Disable timer */ | ||
| 2194 | if (vha->timer_active) | ||
| 2195 | qla2x00_stop_timer(vha); | ||
| 2196 | |||
| 2197 | /* Kill the kernel thread for this host */ | ||
| 2198 | if (ha->dpc_thread) { | ||
| 2199 | struct task_struct *t = ha->dpc_thread; | ||
| 2200 | |||
| 2201 | /* | ||
| 2202 | * qla2xxx_wake_dpc checks for ->dpc_thread | ||
| 2203 | * so we need to zero it out. | ||
| 2204 | */ | ||
| 2205 | ha->dpc_thread = NULL; | ||
| 2206 | kthread_stop(t); | ||
| 2207 | } | ||
| 2208 | |||
| 2177 | qla25xx_delete_queues(vha); | 2209 | qla25xx_delete_queues(vha); |
| 2178 | 2210 | ||
| 2179 | if (ha->flags.fce_enabled) | 2211 | if (ha->flags.fce_enabled) |
| @@ -2185,6 +2217,8 @@ qla2x00_free_device(scsi_qla_host_t *vha) | |||
| 2185 | /* Stop currently executing firmware. */ | 2217 | /* Stop currently executing firmware. */ |
| 2186 | qla2x00_try_to_stop_firmware(vha); | 2218 | qla2x00_try_to_stop_firmware(vha); |
| 2187 | 2219 | ||
| 2220 | vha->flags.online = 0; | ||
| 2221 | |||
| 2188 | /* turn-off interrupts on the card */ | 2222 | /* turn-off interrupts on the card */ |
| 2189 | if (ha->interrupts_on) | 2223 | if (ha->interrupts_on) |
| 2190 | ha->isp_ops->disable_intrs(ha); | 2224 | ha->isp_ops->disable_intrs(ha); |
| @@ -2859,6 +2893,13 @@ qla2x00_do_dpc(void *data) | |||
| 2859 | if (!base_vha->flags.init_done) | 2893 | if (!base_vha->flags.init_done) |
| 2860 | continue; | 2894 | continue; |
| 2861 | 2895 | ||
| 2896 | if (ha->flags.eeh_busy) { | ||
| 2897 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
| 2898 | "qla2x00_do_dpc: dpc_flags: %lx\n", | ||
| 2899 | base_vha->dpc_flags)); | ||
| 2900 | continue; | ||
| 2901 | } | ||
| 2902 | |||
| 2862 | DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no)); | 2903 | DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no)); |
| 2863 | 2904 | ||
| 2864 | ha->dpc_active = 1; | 2905 | ha->dpc_active = 1; |
| @@ -3049,8 +3090,13 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
| 3049 | int index; | 3090 | int index; |
| 3050 | srb_t *sp; | 3091 | srb_t *sp; |
| 3051 | int t; | 3092 | int t; |
| 3093 | uint16_t w; | ||
| 3052 | struct qla_hw_data *ha = vha->hw; | 3094 | struct qla_hw_data *ha = vha->hw; |
| 3053 | struct req_que *req; | 3095 | struct req_que *req; |
| 3096 | |||
| 3097 | /* Hardware read to raise pending EEH errors during mailbox waits. */ | ||
| 3098 | if (!pci_channel_offline(ha->pdev)) | ||
| 3099 | pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); | ||
| 3054 | /* | 3100 | /* |
| 3055 | * Ports - Port down timer. | 3101 | * Ports - Port down timer. |
| 3056 | * | 3102 | * |
| @@ -3252,16 +3298,23 @@ qla2x00_release_firmware(void) | |||
| 3252 | static pci_ers_result_t | 3298 | static pci_ers_result_t |
| 3253 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | 3299 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) |
| 3254 | { | 3300 | { |
| 3255 | scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); | 3301 | scsi_qla_host_t *vha = pci_get_drvdata(pdev); |
| 3302 | struct qla_hw_data *ha = vha->hw; | ||
| 3303 | |||
| 3304 | DEBUG2(qla_printk(KERN_WARNING, ha, "error_detected:state %x\n", | ||
| 3305 | state)); | ||
| 3256 | 3306 | ||
| 3257 | switch (state) { | 3307 | switch (state) { |
| 3258 | case pci_channel_io_normal: | 3308 | case pci_channel_io_normal: |
| 3309 | ha->flags.eeh_busy = 0; | ||
| 3259 | return PCI_ERS_RESULT_CAN_RECOVER; | 3310 | return PCI_ERS_RESULT_CAN_RECOVER; |
| 3260 | case pci_channel_io_frozen: | 3311 | case pci_channel_io_frozen: |
| 3312 | ha->flags.eeh_busy = 1; | ||
| 3261 | pci_disable_device(pdev); | 3313 | pci_disable_device(pdev); |
| 3262 | return PCI_ERS_RESULT_NEED_RESET; | 3314 | return PCI_ERS_RESULT_NEED_RESET; |
| 3263 | case pci_channel_io_perm_failure: | 3315 | case pci_channel_io_perm_failure: |
| 3264 | qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); | 3316 | ha->flags.pci_channel_io_perm_failure = 1; |
| 3317 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); | ||
| 3265 | return PCI_ERS_RESULT_DISCONNECT; | 3318 | return PCI_ERS_RESULT_DISCONNECT; |
| 3266 | } | 3319 | } |
| 3267 | return PCI_ERS_RESULT_NEED_RESET; | 3320 | return PCI_ERS_RESULT_NEED_RESET; |
| @@ -3312,6 +3365,8 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
| 3312 | struct qla_hw_data *ha = base_vha->hw; | 3365 | struct qla_hw_data *ha = base_vha->hw; |
| 3313 | int rc; | 3366 | int rc; |
| 3314 | 3367 | ||
| 3368 | DEBUG17(qla_printk(KERN_WARNING, ha, "slot_reset\n")); | ||
| 3369 | |||
| 3315 | if (ha->mem_only) | 3370 | if (ha->mem_only) |
| 3316 | rc = pci_enable_device_mem(pdev); | 3371 | rc = pci_enable_device_mem(pdev); |
| 3317 | else | 3372 | else |
| @@ -3320,19 +3375,33 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
| 3320 | if (rc) { | 3375 | if (rc) { |
| 3321 | qla_printk(KERN_WARNING, ha, | 3376 | qla_printk(KERN_WARNING, ha, |
| 3322 | "Can't re-enable PCI device after reset.\n"); | 3377 | "Can't re-enable PCI device after reset.\n"); |
| 3323 | |||
| 3324 | return ret; | 3378 | return ret; |
| 3325 | } | 3379 | } |
| 3326 | pci_set_master(pdev); | ||
| 3327 | 3380 | ||
| 3328 | if (ha->isp_ops->pci_config(base_vha)) | 3381 | if (ha->isp_ops->pci_config(base_vha)) |
| 3329 | return ret; | 3382 | return ret; |
| 3330 | 3383 | ||
| 3384 | #ifdef QL_DEBUG_LEVEL_17 | ||
| 3385 | { | ||
| 3386 | uint8_t b; | ||
| 3387 | uint32_t i; | ||
| 3388 | |||
| 3389 | printk("slot_reset_1: "); | ||
| 3390 | for (i = 0; i < 256; i++) { | ||
| 3391 | pci_read_config_byte(ha->pdev, i, &b); | ||
| 3392 | printk("%s%02x", (i%16) ? " " : "\n", b); | ||
| 3393 | } | ||
| 3394 | printk("\n"); | ||
| 3395 | } | ||
| 3396 | #endif | ||
| 3331 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | 3397 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
| 3332 | if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS) | 3398 | if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS) |
| 3333 | ret = PCI_ERS_RESULT_RECOVERED; | 3399 | ret = PCI_ERS_RESULT_RECOVERED; |
| 3334 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | 3400 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
| 3335 | 3401 | ||
| 3402 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
| 3403 | "slot_reset-return:ret=%x\n", ret)); | ||
| 3404 | |||
| 3336 | return ret; | 3405 | return ret; |
| 3337 | } | 3406 | } |
| 3338 | 3407 | ||
| @@ -3343,12 +3412,17 @@ qla2xxx_pci_resume(struct pci_dev *pdev) | |||
| 3343 | struct qla_hw_data *ha = base_vha->hw; | 3412 | struct qla_hw_data *ha = base_vha->hw; |
| 3344 | int ret; | 3413 | int ret; |
| 3345 | 3414 | ||
| 3415 | DEBUG17(qla_printk(KERN_WARNING, ha, "pci_resume\n")); | ||
| 3416 | |||
| 3346 | ret = qla2x00_wait_for_hba_online(base_vha); | 3417 | ret = qla2x00_wait_for_hba_online(base_vha); |
| 3347 | if (ret != QLA_SUCCESS) { | 3418 | if (ret != QLA_SUCCESS) { |
| 3348 | qla_printk(KERN_ERR, ha, | 3419 | qla_printk(KERN_ERR, ha, |
| 3349 | "the device failed to resume I/O " | 3420 | "the device failed to resume I/O " |
| 3350 | "from slot/link_reset"); | 3421 | "from slot/link_reset"); |
| 3351 | } | 3422 | } |
| 3423 | |||
| 3424 | ha->flags.eeh_busy = 0; | ||
| 3425 | |||
| 3352 | pci_cleanup_aer_uncorrect_error_status(pdev); | 3426 | pci_cleanup_aer_uncorrect_error_status(pdev); |
| 3353 | } | 3427 | } |
| 3354 | 3428 | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index c482220f7eed..a65dd95507c6 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | /* | 7 | /* |
| 8 | * Driver version | 8 | * Driver version |
| 9 | */ | 9 | */ |
| 10 | #define QLA2XXX_VERSION "8.03.01-k8" | 10 | #define QLA2XXX_VERSION "8.03.01-k9" |
| 11 | 11 | ||
| 12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
| 13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 3058bb1aff95..fd7b15be7640 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
| @@ -623,6 +623,11 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
| 623 | } | 623 | } |
| 624 | break; | 624 | break; |
| 625 | case INQUIRY: | 625 | case INQUIRY: |
| 626 | if (lun >= host->max_lun) { | ||
| 627 | cmd->result = DID_NO_CONNECT << 16; | ||
| 628 | done(cmd); | ||
| 629 | return 0; | ||
| 630 | } | ||
| 626 | if (id != host->max_id - 1) | 631 | if (id != host->max_id - 1) |
| 627 | break; | 632 | break; |
| 628 | if (!lun && !cmd->device->channel && | 633 | if (!lun && !cmd->device->channel && |
