diff options
author | Chad Dupuis <chad.dupuis@qlogic.com> | 2012-08-22 14:21:00 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-09-24 04:03:36 -0400 |
commit | 5f16b331d83757ad5154af07b449c722fef45d5e (patch) | |
tree | e5ba70e771d5de6cf0e2d5ecf7ceb2ae9a90946d /drivers/scsi/qla2xxx/qla_init.c | |
parent | 09543c09ea37e15f806f29f0cdcbcc9417dbfa01 (diff) |
[SCSI] qla2xxx: Use bitmap to store loop_id's for fcports.
Store used fcport loop_id's in a bitmap so that as opposed to looping through
all fcports to find the next free loop_id, new loop_id lookup can be just be
done via bitops.
[jejb: plus fix for incorrect LOOPID_MAP_SIZE from Andrew Vasquez]
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 81 |
1 files changed, 21 insertions, 60 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a44653b42161..290052352619 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -3285,7 +3285,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, | |||
3285 | */ | 3285 | */ |
3286 | if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) { | 3286 | if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) { |
3287 | fcport->d_id.b24 = new_fcport->d_id.b24; | 3287 | fcport->d_id.b24 = new_fcport->d_id.b24; |
3288 | fcport->loop_id = FC_NO_LOOP_ID; | 3288 | qla2x00_clear_loop_id(fcport); |
3289 | fcport->flags |= (FCF_FABRIC_DEVICE | | 3289 | fcport->flags |= (FCF_FABRIC_DEVICE | |
3290 | FCF_LOGIN_NEEDED); | 3290 | FCF_LOGIN_NEEDED); |
3291 | break; | 3291 | break; |
@@ -3306,7 +3306,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, | |||
3306 | ha->isp_ops->fabric_logout(vha, fcport->loop_id, | 3306 | ha->isp_ops->fabric_logout(vha, fcport->loop_id, |
3307 | fcport->d_id.b.domain, fcport->d_id.b.area, | 3307 | fcport->d_id.b.domain, fcport->d_id.b.area, |
3308 | fcport->d_id.b.al_pa); | 3308 | fcport->d_id.b.al_pa); |
3309 | fcport->loop_id = FC_NO_LOOP_ID; | 3309 | qla2x00_clear_loop_id(fcport); |
3310 | } | 3310 | } |
3311 | 3311 | ||
3312 | break; | 3312 | break; |
@@ -3352,71 +3352,32 @@ int | |||
3352 | qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) | 3352 | qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) |
3353 | { | 3353 | { |
3354 | int rval; | 3354 | int rval; |
3355 | int found; | ||
3356 | fc_port_t *fcport; | ||
3357 | uint16_t first_loop_id; | ||
3358 | struct qla_hw_data *ha = vha->hw; | 3355 | struct qla_hw_data *ha = vha->hw; |
3359 | struct scsi_qla_host *vp; | ||
3360 | struct scsi_qla_host *tvp; | ||
3361 | unsigned long flags = 0; | 3356 | unsigned long flags = 0; |
3362 | 3357 | ||
3363 | rval = QLA_SUCCESS; | 3358 | rval = QLA_SUCCESS; |
3364 | 3359 | ||
3365 | /* Save starting loop ID. */ | 3360 | spin_lock_irqsave(&ha->vport_slock, flags); |
3366 | first_loop_id = dev->loop_id; | ||
3367 | |||
3368 | for (;;) { | ||
3369 | /* Skip loop ID if already used by adapter. */ | ||
3370 | if (dev->loop_id == vha->loop_id) | ||
3371 | dev->loop_id++; | ||
3372 | |||
3373 | /* Skip reserved loop IDs. */ | ||
3374 | while (qla2x00_is_reserved_id(vha, dev->loop_id)) | ||
3375 | dev->loop_id++; | ||
3376 | |||
3377 | /* Reset loop ID if passed the end. */ | ||
3378 | if (dev->loop_id > ha->max_loop_id) { | ||
3379 | /* first loop ID. */ | ||
3380 | dev->loop_id = ha->min_external_loopid; | ||
3381 | } | ||
3382 | |||
3383 | /* Check for loop ID being already in use. */ | ||
3384 | found = 0; | ||
3385 | fcport = NULL; | ||
3386 | |||
3387 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3388 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { | ||
3389 | list_for_each_entry(fcport, &vp->vp_fcports, list) { | ||
3390 | if (fcport->loop_id == dev->loop_id && | ||
3391 | fcport != dev) { | ||
3392 | /* ID possibly in use */ | ||
3393 | found++; | ||
3394 | break; | ||
3395 | } | ||
3396 | } | ||
3397 | if (found) | ||
3398 | break; | ||
3399 | } | ||
3400 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3401 | 3361 | ||
3402 | /* If not in use then it is free to use. */ | 3362 | dev->loop_id = find_first_zero_bit(ha->loop_id_map, |
3403 | if (!found) { | 3363 | LOOPID_MAP_SIZE); |
3404 | ql_dbg(ql_dbg_disc, dev->vha, 0x2086, | 3364 | if (dev->loop_id >= LOOPID_MAP_SIZE || |
3405 | "Assigning new loopid=%x, portid=%x.\n", | 3365 | qla2x00_is_reserved_id(vha, dev->loop_id)) { |
3406 | dev->loop_id, dev->d_id.b24); | 3366 | dev->loop_id = FC_NO_LOOP_ID; |
3407 | break; | 3367 | rval = QLA_FUNCTION_FAILED; |
3408 | } | 3368 | } else |
3369 | set_bit(dev->loop_id, ha->loop_id_map); | ||
3409 | 3370 | ||
3410 | /* ID in use. Try next value. */ | 3371 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
3411 | dev->loop_id++; | ||
3412 | 3372 | ||
3413 | /* If wrap around. No free ID to use. */ | 3373 | if (rval == QLA_SUCCESS) |
3414 | if (dev->loop_id == first_loop_id) { | 3374 | ql_dbg(ql_dbg_disc, dev->vha, 0x2086, |
3415 | dev->loop_id = FC_NO_LOOP_ID; | 3375 | "Assigning new loopid=%x, portid=%x.\n", |
3416 | rval = QLA_FUNCTION_FAILED; | 3376 | dev->loop_id, dev->d_id.b24); |
3417 | break; | 3377 | else |
3418 | } | 3378 | ql_log(ql_log_warn, dev->vha, 0x2087, |
3419 | } | 3379 | "No loop_id's available, portid=%x.\n", |
3380 | dev->d_id.b24); | ||
3420 | 3381 | ||
3421 | return (rval); | 3382 | return (rval); |
3422 | } | 3383 | } |
@@ -3616,7 +3577,7 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport, | |||
3616 | ha->isp_ops->fabric_logout(vha, fcport->loop_id, | 3577 | ha->isp_ops->fabric_logout(vha, fcport->loop_id, |
3617 | fcport->d_id.b.domain, fcport->d_id.b.area, | 3578 | fcport->d_id.b.domain, fcport->d_id.b.area, |
3618 | fcport->d_id.b.al_pa); | 3579 | fcport->d_id.b.al_pa); |
3619 | fcport->loop_id = FC_NO_LOOP_ID; | 3580 | qla2x00_clear_loop_id(fcport); |
3620 | fcport->login_retry = 0; | 3581 | fcport->login_retry = 0; |
3621 | 3582 | ||
3622 | rval = 3; | 3583 | rval = 3; |