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