@@ -5516,4 +5516,8 @@ struct ql_vnd_tgt_stats_resp {
_fp->disc_state, _fp->scan_state, _fp->loop_id, _fp->deleted, \
_fp->flags
+#define TMF_NOT_READY(_fcport) \
+ (!_fcport || IS_SESSION_DELETED(_fcport) || atomic_read(&_fcport->state) != FCS_ONLINE || \
+ !_fcport->vha->hw->flags.fw_started)
+
#endif
@@ -1996,6 +1996,11 @@ qla2x00_tmf_iocb_timeout(void *data)
int rc, h;
unsigned long flags;
+ if (sp->type == SRB_MARKER) {
+ complete(&tmf->u.tmf.comp);
+ return;
+ }
+
rc = qla24xx_async_abort_cmd(sp, false);
if (rc) {
spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
@@ -2023,6 +2028,7 @@ static void qla_marker_sp_done(srb_t *sp, int res)
sp->handle, sp->fcport->d_id.b24, sp->u.iocb_cmd.u.tmf.flags,
sp->u.iocb_cmd.u.tmf.lun, sp->qpair->id);
+ sp->u.iocb_cmd.u.tmf.data = res;
complete(&tmf->u.tmf.comp);
}
@@ -2039,6 +2045,11 @@ static void qla_marker_sp_done(srb_t *sp, int res)
} while (cnt); \
}
+/**
+ * qla26xx_marker: send marker IOCB and wait for the completion of it.
+ * @arg: pointer to argument list.
+ * It is assume caller will provide an fcport pointer and modifier
+ */
int
qla26xx_marker(struct tmf_arg *arg)
{
@@ -2048,6 +2059,14 @@ qla26xx_marker(struct tmf_arg *arg)
int rval = QLA_FUNCTION_FAILED;
fc_port_t *fcport = arg->fcport;
+ if (TMF_NOT_READY(arg->fcport)) {
+ ql_dbg(ql_dbg_taskm, vha, 0x8039,
+ "FC port not ready for marker loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d.\n",
+ fcport->loop_id, fcport->d_id.b24,
+ arg->modifier, arg->lun, arg->qpair->id);
+ return QLA_SUSPENDED;
+ }
+
/* ref: INIT */
sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
if (!sp)
@@ -2074,11 +2093,19 @@ qla26xx_marker(struct tmf_arg *arg)
if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x8031,
- "Marker IOCB failed (%x).\n", rval);
+ "Marker IOCB send failure (%x).\n", rval);
goto done_free_sp;
}
wait_for_completion(&tm_iocb->u.tmf.comp);
+ rval = tm_iocb->u.tmf.data;
+
+ if (rval != QLA_SUCCESS) {
+ ql_log(ql_log_warn, vha, 0x8019,
+ "Marker failed hdl=%x loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d rval %d.\n",
+ sp->handle, fcport->loop_id, fcport->d_id.b24,
+ arg->modifier, arg->lun, sp->qpair->id, rval);
+ }
done_free_sp:
/* ref: INIT */
@@ -2091,6 +2118,8 @@ static void qla2x00_tmf_sp_done(srb_t *sp, int res)
{
struct srb_iocb *tmf = &sp->u.iocb_cmd;
+ if (res)
+ tmf->u.tmf.data = res;
complete(&tmf->u.tmf.comp);
}
@@ -2104,6 +2133,14 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
fc_port_t *fcport = arg->fcport;
+ if (TMF_NOT_READY(arg->fcport)) {
+ ql_dbg(ql_dbg_taskm, vha, 0x8032,
+ "FC port not ready for TM command loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d.\n",
+ fcport->loop_id, fcport->d_id.b24,
+ arg->modifier, arg->lun, arg->qpair->id);
+ return QLA_SUSPENDED;
+ }
+
/* ref: INIT */
sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
if (!sp)
@@ -2178,7 +2215,9 @@ int qla_get_tmf(fc_port_t *fcport)
msleep(1);
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
- if (fcport->deleted) {
+ if (TMF_NOT_READY(fcport)) {
+ ql_log(ql_log_warn, vha, 0x802c,
+ "Unable to acquire TM resource due to disruption.\n");
rc = EIO;
break;
}
@@ -2204,7 +2243,10 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
struct scsi_qla_host *vha = fcport->vha;
struct qla_qpair *qpair;
struct tmf_arg a;
- int i, rval;
+ int i, rval = QLA_SUCCESS;
+
+ if (TMF_NOT_READY(fcport))
+ return QLA_SUSPENDED;
a.vha = fcport->vha;
a.fcport = fcport;
@@ -2223,6 +2265,14 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
qpair = vha->hw->queue_pair_map[i];
if (!qpair)
continue;
+
+ if (TMF_NOT_READY(fcport)) {
+ ql_log(ql_log_warn, vha, 0x8026,
+ "Unable to send TM due to disruption.\n");
+ rval = QLA_SUSPENDED;
+ break;
+ }
+
a.qpair = qpair;
a.flags = flags|TCF_NOTMCMD_TO_TARGET;
rval = __qla2x00_async_tm_cmd(&a);
@@ -2231,10 +2281,14 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
}
}
+ if (rval)
+ goto bailout;
+
a.qpair = vha->hw->base_qpair;
a.flags = flags;
rval = __qla2x00_async_tm_cmd(&a);
+bailout:
if (a.modifier == MK_SYNC_ID_LUN)
qla_put_tmf(fcport);