qla2xxx: Handle chip reset in target mode.
A chip reset can occur after driver submits command to the stack. Abort command processing if a chip reset has occurred or in progress when you get a follow up for a command. 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
c0cb44967b
commit
b6a029e1b0
|
@ -3446,6 +3446,7 @@ struct qla_hw_data {
|
|||
struct work_struct board_disable;
|
||||
|
||||
struct mr_data_fx00 mr;
|
||||
uint32_t chip_reset;
|
||||
|
||||
struct qlt_hw_data tgt;
|
||||
int allow_cna_fw_dump;
|
||||
|
|
|
@ -72,6 +72,7 @@ extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
|
|||
extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
|
||||
extern void *qla2x00_alloc_iocbs_ready(struct scsi_qla_host *, srb_t *);
|
||||
extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
extern fc_port_t *
|
||||
|
|
|
@ -4575,6 +4575,10 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
|
|||
/* Requeue all commands in outstanding command list. */
|
||||
qla2x00_abort_all_cmds(vha, DID_RESET << 16);
|
||||
}
|
||||
|
||||
ha->chip_reset++;
|
||||
/* memory barrier */
|
||||
wmb();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1858,6 +1858,17 @@ static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp)
|
|||
}
|
||||
|
||||
/* Generic Control-SRB manipulation functions. */
|
||||
|
||||
/* hardware_lock assumed to be held. */
|
||||
void *
|
||||
qla2x00_alloc_iocbs_ready(scsi_qla_host_t *vha, srb_t *sp)
|
||||
{
|
||||
if (qla2x00_reset_active(vha))
|
||||
return NULL;
|
||||
|
||||
return qla2x00_alloc_iocbs(vha, sp);
|
||||
}
|
||||
|
||||
void *
|
||||
qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
|
||||
{
|
||||
|
|
|
@ -106,6 +106,8 @@ static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd
|
|||
*cmd, struct atio_from_isp *atio, int ha_locked);
|
||||
static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha,
|
||||
struct qla_tgt_srr_imm *imm, int ha_lock);
|
||||
static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
|
||||
struct qla_tgt_cmd *cmd);
|
||||
/*
|
||||
* Global Variables
|
||||
*/
|
||||
|
@ -1036,7 +1038,7 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha,
|
|||
if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
|
||||
return;
|
||||
|
||||
resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs(vha, NULL);
|
||||
resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs_ready(vha, NULL);
|
||||
if (!resp) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe04a,
|
||||
"qla_target(%d): %s failed: unable to allocate "
|
||||
|
@ -1107,7 +1109,7 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
|
|||
if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
|
||||
return;
|
||||
|
||||
ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(vha, NULL);
|
||||
ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs_ready(vha, NULL);
|
||||
if (ctio == NULL) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe04b,
|
||||
"qla_target(%d): %s failed: unable to allocate "
|
||||
|
@ -1326,6 +1328,21 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
|
|||
mcmd, mcmd->fc_tm_rsp, mcmd->flags);
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
if (qla2x00_reset_active(vha) || mcmd->reset_count != ha->chip_reset) {
|
||||
/*
|
||||
* Either a chip reset is active or this request was from
|
||||
* previous life, just abort the processing.
|
||||
*/
|
||||
ql_dbg(ql_dbg_async, vha, 0xe100,
|
||||
"RESET-TMR active/old-count/new-count = %d/%d/%d.\n",
|
||||
qla2x00_reset_active(vha), mcmd->reset_count,
|
||||
ha->chip_reset);
|
||||
ha->tgt.tgt_ops->free_mcmd(mcmd);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mcmd->flags == QLA24XX_MGMT_SEND_NACK)
|
||||
qlt_send_notify_ack(vha, &mcmd->orig_iocb.imm_ntfy,
|
||||
0, 0, 0, 0, 0, 0);
|
||||
|
@ -2269,6 +2286,21 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
|
|||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) {
|
||||
/*
|
||||
* Either a chip reset is active or this request was from
|
||||
* previous life, just abort the processing.
|
||||
*/
|
||||
cmd->state = QLA_TGT_STATE_PROCESSED;
|
||||
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
|
||||
ql_dbg(ql_dbg_async, vha, 0xe101,
|
||||
"RESET-RSP active/old-count/new-count = %d/%d/%d.\n",
|
||||
qla2x00_reset_active(vha), cmd->reset_count,
|
||||
ha->chip_reset);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Does F/W have an IOCBs for this request */
|
||||
res = qlt_check_reserve_free_req(vha, full_req_cnt);
|
||||
if (unlikely(res))
|
||||
|
@ -2392,6 +2424,21 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
|
|||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) {
|
||||
/*
|
||||
* Either a chip reset is active or this request was from
|
||||
* previous life, just abort the processing.
|
||||
*/
|
||||
cmd->state = QLA_TGT_STATE_NEED_DATA;
|
||||
qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
|
||||
ql_dbg(ql_dbg_async, vha, 0xe102,
|
||||
"RESET-XFR active/old-count/new-count = %d/%d/%d.\n",
|
||||
qla2x00_reset_active(vha), cmd->reset_count,
|
||||
ha->chip_reset);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Does F/W have an IOCBs for this request */
|
||||
res = qlt_check_reserve_free_req(vha, prm.req_cnt);
|
||||
if (res != 0)
|
||||
|
@ -2577,7 +2624,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
|
|||
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha);
|
||||
|
||||
pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL);
|
||||
pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL);
|
||||
if (pkt == NULL) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe050,
|
||||
"qla_target(%d): %s failed: unable to allocate "
|
||||
|
@ -3305,6 +3352,8 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->reset_count = vha->hw->chip_reset;
|
||||
|
||||
INIT_WORK(&cmd->work, qlt_do_work);
|
||||
queue_work(qla_tgt_wq, &cmd->work);
|
||||
return 0;
|
||||
|
@ -3338,6 +3387,7 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
|
|||
}
|
||||
mcmd->tmr_func = fn;
|
||||
mcmd->flags = flags;
|
||||
mcmd->reset_count = vha->hw->chip_reset;
|
||||
|
||||
switch (fn) {
|
||||
case QLA_TGT_CLEAR_ACA:
|
||||
|
|
|
@ -923,6 +923,7 @@ struct qla_tgt_cmd {
|
|||
uint32_t tag;
|
||||
uint32_t unpacked_lun;
|
||||
enum dma_data_direction dma_data_direction;
|
||||
uint32_t reset_count;
|
||||
|
||||
uint16_t loop_id; /* to save extra sess dereferences */
|
||||
struct qla_tgt *tgt; /* to save extra sess dereferences */
|
||||
|
@ -958,6 +959,7 @@ struct qla_tgt_mgmt_cmd {
|
|||
struct se_cmd se_cmd;
|
||||
struct work_struct free_work;
|
||||
unsigned int flags;
|
||||
uint32_t reset_count;
|
||||
#define QLA24XX_MGMT_SEND_NACK 1
|
||||
union {
|
||||
struct atio_from_isp atio;
|
||||
|
|
Loading…
Reference in New Issue