diff options
author | Joe Carnuccio <joe.carnuccio@qlogic.com> | 2012-05-15 14:34:24 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-05-22 06:42:41 -0400 |
commit | 4dc77c36f86c2dc4e3f483146d33b64d12c0da3f (patch) | |
tree | 26f121067d18cc16b2173793153ca7a22d69c781 | |
parent | daae62a33e4f9b998cc8bf985fdf9eda62c10e57 (diff) |
[SCSI] qla2xxx: Avoid losing any fc ports when loop id's are exhausted.
Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 83 |
1 files changed, 20 insertions, 63 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 34fca3e983b0..886b2b653965 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -2910,7 +2910,7 @@ static int | |||
2910 | qla2x00_configure_fabric(scsi_qla_host_t *vha) | 2910 | qla2x00_configure_fabric(scsi_qla_host_t *vha) |
2911 | { | 2911 | { |
2912 | int rval; | 2912 | int rval; |
2913 | fc_port_t *fcport, *fcptemp; | 2913 | fc_port_t *fcport; |
2914 | uint16_t next_loopid; | 2914 | uint16_t next_loopid; |
2915 | uint16_t mb[MAILBOX_REGISTER_COUNT]; | 2915 | uint16_t mb[MAILBOX_REGISTER_COUNT]; |
2916 | uint16_t loop_id; | 2916 | uint16_t loop_id; |
@@ -2948,7 +2948,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2948 | 0xfc, mb, BIT_1|BIT_0); | 2948 | 0xfc, mb, BIT_1|BIT_0); |
2949 | if (rval != QLA_SUCCESS) { | 2949 | if (rval != QLA_SUCCESS) { |
2950 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | 2950 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
2951 | return rval; | 2951 | break; |
2952 | } | 2952 | } |
2953 | if (mb[0] != MBS_COMMAND_COMPLETE) { | 2953 | if (mb[0] != MBS_COMMAND_COMPLETE) { |
2954 | ql_dbg(ql_dbg_disc, vha, 0x2042, | 2954 | ql_dbg(ql_dbg_disc, vha, 0x2042, |
@@ -2984,10 +2984,12 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2984 | if (rval != QLA_SUCCESS) | 2984 | if (rval != QLA_SUCCESS) |
2985 | break; | 2985 | break; |
2986 | 2986 | ||
2987 | /* | 2987 | /* Add new ports to existing port list */ |
2988 | * Logout all previous fabric devices marked lost, except | 2988 | list_splice_tail_init(&new_fcports, &vha->vp_fcports); |
2989 | * FCP2 devices. | 2989 | |
2990 | */ | 2990 | /* Starting free loop ID. */ |
2991 | next_loopid = ha->min_external_loopid; | ||
2992 | |||
2991 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | 2993 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
2992 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) | 2994 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) |
2993 | break; | 2995 | break; |
@@ -2995,6 +2997,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2995 | if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) | 2997 | if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) |
2996 | continue; | 2998 | continue; |
2997 | 2999 | ||
3000 | /* Logout lost/gone fabric devices (non-FCP2) */ | ||
2998 | if (fcport->scan_state != QLA_FCPORT_SCAN_FOUND && | 3001 | if (fcport->scan_state != QLA_FCPORT_SCAN_FOUND && |
2999 | atomic_read(&fcport->state) == FCS_ONLINE) { | 3002 | atomic_read(&fcport->state) == FCS_ONLINE) { |
3000 | qla2x00_mark_device_lost(vha, fcport, | 3003 | qla2x00_mark_device_lost(vha, fcport, |
@@ -3008,76 +3011,30 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
3008 | fcport->d_id.b.domain, | 3011 | fcport->d_id.b.domain, |
3009 | fcport->d_id.b.area, | 3012 | fcport->d_id.b.area, |
3010 | fcport->d_id.b.al_pa); | 3013 | fcport->d_id.b.al_pa); |
3011 | fcport->loop_id = FC_NO_LOOP_ID; | ||
3012 | } | 3014 | } |
3013 | continue; | 3015 | continue; |
3014 | } | 3016 | } |
3015 | fcport->scan_state = QLA_FCPORT_SCAN_NONE; | 3017 | fcport->scan_state = QLA_FCPORT_SCAN_NONE; |
3016 | } | ||
3017 | |||
3018 | /* Starting free loop ID. */ | ||
3019 | next_loopid = ha->min_external_loopid; | ||
3020 | |||
3021 | /* | ||
3022 | * Scan through our port list and login entries that need to be | ||
3023 | * logged in. | ||
3024 | */ | ||
3025 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | ||
3026 | if (atomic_read(&vha->loop_down_timer) || | ||
3027 | test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) | ||
3028 | break; | ||
3029 | 3018 | ||
3030 | if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || | 3019 | /* Login fabric devices that need a login */ |
3031 | (fcport->flags & FCF_LOGIN_NEEDED) == 0) | 3020 | if ((fcport->flags & FCF_LOGIN_NEEDED) != 0 && |
3032 | continue; | 3021 | atomic_read(&vha->loop_down_timer) == 0) { |
3033 | 3022 | if (fcport->loop_id == FC_NO_LOOP_ID) { | |
3034 | if (fcport->loop_id == FC_NO_LOOP_ID) { | 3023 | fcport->loop_id = next_loopid; |
3035 | fcport->loop_id = next_loopid; | 3024 | rval = qla2x00_find_new_loop_id( |
3036 | rval = qla2x00_find_new_loop_id( | 3025 | base_vha, fcport); |
3037 | base_vha, fcport); | 3026 | if (rval != QLA_SUCCESS) { |
3038 | if (rval != QLA_SUCCESS) { | 3027 | /* Ran out of IDs to use */ |
3039 | /* Ran out of IDs to use */ | 3028 | continue; |
3040 | break; | 3029 | } |
3041 | } | 3030 | } |
3042 | } | 3031 | } |
3043 | /* Login and update database */ | ||
3044 | qla2x00_fabric_dev_login(vha, fcport, &next_loopid); | ||
3045 | } | ||
3046 | |||
3047 | /* Exit if out of loop IDs. */ | ||
3048 | if (rval != QLA_SUCCESS) { | ||
3049 | break; | ||
3050 | } | ||
3051 | |||
3052 | /* | ||
3053 | * Login and add the new devices to our port list. | ||
3054 | */ | ||
3055 | list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { | ||
3056 | if (atomic_read(&vha->loop_down_timer) || | ||
3057 | test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) | ||
3058 | break; | ||
3059 | |||
3060 | /* Find a new loop ID to use. */ | ||
3061 | fcport->loop_id = next_loopid; | ||
3062 | rval = qla2x00_find_new_loop_id(base_vha, fcport); | ||
3063 | if (rval != QLA_SUCCESS) { | ||
3064 | /* Ran out of IDs to use */ | ||
3065 | break; | ||
3066 | } | ||
3067 | 3032 | ||
3068 | /* Login and update database */ | 3033 | /* Login and update database */ |
3069 | qla2x00_fabric_dev_login(vha, fcport, &next_loopid); | 3034 | qla2x00_fabric_dev_login(vha, fcport, &next_loopid); |
3070 | |||
3071 | list_move_tail(&fcport->list, &vha->vp_fcports); | ||
3072 | } | 3035 | } |
3073 | } while (0); | 3036 | } while (0); |
3074 | 3037 | ||
3075 | /* Free all new device structures not processed. */ | ||
3076 | list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { | ||
3077 | list_del(&fcport->list); | ||
3078 | kfree(fcport); | ||
3079 | } | ||
3080 | |||
3081 | if (rval) { | 3038 | if (rval) { |
3082 | ql_dbg(ql_dbg_disc, vha, 0x2068, | 3039 | ql_dbg(ql_dbg_disc, vha, 0x2068, |
3083 | "Configure fabric error exit rval=%d.\n", rval); | 3040 | "Configure fabric error exit rval=%d.\n", rval); |