summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorn_hibma <n_hibma@FreeBSD.org>2008-10-24 07:08:42 +0000
committern_hibma <n_hibma@FreeBSD.org>2008-10-24 07:08:42 +0000
commit90f7e74713a608b7604c6f30ce5eb815952197f6 (patch)
treed8b69fa3ec622d16692b63c8740c6170daab311e /sys/dev/usb
parent238f3ee5f4f09380d958cce0cb993bb0cc6d500a (diff)
downloadFreeBSD-src-90f7e74713a608b7604c6f30ce5eb815952197f6.zip
FreeBSD-src-90f7e74713a608b7604c6f30ce5eb815952197f6.tar.gz
- Bugfix: Only claim interface after having checked all endpoints. This
might make Qualcomm and Option cards (which have all endpoints in 1 interface) work. - Change the USB buffer sizes to depend on the transfer speed. With UMTS we use a buffer 384k / 1000 frames/sec * 50msecs =~ 15kB for example. - Add a MODULE_VERSION statement
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/u3g.c82
1 files changed, 40 insertions, 42 deletions
diff --git a/sys/dev/usb/u3g.c b/sys/dev/usb/u3g.c
index 20dc6ed..4305ab6 100644
--- a/sys/dev/usb/u3g.c
+++ b/sys/dev/usb/u3g.c
@@ -48,6 +48,7 @@
#include "usbdevs.h"
+//#define U3G_DEBUG
#ifdef U3G_DEBUG
#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)
@@ -57,7 +58,6 @@ int u3gdebug = 1;
#define DPRINTFN(n, x...) /* nop */
#endif
-#define U3G_BUFSIZ 10240
#define U3G_MAXPORTS 4
#define U3G_CONFIG_INDEX 0
@@ -85,25 +85,42 @@ struct ucom_callback u3g_callback = {
};
+struct u3g_speeds_s {
+ u_int32_t ispeed;
+ u_int32_t ospeed;
+};
+
+static const struct u3g_speeds_s u3g_speeds[] = {
+#define U3GSP_GPRS 0
+ {64000, 64000},
+#define U3GSP_EDGE 1
+ {384000, 64000},
+#define U3GSP_CDMA 2
+ {384000, 64000},
+#define U3GSP_UMTS 3
+ {384000, 64000},
+#define U3GSP_HSDPA 4
+ {1200000, 384000},
+#define U3GSP_HSUPA 5
+ {1200000, 384000},
+#define U3GSP_HSPA 6
+ {7200000, 384000},
+};
+
/*
* Various supported device vendors/products.
*/
struct u3g_dev_type_s {
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
};
+// Note: The entries marked with XXX should be checked for the correct speed
+// indication to set the buffer sizes.
static const struct u3g_dev_type_s u3g_devs[] = {
/* OEM: Option */
{{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G }, U3GSP_UMTS, U3GFL_NONE },
@@ -113,12 +130,12 @@ static const struct u3g_dev_type_s u3g_devs[] = {
{{ 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 }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX
+ {{ USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM }, U3GSP_CDMA, U3GFL_STUB_WAIT },
/* OEM: Huawei */
{{ 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 }, U3GSP_UMTS, U3GFL_STUB_WAIT }, // XXX
+ {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM }, U3GSP_CDMA, U3GFL_STUB_WAIT },
{{ 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
@@ -242,6 +259,7 @@ u3g_attach(device_t self)
}
int bulkin_no = -1, bulkout_no = -1;
+ int claim_iface = 0;
for (n = 0; n < id->bNumEndpoints; n++) {
ed = usbd_interface2endpoint_descriptor(uaa->ifaces[i], n);
if (ed == NULL)
@@ -264,10 +282,11 @@ u3g_attach(device_t 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;
+ // Allocate a buffer enough for 10ms worth of data
+ ucom->sc_ibufsize = u3g_speeds[sc->sc_speed].ispeed/USB_FRAMES_PER_SECOND*10;
+ ucom->sc_ibufsizepad = ucom->sc_ibufsize;
+ ucom->sc_obufsize = u3g_speeds[sc->sc_speed].ospeed/USB_FRAMES_PER_SECOND*10;
ucom->sc_opkthdrlen = 0;
ucom->sc_callback = &u3g_callback;
@@ -284,12 +303,13 @@ u3g_attach(device_t self)
ucom_attach_tty(ucom, devnamefmt, portno);
#endif
- uaa->ifaces[i] = NULL;
+ claim_iface = 1;
portno++;
bulkin_no = bulkout_no = -1;
}
}
-
+ if (claim_iface)
+ uaa->ifaces[i] = NULL; // claim the interface
}
sc->sc_numports = portno;
@@ -327,37 +347,17 @@ u3g_open(void *addr, int portno)
* anyway.
* Note: We abuse the fact that ucom sets the speed through
* ispeed/ospeed, not through ispeedwat/ospeedwat.
+ * XXX Are the speeds correct?
*/
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
- 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;
- }
+ tp->t_ispeedwat = u3g_speeds[sc->sc_speed].ispeed;
+ tp->t_ospeedwat = u3g_speeds[sc->sc_speed].ospeed;
- /* Avoid excessive buffer sizes. On modern fast machines this is
- * not needed.
+ /* Avoid excessive buffer sizes.
* XXX The values here should be checked. Lower them and see
* whether 'lost chars' messages appear.
*/
@@ -366,8 +366,6 @@ u3g_open(void *addr, int portno)
if (tp->t_ospeedwat > 384000)
tp->t_ospeedwat = 384000;
- DPRINTF("ispeedwat = %d, ospeedwat = %d\n",
- tp->t_ispeedwat, tp->t_ospeedwat);
ttsetwater(tp);
}
#endif
@@ -391,7 +389,6 @@ u3g_close(void *addr, int portno)
tp->t_ispeedwat = (speed_t)-1;
tp->t_ospeedwat = (speed_t)-1;
- DPRINTF("ispeedwat = default, ospeedwat = default\n");
ttsetwater(tp);
}
#endif
@@ -415,6 +412,7 @@ static driver_t u3g_driver = {
DRIVER_MODULE(u3g, uhub, u3g_driver, ucom_devclass, usbd_driver_load, 0);
MODULE_DEPEND(u3g, usb, 1, 1, 1);
MODULE_DEPEND(u3g, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
+MODULE_VERSION(u3g, 1);
/*******************************************************************
****** Stub driver to hide devices that need to reinitialise ******
OpenPOWER on IntegriCloud