Commit 6ac52608 authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley

[SCSI] qla2xxx: Correct async-srb issues.

* hold the hardware_lock throughout the duration of ctx-sp
  timeout handling -- could result in use-after-free oops.

* retry a timed-out login-request.

* done() routines are called with the hardware-lock held, issue
qla2x00_mark_device_lost() with proper 'defer' flag.

* FCP2 capabilities are only relevant to target devices.
Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 083a469d
...@@ -60,9 +60,8 @@ qla2x00_ctx_sp_timeout(unsigned long __data) ...@@ -60,9 +60,8 @@ qla2x00_ctx_sp_timeout(unsigned long __data)
ctx = sp->ctx; ctx = sp->ctx;
iocb = ctx->u.iocb_cmd; iocb = ctx->u.iocb_cmd;
iocb->timeout(sp); iocb->timeout(sp);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
iocb->free(sp); iocb->free(sp);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
} }
void void
...@@ -137,8 +136,16 @@ qla2x00_async_iocb_timeout(srb_t *sp) ...@@ -137,8 +136,16 @@ qla2x00_async_iocb_timeout(srb_t *sp)
fcport->d_id.b.area, fcport->d_id.b.al_pa)); fcport->d_id.b.area, fcport->d_id.b.al_pa));
fcport->flags &= ~FCF_ASYNC_SENT; fcport->flags &= ~FCF_ASYNC_SENT;
if (ctx->type == SRB_LOGIN_CMD) if (ctx->type == SRB_LOGIN_CMD) {
struct srb_iocb *lio = ctx->u.iocb_cmd;
qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
/* Retry as needed. */
lio->u.logio.data[0] = MBS_COMMAND_ERROR;
lio->u.logio.data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ?
QLA_LOGIO_LOGIN_RETRIED : 0;
qla2x00_post_async_login_done_work(fcport->vha, fcport,
lio->u.logio.data);
}
} }
static void static void
...@@ -420,10 +427,11 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -420,10 +427,11 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
if (data[1] & QLA_LOGIO_LOGIN_RETRIED) if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
set_bit(RELOGIN_NEEDED, &vha->dpc_flags); set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
else else
qla2x00_mark_device_lost(vha, fcport, 1, 0); qla2x00_mark_device_lost(vha, fcport, 1, 1);
break; break;
case MBS_PORT_ID_USED: case MBS_PORT_ID_USED:
fcport->loop_id = data[1]; fcport->loop_id = data[1];
qla2x00_post_async_logout_work(vha, fcport, NULL);
qla2x00_post_async_login_work(vha, fcport, NULL); qla2x00_post_async_login_work(vha, fcport, NULL);
break; break;
case MBS_LOOP_ID_USED: case MBS_LOOP_ID_USED:
...@@ -431,7 +439,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -431,7 +439,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
rval = qla2x00_find_new_loop_id(vha, fcport); rval = qla2x00_find_new_loop_id(vha, fcport);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
fcport->flags &= ~FCF_ASYNC_SENT; fcport->flags &= ~FCF_ASYNC_SENT;
qla2x00_mark_device_lost(vha, fcport, 1, 0); qla2x00_mark_device_lost(vha, fcport, 1, 1);
break; break;
} }
qla2x00_post_async_login_work(vha, fcport, NULL); qla2x00_post_async_login_work(vha, fcport, NULL);
...@@ -463,7 +471,7 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -463,7 +471,7 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
if (data[1] & QLA_LOGIO_LOGIN_RETRIED) if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
set_bit(RELOGIN_NEEDED, &vha->dpc_flags); set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
else else
qla2x00_mark_device_lost(vha, fcport, 1, 0); qla2x00_mark_device_lost(vha, fcport, 1, 1);
return; return;
} }
......
...@@ -949,7 +949,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -949,7 +949,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
fcport->port_type = FCT_TARGET; fcport->port_type = FCT_TARGET;
if (le16_to_cpu(mbx->mb1) & BIT_0) if (le16_to_cpu(mbx->mb1) & BIT_0)
fcport->port_type = FCT_INITIATOR; fcport->port_type = FCT_INITIATOR;
if (le16_to_cpu(mbx->mb1) & BIT_1) else if (le16_to_cpu(mbx->mb1) & BIT_1)
fcport->flags |= FCF_FCP2_DEVICE; fcport->flags |= FCF_FCP2_DEVICE;
} }
goto logio_done; goto logio_done;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment