mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 00:54:09 +08:00
scsi: qla2xxx: Add a new v2 dport diagnostic feature
FW requires minimum 72 bytes buffer size for D_port result. Buffer size 1024 is mentioned in the FW spec so buffer size is increased to 1024. Rewrite the logic to handle START/RESTART command from SDMAPI. Link: https://lore.kernel.org/r/20220616053508.27186-3-njavali@marvell.com Signed-off-by: Bikash Hazarika <bhazarika@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
bff4873c70
commit
476da8faa3
@ -2424,6 +2424,89 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_do_dport_diagnostics_v2(struct bsg_job *bsg_job)
|
||||
{
|
||||
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
|
||||
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
|
||||
scsi_qla_host_t *vha = shost_priv(host);
|
||||
int rval;
|
||||
struct qla_dport_diag_v2 *dd;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
uint16_t options;
|
||||
|
||||
if (!IS_DPORT_CAPABLE(vha->hw))
|
||||
return -EPERM;
|
||||
|
||||
dd = kzalloc(sizeof(*dd), GFP_KERNEL);
|
||||
if (!dd)
|
||||
return -ENOMEM;
|
||||
|
||||
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||
bsg_job->request_payload.sg_cnt, dd, sizeof(*dd));
|
||||
|
||||
options = dd->options;
|
||||
|
||||
/* Check dport Test in progress */
|
||||
if (options == QLA_GET_DPORT_RESULT_V2 &&
|
||||
vha->dport_status & DPORT_DIAG_IN_PROGRESS) {
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_DPORT_DIAG_IN_PROCESS;
|
||||
goto dportcomplete;
|
||||
}
|
||||
|
||||
/* Check chip reset in progress and start/restart requests arrive */
|
||||
if (vha->dport_status & DPORT_DIAG_CHIP_RESET_IN_PROGRESS &&
|
||||
(options == QLA_START_DPORT_TEST_V2 ||
|
||||
options == QLA_RESTART_DPORT_TEST_V2)) {
|
||||
vha->dport_status &= ~DPORT_DIAG_CHIP_RESET_IN_PROGRESS;
|
||||
}
|
||||
|
||||
/* Check chip reset in progress and get result request arrive */
|
||||
if (vha->dport_status & DPORT_DIAG_CHIP_RESET_IN_PROGRESS &&
|
||||
options == QLA_GET_DPORT_RESULT_V2) {
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_DPORT_DIAG_NOT_RUNNING;
|
||||
goto dportcomplete;
|
||||
}
|
||||
|
||||
rval = qla26xx_dport_diagnostics_v2(vha, dd, mcp);
|
||||
|
||||
if (rval == QLA_SUCCESS) {
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_OK;
|
||||
if (options == QLA_START_DPORT_TEST_V2 ||
|
||||
options == QLA_RESTART_DPORT_TEST_V2) {
|
||||
dd->mbx1 = mcp->mb[0];
|
||||
dd->mbx2 = mcp->mb[1];
|
||||
vha->dport_status |= DPORT_DIAG_IN_PROGRESS;
|
||||
} else if (options == QLA_GET_DPORT_RESULT_V2) {
|
||||
dd->mbx1 = vha->dport_data[1];
|
||||
dd->mbx2 = vha->dport_data[2];
|
||||
}
|
||||
} else {
|
||||
dd->mbx1 = mcp->mb[0];
|
||||
dd->mbx2 = mcp->mb[1];
|
||||
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_DPORT_DIAG_ERR;
|
||||
}
|
||||
|
||||
dportcomplete:
|
||||
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||
bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
|
||||
|
||||
bsg_reply->reply_payload_rcv_len = sizeof(*dd);
|
||||
bsg_job->reply_len = sizeof(*bsg_reply);
|
||||
bsg_reply->result = DID_OK << 16;
|
||||
bsg_job_done(bsg_job, bsg_reply->result,
|
||||
bsg_reply->reply_payload_rcv_len);
|
||||
|
||||
kfree(dd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
|
||||
{
|
||||
@ -2860,6 +2943,9 @@ qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_j
|
||||
case QL_VND_DPORT_DIAGNOSTICS:
|
||||
return qla2x00_do_dport_diagnostics(bsg_job);
|
||||
|
||||
case QL_VND_DPORT_DIAGNOSTICS_V2:
|
||||
return qla2x00_do_dport_diagnostics_v2(bsg_job);
|
||||
|
||||
case QL_VND_EDIF_MGMT:
|
||||
return qla_edif_app_mgmt(bsg_job);
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#define QL_VND_GET_TGT_STATS 0x25
|
||||
#define QL_VND_MANAGE_HOST_PORT 0x26
|
||||
#define QL_VND_MBX_PASSTHRU 0x2B
|
||||
#define QL_VND_DPORT_DIAGNOSTICS_V2 0x2C
|
||||
|
||||
/* BSG Vendor specific subcode returns */
|
||||
#define EXT_STATUS_OK 0
|
||||
@ -60,6 +61,9 @@
|
||||
#define EXT_STATUS_TIMEOUT 30
|
||||
#define EXT_STATUS_THREAD_FAILED 31
|
||||
#define EXT_STATUS_DATA_CMP_FAILED 32
|
||||
#define EXT_STATUS_DPORT_DIAG_ERR 40
|
||||
#define EXT_STATUS_DPORT_DIAG_IN_PROCESS 41
|
||||
#define EXT_STATUS_DPORT_DIAG_NOT_RUNNING 42
|
||||
|
||||
/* BSG definations for interpreting CommandSent field */
|
||||
#define INT_DEF_LB_LOOPBACK_CMD 0
|
||||
@ -288,6 +292,17 @@ struct qla_dport_diag {
|
||||
uint8_t unused[62];
|
||||
} __packed;
|
||||
|
||||
#define QLA_GET_DPORT_RESULT_V2 0 /* Get Result */
|
||||
#define QLA_RESTART_DPORT_TEST_V2 1 /* Restart test */
|
||||
#define QLA_START_DPORT_TEST_V2 2 /* Start test */
|
||||
struct qla_dport_diag_v2 {
|
||||
uint16_t options;
|
||||
uint16_t mbx1;
|
||||
uint16_t mbx2;
|
||||
uint8_t unused[58];
|
||||
uint8_t buf[1024]; /* Test Result */
|
||||
} __packed;
|
||||
|
||||
/* D_Port options */
|
||||
#define QLA_DPORT_RESULT 0x0
|
||||
#define QLA_DPORT_START 0x2
|
||||
|
@ -1173,6 +1173,12 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
|
||||
|
||||
/* ISP mailbox loopback echo diagnostic error code */
|
||||
#define MBS_LB_RESET 0x17
|
||||
|
||||
/* AEN mailbox Port Diagnostics test */
|
||||
#define AEN_START_DIAG_TEST 0x0 /* start the diagnostics */
|
||||
#define AEN_DONE_DIAG_TEST_WITH_NOERR 0x1 /* Done with no errors */
|
||||
#define AEN_DONE_DIAG_TEST_WITH_ERR 0x2 /* Done with error.*/
|
||||
|
||||
/*
|
||||
* Firmware options 1, 2, 3.
|
||||
*/
|
||||
@ -5019,6 +5025,10 @@ typedef struct scsi_qla_host {
|
||||
u64 short_link_down_cnt;
|
||||
struct edif_dbell e_dbell;
|
||||
struct pur_core pur_cinfo;
|
||||
|
||||
#define DPORT_DIAG_IN_PROGRESS BIT_0
|
||||
#define DPORT_DIAG_CHIP_RESET_IN_PROGRESS BIT_1
|
||||
uint16_t dport_status;
|
||||
} scsi_qla_host_t;
|
||||
|
||||
struct qla27xx_image_status {
|
||||
|
@ -555,6 +555,10 @@ qla2x00_dump_mctp_data(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
|
||||
extern int
|
||||
qla26xx_dport_diagnostics(scsi_qla_host_t *, void *, uint, uint);
|
||||
|
||||
extern int
|
||||
qla26xx_dport_diagnostics_v2(scsi_qla_host_t *,
|
||||
struct qla_dport_diag_v2 *, mbx_cmd_t *);
|
||||
|
||||
int qla24xx_send_mb_cmd(struct scsi_qla_host *, mbx_cmd_t *);
|
||||
int qla24xx_gpdb_wait(struct scsi_qla_host *, fc_port_t *, u8);
|
||||
int qla24xx_gidlist_wait(struct scsi_qla_host *, void *, dma_addr_t,
|
||||
|
@ -7208,6 +7208,9 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
|
||||
if (vha->flags.online) {
|
||||
qla2x00_abort_isp_cleanup(vha);
|
||||
|
||||
vha->dport_status |= DPORT_DIAG_CHIP_RESET_IN_PROGRESS;
|
||||
vha->dport_status &= ~DPORT_DIAG_IN_PROGRESS;
|
||||
|
||||
if (vha->hw->flags.port_isolated)
|
||||
return status;
|
||||
|
||||
|
@ -1761,6 +1761,9 @@ global_port_update:
|
||||
break;
|
||||
|
||||
case MBA_DPORT_DIAGNOSTICS:
|
||||
if ((mb[1] & 0xF) == AEN_DONE_DIAG_TEST_WITH_NOERR ||
|
||||
(mb[1] & 0xF) == AEN_DONE_DIAG_TEST_WITH_ERR)
|
||||
vha->dport_status &= ~DPORT_DIAG_IN_PROGRESS;
|
||||
ql_dbg(ql_dbg_async, vha, 0x5052,
|
||||
"D-Port Diagnostics: %04x %04x %04x %04x\n",
|
||||
mb[0], mb[1], mb[2], mb[3]);
|
||||
|
@ -6471,6 +6471,54 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla26xx_dport_diagnostics_v2(scsi_qla_host_t *vha,
|
||||
struct qla_dport_diag_v2 *dd, mbx_cmd_t *mcp)
|
||||
{
|
||||
int rval;
|
||||
dma_addr_t dd_dma;
|
||||
uint size = sizeof(dd->buf);
|
||||
uint16_t options = dd->options;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,
|
||||
"Entered %s.\n", __func__);
|
||||
|
||||
dd_dma = dma_map_single(&vha->hw->pdev->dev,
|
||||
dd->buf, size, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {
|
||||
ql_log(ql_log_warn, vha, 0x1194,
|
||||
"Failed to map dma buffer.\n");
|
||||
return QLA_MEMORY_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
memset(dd->buf, 0, size);
|
||||
|
||||
mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
|
||||
mcp->mb[1] = options;
|
||||
mcp->mb[2] = MSW(LSD(dd_dma));
|
||||
mcp->mb[3] = LSW(LSD(dd_dma));
|
||||
mcp->mb[6] = MSW(MSD(dd_dma));
|
||||
mcp->mb[7] = LSW(MSD(dd_dma));
|
||||
mcp->mb[8] = size;
|
||||
mcp->out_mb = MBX_8 | MBX_7 | MBX_6 | MBX_3 | MBX_2 | MBX_1 | MBX_0;
|
||||
mcp->in_mb = MBX_3 | MBX_2 | MBX_1 | MBX_0;
|
||||
mcp->buf_size = size;
|
||||
mcp->flags = MBX_DMA_IN;
|
||||
mcp->tov = MBX_TOV_SECONDS * 4;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
|
||||
"Done %s.\n", __func__);
|
||||
}
|
||||
|
||||
dma_unmap_single(&vha->hw->pdev->dev, dd_dma, size, DMA_FROM_DEVICE);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void qla2x00_async_mb_sp_done(srb_t *sp, int res)
|
||||
{
|
||||
sp->u.iocb_cmd.u.mbx.rc = res;
|
||||
|
Loading…
Reference in New Issue
Block a user