diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2010-05-04 18:01:26 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-05-16 18:21:47 -0400 |
commit | 5ff1d58410ffb160b388d622ef0c6a0411a05559 (patch) | |
tree | a8d95de2c47bf3b0beaae6730b61b3d84c2bde56 /drivers/scsi/qla2xxx/qla_init.c | |
parent | 99b0bec7bbf3350d1a920a7138fa62c456a8ecf1 (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.c | 88 |
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 | ||
224 | static void | ||
225 | qla2x00_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 | |||
234 | int | ||
235 | qla2x00_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 | |||
267 | done_free_sp: | ||
268 | del_timer_sync(&lio->ctx.timer); | ||
269 | lio->ctx.free(sp); | ||
270 | done: | ||
271 | return rval; | ||
272 | } | ||
273 | |||
223 | int | 274 | int |
224 | qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 275 | qla2x00_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 | ||
322 | int | ||
323 | qla2x00_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.*/ |