1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

usb4bsd umodem2.c patch for Nokia

Discussion in 'FreeBSD Development' started by SaveTheRbtz, Nov 20, 2008.

  1. SaveTheRbtz

    SaveTheRbtz New Member

    Messages:
    83
    Likes Received:
    0
    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?