Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 21 Apr 2007 19:44:22 GMT
From:      Karsten Brandt<spam_schlucker@web.de>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   i386/111990: system freeze in initialization process of an UMTS card "Merlin U630"
Message-ID:  <200704211944.l3LJiMIg063608@www.freebsd.org>
Resent-Message-ID: <200704211950.l3LJo2qo074305@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         111990
>Category:       i386
>Synopsis:       system freeze in initialization process of an UMTS card "Merlin U630"
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Apr 21 19:50:02 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Karsten Brandt
>Release:        6.2
>Organization:
>Environment:
FreeBSD pegasus.local 6.2-STABLE FreeBSD 6.2-STABLE #49: 
Mon Apr 16 18:31:59 UTC 2007     root@pegasus.local:/usr/obj/usr/src/sys/PEGASUS_KERNEL  
i386
>Description:
I use a Merlin U630 UMTS card as device for my internet access.
This card caused in most cases on cold start an error during the initialization 
process for the second Modem channel (second card function). 
The system was freezed until I have rejected the card.
Therefore I have analyzed the startup procedure of the card and found the
point of trouble in the cbb_power function in pccbb.c.

See the following code snippet from pccbb.c.
The point of trouble is marked with [KB].

cbb_power(device_t brdev, int volts)
{
	uint32_t status, sock_ctrl;
	struct cbb_softc *sc = device_get_softc(brdev);
	int timeout;
	int retval = 0;
	uint32_t sockevent;
	uint8_t reg = 0;

	status = cbb_get(sc, CBB_SOCKET_STATE);
	sock_ctrl = cbb_get(sc, CBB_SOCKET_CONTROL);

	sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK;
	switch (volts & CARD_VCCMASK) {
	case 5:
		sock_ctrl |= CBB_SOCKET_CTRL_VCC_5V;
		break;
	case 3:
		sock_ctrl |= CBB_SOCKET_CTRL_VCC_3V;
		break;
	case XV:
		sock_ctrl |= CBB_SOCKET_CTRL_VCC_XV;
		break;
	case YV:
		sock_ctrl |= CBB_SOCKET_CTRL_VCC_YV;
		break;
	case 0:
		break;
	default:
		return (0);			/* power NEVER changed */
	}

	/* VPP == VCC */
	sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK;
	sock_ctrl |= ((sock_ctrl >> 4) & 0x07);

	if (cbb_get(sc, CBB_SOCKET_CONTROL) == sock_ctrl)
		return (1); /* no change necessary */
	DEVPRINTF((sc->dev, "cbb_power: %dV\n", volts));
	if (volts != 0 && sc->chipset == CB_O2MICRO)
		reg = cbb_o2micro_power_hack(sc);

	cbb_set(sc, CBB_SOCKET_CONTROL, sock_ctrl);
// [KB]	status = cbb_get(sc, CBB_SOCKET_STATE);    
// <- function call of cbb_get() lead to a frozen system 
//    until the card will be rejected 

>How-To-Repeat:
see description above
>Fix:
After I have identified the problem, I searched a solution. 
The result of my effort is the following patch:

--- ctm/org_src/sys/dev/pccbb/pccbb.c	Mon Mar 26 05:35:45 2007
+++ sys/dev/pccbb/pccbb.c	Mon Mar 26 05:45:03 2007
@@ -738,21 +738,22 @@
 int
 cbb_power(device_t brdev, int volts)
 {
 	uint32_t status, sock_ctrl;
 	struct cbb_softc *sc = device_get_softc(brdev);
 	int timeout;
 	int retval = 0;
 	uint32_t sockevent;
 	uint8_t reg = 0;
 
-	status = cbb_get(sc, CBB_SOCKET_STATE);
+//[KB 0] moved to place of first use of variable status
+//	status = cbb_get(sc, CBB_SOCKET_STATE);
 	sock_ctrl = cbb_get(sc, CBB_SOCKET_CONTROL);
 
 	sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK;
 	switch (volts & CARD_VCCMASK) {
 	case 5:
 		sock_ctrl |= CBB_SOCKET_CTRL_VCC_5V;
 		break;
 	case 3:
 		sock_ctrl |= CBB_SOCKET_CTRL_VCC_3V;
 		break;
@@ -771,22 +772,26 @@
 	/* VPP == VCC */
 	sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK;
 	sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
 
 	if (cbb_get(sc, CBB_SOCKET_CONTROL) == sock_ctrl)
 		return (1); /* no change necessary */
 	DEVPRINTF((sc->dev, "cbb_power: %dV\n", volts));
 	if (volts != 0 && sc->chipset == CB_O2MICRO)
 		reg = cbb_o2micro_power_hack(sc);
 
+// [KB 1] I don't know, but we couldt try it. And yes, it works!
+	sc->chipinit(sc);
+
 	cbb_set(sc, CBB_SOCKET_CONTROL, sock_ctrl);
-	status = cbb_get(sc, CBB_SOCKET_STATE);
+// [KB 2] moved to the place of first use of status variable 
+//	status = cbb_get(sc, CBB_SOCKET_STATE);
 
 	/* 
 	 * XXX This busy wait is bogus.  We should wait for a power
 	 * interrupt and then whine if the status is bad.  If we're
 	 * worried about the card not coming up, then we should also
 	 * schedule a timeout which we can cancel in the power interrupt.
 	 */
 	timeout = 20;
 	do {
 		DELAY(20*1000);
@@ -800,20 +805,23 @@
 		goto done;
 	}
 
 	/* XXX
 	 * delay 400 ms: thgough the standard defines that the Vcc set-up time
 	 * is 20 ms, some PC-Card bridge requires longer duration.
 	 * XXX Note: We should check the stutus AFTER the delay to give time
 	 * for things to stabilize.
 	 */
 	DELAY(400*1000);
+
+// [KB 3] moved from [KB 0 and KB 2] above
+	status = cbb_get(sc, CBB_SOCKET_STATE);
 
 	if (status & CBB_STATE_BAD_VCC_REQ) {
 		device_printf(sc->dev,
 		    "bad Vcc request. ctrl=0x%x, status=0x%x\n",
 		    sock_ctrl ,status);
 		printf("cbb_power: %dV\n", volts);
 		goto done;
 	}
 	retval = 1;
 done:;

The important part in this patch is marked with [KB 1]. This part initialize the 
card before we try to set the voltage value. This prevent the described problem.
The initialization process for the Merlin U630 looks to be faster and stable now.

The changes marked with [KB 0], [KB 2] and [KB 3] were only inserted for a better 
code structure and makes the code cleaner. On mark [KB 0] the variable 'status' will 
filled with the sock state but this will not used up to the next call of cbb_get 
to get the sock state. On [KB 2] is the second call of cbb_get but the variable
'status' is also here not used direct after this call. The 'status' variable will used
only on the end of the ccb_power function on mark [KB 3]. Therefore I have moved the 
call of cbb_get to this point and removed them from the points, which where marked with
[KB 0] and [KB 2]. 

I hope this was helpfully.

Please, verify this patch with other systems and configurations.
I don't have the possibility to do this. 
For further information you can contact me.

Best regards
Karsten Brandt

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200704211944.l3LJiMIg063608>