>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 [EMAIL PROTECTED]:/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:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to