aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaurav Kashyap <saurav.kashyap@qlogic.com>2012-08-22 14:21:01 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-24 04:10:47 -0400
commita9b6f722f62d0a302b980a4fdcdf9c9933955772 (patch)
treed353225c380d8183faddbf535a6116ada1a41279
parent5f16b331d83757ad5154af07b449c722fef45d5e (diff)
[SCSI] qla2xxx: Implementation of bidirectional.
[jejb: merge fix for introduced warning] Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c29
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c183
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.h16
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c9
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h23
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h38
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c198
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c167
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c1
11 files changed, 656 insertions, 12 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 5ab953029f8d..ff2439bd9b4b 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1251,6 +1251,31 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
1251 state[1], state[2], state[3], state[4]); 1251 state[1], state[2], state[3], state[4]);
1252} 1252}
1253 1253
1254static ssize_t
1255qla2x00_diag_requests_show(struct device *dev,
1256 struct device_attribute *attr, char *buf)
1257{
1258 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1259
1260 if (!IS_BIDI_CAPABLE(vha->hw))
1261 return snprintf(buf, PAGE_SIZE, "\n");
1262
1263 return snprintf(buf, PAGE_SIZE, "%llu\n", vha->bidi_stats.io_count);
1264}
1265
1266static ssize_t
1267qla2x00_diag_megabytes_show(struct device *dev,
1268 struct device_attribute *attr, char *buf)
1269{
1270 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1271
1272 if (!IS_BIDI_CAPABLE(vha->hw))
1273 return snprintf(buf, PAGE_SIZE, "\n");
1274
1275 return snprintf(buf, PAGE_SIZE, "%llu\n",
1276 vha->bidi_stats.transfer_bytes >> 20);
1277}
1278
1254static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); 1279static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
1255static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); 1280static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
1256static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); 1281static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
@@ -1289,6 +1314,8 @@ static DEVICE_ATTR(vn_port_mac_address, S_IRUGO,
1289static DEVICE_ATTR(fabric_param, S_IRUGO, qla2x00_fabric_param_show, NULL); 1314static DEVICE_ATTR(fabric_param, S_IRUGO, qla2x00_fabric_param_show, NULL);
1290static DEVICE_ATTR(fw_state, S_IRUGO, qla2x00_fw_state_show, NULL); 1315static DEVICE_ATTR(fw_state, S_IRUGO, qla2x00_fw_state_show, NULL);
1291static DEVICE_ATTR(thermal_temp, S_IRUGO, qla2x00_thermal_temp_show, NULL); 1316static DEVICE_ATTR(thermal_temp, S_IRUGO, qla2x00_thermal_temp_show, NULL);
1317static DEVICE_ATTR(diag_requests, S_IRUGO, qla2x00_diag_requests_show, NULL);
1318static DEVICE_ATTR(diag_megabytes, S_IRUGO, qla2x00_diag_megabytes_show, NULL);
1292 1319
1293struct device_attribute *qla2x00_host_attrs[] = { 1320struct device_attribute *qla2x00_host_attrs[] = {
1294 &dev_attr_driver_version, 1321 &dev_attr_driver_version,
@@ -1318,6 +1345,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
1318 &dev_attr_fw_state, 1345 &dev_attr_fw_state,
1319 &dev_attr_optrom_gold_fw_version, 1346 &dev_attr_optrom_gold_fw_version,
1320 &dev_attr_thermal_temp, 1347 &dev_attr_thermal_temp,
1348 &dev_attr_diag_requests,
1349 &dev_attr_diag_megabytes,
1321 NULL, 1350 NULL,
1322}; 1351};
1323 1352
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 462ac707b8d6..dac3427ebf24 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1650,6 +1650,186 @@ done:
1650} 1650}
1651 1651
1652static int 1652static int
1653qla24xx_process_bidir_cmd(struct fc_bsg_job *bsg_job)
1654{
1655 struct Scsi_Host *host = bsg_job->shost;
1656 scsi_qla_host_t *vha = shost_priv(host);
1657 struct qla_hw_data *ha = vha->hw;
1658 uint16_t thread_id;
1659 uint32_t rval = EXT_STATUS_OK;
1660 uint16_t req_sg_cnt = 0;
1661 uint16_t rsp_sg_cnt = 0;
1662 uint16_t nextlid = 0;
1663 uint32_t tot_dsds;
1664 srb_t *sp = NULL;
1665 uint32_t req_data_len = 0;
1666 uint32_t rsp_data_len = 0;
1667
1668 /* Check the type of the adapter */
1669 if (!IS_BIDI_CAPABLE(ha)) {
1670 ql_log(ql_log_warn, vha, 0x70a0,
1671 "This adapter is not supported\n");
1672 rval = EXT_STATUS_NOT_SUPPORTED;
1673 goto done;
1674 }
1675
1676 if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
1677 test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
1678 test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
1679 rval = EXT_STATUS_BUSY;
1680 goto done;
1681 }
1682
1683 /* Check if host is online */
1684 if (!vha->flags.online) {
1685 ql_log(ql_log_warn, vha, 0x70a1,
1686 "Host is not online\n");
1687 rval = EXT_STATUS_DEVICE_OFFLINE;
1688 goto done;
1689 }
1690
1691 /* Check if cable is plugged in or not */
1692 if (vha->device_flags & DFLG_NO_CABLE) {
1693 ql_log(ql_log_warn, vha, 0x70a2,
1694 "Cable is unplugged...\n");
1695 rval = EXT_STATUS_INVALID_CFG;
1696 goto done;
1697 }
1698
1699 /* Check if the switch is connected or not */
1700 if (ha->current_topology != ISP_CFG_F) {
1701 ql_log(ql_log_warn, vha, 0x70a3,
1702 "Host is not connected to the switch\n");
1703 rval = EXT_STATUS_INVALID_CFG;
1704 goto done;
1705 }
1706
1707 /* Check if operating mode is P2P */
1708 if (ha->operating_mode != P2P) {
1709 ql_log(ql_log_warn, vha, 0x70a4,
1710 "Host is operating mode is not P2p\n");
1711 rval = EXT_STATUS_INVALID_CFG;
1712 goto done;
1713 }
1714
1715 thread_id = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
1716
1717 mutex_lock(&ha->selflogin_lock);
1718 if (vha->self_login_loop_id == 0) {
1719 /* Initialize all required fields of fcport */
1720 vha->bidir_fcport.vha = vha;
1721 vha->bidir_fcport.d_id.b.al_pa = vha->d_id.b.al_pa;
1722 vha->bidir_fcport.d_id.b.area = vha->d_id.b.area;
1723 vha->bidir_fcport.d_id.b.domain = vha->d_id.b.domain;
1724 vha->bidir_fcport.loop_id = vha->loop_id;
1725
1726 if (qla2x00_fabric_login(vha, &(vha->bidir_fcport), &nextlid)) {
1727 ql_log(ql_log_warn, vha, 0x70a7,
1728 "Failed to login port %06X for bidirectional IOCB\n",
1729 vha->bidir_fcport.d_id.b24);
1730 mutex_unlock(&ha->selflogin_lock);
1731 rval = EXT_STATUS_MAILBOX;
1732 goto done;
1733 }
1734 vha->self_login_loop_id = nextlid - 1;
1735
1736 }
1737 /* Assign the self login loop id to fcport */
1738 mutex_unlock(&ha->selflogin_lock);
1739
1740 vha->bidir_fcport.loop_id = vha->self_login_loop_id;
1741
1742 req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1743 bsg_job->request_payload.sg_list,
1744 bsg_job->request_payload.sg_cnt,
1745 DMA_TO_DEVICE);
1746
1747 if (!req_sg_cnt) {
1748 rval = EXT_STATUS_NO_MEMORY;
1749 goto done;
1750 }
1751
1752 rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
1753 bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
1754 DMA_FROM_DEVICE);
1755
1756 if (!rsp_sg_cnt) {
1757 rval = EXT_STATUS_NO_MEMORY;
1758 goto done_unmap_req_sg;
1759 }
1760
1761 if ((req_sg_cnt != bsg_job->request_payload.sg_cnt) ||
1762 (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
1763 ql_dbg(ql_dbg_user, vha, 0x70a9,
1764 "Dma mapping resulted in different sg counts "
1765 "[request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt: "
1766 "%x dma_reply_sg_cnt: %x]\n",
1767 bsg_job->request_payload.sg_cnt, req_sg_cnt,
1768 bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
1769 rval = EXT_STATUS_NO_MEMORY;
1770 goto done_unmap_sg;
1771 }
1772
1773 if (req_data_len != rsp_data_len) {
1774 rval = EXT_STATUS_BUSY;
1775 ql_log(ql_log_warn, vha, 0x70aa,
1776 "req_data_len != rsp_data_len\n");
1777 goto done_unmap_sg;
1778 }
1779
1780 req_data_len = bsg_job->request_payload.payload_len;
1781 rsp_data_len = bsg_job->reply_payload.payload_len;
1782
1783
1784 /* Alloc SRB structure */
1785 sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
1786 if (!sp) {
1787 ql_dbg(ql_dbg_user, vha, 0x70ac,
1788 "Alloc SRB structure failed\n");
1789 rval = EXT_STATUS_NO_MEMORY;
1790 goto done_unmap_sg;
1791 }
1792
1793 /*Populate srb->ctx with bidir ctx*/
1794 sp->u.bsg_job = bsg_job;
1795 sp->free = qla2x00_bsg_sp_free;
1796 sp->type = SRB_BIDI_CMD;
1797 sp->done = qla2x00_bsg_job_done;
1798
1799 /* Add the read and write sg count */
1800 tot_dsds = rsp_sg_cnt + req_sg_cnt;
1801
1802 rval = qla2x00_start_bidir(sp, vha, tot_dsds);
1803 if (rval != EXT_STATUS_OK)
1804 goto done_free_srb;
1805 /* the bsg request will be completed in the interrupt handler */
1806 return rval;
1807
1808done_free_srb:
1809 mempool_free(sp, ha->srb_mempool);
1810done_unmap_sg:
1811 dma_unmap_sg(&ha->pdev->dev,
1812 bsg_job->reply_payload.sg_list,
1813 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1814done_unmap_req_sg:
1815 dma_unmap_sg(&ha->pdev->dev,
1816 bsg_job->request_payload.sg_list,
1817 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1818done:
1819
1820 /* Return an error vendor specific response
1821 * and complete the bsg request
1822 */
1823 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
1824 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1825 bsg_job->reply->reply_payload_rcv_len = 0;
1826 bsg_job->reply->result = (DID_OK) << 16;
1827 bsg_job->job_done(bsg_job);
1828 /* Always retrun success, vendor rsp carries correct status */
1829 return 0;
1830}
1831
1832static int
1653qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job) 1833qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
1654{ 1834{
1655 switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) { 1835 switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
@@ -1692,6 +1872,9 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
1692 case QL_VND_READ_I2C: 1872 case QL_VND_READ_I2C:
1693 return qla2x00_read_i2c(bsg_job); 1873 return qla2x00_read_i2c(bsg_job);
1694 1874
1875 case QL_VND_DIAG_IO_CMD:
1876 return qla24xx_process_bidir_cmd(bsg_job);
1877
1695 default: 1878 default:
1696 bsg_job->reply->result = (DID_ERROR << 16); 1879 bsg_job->reply->result = (DID_ERROR << 16);
1697 bsg_job->job_done(bsg_job); 1880 bsg_job->job_done(bsg_job);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h
index 1a0ab375ce43..1875ee10e589 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.h
+++ b/drivers/scsi/qla2xxx/qla_bsg.h
@@ -19,15 +19,31 @@
19#define QL_VND_SET_FRU_VERSION 0x0B 19#define QL_VND_SET_FRU_VERSION 0x0B
20#define QL_VND_READ_FRU_STATUS 0x0C 20#define QL_VND_READ_FRU_STATUS 0x0C
21#define QL_VND_WRITE_FRU_STATUS 0x0D 21#define QL_VND_WRITE_FRU_STATUS 0x0D
22#define QL_VND_DIAG_IO_CMD 0x0A
22#define QL_VND_WRITE_I2C 0x10 23#define QL_VND_WRITE_I2C 0x10
23#define QL_VND_READ_I2C 0x11 24#define QL_VND_READ_I2C 0x11
24 25
25/* BSG Vendor specific subcode returns */ 26/* BSG Vendor specific subcode returns */
26#define EXT_STATUS_OK 0 27#define EXT_STATUS_OK 0
27#define EXT_STATUS_ERR 1 28#define EXT_STATUS_ERR 1
29#define EXT_STATUS_BUSY 2
28#define EXT_STATUS_INVALID_PARAM 6 30#define EXT_STATUS_INVALID_PARAM 6
31#define EXT_STATUS_DATA_OVERRUN 7
32#define EXT_STATUS_DATA_UNDERRUN 8
29#define EXT_STATUS_MAILBOX 11 33#define EXT_STATUS_MAILBOX 11
30#define EXT_STATUS_NO_MEMORY 17 34#define EXT_STATUS_NO_MEMORY 17
35#define EXT_STATUS_DEVICE_OFFLINE 22
36
37/*
38 * To support bidirectional iocb
39 * BSG Vendor specific returns
40 */
41#define EXT_STATUS_NOT_SUPPORTED 27
42#define EXT_STATUS_INVALID_CFG 28
43#define EXT_STATUS_DMA_ERR 29
44#define EXT_STATUS_TIMEOUT 30
45#define EXT_STATUS_THREAD_FAILED 31
46#define EXT_STATUS_DATA_CMP_FAILED 32
31 47
32/* BSG definations for interpreting CommandSent field */ 48/* BSG definations for interpreting CommandSent field */
33#define INT_DEF_LB_LOOPBACK_CMD 0 49#define INT_DEF_LB_LOOPBACK_CMD 0
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 0c4fd2cebc17..156f5341a7a3 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -15,17 +15,20 @@
15 * | Mailbox commands | 0x1140 | 0x111a-0x111b | 15 * | Mailbox commands | 0x1140 | 0x111a-0x111b |
16 * | | | 0x112c-0x112e | 16 * | | | 0x112c-0x112e |
17 * | | | 0x113a | 17 * | | | 0x113a |
18 * | Device Discovery | 0x2086 | 0x2020-0x2022 | 18 * | Device Discovery | 0x2087 | 0x2020-0x2022 |
19 * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 | 19 * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 |
20 * | | | 0x302d-0x302e | 20 * | | | 0x302d-0x302e |
21 * | DPC Thread | 0x401c | 0x4002,0x4013 | 21 * | DPC Thread | 0x401c | 0x4002,0x4013 |
22 * | Async Events | 0x505f | 0x502b-0x502f | 22 * | Async Events | 0x505f | 0x502b-0x502f |
23 * | | | 0x5047,0x5052 | 23 * | | | 0x5047,0x5052 |
24 * | Timer Routines | 0x6011 | | 24 * | Timer Routines | 0x6011 | |
25 * | User Space Interactions | 0x709f | 0x7018,0x702e, | 25 * | User Space Interactions | 0x70bb | 0x7018,0x702e, |
26 * | | | 0x7039,0x7045, | 26 * | | | 0x7039,0x7045, |
27 * | | | 0x7073-0x7075, | 27 * | | | 0x7073-0x7075, |
28 * | | | 0x708c | 28 * | | | 0x708c, |
29 * | | | 0x70a5,0x70a6, |
30 * | | | 0x70a8,0x70ab, |
31 * | | | 0x70ad-0x70ae |
29 * | Task Management | 0x803c | 0x8025-0x8026 | 32 * | Task Management | 0x803c | 0x8025-0x8026 |
30 * | | | 0x800b,0x8039 | 33 * | | | 0x800b,0x8039 |
31 * | AER/EEH | 0x9011 | | 34 * | AER/EEH | 0x9011 | |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 28c0b3575616..7ff92ce42821 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -260,6 +260,7 @@ struct srb_iocb {
260#define SRB_ADISC_CMD 6 260#define SRB_ADISC_CMD 6
261#define SRB_TM_CMD 7 261#define SRB_TM_CMD 7
262#define SRB_SCSI_CMD 8 262#define SRB_SCSI_CMD 8
263#define SRB_BIDI_CMD 9
263 264
264typedef struct srb { 265typedef struct srb {
265 atomic_t ref_count; 266 atomic_t ref_count;
@@ -1510,6 +1511,13 @@ typedef struct {
1510#define CS_RETRY 0x82 /* Driver defined */ 1511#define CS_RETRY 0x82 /* Driver defined */
1511#define CS_LOOP_DOWN_ABORT 0x83 /* Driver defined */ 1512#define CS_LOOP_DOWN_ABORT 0x83 /* Driver defined */
1512 1513
1514#define CS_BIDIR_RD_OVERRUN 0x700
1515#define CS_BIDIR_RD_WR_OVERRUN 0x707
1516#define CS_BIDIR_RD_OVERRUN_WR_UNDERRUN 0x715
1517#define CS_BIDIR_RD_UNDERRUN 0x1500
1518#define CS_BIDIR_RD_UNDERRUN_WR_OVERRUN 0x1507
1519#define CS_BIDIR_RD_WR_UNDERRUN 0x1515
1520#define CS_BIDIR_DMA 0x200
1513/* 1521/*
1514 * Status entry status flags 1522 * Status entry status flags
1515 */ 1523 */
@@ -2374,6 +2382,11 @@ struct qla_statistics {
2374 uint64_t output_bytes; 2382 uint64_t output_bytes;
2375}; 2383};
2376 2384
2385struct bidi_statistics {
2386 unsigned long long io_count;
2387 unsigned long long transfer_bytes;
2388};
2389
2377/* Multi queue support */ 2390/* Multi queue support */
2378#define MBC_INITIALIZE_MULTIQ 0x1f 2391#define MBC_INITIALIZE_MULTIQ 0x1f
2379#define QLA_QUE_PAGE 0X1000 2392#define QLA_QUE_PAGE 0X1000
@@ -2671,6 +2684,7 @@ struct qla_hw_data {
2671#define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) 2684#define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS)
2672#define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED) 2685#define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED)
2673#define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha)) 2686#define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha))
2687#define IS_BIDI_CAPABLE(ha) ((IS_QLA25XX(ha) || IS_QLA2031(ha)))
2674 2688
2675 /* HBA serial number */ 2689 /* HBA serial number */
2676 uint8_t serial0; 2690 uint8_t serial0;
@@ -2754,6 +2768,7 @@ struct qla_hw_data {
2754 struct completion mbx_intr_comp; /* Used for completion notification */ 2768 struct completion mbx_intr_comp; /* Used for completion notification */
2755 struct completion dcbx_comp; /* For set port config notification */ 2769 struct completion dcbx_comp; /* For set port config notification */
2756 int notify_dcbx_comp; 2770 int notify_dcbx_comp;
2771 struct mutex selflogin_lock;
2757 2772
2758 /* Basic firmware related information. */ 2773 /* Basic firmware related information. */
2759 uint16_t fw_major_version; 2774 uint16_t fw_major_version;
@@ -2987,6 +3002,13 @@ typedef struct scsi_qla_host {
2987 3002
2988 /* ISP configuration data. */ 3003 /* ISP configuration data. */
2989 uint16_t loop_id; /* Host adapter loop id */ 3004 uint16_t loop_id; /* Host adapter loop id */
3005 uint16_t self_login_loop_id; /* host adapter loop id
3006 * get it on self login
3007 */
3008 fc_port_t bidir_fcport; /* fcport used for bidir cmnds
3009 * no need of allocating it for
3010 * each command
3011 */
2990 3012
2991 port_id_t d_id; /* Host adapter port id */ 3013 port_id_t d_id; /* Host adapter port id */
2992 uint8_t marker_needed; 3014 uint8_t marker_needed;
@@ -3040,6 +3062,7 @@ typedef struct scsi_qla_host {
3040 int seconds_since_last_heartbeat; 3062 int seconds_since_last_heartbeat;
3041 struct fc_host_statistics fc_host_stat; 3063 struct fc_host_statistics fc_host_stat;
3042 struct qla_statistics qla_stats; 3064 struct qla_statistics qla_stats;
3065 struct bidi_statistics bidi_stats;
3043 3066
3044 atomic_t vref_count; 3067 atomic_t vref_count;
3045} scsi_qla_host_t; 3068} scsi_qla_host_t;
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 980b5a7d6471..a678ed5d6884 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -381,6 +381,44 @@ struct init_cb_24xx {
381/* 381/*
382 * ISP queue - command entry structure definition. 382 * ISP queue - command entry structure definition.
383 */ 383 */
384#define COMMAND_BIDIRECTIONAL 0x75
385struct cmd_bidir {
386 uint8_t entry_type; /* Entry type. */
387 uint8_t entry_count; /* Entry count. */
388 uint8_t sys_define; /* System defined */
389 uint8_t entry_status; /* Entry status. */
390
391 uint32_t handle; /* System handle. */
392
393 uint16_t nport_handle; /* N_PORT hanlde. */
394
395 uint16_t timeout; /* Commnad timeout. */
396
397 uint16_t wr_dseg_count; /* Write Data segment count. */
398 uint16_t rd_dseg_count; /* Read Data segment count. */
399
400 struct scsi_lun lun; /* FCP LUN (BE). */
401
402 uint16_t control_flags; /* Control flags. */
403#define BD_WRAP_BACK BIT_3
404#define BD_READ_DATA BIT_1
405#define BD_WRITE_DATA BIT_0
406
407 uint16_t fcp_cmnd_dseg_len; /* Data segment length. */
408 uint32_t fcp_cmnd_dseg_address[2]; /* Data segment address. */
409
410 uint16_t reserved[2]; /* Reserved */
411
412 uint32_t rd_byte_count; /* Total Byte count Read. */
413 uint32_t wr_byte_count; /* Total Byte count write. */
414
415 uint8_t port_id[3]; /* PortID of destination port.*/
416 uint8_t vp_index;
417
418 uint32_t fcp_data_dseg_address[2]; /* Data segment address. */
419 uint16_t fcp_data_dseg_len; /* Data segment length. */
420};
421
384#define COMMAND_TYPE_6 0x48 /* Command Type 6 entry */ 422#define COMMAND_TYPE_6 0x48 /* Command Type 6 entry */
385struct cmd_type_6 { 423struct cmd_type_6 {
386 uint8_t entry_type; /* Entry type. */ 424 uint8_t entry_type; /* Entry type. */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 9eacd2df111b..d7588adc768b 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -188,6 +188,8 @@ extern int qla2x00_start_sp(srb_t *);
188extern uint16_t qla24xx_calc_iocbs(scsi_qla_host_t *, uint16_t); 188extern uint16_t qla24xx_calc_iocbs(scsi_qla_host_t *, uint16_t);
189extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *, uint16_t); 189extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *, uint16_t);
190extern int qla24xx_dif_start_scsi(srb_t *); 190extern int qla24xx_dif_start_scsi(srb_t *);
191extern int qla2x00_start_bidir(srb_t *, struct scsi_qla_host *, uint32_t);
192extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *);
191 193
192extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); 194extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *);
193extern int qla2x00_issue_marker(scsi_qla_host_t *, int); 195extern int qla2x00_issue_marker(scsi_qla_host_t *, int);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 290052352619..fa39411597f9 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -77,7 +77,7 @@ qla2x00_sp_free(void *data, void *ptr)
77 77
78/* Asynchronous Login/Logout Routines -------------------------------------- */ 78/* Asynchronous Login/Logout Routines -------------------------------------- */
79 79
80static inline unsigned long 80unsigned long
81qla2x00_get_async_timeout(struct scsi_qla_host *vha) 81qla2x00_get_async_timeout(struct scsi_qla_host *vha)
82{ 82{
83 unsigned long tmo; 83 unsigned long tmo;
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 23e83757fa5d..74c69ba39a04 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2665,3 +2665,201 @@ done:
2665 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2665 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2666 return rval; 2666 return rval;
2667} 2667}
2668
2669static void
2670qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha,
2671 struct cmd_bidir *cmd_pkt, uint32_t tot_dsds)
2672{
2673 uint16_t avail_dsds;
2674 uint32_t *cur_dsd;
2675 uint32_t req_data_len = 0;
2676 uint32_t rsp_data_len = 0;
2677 struct scatterlist *sg;
2678 int index;
2679 int entry_count = 1;
2680 struct fc_bsg_job *bsg_job = sp->u.bsg_job;
2681
2682 /*Update entry type to indicate bidir command */
2683 *((uint32_t *)(&cmd_pkt->entry_type)) =
2684 __constant_cpu_to_le32(COMMAND_BIDIRECTIONAL);
2685
2686 /* Set the transfer direction, in this set both flags
2687 * Also set the BD_WRAP_BACK flag, firmware will take care
2688 * assigning DID=SID for outgoing pkts.
2689 */
2690 cmd_pkt->wr_dseg_count = cpu_to_le16(bsg_job->request_payload.sg_cnt);
2691 cmd_pkt->rd_dseg_count = cpu_to_le16(bsg_job->reply_payload.sg_cnt);
2692 cmd_pkt->control_flags =
2693 __constant_cpu_to_le16(BD_WRITE_DATA | BD_READ_DATA |
2694 BD_WRAP_BACK);
2695
2696 req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
2697 cmd_pkt->wr_byte_count = cpu_to_le32(req_data_len);
2698 cmd_pkt->rd_byte_count = cpu_to_le32(rsp_data_len);
2699 cmd_pkt->timeout = cpu_to_le16(qla2x00_get_async_timeout(vha) + 2);
2700
2701 vha->bidi_stats.transfer_bytes += req_data_len;
2702 vha->bidi_stats.io_count++;
2703
2704 /* Only one dsd is available for bidirectional IOCB, remaining dsds
2705 * are bundled in continuation iocb
2706 */
2707 avail_dsds = 1;
2708 cur_dsd = (uint32_t *)&cmd_pkt->fcp_data_dseg_address;
2709
2710 index = 0;
2711
2712 for_each_sg(bsg_job->request_payload.sg_list, sg,
2713 bsg_job->request_payload.sg_cnt, index) {
2714 dma_addr_t sle_dma;
2715 cont_a64_entry_t *cont_pkt;
2716
2717 /* Allocate additional continuation packets */
2718 if (avail_dsds == 0) {
2719 /* Continuation type 1 IOCB can accomodate
2720 * 5 DSDS
2721 */
2722 cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req);
2723 cur_dsd = (uint32_t *) cont_pkt->dseg_0_address;
2724 avail_dsds = 5;
2725 entry_count++;
2726 }
2727 sle_dma = sg_dma_address(sg);
2728 *cur_dsd++ = cpu_to_le32(LSD(sle_dma));
2729 *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
2730 *cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
2731 avail_dsds--;
2732 }
2733 /* For read request DSD will always goes to continuation IOCB
2734 * and follow the write DSD. If there is room on the current IOCB
2735 * then it is added to that IOCB else new continuation IOCB is
2736 * allocated.
2737 */
2738 for_each_sg(bsg_job->reply_payload.sg_list, sg,
2739 bsg_job->reply_payload.sg_cnt, index) {
2740 dma_addr_t sle_dma;
2741 cont_a64_entry_t *cont_pkt;
2742
2743 /* Allocate additional continuation packets */
2744 if (avail_dsds == 0) {
2745 /* Continuation type 1 IOCB can accomodate
2746 * 5 DSDS
2747 */
2748 cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req);
2749 cur_dsd = (uint32_t *) cont_pkt->dseg_0_address;
2750 avail_dsds = 5;
2751 entry_count++;
2752 }
2753 sle_dma = sg_dma_address(sg);
2754 *cur_dsd++ = cpu_to_le32(LSD(sle_dma));
2755 *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
2756 *cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
2757 avail_dsds--;
2758 }
2759 /* This value should be same as number of IOCB required for this cmd */
2760 cmd_pkt->entry_count = entry_count;
2761}
2762
2763int
2764qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
2765{
2766
2767 struct qla_hw_data *ha = vha->hw;
2768 unsigned long flags;
2769 uint32_t handle;
2770 uint32_t index;
2771 uint16_t req_cnt;
2772 uint16_t cnt;
2773 uint32_t *clr_ptr;
2774 struct cmd_bidir *cmd_pkt = NULL;
2775 struct rsp_que *rsp;
2776 struct req_que *req;
2777 int rval = EXT_STATUS_OK;
2778 device_reg_t __iomem *reg = ISP_QUE_REG(ha, vha->req->id);
2779
2780 rval = QLA_SUCCESS;
2781
2782 rsp = ha->rsp_q_map[0];
2783 req = vha->req;
2784
2785 /* Send marker if required */
2786 if (vha->marker_needed != 0) {
2787 if (qla2x00_marker(vha, req,
2788 rsp, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS)
2789 return EXT_STATUS_MAILBOX;
2790 vha->marker_needed = 0;
2791 }
2792
2793 /* Acquire ring specific lock */
2794 spin_lock_irqsave(&ha->hardware_lock, flags);
2795
2796 /* Check for room in outstanding command list. */
2797 handle = req->current_outstanding_cmd;
2798 for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
2799 handle++;
2800 if (handle == MAX_OUTSTANDING_COMMANDS)
2801 handle = 1;
2802 if (!req->outstanding_cmds[handle])
2803 break;
2804 }
2805
2806 if (index == MAX_OUTSTANDING_COMMANDS) {
2807 rval = EXT_STATUS_BUSY;
2808 goto queuing_error;
2809 }
2810
2811 /* Calculate number of IOCB required */
2812 req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
2813
2814 /* Check for room on request queue. */
2815 if (req->cnt < req_cnt + 2) {
2816 if (ha->mqenable)
2817 cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
2818 else if (IS_QLA82XX(ha))
2819 cnt = RD_REG_DWORD(&reg->isp82.req_q_out);
2820 else if (IS_FWI2_CAPABLE(ha))
2821 cnt = RD_REG_DWORD(&reg->isp24.req_q_out);
2822 else
2823 cnt = qla2x00_debounce_register(
2824 ISP_REQ_Q_OUT(ha, &reg->isp));
2825
2826 if (req->ring_index < cnt)
2827 req->cnt = cnt - req->ring_index;
2828 else
2829 req->cnt = req->length -
2830 (req->ring_index - cnt);
2831 }
2832 if (req->cnt < req_cnt + 2) {
2833 rval = EXT_STATUS_BUSY;
2834 goto queuing_error;
2835 }
2836
2837 cmd_pkt = (struct cmd_bidir *)req->ring_ptr;
2838 cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
2839
2840 /* Zero out remaining portion of packet. */
2841 /* tagged queuing modifier -- default is TSK_SIMPLE (0).*/
2842 clr_ptr = (uint32_t *)cmd_pkt + 2;
2843 memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
2844
2845 /* Set NPORT-ID (of vha)*/
2846 cmd_pkt->nport_handle = cpu_to_le16(vha->self_login_loop_id);
2847 cmd_pkt->port_id[0] = vha->d_id.b.al_pa;
2848 cmd_pkt->port_id[1] = vha->d_id.b.area;
2849 cmd_pkt->port_id[2] = vha->d_id.b.domain;
2850
2851 qla25xx_build_bidir_iocb(sp, vha, cmd_pkt, tot_dsds);
2852 cmd_pkt->entry_status = (uint8_t) rsp->id;
2853 /* Build command packet. */
2854 req->current_outstanding_cmd = handle;
2855 req->outstanding_cmds[handle] = sp;
2856 sp->handle = handle;
2857 req->cnt -= req_cnt;
2858
2859 /* Send the command to the firmware */
2860 wmb();
2861 qla2x00_start_iocbs(vha, req);
2862queuing_error:
2863 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2864 return rval;
2865}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 0b097766f68d..31ef8e25a61d 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1546,6 +1546,149 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
1546 return 1; 1546 return 1;
1547} 1547}
1548 1548
1549static void
1550qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
1551 struct req_que *req, uint32_t index)
1552{
1553 struct qla_hw_data *ha = vha->hw;
1554 srb_t *sp;
1555 uint16_t comp_status;
1556 uint16_t scsi_status;
1557 uint16_t thread_id;
1558 uint32_t rval = EXT_STATUS_OK;
1559 struct fc_bsg_job *bsg_job = NULL;
1560 sts_entry_t *sts;
1561 struct sts_entry_24xx *sts24;
1562 sts = (sts_entry_t *) pkt;
1563 sts24 = (struct sts_entry_24xx *) pkt;
1564
1565 /* Validate handle. */
1566 if (index >= MAX_OUTSTANDING_COMMANDS) {
1567 ql_log(ql_log_warn, vha, 0x70af,
1568 "Invalid SCSI completion handle 0x%x.\n", index);
1569 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1570 return;
1571 }
1572
1573 sp = req->outstanding_cmds[index];
1574 if (sp) {
1575 /* Free outstanding command slot. */
1576 req->outstanding_cmds[index] = NULL;
1577 bsg_job = sp->u.bsg_job;
1578 } else {
1579 ql_log(ql_log_warn, vha, 0x70b0,
1580 "Req:%d: Invalid ISP SCSI completion handle(0x%x)\n",
1581 req->id, index);
1582
1583 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1584 return;
1585 }
1586
1587 if (IS_FWI2_CAPABLE(ha)) {
1588 comp_status = le16_to_cpu(sts24->comp_status);
1589 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
1590 } else {
1591 comp_status = le16_to_cpu(sts->comp_status);
1592 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
1593 }
1594
1595 thread_id = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
1596 switch (comp_status) {
1597 case CS_COMPLETE:
1598 if (scsi_status == 0) {
1599 bsg_job->reply->reply_payload_rcv_len =
1600 bsg_job->reply_payload.payload_len;
1601 rval = EXT_STATUS_OK;
1602 }
1603 goto done;
1604
1605 case CS_DATA_OVERRUN:
1606 ql_dbg(ql_dbg_user, vha, 0x70b1,
1607 "Command completed with date overrun thread_id=%d\n",
1608 thread_id);
1609 rval = EXT_STATUS_DATA_OVERRUN;
1610 break;
1611
1612 case CS_DATA_UNDERRUN:
1613 ql_dbg(ql_dbg_user, vha, 0x70b2,
1614 "Command completed with date underrun thread_id=%d\n",
1615 thread_id);
1616 rval = EXT_STATUS_DATA_UNDERRUN;
1617 break;
1618 case CS_BIDIR_RD_OVERRUN:
1619 ql_dbg(ql_dbg_user, vha, 0x70b3,
1620 "Command completed with read data overrun thread_id=%d\n",
1621 thread_id);
1622 rval = EXT_STATUS_DATA_OVERRUN;
1623 break;
1624
1625 case CS_BIDIR_RD_WR_OVERRUN:
1626 ql_dbg(ql_dbg_user, vha, 0x70b4,
1627 "Command completed with read and write data overrun "
1628 "thread_id=%d\n", thread_id);
1629 rval = EXT_STATUS_DATA_OVERRUN;
1630 break;
1631
1632 case CS_BIDIR_RD_OVERRUN_WR_UNDERRUN:
1633 ql_dbg(ql_dbg_user, vha, 0x70b5,
1634 "Command completed with read data over and write data "
1635 "underrun thread_id=%d\n", thread_id);
1636 rval = EXT_STATUS_DATA_OVERRUN;
1637 break;
1638
1639 case CS_BIDIR_RD_UNDERRUN:
1640 ql_dbg(ql_dbg_user, vha, 0x70b6,
1641 "Command completed with read data data underrun "
1642 "thread_id=%d\n", thread_id);
1643 rval = EXT_STATUS_DATA_UNDERRUN;
1644 break;
1645
1646 case CS_BIDIR_RD_UNDERRUN_WR_OVERRUN:
1647 ql_dbg(ql_dbg_user, vha, 0x70b7,
1648 "Command completed with read data under and write data "
1649 "overrun thread_id=%d\n", thread_id);
1650 rval = EXT_STATUS_DATA_UNDERRUN;
1651 break;
1652
1653 case CS_BIDIR_RD_WR_UNDERRUN:
1654 ql_dbg(ql_dbg_user, vha, 0x70b8,
1655 "Command completed with read and write data underrun "
1656 "thread_id=%d\n", thread_id);
1657 rval = EXT_STATUS_DATA_UNDERRUN;
1658 break;
1659
1660 case CS_BIDIR_DMA:
1661 ql_dbg(ql_dbg_user, vha, 0x70b9,
1662 "Command completed with data DMA error thread_id=%d\n",
1663 thread_id);
1664 rval = EXT_STATUS_DMA_ERR;
1665 break;
1666
1667 case CS_TIMEOUT:
1668 ql_dbg(ql_dbg_user, vha, 0x70ba,
1669 "Command completed with timeout thread_id=%d\n",
1670 thread_id);
1671 rval = EXT_STATUS_TIMEOUT;
1672 break;
1673 default:
1674 ql_dbg(ql_dbg_user, vha, 0x70bb,
1675 "Command completed with completion status=0x%x "
1676 "thread_id=%d\n", comp_status, thread_id);
1677 rval = EXT_STATUS_ERR;
1678 break;
1679 }
1680 bsg_job->reply->reply_payload_rcv_len = 0;
1681
1682done:
1683 /* Return the vendor specific reply to API */
1684 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
1685 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1686 /* Always return DID_OK, bsg will send the vendor specific response
1687 * in this case only */
1688 sp->done(vha, sp, (DID_OK << 6));
1689
1690}
1691
1549/** 1692/**
1550 * qla2x00_status_entry() - Process a Status IOCB entry. 1693 * qla2x00_status_entry() - Process a Status IOCB entry.
1551 * @ha: SCSI driver HA context 1694 * @ha: SCSI driver HA context
@@ -1573,12 +1716,14 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1573 struct req_que *req; 1716 struct req_que *req;
1574 int logit = 1; 1717 int logit = 1;
1575 int res = 0; 1718 int res = 0;
1719 uint16_t state_flags = 0;
1576 1720
1577 sts = (sts_entry_t *) pkt; 1721 sts = (sts_entry_t *) pkt;
1578 sts24 = (struct sts_entry_24xx *) pkt; 1722 sts24 = (struct sts_entry_24xx *) pkt;
1579 if (IS_FWI2_CAPABLE(ha)) { 1723 if (IS_FWI2_CAPABLE(ha)) {
1580 comp_status = le16_to_cpu(sts24->comp_status); 1724 comp_status = le16_to_cpu(sts24->comp_status);
1581 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK; 1725 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
1726 state_flags = le16_to_cpu(sts24->state_flags);
1582 } else { 1727 } else {
1583 comp_status = le16_to_cpu(sts->comp_status); 1728 comp_status = le16_to_cpu(sts->comp_status);
1584 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK; 1729 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
@@ -1587,17 +1732,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1587 que = MSW(sts->handle); 1732 que = MSW(sts->handle);
1588 req = ha->req_q_map[que]; 1733 req = ha->req_q_map[que];
1589 1734
1590 /* Fast path completion. */
1591 if (comp_status == CS_COMPLETE && scsi_status == 0) {
1592 qla2x00_process_completed_request(vha, req, handle);
1593
1594 return;
1595 }
1596
1597 /* Validate handle. */ 1735 /* Validate handle. */
1598 if (handle < MAX_OUTSTANDING_COMMANDS) { 1736 if (handle < MAX_OUTSTANDING_COMMANDS) {
1599 sp = req->outstanding_cmds[handle]; 1737 sp = req->outstanding_cmds[handle];
1600 req->outstanding_cmds[handle] = NULL;
1601 } else 1738 } else
1602 sp = NULL; 1739 sp = NULL;
1603 1740
@@ -1612,6 +1749,20 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1612 qla2xxx_wake_dpc(vha); 1749 qla2xxx_wake_dpc(vha);
1613 return; 1750 return;
1614 } 1751 }
1752
1753 if (unlikely((state_flags & BIT_1) && (sp->type == SRB_BIDI_CMD))) {
1754 qla25xx_process_bidir_status_iocb(vha, pkt, req, handle);
1755 return;
1756 }
1757
1758 /* Fast path completion. */
1759 if (comp_status == CS_COMPLETE && scsi_status == 0) {
1760 qla2x00_process_completed_request(vha, req, handle);
1761
1762 return;
1763 }
1764
1765 req->outstanding_cmds[handle] = NULL;
1615 cp = GET_CMD_SP(sp); 1766 cp = GET_CMD_SP(sp);
1616 if (cp == NULL) { 1767 if (cp == NULL) {
1617 ql_dbg(ql_dbg_io, vha, 0x3018, 1768 ql_dbg(ql_dbg_io, vha, 0x3018,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 5f990291c259..3e775650c20c 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2203,6 +2203,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2203 ha->mem_only = mem_only; 2203 ha->mem_only = mem_only;
2204 spin_lock_init(&ha->hardware_lock); 2204 spin_lock_init(&ha->hardware_lock);
2205 spin_lock_init(&ha->vport_slock); 2205 spin_lock_init(&ha->vport_slock);
2206 mutex_init(&ha->selflogin_lock);
2206 2207
2207 /* Set ISP-type information. */ 2208 /* Set ISP-type information. */
2208 qla2x00_set_isp_flags(ha); 2209 qla2x00_set_isp_flags(ha);