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 11:42:41 +0100 | 
| 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  qla2x00_configure_fabric(scsi_qla_host_t *vha)  {  	int	rval; -	fc_port_t	*fcport, *fcptemp; +	fc_port_t	*fcport;  	uint16_t	next_loopid;  	uint16_t	mb[MAILBOX_REGISTER_COUNT];  	uint16_t	loop_id; @@ -2948,7 +2948,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)  		    0xfc, mb, BIT_1|BIT_0);  		if (rval != QLA_SUCCESS) {  			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); -			return rval; +			break;  		}  		if (mb[0] != MBS_COMMAND_COMPLETE) {  			ql_dbg(ql_dbg_disc, vha, 0x2042, @@ -2984,10 +2984,12 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)  		if (rval != QLA_SUCCESS)  			break; -		/* -		 * Logout all previous fabric devices marked lost, except -		 * FCP2 devices. -		 */ +		/* Add new ports to existing port list */ +		list_splice_tail_init(&new_fcports, &vha->vp_fcports); + +		/* Starting free loop ID. */ +		next_loopid = ha->min_external_loopid; +  		list_for_each_entry(fcport, &vha->vp_fcports, list) {  			if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))  				break; @@ -2995,6 +2997,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)  			if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)  				continue; +			/* Logout lost/gone fabric devices (non-FCP2) */  			if (fcport->scan_state != QLA_FCPORT_SCAN_FOUND &&  			    atomic_read(&fcport->state) == FCS_ONLINE) {  				qla2x00_mark_device_lost(vha, fcport, @@ -3008,76 +3011,30 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)  					    fcport->d_id.b.domain,  					    fcport->d_id.b.area,  					    fcport->d_id.b.al_pa); -					fcport->loop_id = FC_NO_LOOP_ID;  				}  				continue;  			}  			fcport->scan_state = QLA_FCPORT_SCAN_NONE; -		} - -		/* Starting free loop ID. */ -		next_loopid = ha->min_external_loopid; - -		/* -		 * Scan through our port list and login entries that need to be -		 * logged in. -		 */ -		list_for_each_entry(fcport, &vha->vp_fcports, list) { -			if (atomic_read(&vha->loop_down_timer) || -			    test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) -				break; -			if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || -			    (fcport->flags & FCF_LOGIN_NEEDED) == 0) -				continue; - -			if (fcport->loop_id == FC_NO_LOOP_ID) { -				fcport->loop_id = next_loopid; -				rval = qla2x00_find_new_loop_id( -				    base_vha, fcport); -				if (rval != QLA_SUCCESS) { -					/* Ran out of IDs to use */ -					break; +			/* Login fabric devices that need a login */ +			if ((fcport->flags & FCF_LOGIN_NEEDED) != 0 && +			    atomic_read(&vha->loop_down_timer) == 0) { +				if (fcport->loop_id == FC_NO_LOOP_ID) { +					fcport->loop_id = next_loopid; +					rval = qla2x00_find_new_loop_id( +					    base_vha, fcport); +					if (rval != QLA_SUCCESS) { +						/* Ran out of IDs to use */ +						continue; +					}  				}  			} -			/* Login and update database */ -			qla2x00_fabric_dev_login(vha, fcport, &next_loopid); -		} - -		/* Exit if out of loop IDs. */ -		if (rval != QLA_SUCCESS) { -			break; -		} - -		/* -		 * Login and add the new devices to our port list. -		 */ -		list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { -			if (atomic_read(&vha->loop_down_timer) || -			    test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) -				break; - -			/* Find a new loop ID to use. */ -			fcport->loop_id = next_loopid; -			rval = qla2x00_find_new_loop_id(base_vha, fcport); -			if (rval != QLA_SUCCESS) { -				/* Ran out of IDs to use */ -				break; -			}  			/* Login and update database */  			qla2x00_fabric_dev_login(vha, fcport, &next_loopid); - -			list_move_tail(&fcport->list, &vha->vp_fcports);  		}  	} while (0); -	/* Free all new device structures not processed. */ -	list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { -		list_del(&fcport->list); -		kfree(fcport); -	} -  	if (rval) {  		ql_dbg(ql_dbg_disc, vha, 0x2068,  		    "Configure fabric error exit rval=%d.\n", rval); | 
