usb/91546: [umodem][path] Nokia 6630 mobile phone does not work as modem

Alexey Illarionov littlesavage at rambler.ru
Sun Jan 8 21:20:05 PST 2006


>Number:         91546
>Category:       usb
>Synopsis:       [umodem][path] Nokia 6630 mobile phone does not work
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-usb
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 09 05:20:03 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Alexey Illarionov
>Release:        FreeBSD 5.4-RELEASE-p8 i386
>Organization:
>Environment:
System: FreeBSD ls.orionet.ru 5.4-RELEASE-p8 FreeBSD 5.4-RELEASE-p8 #23: Sun Jan 8 08:16:20 MSK 2006 alexey at ls.orionet.ru:/usr/obj/usr/src/sys/LS i386
Nokia 6630 mobile phone

usbdevs -v
Controller /dev/usb0:
addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), VIA(0x0000), rev 1.00
 port 1 powered
 port 2 addr 2: full speed, power 100 mA, config 1, Nokia 6630(0x0410), Nokia(0x0421), rev 0.00
Controller /dev/usb1:
addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), VIA(0x0000), rev 1.00
 port 1 powered
 port 2 powered

	
>Description:

Nokia 6630 does not work as modem when connected by USB cable.
It is defined as ugen device:
ugen0: Nokia Nokia 6630, rev 2.00/0.00, addr 2

It seems that this phone return ACM descriptor to umodem driver, 
but does not return CM descriptor.

It's work fine after patching:
ucom0: Nokia Nokia 6630, rev 2.00/0.00, addr 2, iclass 2/2
ucom0: data interface 9, has CM over data, has break
ucom0: status change notification available

(minicom)
ATZ
OK
ATI0I1I2I3I4I5I6I7
Nokia

354349009044523

V 3.0436v32
04-01-05
RM-1
(c) NOKIA.

Nokia 6630

2004_wk35

OK
	
>How-To-Repeat:
    Try to use Nokia 6630 as modem.
	
>Fix:

__FBSDID("$FreeBSD: src/sys/dev/usb/umodem.c,v 1.53.2.2 2005/02/08 12:44:09 akiyama Exp $");

--- umodem.c.orig	Tue Feb  8 15:44:09 2005
+++ umodem.c	Mon Jan  9 06:50:07 2006
@@ -69,6 +69,7 @@
 /*
  * Comm Class spec:  http://www.usb.org/developers/devclass_docs/usbccs10.pdf
  *                   http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
+ *		     http://www.usb.org/developers/devclass_docs/cdc_wmc10.zip
  */
 
 /*
@@ -176,6 +177,8 @@
 					  usb_cdc_line_state_t *state);
 
 Static void	umodem_get_caps(usbd_device_handle, int *, int *);
+Static usb_cdc_union_descriptor_t  * 
+    umodem_get_union(usbd_device_handle dev, int iface_no);
 
 Static void	umodem_get_status(void *, int portno, u_char *lsr, u_char *msr);
 Static void	umodem_set(void *, int, int, int);
@@ -274,6 +277,7 @@
 	usb_interface_descriptor_t *id;
 	usb_endpoint_descriptor_t *ed;
 	usb_cdc_cm_descriptor_t *cmd;
+	usb_cdc_union_descriptor_t *cud;
 	char *devinfo = NULL;
 	const char *devname;
 	usbd_status err;
@@ -306,10 +310,13 @@
 	/* Get the data interface no. */
 	cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
 	if (cmd == NULL) {
-		printf("%s: no CM descriptor\n", devname);
+		cud = umodem_get_union(dev, sc->sc_ctl_iface_no);
+		if (cud == NULL) {
+		    printf("%s: no CM and Union descriptors\n", devname);
 		goto bad;
-	}
-	sc->sc_data_iface_no = data_ifcno = cmd->bDataInterface;
+		}else data_ifcno = cud->bSlaveInterface[0];
+	}else data_ifcno = cmd->bDataInterface;
+	sc->sc_data_iface_no = data_ifcno;
 
 	printf("%s: data interface %d, has %sCM over data, has %sbreak\n",
 	       devname, data_ifcno,
@@ -555,19 +562,36 @@
 
 	*cm = *acm = 0;
 
-	cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
-	if (cmd == NULL) {
-		DPRINTF(("umodem_get_desc: no CM desc\n"));
-		return;
-	}
-	*cm = cmd->bmCapabilities;
-
 	cad = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM);
 	if (cad == NULL) {
 		DPRINTF(("umodem_get_desc: no ACM desc\n"));
 		return;
 	}
 	*acm = cad->bmCapabilities;
+
+	cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
+	if (cmd == NULL) {
+		DPRINTF(("umodem_get_desc: no CM desc\n"));
+		*cm = USB_CDC_CM_DOES_CM | USB_CDC_CM_OVER_DATA;
+	}else *cm = cmd->bmCapabilities;
+}
+
+usb_cdc_union_descriptor_t  *
+umodem_get_union(usbd_device_handle dev, int iface_no)
+{
+    usb_cdc_union_descriptor_t *desc;
+    usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
+    uByte *p = (uByte *)cd;
+    uByte *end = p + UGETW(cd->wTotalLength);
+    while (p < end) {
+	desc = (usb_cdc_union_descriptor_t *)p;
+	if (desc->bDescriptorType ==  UDESC_CS_INTERFACE &&
+		desc->bDescriptorSubtype == UDESCSUB_CDC_UNION &&
+		desc->bMasterInterface == iface_no)
+	    return (desc);
+	p += desc->bLength;
+    }
+    return (0);
 }
 
 void



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


More information about the freebsd-usb mailing list