diff options
Diffstat (limited to 'drivers/scsi/qedf/qedf_io.c')
| -rw-r--r-- | drivers/scsi/qedf/qedf_io.c | 120 |
1 files changed, 45 insertions, 75 deletions
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index 99a56ca1fb16..fcfc3bed02c6 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c @@ -310,7 +310,7 @@ struct qedf_ioreq *qedf_alloc_cmd(struct qedf_rport *fcport, u8 cmd_type) if (!free_sqes) { QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, - "Returning NULL, free_sqes=%d.\n ", + "Returning NULL, free_sqes=%d.\n", free_sqes); goto out_failed; } @@ -546,7 +546,7 @@ static int qedf_build_bd_list_from_sg(struct qedf_ioreq *io_req) } static void qedf_build_fcp_cmnd(struct qedf_ioreq *io_req, - struct fcp_cmnd *fcp_cmnd) + struct fcp_cmnd *fcp_cmnd) { struct scsi_cmnd *sc_cmd = io_req->sc_cmd; @@ -554,8 +554,12 @@ static void qedf_build_fcp_cmnd(struct qedf_ioreq *io_req, memset(fcp_cmnd, 0, FCP_CMND_LEN); /* 8 bytes: SCSI LUN info */ - int_to_scsilun(sc_cmd->device->lun, - (struct scsi_lun *)&fcp_cmnd->fc_lun); + if (io_req->cmd_type == QEDF_TASK_MGMT_CMD) + int_to_scsilun(io_req->tm_lun, + (struct scsi_lun *)&fcp_cmnd->fc_lun); + else + int_to_scsilun(sc_cmd->device->lun, + (struct scsi_lun *)&fcp_cmnd->fc_lun); /* 4 bytes: flag info */ fcp_cmnd->fc_pri_ta = 0; @@ -804,7 +808,6 @@ static void qedf_trace_io(struct qedf_rport *fcport, struct qedf_ioreq *io_req, struct qedf_io_log *io_log; struct scsi_cmnd *sc_cmd = io_req->sc_cmd; unsigned long flags; - uint8_t op; spin_lock_irqsave(&qedf->io_trace_lock, flags); @@ -813,7 +816,7 @@ static void qedf_trace_io(struct qedf_rport *fcport, struct qedf_ioreq *io_req, io_log->task_id = io_req->xid; io_log->port_id = fcport->rdata->ids.port_id; io_log->lun = sc_cmd->device->lun; - io_log->op = op = sc_cmd->cmnd[0]; + io_log->op = sc_cmd->cmnd[0]; io_log->lba[0] = sc_cmd->cmnd[2]; io_log->lba[1] = sc_cmd->cmnd[3]; io_log->lba[2] = sc_cmd->cmnd[4]; @@ -857,7 +860,7 @@ int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req) /* Initialize rest of io_req fileds */ io_req->data_xfer_len = scsi_bufflen(sc_cmd); - sc_cmd->SCp.ptr = (char *)io_req; + qedf_priv(sc_cmd)->io_req = io_req; io_req->sge_type = QEDF_IOREQ_FAST_SGE; /* Assume fast SGL by default */ /* Record which cpu this request is associated with */ @@ -894,7 +897,7 @@ int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req) return -EINVAL; } - /* Record LUN number for later use if we neeed them */ + /* Record LUN number for later use if we need them */ io_req->lun = (int)sc_cmd->device->lun; /* Obtain free SQE */ @@ -1065,8 +1068,7 @@ static void qedf_parse_fcp_rsp(struct qedf_ioreq *io_req, io_req->fcp_resid = fcp_rsp->fcp_resid; io_req->scsi_comp_flags = rsp_flags; - CMD_SCSI_STATUS(sc_cmd) = io_req->cdb_status = - fcp_rsp->scsi_status_code; + io_req->cdb_status = fcp_rsp->scsi_status_code; if (rsp_flags & FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID) @@ -1097,7 +1099,7 @@ static void qedf_parse_fcp_rsp(struct qedf_ioreq *io_req, } /* The sense buffer can be NULL for TMF commands */ - if (sc_cmd->sense_buffer) { + if (sc_cmd && sc_cmd->sense_buffer) { memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); if (fcp_sns_len) memcpy(sc_cmd->sense_buffer, sense_data, @@ -1150,9 +1152,9 @@ void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, return; } - if (!sc_cmd->SCp.ptr) { - QEDF_WARN(&(qedf->dbg_ctx), "SCp.ptr is NULL, returned in " - "another context.\n"); + if (!qedf_priv(sc_cmd)->io_req) { + QEDF_WARN(&(qedf->dbg_ctx), + "io_req is NULL, returned in another context.\n"); return; } @@ -1312,7 +1314,7 @@ out: clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); io_req->sc_cmd = NULL; - sc_cmd->SCp.ptr = NULL; + qedf_priv(sc_cmd)->io_req = NULL; scsi_done(sc_cmd); kref_put(&io_req->refcount, qedf_release_cmd); } @@ -1354,9 +1356,9 @@ void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, goto bad_scsi_ptr; } - if (!sc_cmd->SCp.ptr) { - QEDF_WARN(&(qedf->dbg_ctx), "SCp.ptr is NULL, returned in " - "another context.\n"); + if (!qedf_priv(sc_cmd)->io_req) { + QEDF_WARN(&(qedf->dbg_ctx), + "io_req is NULL, returned in another context.\n"); return; } @@ -1409,7 +1411,7 @@ void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, qedf_trace_io(io_req->fcport, io_req, QEDF_IO_TRACE_RSP); io_req->sc_cmd = NULL; - sc_cmd->SCp.ptr = NULL; + qedf_priv(sc_cmd)->io_req = NULL; scsi_done(sc_cmd); kref_put(&io_req->refcount, qedf_release_cmd); return; @@ -1582,7 +1584,7 @@ static void qedf_flush_els_req(struct qedf_ctx *qedf, /* A value of -1 for lun is a wild card that means flush all * active SCSI I/Os for the target. */ -void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) +void qedf_flush_active_ios(struct qedf_rport *fcport, u64 lun) { struct qedf_ioreq *io_req; struct qedf_ctx *qedf; @@ -1770,10 +1772,6 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) kref_put(&io_req->refcount, qedf_release_cmd); continue; } - if (lun > -1) { - if (io_req->lun != lun) - continue; - } /* * Use kref_get_unless_zero in the unlikely case the command @@ -1906,6 +1904,7 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) goto drop_rdata_kref; } + spin_lock_irqsave(&fcport->rport_lock, flags); if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { @@ -1913,17 +1912,20 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n", io_req->xid, io_req->sc_cmd); rc = 1; + spin_unlock_irqrestore(&fcport->rport_lock, flags); goto drop_rdata_kref; } + /* Set the command type to abort */ + io_req->cmd_type = QEDF_ABTS; + spin_unlock_irqrestore(&fcport->rport_lock, flags); + kref_get(&io_req->refcount); xid = io_req->xid; qedf->control_requests++; qedf->packet_aborts++; - /* Set the command type to abort */ - io_req->cmd_type = QEDF_ABTS; io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; set_bit(QEDF_CMD_IN_ABORT, &io_req->flags); @@ -2212,7 +2214,9 @@ process_els: refcount, fcport, fcport->rdata->ids.port_id); /* Cleanup cmds re-use the same TID as the original I/O */ + spin_lock_irqsave(&fcport->rport_lock, flags); io_req->cmd_type = QEDF_CLEANUP; + spin_unlock_irqrestore(&fcport->rport_lock, flags); io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; init_completion(&io_req->cleanup_done); @@ -2250,6 +2254,7 @@ process_els: io_req->tm_flags == FCP_TMF_TGT_RESET) { clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); io_req->sc_cmd = NULL; + kref_put(&io_req->refcount, qedf_release_cmd); complete(&io_req->tm_done); } @@ -2282,7 +2287,7 @@ void qedf_process_cleanup_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, complete(&io_req->cleanup_done); } -static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, +static int qedf_execute_tmf(struct qedf_rport *fcport, u64 tm_lun, uint8_t tm_flags) { struct qedf_ioreq *io_req; @@ -2292,17 +2297,10 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, int rc = 0; uint16_t xid; int tmo = 0; - int lun = 0; unsigned long flags; struct fcoe_wqe *sqe; u16 sqe_idx; - if (!sc_cmd) { - QEDF_ERR(&qedf->dbg_ctx, "sc_cmd is NULL\n"); - return FAILED; - } - - lun = (int)sc_cmd->device->lun; if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { QEDF_ERR(&(qedf->dbg_ctx), "fcport not offloaded\n"); rc = FAILED; @@ -2322,13 +2320,10 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, qedf->target_resets++; /* Initialize rest of io_req fields */ - io_req->sc_cmd = sc_cmd; + io_req->sc_cmd = NULL; io_req->fcport = fcport; io_req->cmd_type = QEDF_TASK_MGMT_CMD; - /* Record which cpu this request is associated with */ - io_req->cpu = smp_processor_id(); - /* Set TM flags */ io_req->io_req_flags = QEDF_READ; io_req->data_xfer_len = 0; @@ -2336,6 +2331,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, /* Default is to return a SCSI command when an error occurs */ io_req->return_scsi_cmd_on_abts = false; + io_req->tm_lun = tm_lun; /* Obtain exchange id */ xid = io_req->xid; @@ -2350,6 +2346,9 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, spin_lock_irqsave(&fcport->rport_lock, flags); + /* Record which cpu this request is associated with */ + io_req->cpu = smp_processor_id(); + sqe_idx = qedf_get_sqe_idx(fcport); sqe = &fcport->sq[sqe_idx]; memset(sqe, 0, sizeof(struct fcoe_wqe)); @@ -2390,7 +2389,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, if (tm_flags == FCP_TMF_LUN_RESET) - qedf_flush_active_ios(fcport, lun); + qedf_flush_active_ios(fcport, tm_lun); else qedf_flush_active_ios(fcport, -1); @@ -2405,23 +2404,18 @@ no_flush: return rc; } -int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) +int qedf_initiate_tmf(struct fc_rport *rport, u64 lun, u8 tm_flags) { - struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); struct fc_rport_libfc_priv *rp = rport->dd_data; struct qedf_rport *fcport = (struct qedf_rport *)&rp[1]; - struct qedf_ctx *qedf; - struct fc_lport *lport = shost_priv(sc_cmd->device->host); + struct qedf_ctx *qedf = fcport->qedf; + struct fc_lport *lport = rp->local_port; int rc = SUCCESS; - int rval; - struct qedf_ioreq *io_req = NULL; - int ref_cnt = 0; struct fc_rport_priv *rdata = fcport->rdata; QEDF_ERR(NULL, - "tm_flags 0x%x sc_cmd %p op = 0x%02x target_id = 0x%x lun=%d\n", - tm_flags, sc_cmd, sc_cmd->cmd_len ? sc_cmd->cmnd[0] : 0xff, - rport->scsi_target_id, (int)sc_cmd->device->lun); + "tm_flags 0x%x target_id = 0x%x lun=%llu\n", + tm_flags, rport->scsi_target_id, lun); if (!rdata || !kref_get_unless_zero(&rdata->kref)) { QEDF_ERR(NULL, "stale rport\n"); @@ -2432,33 +2426,10 @@ int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) (tm_flags == FCP_TMF_TGT_RESET) ? "TARGET RESET" : "LUN RESET"); - if (sc_cmd->SCp.ptr) { - io_req = (struct qedf_ioreq *)sc_cmd->SCp.ptr; - ref_cnt = kref_read(&io_req->refcount); - QEDF_ERR(NULL, - "orig io_req = %p xid = 0x%x ref_cnt = %d.\n", - io_req, io_req->xid, ref_cnt); - } - - rval = fc_remote_port_chkready(rport); - if (rval) { - QEDF_ERR(NULL, "device_reset rport not ready\n"); - rc = FAILED; - goto tmf_err; - } - - rc = fc_block_scsi_eh(sc_cmd); + rc = fc_block_rport(rport); if (rc) goto tmf_err; - if (!fcport) { - QEDF_ERR(NULL, "device_reset: rport is NULL\n"); - rc = FAILED; - goto tmf_err; - } - - qedf = fcport->qedf; - if (!qedf) { QEDF_ERR(NULL, "qedf is NULL.\n"); rc = FAILED; @@ -2495,7 +2466,7 @@ int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) goto tmf_err; } - rc = qedf_execute_tmf(fcport, sc_cmd, tm_flags); + rc = qedf_execute_tmf(fcport, lun, tm_flags); tmf_err: kref_put(&rdata->kref, fc_rport_destroy); @@ -2512,7 +2483,6 @@ void qedf_process_tmf_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, fcp_rsp = &cqe->cqe_info.rsp_info; qedf_parse_fcp_rsp(io_req, fcp_rsp); - io_req->sc_cmd = NULL; complete(&io_req->tm_done); } |
