From owner-svn-src-all@FreeBSD.ORG Wed Oct 15 21:36:13 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2037D1065689 for ; Wed, 15 Oct 2008 21:36:13 +0000 (UTC) (envelope-from nick@van-laarhoven.org) Received: from hpsmtp-eml19.kpnxchange.com (hpsmtp-eml19.KPNXCHANGE.COM [213.75.38.84]) by mx1.freebsd.org (Postfix) with ESMTP id 74FDF8FC16 for ; Wed, 15 Oct 2008 21:36:12 +0000 (UTC) (envelope-from nick@van-laarhoven.org) Received: from hpsmtp-eml02.kpnxchange.com ([213.75.38.102]) by hpsmtp-eml19.kpnxchange.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 15 Oct 2008 23:36:10 +0200 Received: from uitsmijter.van-laarhoven.org ([81.207.207.222]) by hpsmtp-eml02.kpnxchange.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 15 Oct 2008 23:36:07 +0200 Received: (qmail 97497 invoked by uid 98); 15 Oct 2008 21:36:05 -0000 Received: from 10.66.0.133 (nick@10.66.0.133) by uitsmijter.van-laarhoven.org (envelope-from , uid 82) with qmail-scanner-2.01 (clamdscan: 0.92/5270. f-prot: 4.6.7/3.16.15. spamassassin: 3.2.3. Clear:RC:1(10.66.0.133):. Processed in 0.814118 secs); 15 Oct 2008 21:36:05 -0000 Received: from unknown (HELO van-laarhoven.org) (nick@10.66.0.133) by uitsmijter.van-laarhoven.org with SMTP; 15 Oct 2008 21:36:04 -0000 Received: (nullmailer pid 22475 invoked by uid 1001); Wed, 15 Oct 2008 21:36:03 -0000 From: Nick Hibma To: svn-src-all@freebsd.org Date: Wed, 15 Oct 2008 23:36:02 +0200 User-Agent: KMail/1.9.7 References: <200810152125.m9FLPC0H043714@svn.freebsd.org> In-Reply-To: <200810152125.m9FLPC0H043714@svn.freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200810152336.03242.nick@van-laarhoven.org> X-OriginalArrivalTime: 15 Oct 2008 21:36:07.0935 (UTC) FILETIME=[08BBE8F0:01C92F0E] Subject: Re: svn commit: r183925 - head/sys/dev/usb X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Oct 2008 21:36:13 -0000 I'm curious to hear back from people testing this driver. Transfer speeds up to 260kB/s have been achieved with a Huawei E220 dongle having a reasonable signal. Please supply the usual: Output of usbctl -f /dev/usbX (or usbdevs -v), dmesg, and if possible speed comparisons between FBSD and windows at the same location and roughly in the same time frame. Nick > Author: n_hibma > Date: Wed Oct 15 21:25:11 2008 > New Revision: 183925 > URL: http://svn.freebsd.org/changeset/base/183925 > > Log: > Rewrite the driver to better support the Huawei devices. It should now > support the Sierra and Novatel devices, ignore all umass devices and hide > the umass devices that represent the CD ROM devices (but not the SD card > slot in the Huawei Mobile dongle). > > Note: This driver in FBSD7 seems to suffer from memory corruption when > used with an Option GT Quad. The E220 however works flawlessly. > > Also add the ID for the Option GTMaxHSUPA, provided by Olivier Fromme. > > Modified: > head/sys/dev/usb/u3g.c > head/sys/dev/usb/ubsa.c > head/sys/dev/usb/usbdevs > > Modified: head/sys/dev/usb/u3g.c > ========================================================================= >===== --- head/sys/dev/usb/u3g.c Wed Oct 15 20:44:00 2008 (r183924) > +++ head/sys/dev/usb/u3g.c Wed Oct 15 21:25:11 2008 (r183925) > @@ -19,6 +19,14 @@ > * $FreeBSD$ > */ > > +/* > + * Notes: > + * - The detour through the tty layer is ridiculously expensive wrt > buffering + * due to the high speeds. > + * We should consider adding a simple r/w device which allows > attaching of PPP + * in a more efficient way. > + */ > + > #include > #include > #include > @@ -40,43 +48,39 @@ > > #include "usbdevs.h" > > +#define U3G_DEBUG 1 > #ifdef U3G_DEBUG > -#define DPRINTFN(n, x) do { if (u3gdebug > (n)) printf x; } while (0) > -int u3gtebug = 0; > +#define DPRINTF(x...) do { if (u3gdebug) device_printf(self, ##x); } > while (0) +#define DPRINTFN(n, x...) do { if (u3gdebug > (n)) > device_printf(self, ##x); } while (0) +int u3gdebug = 1; > #else > -#define DPRINTFN(n, x) > +#define DPRINTF(x...) /* nop */ > +#define DPRINTFN(n, x...) /* nop */ > #endif > -#define DPRINTF(x) DPRINTFN(0, x) > > -#define U3G_BUFSIZ 1024 > +#define U3G_BUFSIZ 10240 > #define U3G_MAXPORTS 4 > #define U3G_CONFIG_INDEX 0 > > struct u3g_softc { > - struct ucom_softc sc_ucom[U3G_MAXPORTS];; > + struct ucom_softc sc_ucom[U3G_MAXPORTS]; > device_t sc_dev; > usbd_device_handle sc_udev; > - u_int16_t sc_flags; > - u_char sc_msr; > - u_char sc_lsr; > - u_char numports; > - > - usbd_interface_handle sc_intr_iface; /* interrupt interface */ > -#ifdef U3G_DEBUG > - int sc_intr_number; /* interrupt number */ > - usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */ > - u_char *sc_intr_buf; /* interrupt buffer */ > -#endif > - int sc_isize; > + u_int8_t sc_speed; > + u_int8_t sc_flags; > + u_char sc_numports; > }; > > +static int u3g_open(void *addr, int portno); > +static void u3g_close(void *addr, int portno); > + > struct ucom_callback u3g_callback = { > NULL, > NULL, > NULL, > NULL, > - NULL, > - NULL, > + u3g_open, > + u3g_close, > NULL, > NULL, > }; > @@ -86,81 +90,106 @@ struct ucom_callback u3g_callback = { > * Various supported device vendors/products. > */ > struct u3g_dev_type_s { > - struct usb_devno u3g_dev; > - u_int16_t u3g_flags; > -#define U3GFL_NONE 0x0000 > -#define U3GFL_HUAWEI_INIT 0x0001 /* Send USB command to reset iface to > ucom mode */ + struct usb_devno devno; > + u_int8_t speed; > +#define U3GSP_GPRS 1 > +#define U3GSP_EDGE 2 > +#define U3GSP_UMTS 3 > +#define U3GSP_HSDPA 4 > +#define U3GSP_HSUPA 5 > +#define U3GSP_HSPA 6 > + > + u_int8_t flags; > +#define U3GFL_NONE 0x00 > +#define U3GFL_HUAWEI_INIT 0x01 // Requires init (Huawei cards) > +#define U3GFL_STUB_WAIT 0x02 // Device reappears after a short delay > }; > > static const struct u3g_dev_type_s u3g_devs[] = { > /* OEM: Option */ > - {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G }, U3GFL_NONE }, > - {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD }, U3GFL_NONE }, > - {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS }, U3GFL_NONE }, > - {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36 }, U3GFL_NONE }, > - {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G }, U3GFL_NONE }, > + {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G > }, U3GSP_UMTS, U3GFL_NONE }, + {{ USB_VENDOR_OPTION, > USB_PRODUCT_OPTION_GT3GQUAD }, U3GSP_UMTS, U3GFL_NONE }, + {{ > USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS }, U3GSP_UMTS, U3GFL_NONE > }, + {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36 > }, U3GSP_HSDPA, U3GFL_NONE }, + {{ USB_VENDOR_OPTION, > USB_PRODUCT_OPTION_GTMAXHSUPA }, U3GSP_HSDPA, U3GFL_NONE }, + {{ > USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G > }, U3GSP_UMTS, U3GFL_NONE }, /* OEM: Qualcomm, Inc. */ > - {{ USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM > }, U3GFL_NONE }, + {{ USB_VENDOR_QUALCOMMINC, > USB_PRODUCT_QUALCOMMINC_CDMA_MSM }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX > /* OEM: Huawei */ > - /* Handled separately. Do not add! > - {{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE }, U3GFL_NONE }, > - {{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220 }, U3GFL_NONE }, > - */ > + {{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE > }, U3GSP_HSDPA, U3GFL_HUAWEI_INIT }, + {{ USB_VENDOR_HUAWEI, > USB_PRODUCT_HUAWEI_E220 }, U3GSP_HSDPA, U3GFL_HUAWEI_INIT }, /* OEM: > Novatel */ > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740 }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D }, U3GFL_NONE }, > - {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870 }, U3GFL_NONE }, > - {{ USB_VENDOR_DELL, USB_PRODUCT_DELL_U740 }, U3GFL_NONE }, > + {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM > }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX + {{ USB_VENDOR_NOVATEL, > USB_PRODUCT_NOVATEL_ES620 }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX + {{ > USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D > }, U3GSP_HSUPA, U3GFL_STUB_WAIT }, + {{ USB_VENDOR_NOVATEL, > USB_PRODUCT_NOVATEL_U720 }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX + {{ > USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727 > }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX + {{ USB_VENDOR_NOVATEL, > USB_PRODUCT_NOVATEL_U740 }, U3GSP_HSDPA, U3GFL_STUB_WAIT }, + {{ > USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2 > }, U3GSP_HSDPA, U3GFL_STUB_WAIT }, + {{ USB_VENDOR_NOVATEL, > USB_PRODUCT_NOVATEL_U870 }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX + {{ > USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620 > }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX + {{ USB_VENDOR_NOVATEL, > USB_PRODUCT_NOVATEL_V640 }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX + {{ > USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720 > }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX + {{ USB_VENDOR_NOVATEL, > USB_PRODUCT_NOVATEL_V740 }, U3GSP_HSDPA, U3GFL_STUB_WAIT }, + {{ > USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D > }, U3GSP_HSUPA, U3GFL_STUB_WAIT }, + {{ USB_VENDOR_NOVATEL, > USB_PRODUCT_NOVATEL_XU870 }, U3GSP_HSDPA, U3GFL_STUB_WAIT }, + {{ > USB_VENDOR_DELL, USB_PRODUCT_DELL_U740 > }, U3GSP_HSDPA, U3GFL_STUB_WAIT }, + /* OEM: Merlin */ > + {{ USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620 > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + /* OEM: Sierra Wireless: */ > + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580 > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ USB_VENDOR_SIERRA, > USB_PRODUCT_SIERRA_AIRCARD595 }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ > USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U }, U3GSP_UMTS, U3GFL_NONE > }, // XXX + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ USB_VENDOR_SIERRA, > USB_PRODUCT_SIERRA_C597 }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ > USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880 }, U3GSP_UMTS, U3GFL_NONE > }, // XXX + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ USB_VENDOR_SIERRA, > USB_PRODUCT_SIERRA_AC880U }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ > USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881 }, U3GSP_UMTS, U3GFL_NONE > }, // XXX + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ USB_VENDOR_SIERRA, > USB_PRODUCT_SIERRA_AC881U }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ > USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625 }, U3GSP_UMTS, U3GFL_NONE > }, // XXX + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720 > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ USB_VENDOR_SIERRA, > USB_PRODUCT_SIERRA_MC5720_2 }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ > USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725 }, U3GSP_UMTS, U3GFL_NONE > }, // XXX + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725 > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ USB_VENDOR_SIERRA, > USB_PRODUCT_SIERRA_AIRCARD875 }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ > USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755 }, U3GSP_UMTS, U3GFL_NONE > }, // XXX + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2 > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ USB_VENDOR_SIERRA, > USB_PRODUCT_SIERRA_MC8755_3 }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ > USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765 }, U3GSP_UMTS, U3GFL_NONE > }, // XXX + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U > }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ USB_VENDOR_SIERRA, > USB_PRODUCT_SIERRA_MC8775_2 }, U3GSP_UMTS, U3GFL_NONE }, // XXX + {{ > USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780 }, U3GSP_UMTS, U3GFL_NONE > }, // XXX + {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781 > }, U3GSP_UMTS, U3GFL_NONE }, // XXX }; > #define u3g_lookup(v, p) ((const struct u3g_dev_type_s > *)usb_lookup(u3g_devs, v, p)) > > -#ifdef U3G_DEBUG > -static void > -u3g_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status > status) -{ > - struct u3g_softc *sc = (struct u3g_softc *)priv; > - device_printf(sc->sc_dev, "Interrupt callback\n"); > -} > -#endif > - > static int > u3g_match(device_t self) > { > struct usb_attach_arg *uaa = device_get_ivars(self); > - usb_interface_descriptor_t *id; > const struct u3g_dev_type_s *u3g_dev_type; > > - if (uaa->vendor == USB_VENDOR_HUAWEI) { > - if (uaa->iface) { > - /* We attach to the interface instead of the device as > - * some devices have a built-in SD card reader on the > - * second interface. If the interface class of the > - * first interface is no longer mass storage it has > - * changed appearance and we should attach it. > - */ > - id = usbd_get_interface_descriptor(uaa->iface); > - if (id && id->bInterfaceClass == UICLASS_VENDOR) > - return (UMATCH_VENDOR_PRODUCT_CONF_IFACE); > - } > + if (!uaa->iface) > return UMATCH_NONE; > - } > > u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product); > - if (u3g_dev_type) > - return UMATCH_VENDOR_PRODUCT; > + if (!u3g_dev_type) > + return UMATCH_NONE; > > - return UMATCH_NONE; > + if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT) { > + /* If the interface class of the first interface is no longer > + * mass storage the card has changed to modem (see u3g_attach() > + * below). > + */ > + usb_interface_descriptor_t *id; > + id = usbd_get_interface_descriptor(uaa->iface); > + if (!id || id->bInterfaceClass == UICLASS_MASS) > + return UMATCH_NONE; > + } > + > + return UMATCH_VENDOR_PRODUCT_CONF_IFACE; > } > > static int > @@ -168,120 +197,105 @@ u3g_attach(device_t self) > { > struct u3g_softc *sc = device_get_softc(self); > struct usb_attach_arg *uaa = device_get_ivars(self); > + const struct u3g_dev_type_s *u3g_dev_type; > usbd_device_handle dev = uaa->device; > - usbd_interface_handle iface; > usb_interface_descriptor_t *id; > usb_endpoint_descriptor_t *ed; > - usbd_status error; > int i, n; > usb_config_descriptor_t *cd; > - struct ucom_softc *ucom = NULL; > char devnamefmt[32]; > > - sc->sc_dev = self; > -#ifdef U3G_DEBUG > - sc->sc_intr_number = -1; > - sc->sc_intr_pipe = NULL; > -#endif > - /* Move the device into the configured state. */ > - error = usbd_set_config_index(dev, U3G_CONFIG_INDEX, 1); > - if (error) { > - device_printf(self, "failed to set configuration: %s\n", > - usbd_errstr(error)); > - goto bad; > - } > - > /* get the config descriptor */ > cd = usbd_get_config_descriptor(dev); > - > if (cd == NULL) { > device_printf(self, "failed to get configuration descriptor\n"); > - goto bad; > + return ENXIO; > } > > + sc->sc_dev = self; > sc->sc_udev = dev; > - sc->numports = (cd->bNumInterface <= > U3G_MAXPORTS)?cd->bNumInterface:U3G_MAXPORTS; - for ( i = 0; i < > sc->numports; i++ ) { > - ucom = &sc->sc_ucom[i]; > - > - ucom->sc_dev = self; > - ucom->sc_udev = dev; > - error = usbd_device2interface_handle(dev, i, &iface); > - if (error) { > - device_printf(ucom->sc_dev, > - "failed to get interface, err=%s\n", > - usbd_errstr(error)); > - ucom->sc_dying = 1; > - goto bad; > + > + u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product); > + sc->sc_flags = u3g_dev_type->flags; > + sc->sc_speed = u3g_dev_type->speed; > + > + sprintf(devnamefmt,"U%d.%%d", device_get_unit(self)); > + int portno = 0; > + for (i = 0; i < uaa->nifaces && portno < U3G_MAXPORTS; i++) { > + if (uaa->ifaces[i] == NULL) > + continue; > + > + id = usbd_get_interface_descriptor(uaa->ifaces[i]); > + if (id && id->bInterfaceClass == UICLASS_MASS) { > + /* We attach to the interface instead of the device as > + * some devices have a built-in SD card reader. > + * Claim the first umass device (cdX) as it contains > + * only Windows drivers anyway (CD-ROM), hiding it. > + */ > +#ifndef U3G_DEBUG > + if (!bootverbose) > + if (uaa->vendor == USB_VENDOR_HUAWEI) > + if (id->bInterfaceNumber == 2) > + uaa->ifaces[i] = NULL; > +#endif > + continue; > } > - id = usbd_get_interface_descriptor(iface); > - ucom->sc_iface = iface; > > - ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1; > + int bulkin_no = -1, bulkout_no = -1; > for (n = 0; n < id->bNumEndpoints; n++) { > - ed = usbd_interface2endpoint_descriptor(iface, n); > - if (ed == NULL) { > - device_printf(ucom->sc_dev, > - "could not read endpoint descriptor\n"); > - goto bad; > - } > + ed = usbd_interface2endpoint_descriptor(uaa->ifaces[i], n); > + if (ed == NULL) > + continue; > if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN > && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) > - ucom->sc_bulkin_no = ed->bEndpointAddress; > + bulkin_no = ed->bEndpointAddress; > else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT > && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) > - ucom->sc_bulkout_no = ed->bEndpointAddress; > - } > - if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) { > - device_printf(ucom->sc_dev, "missing endpoint\n"); > - goto bad; > - } > - ucom->sc_parent = sc; > - ucom->sc_ibufsize = U3G_BUFSIZ; > - ucom->sc_obufsize = U3G_BUFSIZ; > - ucom->sc_ibufsizepad = U3G_BUFSIZ; > - ucom->sc_opkthdrlen = 0; > - > - ucom->sc_callback = &u3g_callback; > - > - sprintf(devnamefmt,"U%d.%%d", device_get_unit(self)); > - DPRINTF(("u3g: in=0x%x out=0x%x, devname=%s\n", > - ucom->sc_bulkin_no, ucom->sc_bulkout_no, devnamefmt)); > + bulkout_no = ed->bEndpointAddress; > + > + /* If we have found a pair of bulk-in/-out endpoints > + * create a serial port for it. Note: We assume that > + * the bulk-in and bulk-out endpoints appear in pairs. > + */ > + if (bulkin_no != -1 && bulkout_no != -1) { > + struct ucom_softc *ucom = &sc->sc_ucom[portno]; > + > + ucom->sc_dev = self; > + ucom->sc_udev = dev; > + ucom->sc_iface = uaa->ifaces[i]; > + ucom->sc_bulkin_no = bulkin_no; > + ucom->sc_ibufsize = U3G_BUFSIZ; > + ucom->sc_ibufsizepad = U3G_BUFSIZ; // XXX What's this? > + ucom->sc_bulkout_no = bulkout_no; > + ucom->sc_obufsize = U3G_BUFSIZ; > + ucom->sc_opkthdrlen = 0; > + > + ucom->sc_callback = &u3g_callback; > + ucom->sc_parent = sc; > + ucom->sc_portno = portno; > + > + DPRINTF("port=%d iface=%d in=0x%x out=0x%x\n", > + portno, i, > + ucom->sc_bulkin_no, > + ucom->sc_bulkout_no); > #if __FreeBSD_version < 800000 > - ucom_attach_tty(ucom, TS_CALLOUT, devnamefmt, i); > + ucom_attach_tty(ucom, TS_CALLOUT, devnamefmt, portno); > #else > - ucom_attach_tty(ucom, devnamefmt, i); > + ucom_attach_tty(ucom, devnamefmt, portno); > #endif > - } > -#ifdef U3G_DEBUG > - if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) { > - sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); > - error = usbd_open_pipe_intr(sc->sc_intr_iface, > - sc->sc_intr_number, > - USBD_SHORT_XFER_OK, > - &sc->sc_intr_pipe, > - sc, > - sc->sc_intr_buf, > - sc->sc_isize, > - u3g_intr, > - 100); > - if (error) { > - device_printf(self, > - "cannot open interrupt pipe (addr %d)\n", > - sc->sc_intr_number); > - goto bad; > + > + uaa->ifaces[i] = NULL; > + portno++; > + bulkin_no = bulkout_no = -1; > + } > } > + > } > -#endif > - device_printf(self, "configured %d serial ports (/dev/cuaU%d.X)\n", > - sc->numports, device_get_unit(self)); > + sc->sc_numports = portno; > > + device_printf(self, "configured %d serial ports (%s)\n", > + sc->sc_numports, devnamefmt); > return 0; > - > -bad: > - DPRINTF(("u3g_attach: ATTACH ERROR\n")); > - ucom->sc_dying = 1; > - return ENXIO; > } > > static int > @@ -291,39 +305,98 @@ u3g_detach(device_t self) > int rv = 0; > int i; > > - DPRINTF(("u3g_detach: sc=%p\n", sc)); > - > - for (i = 0; i < sc->numports; i++) { > - if(sc->sc_ucom[i].sc_udev) { > - sc->sc_ucom[i].sc_dying = 1; > - rv = ucom_detach(&sc->sc_ucom[i]); > - if(rv != 0) { > - device_printf(self, "Can't deallocat port %d\n", i); > - return rv; > - } > + for (i = 0; i < sc->sc_numports; i++) { > + sc->sc_ucom[i].sc_dying = 1; > + rv = ucom_detach(&sc->sc_ucom[i]); > + if (rv != 0) { > + device_printf(self, "ucom_detach(U%d.%d\n", device_get_unit(self), > i); + return rv; > } > } > > + return 0; > +} > + > +static int > +u3g_open(void *addr, int portno) > +{ > +#if __FreeBSD_version < 800000 > + /* Supply generous buffering for these cards to avoid disappointments > + * when setting the speed incorrectly. Only do this for the first port > + * assuming that the rest of the ports are used for diagnostics only > + * anyway. > + * Note: We abuse the fact that ucom sets the speed through > + * ispeed/ospeed, not through ispeedwat/ospeedwat. > + */ > + if (portno == 0) { > + struct u3g_softc *sc = addr; > + struct ucom_softc *ucom = &sc->sc_ucom[portno]; > + struct tty *tp = ucom->sc_tty; > #ifdef U3G_DEBUG > - if (sc->sc_intr_pipe != NULL) { > - int err = usbd_abort_pipe(sc->sc_intr_pipe); > - if (err) > - device_printf(self, > - "abort interrupt pipe failed: %s\n", > - usbd_errstr(err)); > - err = usbd_close_pipe(sc->sc_intr_pipe); > - if (err) > - device_printf(self, > - "close interrupt pipe failed: %s\n", > - usbd_errstr(err)); > - free(sc->sc_intr_buf, M_USBDEV); > - sc->sc_intr_pipe = NULL; > + device_t self = sc->sc_dev; > +#endif > + > + if (sc->sc_speed&U3GSP_HSPA) { > + tp->t_ispeedwat = 7200000; > + tp->t_ospeedwat = 384000; > + } else if (sc->sc_speed&U3GSP_HSUPA) { > + tp->t_ispeedwat = 1200000; > + tp->t_ospeedwat = 384000; > + } else if (sc->sc_speed&U3GSP_HSDPA) { > + tp->t_ispeedwat = 1200000; > + tp->t_ospeedwat = 384000; > + } else if (sc->sc_speed&U3GSP_UMTS) { > + tp->t_ispeedwat = 384000; > + tp->t_ospeedwat = 64000; > + } else if (sc->sc_speed&U3GSP_EDGE) { > + tp->t_ispeedwat = 384000; > + tp->t_ospeedwat = 64000; > + } else { > + tp->t_ispeedwat = 64000; > + tp->t_ospeedwat = 64000; > + } > + > + /* Avoid excessive buffer sizes. On modern fast machines this is > + * not needed. > + * XXX The values here should be checked. Lower them and see > + * whether 'lost chars' messages appear. > + */ > + if (tp->t_ispeedwat > 384000) > + tp->t_ispeedwat = 384000; > + if (tp->t_ospeedwat > 384000) > + tp->t_ospeedwat = 384000; > + > + DPRINTF("ispeedwat = %d, ospeedwat = %d\n", > + tp->t_ispeedwat, tp->t_ospeedwat); > + ttsetwater(tp); > } > #endif > > return 0; > } > > +static void > +u3g_close(void *addr, int portno) > +{ > +#if __FreeBSD_version < 800000 > + if (portno == 0) { /* see u3g_open() */ > + /* Reduce the buffers allocated above again */ > + struct u3g_softc *sc = addr; > + struct ucom_softc *ucom = &sc->sc_ucom[portno]; > + struct tty *tp = ucom->sc_tty; > +#ifdef U3G_DEBUG > + device_t self = sc->sc_dev; > +#endif > + > + tp->t_ispeedwat = (speed_t)-1; > + tp->t_ospeedwat = (speed_t)-1; > + > + DPRINTF("ispeedwat = default, ospeedwat = default\n"); > + ttsetwater(tp); > + } > +#endif > +} > + > static device_method_t u3g_methods[] = { > /* Device interface */ > DEVMETHOD(device_probe, u3g_match), > @@ -365,32 +438,29 @@ static int > u3gstub_match(device_t self) > { > struct usb_attach_arg *uaa = device_get_ivars(self); > - usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device); > + const struct u3g_dev_type_s *u3g_dev_type; > usb_interface_descriptor_t *id; > > - /* These are 3G modem devices (E220, Mobile, etc.) with auto-install > - * flash disks for Windows/MacOSX through the first interface. > + /* This stub handles 3G modem devices (E220, Mobile, etc.) with > + * auto-install flash disks for Windows/MacOSX on the first interface. > + * After some command or some delay they change appearance to a modem. > */ > - if (uaa->vendor == USB_VENDOR_HUAWEI) { > - /* The Huawei device presents itself as a umass device with > - * Windows drivers on it. After installation of the driver, it > - * reinits into a 3G serial device. > - */ > - if (uaa->iface) { > - id = usbd_get_interface_descriptor(uaa->iface); > - if (id && id->bInterfaceNumber == 0 && id->bInterfaceClass == > UICLASS_MASS) { - u3gstub_huawei_init(uaa->device); > - return (UMATCH_VENDOR_PRODUCT_CONF_IFACE); > - } > - } > - } > > - if (UGETW(dd->idVendor) == USB_VENDOR_QUALCOMMINC > - || UGETW(dd->idVendor) == USB_VENDOR_NOVATEL) { > - /* Device by these vendors will automatically reappear as a > - * ucom device if ignored (or if sent an eject command). > + if (!uaa->iface) > + return UMATCH_NONE; > + > + u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product); > + if (!u3g_dev_type) > + return UMATCH_NONE; > + > + if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT > + || u3g_dev_type->flags&U3GFL_STUB_WAIT) { > + /* We assume that if the first interface is still a mass > + * storage device the device has not yet changed appearance. > */ > - return UMATCH_VENDOR_PRODUCT; > + id = usbd_get_interface_descriptor(uaa->iface); > + if (id && id->bInterfaceNumber == 0 && id->bInterfaceClass == > UICLASS_MASS) + return UMATCH_VENDOR_PRODUCT; > } > > return UMATCH_NONE; > @@ -399,11 +469,28 @@ u3gstub_match(device_t self) > static int > u3gstub_attach(device_t self) > { > -#if 0 > - if (!bootverbose) > + struct usb_attach_arg *uaa = device_get_ivars(self); > + const struct u3g_dev_type_s *u3g_dev_type; > + int i; > +#ifndef U3G_DEBUG > + if (!bootverbose) // hide the stub attachment > device_quiet(self); > #endif > > + if (uaa->iface) > + for (i = 0; i < uaa->nifaces; i++) > + uaa->ifaces[i] = NULL; // claim all interfaces > + > + u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product); > + if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT) { > + /* XXX Should we delay the kick? > + */ > + DPRINTF("changing Huawei modem to modem mode\n"); > + u3gstub_huawei_init(uaa->device); > + } else if (u3g_dev_type->flags&U3GFL_STUB_WAIT) { > + /* nop */ > + } > + > return 0; > } > > > Modified: head/sys/dev/usb/ubsa.c > ========================================================================= >===== --- head/sys/dev/usb/ubsa.c Wed Oct 15 20:44:00 2008 (r183924) > +++ head/sys/dev/usb/ubsa.c Wed Oct 15 21:25:11 2008 (r183925) > @@ -226,52 +226,6 @@ static const struct ubsa_product { > { USB_VENDOR_GOHUBS, USB_PRODUCT_GOHUBS_GOCOM232 }, > /* Peracom */ > { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1 }, > - /* Merlin */ > - { USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620 }, > - /* Sierra Wireless AirCard 580 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580 }, > - /* Sierra Wireless AirCard 595 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595 }, > - /* Sierra Wireless AirCard 595U */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U }, > - /* Sierra Wireless AirCard 597E */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E }, > - /* Sierra Wireless Compass 597 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597 }, > - /* Sierra Wireless AirCard 880 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880 }, > - /* Sierra Wireless AirCard 880E */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E }, > - /* Sierra Wireless AirCard 880U */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U }, > - /* Sierra Wireless AirCard 881 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881 }, > - /* Sierra Wireless AirCard 881E */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E }, > - /* Sierra Wireless AirCard 881U */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U }, > - /* Sierra Wireless EM5625 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625 }, > - /* Sierra Wireless MC5720 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720 }, > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2 }, > - /* Sierra Wireless MC5725 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725 }, > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725 }, > - /* Sierra Wireless MC8755 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875 }, > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755 }, > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2 }, > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3 }, > - /* Sierra Wireless MC8765 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765 }, > - /* Sierra Wireless MC8775 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U }, > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2 }, > - /* Sierra Wireless MC8780 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780 }, > - /* Sierra Wireless MC8781 */ > - { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781 }, > { 0, 0 } > }; > > > Modified: head/sys/dev/usb/usbdevs > ========================================================================= >===== --- head/sys/dev/usb/usbdevs Wed Oct 15 20:44:00 2008 (r183924) > +++ head/sys/dev/usb/usbdevs Wed Oct 15 21:25:11 2008 (r183925) > @@ -1872,6 +1872,7 @@ product OPTION GT3G 0x6000 GlobeTrotter > product OPTION GT3GQUAD 0x6300 GlobeTrotter 3G QUAD datacard > product OPTION GT3GPLUS 0x6600 GlobeTrotter 3G+ datacard > product OPTION GTMAX36 0x6701 GlobeTrotter Max 3.6 Modem > +product OPTION GTMAXHSUPA 0x7001 GlobeTrotter HSUPA > > /* OQO */ > product OQO WIFI01 0x0002 model 01 WiFi interface > _______________________________________________ > svn-src-all@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/svn-src-all > To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"