aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Carnuccio <joe.carnuccio@qlogic.com>2012-05-15 14:34:24 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-05-22 06:42:41 -0400
commit4dc77c36f86c2dc4e3f483146d33b64d12c0da3f (patch)
tree26f121067d18cc16b2173793153ca7a22d69c781
parentdaae62a33e4f9b998cc8bf985fdf9eda62c10e57 (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.c83
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
2910qla2x00_configure_fabric(scsi_qla_host_t *vha) 2910qla2x00_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);