aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2010-05-04 18:01:26 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-16 18:21:47 -0400
commit5ff1d58410ffb160b388d622ef0c6a0411a05559 (patch)
treea8d95de2c47bf3b0beaae6730b61b3d84c2bde56 /drivers/scsi/qla2xxx/qla_init.c
parent99b0bec7bbf3350d1a920a7138fa62c456a8ecf1 (diff)
[SCSI] qla2xxx: Limit mailbox command contention for ADISC requests.
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.c88
1 files changed, 82 insertions, 6 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index c3c2c3627a7..4e7a3d5493e 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -119,6 +119,7 @@ qla2x00_async_logio_timeout(srb_t *sp)
119 "scsi(%ld:%x): Async-%s timeout.\n", 119 "scsi(%ld:%x): Async-%s timeout.\n",
120 fcport->vha->host_no, sp->handle, lio->ctx.name)); 120 fcport->vha->host_no, sp->handle, lio->ctx.name));
121 121
122 fcport->flags &= ~FCF_ASYNC_SENT;
122 if (lio->ctx.type == SRB_LOGIN_CMD) 123 if (lio->ctx.type == SRB_LOGIN_CMD)
123 qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); 124 qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
124} 125}
@@ -220,6 +221,56 @@ done:
220 return rval; 221 return rval;
221} 222}
222 223
224static void
225qla2x00_async_adisc_ctx_done(srb_t *sp)
226{
227 struct srb_logio *lio = sp->ctx;
228
229 qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport,
230 lio->data);
231 lio->ctx.free(sp);
232}
233
234int
235qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
236 uint16_t *data)
237{
238 struct qla_hw_data *ha = vha->hw;
239 srb_t *sp;
240 struct srb_logio *lio;
241 int rval;
242
243 rval = QLA_FUNCTION_FAILED;
244 sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio),
245 ELS_TMO_2_RATOV(ha) + 2);
246 if (!sp)
247 goto done;
248
249 lio = sp->ctx;
250 lio->ctx.type = SRB_ADISC_CMD;
251 lio->ctx.name = "adisc";
252 lio->ctx.timeout = qla2x00_async_logio_timeout;
253 lio->ctx.done = qla2x00_async_adisc_ctx_done;
254 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
255 lio->flags |= SRB_LOGIN_RETRIED;
256 rval = qla2x00_start_sp(sp);
257 if (rval != QLA_SUCCESS)
258 goto done_free_sp;
259
260 DEBUG2(printk(KERN_DEBUG
261 "scsi(%ld:%x): Async-adisc - loop-id=%x portid=%02x%02x%02x.\n",
262 fcport->vha->host_no, sp->handle, fcport->loop_id,
263 fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa));
264
265 return rval;
266
267done_free_sp:
268 del_timer_sync(&lio->ctx.timer);
269 lio->ctx.free(sp);
270done:
271 return rval;
272}
273
223int 274int
224qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, 275qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
225 uint16_t *data) 276 uint16_t *data)
@@ -229,15 +280,14 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
229 switch (data[0]) { 280 switch (data[0]) {
230 case MBS_COMMAND_COMPLETE: 281 case MBS_COMMAND_COMPLETE:
231 if (fcport->flags & FCF_FCP2_DEVICE) { 282 if (fcport->flags & FCF_FCP2_DEVICE) {
232 rval = qla2x00_get_port_database(vha, fcport, BIT_1); 283 fcport->flags |= FCF_ASYNC_SENT;
233 if (rval != QLA_SUCCESS) { 284 qla2x00_post_async_adisc_work(vha, fcport, data);
234 qla2x00_mark_device_lost(vha, fcport, 1, 0); 285 break;
235 break;
236 }
237 } 286 }
238 qla2x00_update_fcport(vha, fcport); 287 qla2x00_update_fcport(vha, fcport);
239 break; 288 break;
240 case MBS_COMMAND_ERROR: 289 case MBS_COMMAND_ERROR:
290 fcport->flags &= ~FCF_ASYNC_SENT;
241 if (data[1] & QLA_LOGIO_LOGIN_RETRIED) 291 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
242 set_bit(RELOGIN_NEEDED, &vha->dpc_flags); 292 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
243 else 293 else
@@ -251,6 +301,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
251 fcport->loop_id++; 301 fcport->loop_id++;
252 rval = qla2x00_find_new_loop_id(vha, fcport); 302 rval = qla2x00_find_new_loop_id(vha, fcport);
253 if (rval != QLA_SUCCESS) { 303 if (rval != QLA_SUCCESS) {
304 fcport->flags &= ~FCF_ASYNC_SENT;
254 qla2x00_mark_device_lost(vha, fcport, 1, 0); 305 qla2x00_mark_device_lost(vha, fcport, 1, 0);
255 break; 306 break;
256 } 307 }
@@ -268,6 +319,26 @@ qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
268 return QLA_SUCCESS; 319 return QLA_SUCCESS;
269} 320}
270 321
322int
323qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
324 uint16_t *data)
325{
326 if (data[0] == MBS_COMMAND_COMPLETE) {
327 qla2x00_update_fcport(vha, fcport);
328
329 return QLA_SUCCESS;
330 }
331
332 /* Retry login. */
333 fcport->flags &= ~FCF_ASYNC_SENT;
334 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
335 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
336 else
337 qla2x00_mark_device_lost(vha, fcport, 1, 0);
338
339 return QLA_SUCCESS;
340}
341
271/****************************************************************************/ 342/****************************************************************************/
272/* QLogic ISP2x00 Hardware Support Functions. */ 343/* QLogic ISP2x00 Hardware Support Functions. */
273/****************************************************************************/ 344/****************************************************************************/
@@ -2062,6 +2133,7 @@ qla2x00_nvram_config(scsi_qla_host_t *vha)
2062 if (IS_QLA23XX(ha)) { 2133 if (IS_QLA23XX(ha)) {
2063 nv->firmware_options[0] |= BIT_2; 2134 nv->firmware_options[0] |= BIT_2;
2064 nv->firmware_options[0] &= ~BIT_3; 2135 nv->firmware_options[0] &= ~BIT_3;
2136 nv->firmware_options[0] &= ~BIT_6;
2065 nv->add_firmware_options[1] |= BIT_5 | BIT_4; 2137 nv->add_firmware_options[1] |= BIT_5 | BIT_4;
2066 2138
2067 if (IS_QLA2300(ha)) { 2139 if (IS_QLA2300(ha)) {
@@ -2680,7 +2752,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
2680 PORT_RETRY_TIME; 2752 PORT_RETRY_TIME;
2681 atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * 2753 atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
2682 PORT_RETRY_TIME); 2754 PORT_RETRY_TIME);
2683 fcport->flags &= ~FCF_LOGIN_NEEDED; 2755 fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
2684 2756
2685 qla2x00_iidma_fcport(vha, fcport); 2757 qla2x00_iidma_fcport(vha, fcport);
2686 2758
@@ -3326,11 +3398,15 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport,
3326 retry = 0; 3398 retry = 0;
3327 3399
3328 if (IS_ALOGIO_CAPABLE(ha)) { 3400 if (IS_ALOGIO_CAPABLE(ha)) {
3401 if (fcport->flags & FCF_ASYNC_SENT)
3402 return rval;
3403 fcport->flags |= FCF_ASYNC_SENT;
3329 rval = qla2x00_post_async_login_work(vha, fcport, NULL); 3404 rval = qla2x00_post_async_login_work(vha, fcport, NULL);
3330 if (!rval) 3405 if (!rval)
3331 return rval; 3406 return rval;
3332 } 3407 }
3333 3408
3409 fcport->flags &= ~FCF_ASYNC_SENT;
3334 rval = qla2x00_fabric_login(vha, fcport, next_loopid); 3410 rval = qla2x00_fabric_login(vha, fcport, next_loopid);
3335 if (rval == QLA_SUCCESS) { 3411 if (rval == QLA_SUCCESS) {
3336 /* Send an ADISC to FCP2 devices.*/ 3412 /* Send an ADISC to FCP2 devices.*/