aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2010-05-28 18:08:19 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:01:21 -0400
commit6ac5260850841eb4055811a68ff47d658ebe9a59 (patch)
tree00e6bc407c4732ffb709ba9de7d8c743b9520194 /drivers/scsi/qla2xxx/qla_init.c
parent083a469db4ecf3b286a96b5b722c37fc1affe0be (diff)
[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: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 4bf973483818..cc7352545081 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -60,9 +60,8 @@ qla2x00_ctx_sp_timeout(unsigned long __data)
60 ctx = sp->ctx; 60 ctx = sp->ctx;
61 iocb = ctx->u.iocb_cmd; 61 iocb = ctx->u.iocb_cmd;
62 iocb->timeout(sp); 62 iocb->timeout(sp);
63 spin_unlock_irqrestore(&ha->hardware_lock, flags);
64
65 iocb->free(sp); 63 iocb->free(sp);
64 spin_unlock_irqrestore(&ha->hardware_lock, flags);
66} 65}
67 66
68void 67void
@@ -137,8 +136,16 @@ qla2x00_async_iocb_timeout(srb_t *sp)
137 fcport->d_id.b.area, fcport->d_id.b.al_pa)); 136 fcport->d_id.b.area, fcport->d_id.b.al_pa));
138 137
139 fcport->flags &= ~FCF_ASYNC_SENT; 138 fcport->flags &= ~FCF_ASYNC_SENT;
140 if (ctx->type == SRB_LOGIN_CMD) 139 if (ctx->type == SRB_LOGIN_CMD) {
140 struct srb_iocb *lio = ctx->u.iocb_cmd;
141 qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); 141 qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
142 /* Retry as needed. */
143 lio->u.logio.data[0] = MBS_COMMAND_ERROR;
144 lio->u.logio.data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ?
145 QLA_LOGIO_LOGIN_RETRIED : 0;
146 qla2x00_post_async_login_done_work(fcport->vha, fcport,
147 lio->u.logio.data);
148 }
142} 149}
143 150
144static void 151static void
@@ -420,10 +427,11 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
420 if (data[1] & QLA_LOGIO_LOGIN_RETRIED) 427 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
421 set_bit(RELOGIN_NEEDED, &vha->dpc_flags); 428 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
422 else 429 else
423 qla2x00_mark_device_lost(vha, fcport, 1, 0); 430 qla2x00_mark_device_lost(vha, fcport, 1, 1);
424 break; 431 break;
425 case MBS_PORT_ID_USED: 432 case MBS_PORT_ID_USED:
426 fcport->loop_id = data[1]; 433 fcport->loop_id = data[1];
434 qla2x00_post_async_logout_work(vha, fcport, NULL);
427 qla2x00_post_async_login_work(vha, fcport, NULL); 435 qla2x00_post_async_login_work(vha, fcport, NULL);
428 break; 436 break;
429 case MBS_LOOP_ID_USED: 437 case MBS_LOOP_ID_USED:
@@ -431,7 +439,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
431 rval = qla2x00_find_new_loop_id(vha, fcport); 439 rval = qla2x00_find_new_loop_id(vha, fcport);
432 if (rval != QLA_SUCCESS) { 440 if (rval != QLA_SUCCESS) {
433 fcport->flags &= ~FCF_ASYNC_SENT; 441 fcport->flags &= ~FCF_ASYNC_SENT;
434 qla2x00_mark_device_lost(vha, fcport, 1, 0); 442 qla2x00_mark_device_lost(vha, fcport, 1, 1);
435 break; 443 break;
436 } 444 }
437 qla2x00_post_async_login_work(vha, fcport, NULL); 445 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 if (data[1] & QLA_LOGIO_LOGIN_RETRIED) 471 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
464 set_bit(RELOGIN_NEEDED, &vha->dpc_flags); 472 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
465 else 473 else
466 qla2x00_mark_device_lost(vha, fcport, 1, 0); 474 qla2x00_mark_device_lost(vha, fcport, 1, 1);
467 475
468 return; 476 return;
469} 477}