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/fr...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?