qla2xxx: Add Host reset handling in target mode.
Signed-off-by: Arun Easi <arun.easi@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
dd9c4eff77
commit
c0cb44967b
|
@ -68,7 +68,7 @@
|
|||
* | | | 0xd101-0xd1fe |
|
||||
* | | | 0xd214-0xd2fe |
|
||||
* | Target Mode | 0xe078 | |
|
||||
* | Target Mode Management | 0xf072 | 0xf002-0xf003 |
|
||||
* | Target Mode Management | 0xf072 | 0xf002 |
|
||||
* | | | 0xf046-0xf049 |
|
||||
* | Target Mode Task Management | 0x1000b | |
|
||||
* ----------------------------------------------------------------------
|
||||
|
|
|
@ -766,4 +766,5 @@ extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
|
|||
extern int qla8044_abort_isp(scsi_qla_host_t *);
|
||||
extern int qla8044_check_fw_alive(struct scsi_qla_host *);
|
||||
|
||||
extern void qlt_host_reset_handler(struct qla_hw_data *ha);
|
||||
#endif /* _QLA_GBL_H */
|
||||
|
|
|
@ -1363,6 +1363,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
|
|||
struct qla_hw_data *ha = vha->hw;
|
||||
struct req_que *req;
|
||||
|
||||
qlt_host_reset_handler(ha);
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
for (que = 0; que < ha->max_req_queues; que++) {
|
||||
req = ha->req_q_map[que];
|
||||
|
|
|
@ -2843,6 +2843,80 @@ static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
|
|||
return cmd;
|
||||
}
|
||||
|
||||
/* hardware_lock should be held by caller. */
|
||||
static void
|
||||
qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
uint32_t handle;
|
||||
|
||||
if (cmd->sg_mapped)
|
||||
qlt_unmap_sg(vha, cmd);
|
||||
|
||||
handle = qlt_make_handle(vha);
|
||||
|
||||
/* TODO: fix debug message type and ids. */
|
||||
if (cmd->state == QLA_TGT_STATE_PROCESSED) {
|
||||
ql_dbg(ql_dbg_io, vha, 0xff00,
|
||||
"HOST-ABORT: handle=%d, state=PROCESSED.\n", handle);
|
||||
} else if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
|
||||
cmd->write_data_transferred = 0;
|
||||
cmd->state = QLA_TGT_STATE_DATA_IN;
|
||||
|
||||
ql_dbg(ql_dbg_io, vha, 0xff01,
|
||||
"HOST-ABORT: handle=%d, state=DATA_IN.\n", handle);
|
||||
|
||||
ha->tgt.tgt_ops->handle_data(cmd);
|
||||
return;
|
||||
} else if (cmd->state == QLA_TGT_STATE_ABORTED) {
|
||||
ql_dbg(ql_dbg_io, vha, 0xff02,
|
||||
"HOST-ABORT: handle=%d, state=ABORTED.\n", handle);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_io, vha, 0xff03,
|
||||
"HOST-ABORT: handle=%d, state=BAD(%d).\n", handle,
|
||||
cmd->state);
|
||||
dump_stack();
|
||||
}
|
||||
|
||||
ha->tgt.tgt_ops->free_cmd(cmd);
|
||||
}
|
||||
|
||||
void
|
||||
qlt_host_reset_handler(struct qla_hw_data *ha)
|
||||
{
|
||||
struct qla_tgt_cmd *cmd;
|
||||
unsigned long flags;
|
||||
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
||||
scsi_qla_host_t *vha = NULL;
|
||||
struct qla_tgt *tgt = base_vha->vha_tgt.qla_tgt;
|
||||
uint32_t i;
|
||||
|
||||
if (!base_vha->hw->tgt.tgt_ops)
|
||||
return;
|
||||
|
||||
if (!tgt || qla_ini_mode_enabled(base_vha)) {
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003,
|
||||
"Target mode disabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xff10,
|
||||
"HOST-ABORT-HNDLR: base_vha->dpc_flags=%lx.\n",
|
||||
base_vha->dpc_flags);
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
for (i = 1; i < DEFAULT_OUTSTANDING_COMMANDS + 1; i++) {
|
||||
cmd = qlt_get_cmd(base_vha, i);
|
||||
if (!cmd)
|
||||
continue;
|
||||
/* ha->tgt.cmds entry is cleared by qlt_get_cmd. */
|
||||
vha = cmd->vha;
|
||||
qlt_abort_cmd_on_host_reset(vha, cmd);
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue