From mjacob@FreeBSD.org  Wed Feb 17 01:36:23 2010
Return-Path: <mjacob@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id D4C971065672
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 17 Feb 2010 01:36:23 +0000 (UTC)
	(envelope-from mjacob@FreeBSD.org)
Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28])
	by mx1.freebsd.org (Postfix) with ESMTP id AB5988FC1A
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 17 Feb 2010 01:36:23 +0000 (UTC)
Received: from freefall.freebsd.org (localhost [127.0.0.1])
	by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id o1H1aNlj007899
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 17 Feb 2010 01:36:23 GMT
	(envelope-from mjacob@freefall.freebsd.org)
Received: (from mjacob@localhost)
	by freefall.freebsd.org (8.14.3/8.14.3/Submit) id o1H1aNu6007898;
	Wed, 17 Feb 2010 01:36:23 GMT
	(envelope-from mjacob)
Message-Id: <201002170136.o1H1aNu6007898@freefall.freebsd.org>
Date: Wed, 17 Feb 2010 01:36:23 GMT
From: Matt Jacob <mjacob@freebsd.org>
Reply-To: Matt Jacob <mjacob@freebsd.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc: osharoiko@gmail.com
Subject: confusion and failure to relogin to FC targets after loop down
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         144026
>Category:       kern
>Synopsis:       [isp] confusion and failure to relogin to FC targets after loop down
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    mjacob
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 17 01:40:01 UTC 2010
>Closed-Date:    Sat Apr 24 23:33:26 UTC 2010
>Last-Modified:  Sat Apr 24 23:33:26 UTC 2010
>Originator:     Matt Jacob
>Release:        FreeBSD 8.0-RC1 i386
>Organization:
Feral Software
>Environment:
Any recent FreeBSD system.

>Description:
This is for the ISP(4) HBA dreiver.

For a SAN topology, after a cable pull from the isp HBA to the Switch, a restoral
after Loop Down timouet leads to the inability to talk to the devices that were there before.
Apparently the QLogic f/w sees them as logged in still.

Here is an annotated set of messages that shows the problem:

1. Contents of the fabric:
....
isp1: Chan 0 WWPN 0x2101001b32af095d PortID 0x020900 N-Port Handle 0, Connection 'F Port'
isp1: Chan 0 PortID 0x0205da handle 0x1 role Target arrived at tgt 0 WWPN 0x21000004cf20f854
isp1: Chan 0 PortID 0x0205dc handle 0x2 role Target arrived at tgt 1 WWPN 0x2100002037fd9c23
isp1: Chan 0 PortID 0x0205e0 handle 0x3 role Target arrived at tgt 2 WWPN 0x2100002037fd8d49
isp1: Chan 0 PortID 0x0205e1 handle 0x4 role Target arrived at tgt 3 WWPN 0x2100002037fd94b4
isp1: Chan 0 PortID 0x0205e2 handle 0x5 role Target arrived at tgt 4 WWPN 0x2100002037fd8d5f
isp1: Chan 0 PortID 0x0205e4 handle 0x6 role Target arrived at tgt 5 WWPN 0x2100002037fd8e7e
isp1: Chan 0 PortID 0x0205e8 handle 0x7 role Target arrived at tgt 6 WWPN 0x2100002037fd8b22
isp1: Chan 0 PortID 0x0205ef handle 0x8 role Target arrived at tgt 7 WWPN 0x21000004cf0099b8
isp1: Chan 0 PortID 0xfffffe handle 0x7fe role (none) stayed WWPN 0x200900c0dd0c87bd

2. A *short* cable pull (less than Loop Down Timeout):
...
isp1: Chan 0 Name Server Database Changed
isp1: Chan 0 PortID 0x0205da handle 0x1 role Target gone zombie at tgt 0 WWPN 0x21000004cf20f854
isp1: Chan 0 PortID 0x0205dc handle 0x2 role Target gone zombie at tgt 1 WWPN 0x2100002037fd9c23
isp1: Chan 0 PortID 0x0205e0 handle 0x3 role Target gone zombie at tgt 2 WWPN 0x2100002037fd8d49
isp1: Chan 0 PortID 0x0205e1 handle 0x4 role Target gone zombie at tgt 3 WWPN 0x2100002037fd94b4
isp1: Chan 0 PortID 0x0205e2 handle 0x5 role Target gone zombie at tgt 4 WWPN 0x2100002037fd8d5f
isp1: Chan 0 PortID 0x0205e4 handle 0x6 role Target gone zombie at tgt 5 WWPN 0x2100002037fd8e7e
isp1: Chan 0 PortID 0x0205e8 handle 0x7 role Target gone zombie at tgt 6 WWPN 0x2100002037fd8b22
isp1: Chan 0 PortID 0x0205ef handle 0x8 role Target gone zombie at tgt 7 WWPN 0x21000004cf0099b8
isp1: Chan 0 PortID 0xfffffe handle 0x7fe role (none) stayed WWPN 0x200900c0dd0c87bd
isp1: Chan 0 Name Server Database Changed
isp1: Chan 0 PortID 0x0205da handle 0x9 role Target stayed at tgt 0 WWPN 0x21000004cf20f854
isp1: Chan 0 PortID 0x0205dc handle 0xa role Target stayed at tgt 1 WWPN 0x2100002037fd9c23
isp1: Chan 0 PortID 0x0205e0 handle 0xb role Target stayed at tgt 2 WWPN 0x2100002037fd8d49
isp1: Chan 0 PortID 0x0205e1 handle 0xc role Target stayed at tgt 3 WWPN 0x2100002037fd94b4
isp1: Chan 0 PortID 0x0205e2 handle 0xd role Target stayed at tgt 4 WWPN 0x2100002037fd8d5f
isp1: Chan 0 PortID 0x0205e4 handle 0xe role Target stayed at tgt 5 WWPN 0x2100002037fd8e7e
isp1: Chan 0 PortID 0x0205e8 handle 0xf role Target stayed at tgt 6 WWPN 0x2100002037fd8b22
isp1: Chan 0 PortID 0x0205ef handle 0x10 role Target stayed at tgt 7 WWPN 0x21000004cf0099b8
isp1: Chan 0 PortID 0xfffffe handle 0x7fe role (none) stayed WWPN 0x200900c0dd0c87bd

Everything is fine.

3. A *long* cable pull (> than Loop Down Timeout):

Devices go away....
.....
isp1: Chan 0: LIP Received
isp1: Chan 0: LOOP Down
isp1: Chan 0 PortID 0x0205da Departed from Target 0 because of Loop Down Timeout
(pass0:isp1:0:0:0): lost device
(pass0:isp1:0:0:0): removing device entry
(da0:isp1:0:0:0): lost device
(da0:isp1:0:0:0): removing device entry
isp1: Chan 0 PortID 0x0205dc Departed from Target 1 because of Loop Down Timeout
(pass1:isp1:0:1:0): lost device
(pass1:isp1:0:1:0): removing device entry
(da1:isp1:0:1:0): lost device
(da1:isp1:0:1:0): removing device entry
isp1: Chan 0 PortID 0x0205e0 Departed from Target 2 because of Loop Down Timeout
(pass2:isp1:0:2:0): lost device
(pass2:isp1:0:2:0): removing device entry
(da2:isp1:0:2:0): lost device
(da2:isp1:0:2:0): removing device entry
isp1: Chan 0 PortID 0x0205e1 Departed from Target 3 because of Loop Down Timeout
(pass3:isp1:0:3:0): lost device
(pass3:isp1:0:3:0): removing device entry
(da3:isp1:0:3:0): lost device
(da3:isp1:0:3:0): removing device entry
isp1: Chan 0 PortID 0x0205e2 Departed from Target 4 because of Loop Down Timeout
(pass4:isp1:0:4:0): lost device
(pass4:isp1:0:4:0): removing device entry
(da4:isp1:0:4:0): lost device
(da4:isp1:0:4:0): removing device entry
isp1: Chan 0 PortID 0x0205e4 Departed from Target 5 because of Loop Down Timeout
(pass5:isp1:0:5:0): lost device
(pass5:isp1:0:5:0): removing device entry
(da5:isp1:0:5:0): lost device
(da5:isp1:0:5:0): removing device entry
isp1: Chan 0 PortID 0x0205e8 Departed from Target 6 because of Loop Down Timeout
(pass6:isp1:0:6:0): lost device
(pass6:isp1:0:6:0): removing device entry
(da6:isp1:0:6:0): lost device
(da6:isp1:0:6:0): removing device entry
isp1: Chan 0 PortID 0x0205ef Departed from Target 7 because of Loop Down Timeout
(pass7:isp1:0:7:0): lost device
(pass7:isp1:0:7:0): removing device entry
(da7:isp1:0:7:0): lost device
(da7:isp1:0:7:0): removing device entry
isp1: Chan 0 Firmware State <Config Wait->Loss Of Sync>

....
Loop comes back up:

isp1: Chan 0: LOOP Reset
isp1: Chan 0: LIP Received
isp1: Chan 0: LIP Received
isp1: Chan 0: LOOP Reset
isp1: Chan 0: LIP Received
isp1: Chan 0 Loop UP
isp1: Chan 0 Port Database Changed
isp1: Chan 0 Firmware State <Config Wait->Ready>
isp1: Chan 0 2Gb link speed

Fabric begins re-evaluating:
....
isp1: Chan 0 WWPN 0x2101001b32af095d PortID 0x020900 N-Port Handle 0, Connection 'F Port'
isp1: Chan 0 PLOGX PortID 0x0205da to N-Port handle 0x11: already logged in with N-Port handle 0x9
isp1: Chan 0 new device 0x0205da@0x9 disappeared
isp1: Chan 0 PLOGX PortID 0x0205dc to N-Port handle 0x11: already logged in with N-Port handle 0xa
isp1: Chan 0 Port Database Changed
isp1: Chan 0 Port Database Changed
isp1: Chan 0 PLOGX PortID 0x0205da to N-Port handle 0x11: already logged in with N-Port handle 0x9
isp1: Chan 0 new device 0x0205da@0x9 disappeared
isp1: Chan 0 PLOGX PortID 0x0205dc to N-Port handle 0x11: already logged in with N-Port handle 0xa
isp1: Chan 0 new device 0x0205dc@0xa disappeared
isp1: Chan 0 PLOGX PortID 0x0205e0 to N-Port handle 0x11: already logged in with N-Port handle 0xb
isp1: Chan 0 new device 0x0205e0@0xb disappeared
isp1: Chan 0 PLOGX PortID 0x0205e1 to N-Port handle 0x11: already logged in with N-Port handle 0xc
isp1: Chan 0 new device 0x0205e1@0xc disappeared
isp1: Chan 0 PLOGX PortID 0x0205e2 to N-Port handle 0x11: already logged in with N-Port handle 0xd
isp1: Chan 0 new device 0x0205e2@0xd disappeared
isp1: Chan 0 PLOGX PortID 0x0205e4 to N-Port handle 0x11: already logged in with N-Port handle 0xe
isp1: Chan 0 new device 0x0205e4@0xe disappeared
isp1: Chan 0 PLOGX PortID 0x0205e8 to N-Port handle 0x11: already logged in with N-Port handle 0xf
isp1: Chan 0 new device 0x0205e8@0xf disappeared
isp1: Chan 0 PLOGX PortID 0x0205ef to N-Port handle 0x11: already logged in with N-Port handle 0x10
isp1: Chan 0 new device 0x0205ef@0x10 disappeared
isp1: Chan 0 PortID 0xfffffe handle 0x7fe role (none) stayed WWPN 0x200900c0dd0c87bd

4. Lossage

At this point *nothing* is entered in the isp driver's port database except the fabric name server.
The devices cannot be reattached.

>How-To-Repeat:
Pull the cable for 30 seconds. Put it back in.
>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->mjacob@freebsd.org 
Responsible-Changed-By: mjacob 
Responsible-Changed-When: Wed Feb 17 01:42:30 UTC 2010 
Responsible-Changed-Why:  
Taking ownership 

http://www.freebsd.org/cgi/query-pr.cgi?pr=144026 
Responsible-Changed-From-To: mjacob@freebsd.org->mjacob 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Feb 17 03:45:32 UTC 2010 
Responsible-Changed-Why:  
Canonicalize assignment. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=144026 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/144026: commit references a PR
Date: Thu, 18 Feb 2010 18:36:30 +0000 (UTC)

 Author: mjacob
 Date: Thu Feb 18 18:35:09 2010
 New Revision: 204050
 URL: http://svn.freebsd.org/changeset/base/204050
 
 Log:
   Don't try and re-use a handle, even if the firmware tells you that's what is logged in.
   
   PR:		kern/144026
   MFC after:	1 week
 
 Modified:
   head/sys/dev/isp/isp.c
 
 Modified: head/sys/dev/isp/isp.c
 ==============================================================================
 --- head/sys/dev/isp/isp.c	Thu Feb 18 17:11:06 2010	(r204049)
 +++ head/sys/dev/isp/isp.c	Thu Feb 18 18:35:09 2010	(r204050)
 @@ -2182,9 +2182,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
  		msg = "no Exchange Control Block";
  		break;
  	case PLOGX_IOCBERR_FAILED:
 -		ISP_SNPRINTF(buf, sizeof (buf),
 -		    "reason 0x%x (last LOGIN state 0x%x)",
 -		    parm1 & 0xff, (parm1 >> 8) & 0xff);
 +		ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
  		msg = buf;
  		break;
  	case PLOGX_IOCBERR_NOFABRIC:
 @@ -2194,8 +2192,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
  		msg = "firmware not ready";
  		break;
  	case PLOGX_IOCBERR_NOLOGIN:
 -		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)",
 -		    parm1);
 +		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
  		msg = buf;
  		rval = MBOX_NOT_LOGGED_IN;
  		break;
 @@ -2207,21 +2204,18 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
  		msg = "no PCB allocated";
  		break;
  	case PLOGX_IOCBERR_EINVAL:
 -		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x",
 -		    parm1);
 +		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
  		msg = buf;
  		break;
  	case PLOGX_IOCBERR_PORTUSED:
  		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
 -		ISP_SNPRINTF(buf, sizeof (buf),
 -		    "already logged in with N-Port handle 0x%x", parm1);
 +		ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
  		msg = buf;
  		rval = MBOX_PORT_ID_USED | (parm1 << 16);
  		break;
  	case PLOGX_IOCBERR_HNDLUSED:
  		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
 -		ISP_SNPRINTF(buf, sizeof (buf),
 -		    "handle already used for PortID 0x%06x", parm1);
 +		ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
  		msg = buf;
  		rval = MBOX_LOOP_ID_USED;
  		break;
 @@ -2232,15 +2226,12 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
  		msg = "no FLOGI_ACC";
  		break;
  	default:
 -		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x",
 -		    plp->plogx_status, flags);
 +		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
  		msg = buf;
  		break;
  	}
  	if (msg) {
 -		isp_prt(isp, ISP_LOGERR,
 -		    "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
 -		    chan, portid, handle, msg);
 +		isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
  	}
  out:
  	if (gs == 0) {
 @@ -3901,8 +3892,7 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
   * Find an unused handle and try and use to login to a port.
   */
  static int
 -isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
 -    uint16_t *ohp)
 +isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
  {
  	int lim, i, r;
  	uint16_t handle;
 @@ -3922,8 +3912,7 @@ isp_login_device(ispsoftc_t *isp, int ch
  		 */
  		r = isp_getpdb(isp, chan, handle, p, 0);
  		if (r == 0 && p->portid != portid) {
 -			(void) isp_plogx(isp, chan, handle, portid,
 -			    PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
 +			(void) isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1);
  		} else if (r == 0) {
  			break;
  		}
 @@ -3933,8 +3922,7 @@ isp_login_device(ispsoftc_t *isp, int ch
  		/*
  		 * Now try and log into the device
  		 */
 -		r = isp_plogx(isp, chan, handle, portid,
 -		    PLOGX_FLG_CMD_PLOGI, 1);
 +		r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
  		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
  			return (-1);
  		}
 @@ -3942,7 +3930,26 @@ isp_login_device(ispsoftc_t *isp, int ch
  			*ohp = handle;
  			break;
  		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
 -			handle = r >> 16;
 +			/*
 +			 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
 +			 * handle. We need to break that association. We used to try and just substitute the handle, but then
 +			 * failed to get any data via isp_getpdb (below).
 +			 */
 +			if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
 +				isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
 +			}
 +			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 +				return (-1);
 +			}
 +			r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
 +			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 +				return (-1);
 +			}
 +			if (r == 0) {
 +				*ohp = handle;
 +			} else {
 +				i = lim;
 +			}
  			break;
  		} else if (r != MBOX_LOOP_ID_USED) {
  			i = lim;
 @@ -3956,8 +3963,7 @@ isp_login_device(ispsoftc_t *isp, int ch
  	}
  
  	if (i == lim) {
 -		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed",
 -		    chan, portid);
 +		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
  		return (-1);
  	}
  
 @@ -3971,15 +3977,12 @@ isp_login_device(ispsoftc_t *isp, int ch
  		return (-1);
  	}
  	if (r != 0) {
 -		isp_prt(isp, ISP_LOGERR,
 -		    "Chan %d new device 0x%06x@0x%x disappeared",
 -		    chan, portid, handle);
 +		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
  		return (-1);
  	}
  
  	if (p->handle != handle || p->portid != portid) {
 -		isp_prt(isp, ISP_LOGERR,
 -		    "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
 +		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
  		    chan, portid, handle, p->portid, p->handle);
  		return (-1);
  	}
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/144026: commit references a PR
Date: Sat, 24 Apr 2010 23:21:01 +0000 (UTC)

 Author: mjacob
 Date: Sat Apr 24 23:20:51 2010
 New Revision: 207175
 URL: http://svn.freebsd.org/changeset/base/207175
 
 Log:
   This is an MFC of 204050.
   
   Don't try and re-use a handle, even if the firmware tells you that's what is logged in.
   
   PR:             kern/144026
 
 Modified:
   stable/8/sys/dev/isp/isp.c
 Directory Properties:
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
   stable/8/sys/dev/xen/xenpci/   (props changed)
   stable/8/sys/geom/sched/   (props changed)
 
 Modified: stable/8/sys/dev/isp/isp.c
 ==============================================================================
 --- stable/8/sys/dev/isp/isp.c	Sat Apr 24 23:13:05 2010	(r207174)
 +++ stable/8/sys/dev/isp/isp.c	Sat Apr 24 23:20:51 2010	(r207175)
 @@ -2167,9 +2167,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
  		msg = "no Exchange Control Block";
  		break;
  	case PLOGX_IOCBERR_FAILED:
 -		ISP_SNPRINTF(buf, sizeof (buf),
 -		    "reason 0x%x (last LOGIN state 0x%x)",
 -		    parm1 & 0xff, (parm1 >> 8) & 0xff);
 +		ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
  		msg = buf;
  		break;
  	case PLOGX_IOCBERR_NOFABRIC:
 @@ -2179,8 +2177,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
  		msg = "firmware not ready";
  		break;
  	case PLOGX_IOCBERR_NOLOGIN:
 -		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)",
 -		    parm1);
 +		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
  		msg = buf;
  		rval = MBOX_NOT_LOGGED_IN;
  		break;
 @@ -2192,21 +2189,18 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
  		msg = "no PCB allocated";
  		break;
  	case PLOGX_IOCBERR_EINVAL:
 -		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x",
 -		    parm1);
 +		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
  		msg = buf;
  		break;
  	case PLOGX_IOCBERR_PORTUSED:
  		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
 -		ISP_SNPRINTF(buf, sizeof (buf),
 -		    "already logged in with N-Port handle 0x%x", parm1);
 +		ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
  		msg = buf;
  		rval = MBOX_PORT_ID_USED | (parm1 << 16);
  		break;
  	case PLOGX_IOCBERR_HNDLUSED:
  		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
 -		ISP_SNPRINTF(buf, sizeof (buf),
 -		    "handle already used for PortID 0x%06x", parm1);
 +		ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
  		msg = buf;
  		rval = MBOX_LOOP_ID_USED;
  		break;
 @@ -2217,15 +2211,12 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
  		msg = "no FLOGI_ACC";
  		break;
  	default:
 -		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x",
 -		    plp->plogx_status, flags);
 +		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
  		msg = buf;
  		break;
  	}
  	if (msg) {
 -		isp_prt(isp, ISP_LOGERR,
 -		    "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
 -		    chan, portid, handle, msg);
 +		isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
  	}
  out:
  	if (gs == 0) {
 @@ -3886,8 +3877,7 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
   * Find an unused handle and try and use to login to a port.
   */
  static int
 -isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
 -    uint16_t *ohp)
 +isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
  {
  	int lim, i, r;
  	uint16_t handle;
 @@ -3907,8 +3897,7 @@ isp_login_device(ispsoftc_t *isp, int ch
  		 */
  		r = isp_getpdb(isp, chan, handle, p, 0);
  		if (r == 0 && p->portid != portid) {
 -			(void) isp_plogx(isp, chan, handle, portid,
 -			    PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
 +			(void) isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1);
  		} else if (r == 0) {
  			break;
  		}
 @@ -3918,8 +3907,7 @@ isp_login_device(ispsoftc_t *isp, int ch
  		/*
  		 * Now try and log into the device
  		 */
 -		r = isp_plogx(isp, chan, handle, portid,
 -		    PLOGX_FLG_CMD_PLOGI, 1);
 +		r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
  		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
  			return (-1);
  		}
 @@ -3927,7 +3915,26 @@ isp_login_device(ispsoftc_t *isp, int ch
  			*ohp = handle;
  			break;
  		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
 -			handle = r >> 16;
 +			/*
 +			 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
 +			 * handle. We need to break that association. We used to try and just substitute the handle, but then
 +			 * failed to get any data via isp_getpdb (below).
 +			 */
 +			if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
 +				isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
 +			}
 +			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 +				return (-1);
 +			}
 +			r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
 +			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
 +				return (-1);
 +			}
 +			if (r == 0) {
 +				*ohp = handle;
 +			} else {
 +				i = lim;
 +			}
  			break;
  		} else if (r != MBOX_LOOP_ID_USED) {
  			i = lim;
 @@ -3941,8 +3948,7 @@ isp_login_device(ispsoftc_t *isp, int ch
  	}
  
  	if (i == lim) {
 -		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed",
 -		    chan, portid);
 +		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
  		return (-1);
  	}
  
 @@ -3956,15 +3962,12 @@ isp_login_device(ispsoftc_t *isp, int ch
  		return (-1);
  	}
  	if (r != 0) {
 -		isp_prt(isp, ISP_LOGERR,
 -		    "Chan %d new device 0x%06x@0x%x disappeared",
 -		    chan, portid, handle);
 +		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
  		return (-1);
  	}
  
  	if (p->handle != handle || p->portid != portid) {
 -		isp_prt(isp, ISP_LOGERR,
 -		    "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
 +		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
  		    chan, portid, handle, p->portid, p->handle);
  		return (-1);
  	}
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: mjacob 
State-Changed-When: Sat Apr 24 23:32:59 UTC 2010 
State-Changed-Why:  
Fix is now in head, releng_8 and releng_7 

http://www.freebsd.org/cgi/query-pr.cgi?pr=144026 
>Unformatted:
