|
@@ -853,8 +853,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
|
|
|
req->outstanding_cmds[index] = NULL;
|
|
|
|
|
|
/* Save ISP completion status */
|
|
|
- sp->cmd->result = DID_OK << 16;
|
|
|
- qla2x00_sp_compl(ha, sp);
|
|
|
+ sp->done(ha, sp, DID_OK << 16);
|
|
|
} else {
|
|
|
ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n");
|
|
|
|
|
@@ -911,7 +910,6 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
fc_port_t *fcport;
|
|
|
srb_t *sp;
|
|
|
struct srb_iocb *lio;
|
|
|
- struct srb_ctx *ctx;
|
|
|
uint16_t *data;
|
|
|
uint16_t status;
|
|
|
|
|
@@ -919,9 +917,8 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
if (!sp)
|
|
|
return;
|
|
|
|
|
|
- ctx = sp->ctx;
|
|
|
- lio = ctx->u.iocb_cmd;
|
|
|
- type = ctx->name;
|
|
|
+ lio = &sp->u.iocb_cmd;
|
|
|
+ type = sp->name;
|
|
|
fcport = sp->fcport;
|
|
|
data = lio->u.logio.data;
|
|
|
|
|
@@ -945,7 +942,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
}
|
|
|
|
|
|
status = le16_to_cpu(mbx->status);
|
|
|
- if (status == 0x30 && ctx->type == SRB_LOGIN_CMD &&
|
|
|
+ if (status == 0x30 && sp->type == SRB_LOGIN_CMD &&
|
|
|
le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE)
|
|
|
status = 0;
|
|
|
if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
|
|
@@ -956,7 +953,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
le16_to_cpu(mbx->mb1));
|
|
|
|
|
|
data[0] = MBS_COMMAND_COMPLETE;
|
|
|
- if (ctx->type == SRB_LOGIN_CMD) {
|
|
|
+ if (sp->type == SRB_LOGIN_CMD) {
|
|
|
fcport->port_type = FCT_TARGET;
|
|
|
if (le16_to_cpu(mbx->mb1) & BIT_0)
|
|
|
fcport->port_type = FCT_INITIATOR;
|
|
@@ -987,7 +984,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
le16_to_cpu(mbx->mb7));
|
|
|
|
|
|
logio_done:
|
|
|
- lio->done(sp);
|
|
|
+ sp->done(vha, sp, 0);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -996,29 +993,18 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
{
|
|
|
const char func[] = "CT_IOCB";
|
|
|
const char *type;
|
|
|
- struct qla_hw_data *ha = vha->hw;
|
|
|
srb_t *sp;
|
|
|
- struct srb_ctx *sp_bsg;
|
|
|
struct fc_bsg_job *bsg_job;
|
|
|
uint16_t comp_status;
|
|
|
+ int res;
|
|
|
|
|
|
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
|
|
|
if (!sp)
|
|
|
return;
|
|
|
|
|
|
- sp_bsg = sp->ctx;
|
|
|
- bsg_job = sp_bsg->u.bsg_job;
|
|
|
+ bsg_job = sp->u.bsg_job;
|
|
|
|
|
|
- type = NULL;
|
|
|
- switch (sp_bsg->type) {
|
|
|
- case SRB_CT_CMD:
|
|
|
- type = "ct pass-through";
|
|
|
- break;
|
|
|
- default:
|
|
|
- ql_log(ql_log_warn, vha, 0x5047,
|
|
|
- "Unrecognized SRB: (%p) type=%d.\n", sp, sp_bsg->type);
|
|
|
- return;
|
|
|
- }
|
|
|
+ type = "ct pass-through";
|
|
|
|
|
|
comp_status = le16_to_cpu(pkt->comp_status);
|
|
|
|
|
@@ -1030,7 +1016,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
|
|
|
if (comp_status != CS_COMPLETE) {
|
|
|
if (comp_status == CS_DATA_UNDERRUN) {
|
|
|
- bsg_job->reply->result = DID_OK << 16;
|
|
|
+ res = DID_OK << 16;
|
|
|
bsg_job->reply->reply_payload_rcv_len =
|
|
|
le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
|
|
|
|
|
@@ -1043,30 +1029,19 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
ql_log(ql_log_warn, vha, 0x5049,
|
|
|
"CT pass-through-%s error "
|
|
|
"comp_status-status=0x%x.\n", type, comp_status);
|
|
|
- bsg_job->reply->result = DID_ERROR << 16;
|
|
|
+ res = DID_ERROR << 16;
|
|
|
bsg_job->reply->reply_payload_rcv_len = 0;
|
|
|
}
|
|
|
ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035,
|
|
|
(uint8_t *)pkt, sizeof(*pkt));
|
|
|
} else {
|
|
|
- bsg_job->reply->result = DID_OK << 16;
|
|
|
+ res = DID_OK << 16;
|
|
|
bsg_job->reply->reply_payload_rcv_len =
|
|
|
bsg_job->reply_payload.payload_len;
|
|
|
bsg_job->reply_len = 0;
|
|
|
}
|
|
|
|
|
|
- dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
|
|
|
- bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
|
|
|
-
|
|
|
- dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
|
|
|
- bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
|
|
|
-
|
|
|
- if (sp_bsg->type == SRB_ELS_CMD_HST || sp_bsg->type == SRB_CT_CMD)
|
|
|
- kfree(sp->fcport);
|
|
|
-
|
|
|
- kfree(sp->ctx);
|
|
|
- mempool_free(sp, ha->srb_mempool);
|
|
|
- bsg_job->job_done(bsg_job);
|
|
|
+ sp->done(vha, sp, res);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -1075,22 +1050,20 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
{
|
|
|
const char func[] = "ELS_CT_IOCB";
|
|
|
const char *type;
|
|
|
- struct qla_hw_data *ha = vha->hw;
|
|
|
srb_t *sp;
|
|
|
- struct srb_ctx *sp_bsg;
|
|
|
struct fc_bsg_job *bsg_job;
|
|
|
uint16_t comp_status;
|
|
|
uint32_t fw_status[3];
|
|
|
uint8_t* fw_sts_ptr;
|
|
|
+ int res;
|
|
|
|
|
|
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
|
|
|
if (!sp)
|
|
|
return;
|
|
|
- sp_bsg = sp->ctx;
|
|
|
- bsg_job = sp_bsg->u.bsg_job;
|
|
|
+ bsg_job = sp->u.bsg_job;
|
|
|
|
|
|
type = NULL;
|
|
|
- switch (sp_bsg->type) {
|
|
|
+ switch (sp->type) {
|
|
|
case SRB_ELS_CMD_RPT:
|
|
|
case SRB_ELS_CMD_HST:
|
|
|
type = "els";
|
|
@@ -1100,7 +1073,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
break;
|
|
|
default:
|
|
|
ql_log(ql_log_warn, vha, 0x503e,
|
|
|
- "Unrecognized SRB: (%p) type=%d.\n", sp, sp_bsg->type);
|
|
|
+ "Unrecognized SRB: (%p) type=%d.\n", sp, sp->type);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -1116,9 +1089,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
|
|
|
if (comp_status != CS_COMPLETE) {
|
|
|
if (comp_status == CS_DATA_UNDERRUN) {
|
|
|
- bsg_job->reply->result = DID_OK << 16;
|
|
|
+ res = DID_OK << 16;
|
|
|
bsg_job->reply->reply_payload_rcv_len =
|
|
|
- le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count);
|
|
|
+ le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->total_byte_count);
|
|
|
|
|
|
ql_log(ql_log_info, vha, 0x503f,
|
|
|
"ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x "
|
|
@@ -1138,7 +1111,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
pkt)->error_subcode_1),
|
|
|
le16_to_cpu(((struct els_sts_entry_24xx *)
|
|
|
pkt)->error_subcode_2));
|
|
|
- bsg_job->reply->result = DID_ERROR << 16;
|
|
|
+ res = DID_ERROR << 16;
|
|
|
bsg_job->reply->reply_payload_rcv_len = 0;
|
|
|
fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
|
|
|
memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
|
|
@@ -1147,23 +1120,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
(uint8_t *)pkt, sizeof(*pkt));
|
|
|
}
|
|
|
else {
|
|
|
- bsg_job->reply->result = DID_OK << 16;
|
|
|
+ res = DID_OK << 16;
|
|
|
bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
|
|
|
bsg_job->reply_len = 0;
|
|
|
}
|
|
|
|
|
|
- dma_unmap_sg(&ha->pdev->dev,
|
|
|
- bsg_job->request_payload.sg_list,
|
|
|
- bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
|
|
|
- dma_unmap_sg(&ha->pdev->dev,
|
|
|
- bsg_job->reply_payload.sg_list,
|
|
|
- bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
|
|
|
- if ((sp_bsg->type == SRB_ELS_CMD_HST) ||
|
|
|
- (sp_bsg->type == SRB_CT_CMD))
|
|
|
- kfree(sp->fcport);
|
|
|
- kfree(sp->ctx);
|
|
|
- mempool_free(sp, ha->srb_mempool);
|
|
|
- bsg_job->job_done(bsg_job);
|
|
|
+ sp->done(vha, sp, res);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -1175,7 +1137,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
fc_port_t *fcport;
|
|
|
srb_t *sp;
|
|
|
struct srb_iocb *lio;
|
|
|
- struct srb_ctx *ctx;
|
|
|
uint16_t *data;
|
|
|
uint32_t iop[2];
|
|
|
|
|
@@ -1183,9 +1144,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
if (!sp)
|
|
|
return;
|
|
|
|
|
|
- ctx = sp->ctx;
|
|
|
- lio = ctx->u.iocb_cmd;
|
|
|
- type = ctx->name;
|
|
|
+ lio = &sp->u.iocb_cmd;
|
|
|
+ type = sp->name;
|
|
|
fcport = sp->fcport;
|
|
|
data = lio->u.logio.data;
|
|
|
|
|
@@ -1213,7 +1173,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
le32_to_cpu(logio->io_parameter[0]));
|
|
|
|
|
|
data[0] = MBS_COMMAND_COMPLETE;
|
|
|
- if (ctx->type != SRB_LOGIN_CMD)
|
|
|
+ if (sp->type != SRB_LOGIN_CMD)
|
|
|
goto logio_done;
|
|
|
|
|
|
iop[0] = le32_to_cpu(logio->io_parameter[0]);
|
|
@@ -1256,7 +1216,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
le32_to_cpu(logio->io_parameter[1]));
|
|
|
|
|
|
logio_done:
|
|
|
- lio->done(sp);
|
|
|
+ sp->done(vha, sp, 0);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -1268,7 +1228,6 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
fc_port_t *fcport;
|
|
|
srb_t *sp;
|
|
|
struct srb_iocb *iocb;
|
|
|
- struct srb_ctx *ctx;
|
|
|
struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
|
|
|
int error = 1;
|
|
|
|
|
@@ -1276,9 +1235,8 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
if (!sp)
|
|
|
return;
|
|
|
|
|
|
- ctx = sp->ctx;
|
|
|
- iocb = ctx->u.iocb_cmd;
|
|
|
- type = ctx->name;
|
|
|
+ iocb = &sp->u.iocb_cmd;
|
|
|
+ type = sp->name;
|
|
|
fcport = sp->fcport;
|
|
|
|
|
|
if (sts->entry_status) {
|
|
@@ -1312,7 +1270,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|
|
(uint8_t *)sts, sizeof(*sts));
|
|
|
}
|
|
|
|
|
|
- iocb->done(sp);
|
|
|
+ sp->done(vha, sp, 0);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1398,25 +1356,32 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
|
|
|
|
|
|
static inline void
|
|
|
qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
|
|
|
- uint32_t sense_len, struct rsp_que *rsp)
|
|
|
+ uint32_t sense_len, struct rsp_que *rsp, int res)
|
|
|
{
|
|
|
struct scsi_qla_host *vha = sp->fcport->vha;
|
|
|
- struct scsi_cmnd *cp = sp->cmd;
|
|
|
+ struct scsi_cmnd *cp = GET_CMD_SP(sp);
|
|
|
+ uint32_t track_sense_len;
|
|
|
|
|
|
if (sense_len >= SCSI_SENSE_BUFFERSIZE)
|
|
|
sense_len = SCSI_SENSE_BUFFERSIZE;
|
|
|
|
|
|
- sp->request_sense_length = sense_len;
|
|
|
- sp->request_sense_ptr = cp->sense_buffer;
|
|
|
- if (sp->request_sense_length > par_sense_len)
|
|
|
+ SET_CMD_SENSE_LEN(sp, sense_len);
|
|
|
+ SET_CMD_SENSE_PTR(sp, cp->sense_buffer);
|
|
|
+ track_sense_len = sense_len;
|
|
|
+
|
|
|
+ if (sense_len > par_sense_len)
|
|
|
sense_len = par_sense_len;
|
|
|
|
|
|
memcpy(cp->sense_buffer, sense_data, sense_len);
|
|
|
|
|
|
- sp->request_sense_ptr += sense_len;
|
|
|
- sp->request_sense_length -= sense_len;
|
|
|
- if (sp->request_sense_length != 0)
|
|
|
+ SET_CMD_SENSE_PTR(sp, cp->sense_buffer + sense_len);
|
|
|
+ track_sense_len -= sense_len;
|
|
|
+ SET_CMD_SENSE_LEN(sp, track_sense_len);
|
|
|
+
|
|
|
+ if (track_sense_len != 0) {
|
|
|
rsp->status_srb = sp;
|
|
|
+ cp->result = res;
|
|
|
+ }
|
|
|
|
|
|
if (sense_len) {
|
|
|
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c,
|
|
@@ -1444,7 +1409,7 @@ static inline int
|
|
|
qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
|
|
|
{
|
|
|
struct scsi_qla_host *vha = sp->fcport->vha;
|
|
|
- struct scsi_cmnd *cmd = sp->cmd;
|
|
|
+ struct scsi_cmnd *cmd = GET_CMD_SP(sp);
|
|
|
uint8_t *ap = &sts24->data[12];
|
|
|
uint8_t *ep = &sts24->data[20];
|
|
|
uint32_t e_ref_tag, a_ref_tag;
|
|
@@ -1588,6 +1553,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
uint16_t que;
|
|
|
struct req_que *req;
|
|
|
int logit = 1;
|
|
|
+ int res = 0;
|
|
|
|
|
|
sts = (sts_entry_t *) pkt;
|
|
|
sts24 = (struct sts_entry_24xx *) pkt;
|
|
@@ -1627,7 +1593,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
qla2xxx_wake_dpc(vha);
|
|
|
return;
|
|
|
}
|
|
|
- cp = sp->cmd;
|
|
|
+ cp = GET_CMD_SP(sp);
|
|
|
if (cp == NULL) {
|
|
|
ql_dbg(ql_dbg_io, vha, 0x3018,
|
|
|
"Command already returned (0x%x/%p).\n",
|
|
@@ -1680,7 +1646,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
"FCP I/O protocol failure (0x%x/0x%x).\n",
|
|
|
rsp_info_len, rsp_info[3]);
|
|
|
|
|
|
- cp->result = DID_BUS_BUSY << 16;
|
|
|
+ res = DID_BUS_BUSY << 16;
|
|
|
goto out;
|
|
|
}
|
|
|
}
|
|
@@ -1697,7 +1663,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
case CS_COMPLETE:
|
|
|
case CS_QUEUE_FULL:
|
|
|
if (scsi_status == 0) {
|
|
|
- cp->result = DID_OK << 16;
|
|
|
+ res = DID_OK << 16;
|
|
|
break;
|
|
|
}
|
|
|
if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
|
|
@@ -1712,11 +1678,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
"detected (0x%x of 0x%x bytes).\n",
|
|
|
resid, scsi_bufflen(cp));
|
|
|
|
|
|
- cp->result = DID_ERROR << 16;
|
|
|
+ res = DID_ERROR << 16;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- cp->result = DID_OK << 16 | lscsi_status;
|
|
|
+ res = DID_OK << 16 | lscsi_status;
|
|
|
|
|
|
if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
|
|
|
ql_dbg(ql_dbg_io, vha, 0x301b,
|
|
@@ -1732,7 +1698,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
break;
|
|
|
|
|
|
qla2x00_handle_sense(sp, sense_data, par_sense_len, sense_len,
|
|
|
- rsp);
|
|
|
+ rsp, res);
|
|
|
break;
|
|
|
|
|
|
case CS_DATA_UNDERRUN:
|
|
@@ -1746,7 +1712,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
"(0x%x of 0x%x bytes).\n",
|
|
|
resid, scsi_bufflen(cp));
|
|
|
|
|
|
- cp->result = DID_ERROR << 16 | lscsi_status;
|
|
|
+ res = DID_ERROR << 16 | lscsi_status;
|
|
|
goto check_scsi_status;
|
|
|
}
|
|
|
|
|
@@ -1758,7 +1724,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
"detected (0x%x of 0x%x bytes).\n",
|
|
|
resid, scsi_bufflen(cp));
|
|
|
|
|
|
- cp->result = DID_ERROR << 16;
|
|
|
+ res = DID_ERROR << 16;
|
|
|
break;
|
|
|
}
|
|
|
} else {
|
|
@@ -1766,11 +1732,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|
|
"Dropped frame(s) detected (0x%x "
|
|
|
"of 0x%x bytes).\n", resid, scsi_bufflen(cp));
|
|
|
|
|
|
- cp->result = DID_ERROR << 16 | lscsi_status;
|
|
|
+ res = DID_ERROR << 16 | lscsi_status;
|
|
|
goto check_scsi_status;
|
|
|
}
|
|
|
|
|
|
- cp->result = DID_OK << 16 | lscsi_status;
|
|
|
+ res = DID_OK << 16 | lscsi_status;
|
|
|
logit = 0;
|
|
|
|
|
|
check_scsi_status:
|
|
@@ -1793,7 +1759,7 @@ check_scsi_status:
|
|
|
break;
|
|
|
|
|
|
qla2x00_handle_sense(sp, sense_data, par_sense_len,
|
|
|
- sense_len, rsp);
|
|
|
+ sense_len, rsp, res);
|
|
|
}
|
|
|
break;
|
|
|
|
|
@@ -1810,7 +1776,7 @@ check_scsi_status:
|
|
|
* while we try to recover so instruct the mid layer
|
|
|
* to requeue until the class decides how to handle this.
|
|
|
*/
|
|
|
- cp->result = DID_TRANSPORT_DISRUPTED << 16;
|
|
|
+ res = DID_TRANSPORT_DISRUPTED << 16;
|
|
|
|
|
|
if (comp_status == CS_TIMEOUT) {
|
|
|
if (IS_FWI2_CAPABLE(ha))
|
|
@@ -1829,14 +1795,14 @@ check_scsi_status:
|
|
|
break;
|
|
|
|
|
|
case CS_ABORTED:
|
|
|
- cp->result = DID_RESET << 16;
|
|
|
+ res = DID_RESET << 16;
|
|
|
break;
|
|
|
|
|
|
case CS_DIF_ERROR:
|
|
|
logit = qla2x00_handle_dif_error(sp, sts24);
|
|
|
break;
|
|
|
default:
|
|
|
- cp->result = DID_ERROR << 16;
|
|
|
+ res = DID_ERROR << 16;
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -1847,7 +1813,7 @@ out:
|
|
|
"nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x "
|
|
|
"cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x "
|
|
|
"rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n",
|
|
|
- comp_status, scsi_status, cp->result, vha->host_no,
|
|
|
+ comp_status, scsi_status, res, vha->host_no,
|
|
|
cp->device->id, cp->device->lun, fcport->d_id.b.domain,
|
|
|
fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id,
|
|
|
cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
|
|
@@ -1856,7 +1822,7 @@ out:
|
|
|
resid_len, fw_resid_len);
|
|
|
|
|
|
if (rsp->status_srb == NULL)
|
|
|
- qla2x00_sp_compl(ha, sp);
|
|
|
+ sp->done(ha, sp, res);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1869,84 +1835,52 @@ out:
|
|
|
static void
|
|
|
qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
|
|
|
{
|
|
|
- uint8_t sense_sz = 0;
|
|
|
+ uint8_t sense_sz = 0;
|
|
|
struct qla_hw_data *ha = rsp->hw;
|
|
|
struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
|
|
|
- srb_t *sp = rsp->status_srb;
|
|
|
+ srb_t *sp = rsp->status_srb;
|
|
|
struct scsi_cmnd *cp;
|
|
|
+ uint32_t sense_len;
|
|
|
+ uint8_t *sense_ptr;
|
|
|
|
|
|
- if (sp != NULL && sp->request_sense_length != 0) {
|
|
|
- cp = sp->cmd;
|
|
|
- if (cp == NULL) {
|
|
|
- ql_log(ql_log_warn, vha, 0x3025,
|
|
|
- "cmd is NULL: already returned to OS (sp=%p).\n",
|
|
|
- sp);
|
|
|
+ if (!sp || !GET_CMD_SENSE_LEN(sp))
|
|
|
+ return;
|
|
|
|
|
|
- rsp->status_srb = NULL;
|
|
|
- return;
|
|
|
- }
|
|
|
+ sense_len = GET_CMD_SENSE_LEN(sp);
|
|
|
+ sense_ptr = GET_CMD_SENSE_PTR(sp);
|
|
|
|
|
|
- if (sp->request_sense_length > sizeof(pkt->data)) {
|
|
|
- sense_sz = sizeof(pkt->data);
|
|
|
- } else {
|
|
|
- sense_sz = sp->request_sense_length;
|
|
|
- }
|
|
|
+ cp = GET_CMD_SP(sp);
|
|
|
+ if (cp == NULL) {
|
|
|
+ ql_log(ql_log_warn, vha, 0x3025,
|
|
|
+ "cmd is NULL: already returned to OS (sp=%p).\n", sp);
|
|
|
|
|
|
- /* Move sense data. */
|
|
|
- if (IS_FWI2_CAPABLE(ha))
|
|
|
- host_to_fcp_swap(pkt->data, sizeof(pkt->data));
|
|
|
- memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
|
|
|
- ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c,
|
|
|
- sp->request_sense_ptr, sense_sz);
|
|
|
-
|
|
|
- sp->request_sense_ptr += sense_sz;
|
|
|
- sp->request_sense_length -= sense_sz;
|
|
|
-
|
|
|
- /* Place command on done queue. */
|
|
|
- if (sp->request_sense_length == 0) {
|
|
|
- rsp->status_srb = NULL;
|
|
|
- qla2x00_sp_compl(ha, sp);
|
|
|
- }
|
|
|
+ rsp->status_srb = NULL;
|
|
|
+ return;
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-static int
|
|
|
-qla2x00_free_sp_ctx(scsi_qla_host_t *vha, srb_t *sp)
|
|
|
-{
|
|
|
- struct qla_hw_data *ha = vha->hw;
|
|
|
- struct srb_ctx *ctx;
|
|
|
+ if (sense_len > sizeof(pkt->data))
|
|
|
+ sense_sz = sizeof(pkt->data);
|
|
|
+ else
|
|
|
+ sense_sz = sense_len;
|
|
|
|
|
|
- if (!sp->ctx)
|
|
|
- return 1;
|
|
|
+ /* Move sense data. */
|
|
|
+ if (IS_FWI2_CAPABLE(ha))
|
|
|
+ host_to_fcp_swap(pkt->data, sizeof(pkt->data));
|
|
|
+ memcpy(sense_ptr, pkt->data, sense_sz);
|
|
|
+ ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c,
|
|
|
+ sense_ptr, sense_sz);
|
|
|
|
|
|
- ctx = sp->ctx;
|
|
|
+ sense_len -= sense_sz;
|
|
|
+ sense_ptr += sense_sz;
|
|
|
|
|
|
- if (ctx->type == SRB_LOGIN_CMD ||
|
|
|
- ctx->type == SRB_LOGOUT_CMD ||
|
|
|
- ctx->type == SRB_TM_CMD) {
|
|
|
- ctx->u.iocb_cmd->done(sp);
|
|
|
- return 0;
|
|
|
- } else if (ctx->type == SRB_ADISC_CMD) {
|
|
|
- ctx->u.iocb_cmd->free(sp);
|
|
|
- return 0;
|
|
|
- } else {
|
|
|
- struct fc_bsg_job *bsg_job;
|
|
|
-
|
|
|
- bsg_job = ctx->u.bsg_job;
|
|
|
- if (ctx->type == SRB_ELS_CMD_HST ||
|
|
|
- ctx->type == SRB_CT_CMD)
|
|
|
- kfree(sp->fcport);
|
|
|
-
|
|
|
- bsg_job->reply->reply_data.ctels_reply.status =
|
|
|
- FC_CTELS_STATUS_OK;
|
|
|
- bsg_job->reply->result = DID_ERROR << 16;
|
|
|
- bsg_job->reply->reply_payload_rcv_len = 0;
|
|
|
- kfree(sp->ctx);
|
|
|
- mempool_free(sp, ha->srb_mempool);
|
|
|
- bsg_job->job_done(bsg_job);
|
|
|
- return 0;
|
|
|
+ SET_CMD_SENSE_PTR(sp, sense_ptr);
|
|
|
+ SET_CMD_SENSE_LEN(sp, sense_len);
|
|
|
+
|
|
|
+ /* Place command on done queue. */
|
|
|
+ if (sense_len == 0) {
|
|
|
+ rsp->status_srb = NULL;
|
|
|
+ sp->done(ha, sp, cp->result);
|
|
|
}
|
|
|
- return 1;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1962,43 +1896,18 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
|
|
|
const char func[] = "ERROR-IOCB";
|
|
|
uint16_t que = MSW(pkt->handle);
|
|
|
struct req_que *req = ha->req_q_map[que];
|
|
|
+ int res = DID_ERROR << 16;
|
|
|
|
|
|
- if (pkt->entry_status & RF_INV_E_ORDER)
|
|
|
- ql_dbg(ql_dbg_async, vha, 0x502a,
|
|
|
- "Invalid Entry Order.\n");
|
|
|
- else if (pkt->entry_status & RF_INV_E_COUNT)
|
|
|
- ql_dbg(ql_dbg_async, vha, 0x502b,
|
|
|
- "Invalid Entry Count.\n");
|
|
|
- else if (pkt->entry_status & RF_INV_E_PARAM)
|
|
|
- ql_dbg(ql_dbg_async, vha, 0x502c,
|
|
|
- "Invalid Entry Parameter.\n");
|
|
|
- else if (pkt->entry_status & RF_INV_E_TYPE)
|
|
|
- ql_dbg(ql_dbg_async, vha, 0x502d,
|
|
|
- "Invalid Entry Type.\n");
|
|
|
- else if (pkt->entry_status & RF_BUSY)
|
|
|
- ql_dbg(ql_dbg_async, vha, 0x502e,
|
|
|
- "Busy.\n");
|
|
|
- else
|
|
|
- ql_dbg(ql_dbg_async, vha, 0x502f,
|
|
|
- "UNKNOWN flag error.\n");
|
|
|
+ ql_dbg(ql_dbg_async, vha, 0x502a,
|
|
|
+ "type of error status in response: 0x%x\n", pkt->entry_status);
|
|
|
+
|
|
|
+ if (pkt->entry_status & RF_BUSY)
|
|
|
+ res = DID_BUS_BUSY << 16;
|
|
|
|
|
|
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
|
|
|
- if (sp) {
|
|
|
- if (qla2x00_free_sp_ctx(vha, sp)) {
|
|
|
- if (pkt->entry_status &
|
|
|
- (RF_INV_E_ORDER | RF_INV_E_COUNT |
|
|
|
- RF_INV_E_PARAM | RF_INV_E_TYPE)) {
|
|
|
- sp->cmd->result = DID_ERROR << 16;
|
|
|
- } else if (pkt->entry_status & RF_BUSY) {
|
|
|
- sp->cmd->result = DID_BUS_BUSY << 16;
|
|
|
- } else {
|
|
|
- sp->cmd->result = DID_ERROR << 16;
|
|
|
- }
|
|
|
- qla2x00_sp_compl(ha, sp);
|
|
|
- }
|
|
|
- } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
|
|
|
- COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7
|
|
|
- || pkt->entry_type == COMMAND_TYPE_6) {
|
|
|
+ if (sp)
|
|
|
+ sp->done(ha, sp, res);
|
|
|
+ else {
|
|
|
ql_log(ql_log_warn, vha, 0x5030,
|
|
|
"Error entry - invalid handle.\n");
|
|
|
|