|
@@ -347,6 +347,94 @@ done:
|
|
|
return rval;
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+qla24xx_abort_iocb_timeout(void *data)
|
|
|
+{
|
|
|
+ srb_t *sp = (srb_t *)data;
|
|
|
+ struct srb_iocb *abt = &sp->u.iocb_cmd;
|
|
|
+
|
|
|
+ abt->u.abt.comp_status = CS_TIMEOUT;
|
|
|
+ complete(&abt->u.abt.comp);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+qla24xx_abort_sp_done(void *data, void *ptr, int res)
|
|
|
+{
|
|
|
+ srb_t *sp = (srb_t *)ptr;
|
|
|
+ struct srb_iocb *abt = &sp->u.iocb_cmd;
|
|
|
+
|
|
|
+ complete(&abt->u.abt.comp);
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+qla24xx_async_abort_cmd(srb_t *cmd_sp)
|
|
|
+{
|
|
|
+ scsi_qla_host_t *vha = cmd_sp->fcport->vha;
|
|
|
+ fc_port_t *fcport = cmd_sp->fcport;
|
|
|
+ struct srb_iocb *abt_iocb;
|
|
|
+ srb_t *sp;
|
|
|
+ int rval = QLA_FUNCTION_FAILED;
|
|
|
+
|
|
|
+ sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
|
|
|
+ if (!sp)
|
|
|
+ goto done;
|
|
|
+
|
|
|
+ abt_iocb = &sp->u.iocb_cmd;
|
|
|
+ sp->type = SRB_ABT_CMD;
|
|
|
+ sp->name = "abort";
|
|
|
+ qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
|
|
|
+ abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
|
|
|
+ sp->done = qla24xx_abort_sp_done;
|
|
|
+ abt_iocb->timeout = qla24xx_abort_iocb_timeout;
|
|
|
+ init_completion(&abt_iocb->u.abt.comp);
|
|
|
+
|
|
|
+ rval = qla2x00_start_sp(sp);
|
|
|
+ if (rval != QLA_SUCCESS)
|
|
|
+ goto done_free_sp;
|
|
|
+
|
|
|
+ ql_dbg(ql_dbg_async, vha, 0x507c,
|
|
|
+ "Abort command issued - hdl=%x, target_id=%x\n",
|
|
|
+ cmd_sp->handle, fcport->tgt_id);
|
|
|
+
|
|
|
+ wait_for_completion(&abt_iocb->u.abt.comp);
|
|
|
+
|
|
|
+ rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
|
|
|
+ QLA_SUCCESS : QLA_FUNCTION_FAILED;
|
|
|
+
|
|
|
+done_free_sp:
|
|
|
+ sp->free(vha, sp);
|
|
|
+done:
|
|
|
+ return rval;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+qla24xx_async_abort_command(srb_t *sp)
|
|
|
+{
|
|
|
+ unsigned long flags = 0;
|
|
|
+
|
|
|
+ uint32_t handle;
|
|
|
+ fc_port_t *fcport = sp->fcport;
|
|
|
+ struct scsi_qla_host *vha = fcport->vha;
|
|
|
+ struct qla_hw_data *ha = vha->hw;
|
|
|
+ struct req_que *req = vha->req;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&ha->hardware_lock, flags);
|
|
|
+ for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
|
|
|
+ if (req->outstanding_cmds[handle] == sp)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
|
+ if (handle == req->num_outstanding_cmds) {
|
|
|
+ /* Command not found. */
|
|
|
+ return QLA_FUNCTION_FAILED;
|
|
|
+ }
|
|
|
+ if (sp->type == SRB_FXIOCB_DCMD)
|
|
|
+ return qlafx00_fx_disc(vha, &vha->hw->mr.fcport,
|
|
|
+ FXDISC_ABORT_IOCTL);
|
|
|
+
|
|
|
+ return qla24xx_async_abort_cmd(sp);
|
|
|
+}
|
|
|
+
|
|
|
void
|
|
|
qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
|
|
|
uint16_t *data)
|