aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c44
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.h12
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c58
6 files changed, 122 insertions, 5 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 8cadc4da7d59..592e9249db02 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -2296,6 +2296,47 @@ done:
2296} 2296}
2297 2297
2298static int 2298static int
2299qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
2300{
2301 struct Scsi_Host *host = bsg_job->shost;
2302 scsi_qla_host_t *vha = shost_priv(host);
2303 int rval;
2304 struct qla_dport_diag *dd;
2305
2306 if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
2307 return -EPERM;
2308
2309 dd = kmalloc(sizeof(*dd), GFP_KERNEL);
2310 if (!dd) {
2311 ql_log(ql_log_warn, vha, 0x70db,
2312 "Failed to allocate memory for dport.\n");
2313 return -ENOMEM;
2314 }
2315
2316 sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2317 bsg_job->request_payload.sg_cnt, dd, sizeof(*dd));
2318
2319 rval = qla26xx_dport_diagnostics(
2320 vha, dd->buf, sizeof(dd->buf), dd->options);
2321 if (rval == QLA_SUCCESS) {
2322 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2323 bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
2324 }
2325
2326 bsg_job->reply->reply_payload_rcv_len = sizeof(*dd);
2327 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
2328 rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
2329
2330 bsg_job->reply_len = sizeof(*bsg_job->reply);
2331 bsg_job->reply->result = DID_OK << 16;
2332 bsg_job->job_done(bsg_job);
2333
2334 kfree(dd);
2335
2336 return 0;
2337}
2338
2339static int
2299qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job) 2340qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
2300{ 2341{
2301 switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) { 2342 switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
@@ -2362,6 +2403,9 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
2362 case QL_VND_GET_PRIV_STATS: 2403 case QL_VND_GET_PRIV_STATS:
2363 return qla2x00_get_priv_stats(bsg_job); 2404 return qla2x00_get_priv_stats(bsg_job);
2364 2405
2406 case QL_VND_DPORT_DIAGNOSTICS:
2407 return qla2x00_do_dport_diagnostics(bsg_job);
2408
2365 default: 2409 default:
2366 return -ENOSYS; 2410 return -ENOSYS;
2367 } 2411 }
diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h
index c80192d45536..3b1045f95d6f 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.h
+++ b/drivers/scsi/qla2xxx/qla_bsg.h
@@ -29,6 +29,7 @@
29#define QL_VND_SET_FLASH_UPDATE_CAPS 0x16 29#define QL_VND_SET_FLASH_UPDATE_CAPS 0x16
30#define QL_VND_GET_BBCR_DATA 0x17 30#define QL_VND_GET_BBCR_DATA 0x17
31#define QL_VND_GET_PRIV_STATS 0x18 31#define QL_VND_GET_PRIV_STATS 0x18
32#define QL_VND_DPORT_DIAGNOSTICS 0x19
32 33
33/* BSG Vendor specific subcode returns */ 34/* BSG Vendor specific subcode returns */
34#define EXT_STATUS_OK 0 35#define EXT_STATUS_OK 0
@@ -266,4 +267,15 @@ struct qla_bbcr_data {
266 uint16_t mbx1; /* Port state */ 267 uint16_t mbx1; /* Port state */
267 uint8_t reserved[9]; 268 uint8_t reserved[9];
268} __packed; 269} __packed;
270
271struct qla_dport_diag {
272 uint16_t options;
273 uint32_t buf[16];
274 uint8_t unused[62];
275} __packed;
276
277/* D_Port options */
278#define QLA_DPORT_RESULT 0x0
279#define QLA_DPORT_START 0x2
280
269#endif 281#endif
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 2790e5f2f29c..2a1eb027e162 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -14,7 +14,7 @@
14 * | Module Init and Probe | 0x018f | 0x0146 | 14 * | Module Init and Probe | 0x018f | 0x0146 |
15 * | | | 0x015b-0x0160 | 15 * | | | 0x015b-0x0160 |
16 * | | | 0x016e | 16 * | | | 0x016e |
17 * | Mailbox commands | 0x1191 | | 17 * | Mailbox commands | 0x1196 | |
18 * | | | | 18 * | | | |
19 * | Device Discovery | 0x2003 | 0x2016 | 19 * | Device Discovery | 0x2003 | 0x2016 |
20 * | | | 0x2011-0x2012, | 20 * | | | 0x2011-0x2012, |
@@ -41,7 +41,6 @@
41 * | | | 0x70ad-0x70ae | 41 * | | | 0x70ad-0x70ae |
42 * | | | 0x70d0-0x70d6 | 42 * | | | 0x70d0-0x70d6 |
43 * | | | 0x70d7-0x70db | 43 * | | | 0x70d7-0x70db |
44 * | | | 0x70db |
45 * | Task Management | 0x803d | 0x8000,0x800b | 44 * | Task Management | 0x803d | 0x8000,0x800b |
46 * | | | 0x8019 | 45 * | | | 0x8019 |
47 * | | | 0x8025,0x8026 | 46 * | | | 0x8025,0x8026 |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index be24e6260976..6ca00813c71f 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -445,6 +445,9 @@ qla2x00_port_logout(scsi_qla_host_t *, struct fc_port *);
445extern int 445extern int
446qla2x00_dump_mctp_data(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t); 446qla2x00_dump_mctp_data(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
447 447
448extern int
449qla26xx_dport_diagnostics(scsi_qla_host_t *, void *, uint, uint);
450
448/* 451/*
449 * Global Function Prototypes in qla_isr.c source file. 452 * Global Function Prototypes in qla_isr.c source file.
450 */ 453 */
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a2d7935ffeea..6b5f97e8c07b 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1152,10 +1152,13 @@ global_port_update:
1152 1152
1153 case MBA_DPORT_DIAGNOSTICS: 1153 case MBA_DPORT_DIAGNOSTICS:
1154 ql_dbg(ql_dbg_async, vha, 0x5052, 1154 ql_dbg(ql_dbg_async, vha, 0x5052,
1155 "D-Port Diagnostics: %04x %04x=%s\n", mb[0], mb[1], 1155 "D-Port Diagnostics: %04x result=%s index=%u size=%u\n",
1156 mb[0],
1156 mb[1] == 0 ? "start" : 1157 mb[1] == 0 ? "start" :
1157 mb[1] == 1 ? "done (ok)" : 1158 mb[1] == 1 ? "done (ok)" :
1158 mb[1] == 2 ? "done (error)" : "other"); 1159 mb[1] == 2 ? "done (error)" : "other",
1160 LSB(mb[2]),
1161 mb[3]);
1159 break; 1162 break;
1160 1163
1161 case MBA_TEMPERATURE_ALERT: 1164 case MBA_TEMPERATURE_ALERT:
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 97099ce2df15..0f7b83a37a36 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1872,7 +1872,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
1872 states[0] = mcp->mb[1]; 1872 states[0] = mcp->mb[1];
1873 if (IS_FWI2_CAPABLE(vha->hw)) { 1873 if (IS_FWI2_CAPABLE(vha->hw)) {
1874 states[1] = mcp->mb[2]; 1874 states[1] = mcp->mb[2];
1875 states[2] = mcp->mb[3]; 1875 states[2] = mcp->mb[3]; /* SFP info */
1876 states[3] = mcp->mb[4]; 1876 states[3] = mcp->mb[4];
1877 states[4] = mcp->mb[5]; 1877 states[4] = mcp->mb[5];
1878 states[5] = mcp->mb[6]; /* DPORT status */ 1878 states[5] = mcp->mb[6]; /* DPORT status */
@@ -5748,3 +5748,59 @@ qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5748 5748
5749 return rval; 5749 return rval;
5750} 5750}
5751
5752int
5753qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
5754 void *dd_buf, uint size, uint options)
5755{
5756 int rval;
5757 mbx_cmd_t mc;
5758 mbx_cmd_t *mcp = &mc;
5759 dma_addr_t dd_dma;
5760
5761 if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
5762 return QLA_FUNCTION_FAILED;
5763
5764 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
5765 "Entered %s.\n", __func__);
5766
5767 if (size < 1024) {
5768 ql_log(ql_log_warn, vha, 0x1193, "Failed insufficient size.\n");
5769 return QLA_FUNCTION_PARAMETER_ERROR;
5770 }
5771
5772 dd_dma = dma_map_single(&vha->hw->pdev->dev,
5773 dd_buf, size, DMA_FROM_DEVICE);
5774 if (!dd_dma) {
5775 ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n");
5776 return QLA_MEMORY_ALLOC_FAILED;
5777 }
5778
5779 memset(dd_buf, 0, size);
5780
5781 mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
5782 mcp->mb[1] = options;
5783 mcp->mb[2] = MSW(LSD(dd_dma));
5784 mcp->mb[3] = LSW(LSD(dd_dma));
5785 mcp->mb[6] = MSW(MSD(dd_dma));
5786 mcp->mb[7] = LSW(MSD(dd_dma));
5787 mcp->mb[8] = size;
5788 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
5789 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5790 mcp->buf_size = size;
5791 mcp->flags = MBX_DMA_IN;
5792 mcp->tov = MBX_TOV_SECONDS * 4;
5793 rval = qla2x00_mailbox_command(vha, mcp);
5794
5795 if (rval != QLA_SUCCESS) {
5796 ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
5797 } else {
5798 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
5799 "Done %s.\n", __func__);
5800 }
5801
5802 dma_unmap_single(&vha->hw->pdev->dev, dd_dma,
5803 size, DMA_FROM_DEVICE);
5804
5805 return rval;
5806}