|
@@ -2246,53 +2246,53 @@ qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
|
|
|
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
|
|
|
struct link_statistics *stats = NULL;
|
|
|
dma_addr_t stats_dma;
|
|
|
- int rval = QLA_FUNCTION_FAILED;
|
|
|
+ int rval;
|
|
|
+ uint32_t *cmd = bsg_job->request->rqst_data.h_vendor.vendor_cmd;
|
|
|
+ uint options = cmd[0] == QL_VND_GET_PRIV_STATS_EX ? cmd[1] : 0;
|
|
|
|
|
|
if (test_bit(UNLOADING, &vha->dpc_flags))
|
|
|
- goto done;
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
if (unlikely(pci_channel_offline(ha->pdev)))
|
|
|
- goto done;
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
if (qla2x00_reset_active(vha))
|
|
|
- goto done;
|
|
|
+ return -EBUSY;
|
|
|
|
|
|
if (!IS_FWI2_CAPABLE(ha))
|
|
|
- goto done;
|
|
|
+ return -EPERM;
|
|
|
|
|
|
stats = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
- sizeof(struct link_statistics), &stats_dma, GFP_KERNEL);
|
|
|
+ sizeof(*stats), &stats_dma, GFP_KERNEL);
|
|
|
if (!stats) {
|
|
|
ql_log(ql_log_warn, vha, 0x70e2,
|
|
|
- "Failed to allocate memory for stats.\n");
|
|
|
- goto done;
|
|
|
+ "Failed to allocate memory for stats.\n");
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- memset(stats, 0, sizeof(struct link_statistics));
|
|
|
+ memset(stats, 0, sizeof(*stats));
|
|
|
|
|
|
- rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, 0);
|
|
|
+ rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options);
|
|
|
|
|
|
- if (rval != QLA_SUCCESS)
|
|
|
- goto done_free;
|
|
|
-
|
|
|
- ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e3,
|
|
|
- (uint8_t *)stats, sizeof(struct link_statistics));
|
|
|
-
|
|
|
- sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
|
|
- bsg_job->reply_payload.sg_cnt, stats, sizeof(struct link_statistics));
|
|
|
- bsg_job->reply->reply_payload_rcv_len = sizeof(struct link_statistics);
|
|
|
+ if (rval == QLA_SUCCESS) {
|
|
|
+ ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e3,
|
|
|
+ (uint8_t *)stats, sizeof(*stats));
|
|
|
+ sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
|
|
+ bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats));
|
|
|
+ }
|
|
|
|
|
|
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
|
|
|
+ bsg_job->reply->reply_payload_rcv_len = sizeof(*stats);
|
|
|
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
|
|
|
+ rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
|
|
|
|
|
|
- bsg_job->reply_len = sizeof(struct fc_bsg_reply);
|
|
|
+ bsg_job->reply_len = sizeof(*bsg_job->reply);
|
|
|
bsg_job->reply->result = DID_OK << 16;
|
|
|
bsg_job->job_done(bsg_job);
|
|
|
|
|
|
-done_free:
|
|
|
- dma_free_coherent(&ha->pdev->dev, sizeof(struct link_statistics),
|
|
|
+ dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
|
|
|
stats, stats_dma);
|
|
|
-done:
|
|
|
- return rval;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -2401,6 +2401,7 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
|
|
|
return qla27xx_get_bbcr_data(bsg_job);
|
|
|
|
|
|
case QL_VND_GET_PRIV_STATS:
|
|
|
+ case QL_VND_GET_PRIV_STATS_EX:
|
|
|
return qla2x00_get_priv_stats(bsg_job);
|
|
|
|
|
|
case QL_VND_DPORT_DIAGNOSTICS:
|