usb4bsd umodem2.c patch for Nokia

Here is rewritten patch for umodem.c that allows me to use GPRS modem in my Nokia N70
Code:
--- umodem2.c.orig	2008-11-06 20:26:12.000000000 +0300
+++ umodem2.c	2008-11-20 08:43:39.000000000 +0300
@@ -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
  */
 
 /*
@@ -173,6 +174,7 @@
 static void umodem_start_write(struct usb2_com_softc *ucom);
 static void umodem_stop_write(struct usb2_com_softc *ucom);
 static void umodem_get_caps(struct usb2_attach_arg *uaa, uint8_t *cm, uint8_t *acm);
+static struct usb2_cdc_union_descriptor *umodem_get_union(struct usb2_attach_arg *uaa, uint8_t iface_no);
 static void umodem_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr);
 static int umodem_pre_param(struct usb2_com_softc *ucom, struct termios *t);
 static void umodem_cfg_param(struct usb2_com_softc *ucom, struct termios *t);
@@ -316,6 +318,7 @@
 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
 	struct umodem_softc *sc = device_get_softc(dev);
 	struct usb2_cdc_cm_descriptor *cmd;
+	struct usb2_cdc_union_descriptor *cud;
 	uint8_t i;
 	int error;
 
@@ -335,10 +338,12 @@
 	cmd = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
 
 	if ((cmd == NULL) || (cmd->bLength < sizeof(*cmd))) {
-		device_printf(dev, "no CM descriptor!\n");
-		goto detach;
-	}
-	sc->sc_data_iface_no = cmd->bDataInterface;
+		cud = umodem_get_union(uaa, sc->sc_ctrl_iface_no);
+		if (cud == NULL) {
+			device_printf(dev, "no CM descriptor!\n");
+			goto detach;
+		}else sc->sc_data_iface_no = cud->bSlaveInterface[0];
+	}else sc->sc_data_iface_no = cmd->bDataInterface;
 
 	device_printf(dev, "data interface %d, has %sCM over "
 	    "data, has %sbreak\n",
@@ -467,14 +472,6 @@
 	struct usb2_cdc_acm_descriptor *cad;
 
 	*cm = *acm = 0;
-
-	cmd = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
-	if ((cmd == NULL) || (cmd->bLength < sizeof(*cmd))) {
-		DPRINTF("no CM desc\n");
-		return;
-	}
-	*cm = cmd->bmCapabilities;
-
 	cad = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM);
 	if ((cad == NULL) || (cad->bLength < sizeof(*cad))) {
 		DPRINTF("no ACM desc\n");
@@ -482,9 +479,36 @@
 	}
 	*acm = cad->bmCapabilities;
 
+        cmd = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
+        if ((cmd == NULL) || (cmd->bLength < sizeof(*cmd))) {
+                DPRINTF("no CM desc\n");
+                *cm = USB_CDC_CM_DOES_CM | USB_CDC_CM_OVER_DATA;
+        }else *cm = cmd->bmCapabilities;
+
 	return;
 }
 
+static struct usb2_cdc_union_descriptor *
+umodem_get_union(struct usb2_attach_arg *uaa, uint8_t iface_no)
+{
+	struct usb2_cdc_union_descriptor *desc;
+	struct usb2_config_descriptor *cd;
+
+	cd = usb2_get_config_descriptor(uaa->device);
+	
+	uByte *p = (uByte *)cd;
+	uByte *end = p + UGETW(cd->wTotalLength);
+		while (p < end) {
+		desc = (struct usb2_cdc_union_descriptor *)p;
+ 			if (desc->bDescriptorType ==  UDESC_CS_INTERFACE &&
+				desc->bDescriptorSubtype == UDESCSUB_CDC_UNION &&
+				desc->bMasterInterface == iface_no)
+					return (desc);
+		p += desc->bLength;
+		}
+	return (0);
+}
+
 static void
 umodem_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
 {
So it's seen now like umodem, not only ugen
Code:
umodem0: <Nokia product 0x043a, class 2/0, rev 2.00/0.00, addr 3> on usbus0
umodem0: data interface 9, has CM over data, has break
umodem0: status change notification available

Be careful using it 'cause i'm not specialist in C++ =)

PS. Original patch for umodem.c can be found here
http://opticomspb.ru/~savetherbtz/freebsd/umodem-freebsd-8.diff
Original patch for RELENG_7
http://www.freebsd.org/cgi/query-pr.cgi?pr=91546

PPS. Maybe someone can adopt last patch from here http://www.freebsd.org/cgi/query-pr.cgi?pr=usb/117185 for usb4bsd's umodem2.c or at least commit it in this form in HEAD?
 
Back
Top