PERFORCE change 153231 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Nov 19 11:15:24 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=153231
Change 153231 by hselasky at hselasky_laptop001 on 2008/11/19 19:14:55
Import USB 3G driver.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#34 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_msctest.c#10 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_msctest.h#6 edit
.. //depot/projects/usb/src/sys/dev/usb2/serial/u3g2.c#1 add
.. //depot/projects/usb/src/sys/modules/usb2/Makefile#5 edit
.. //depot/projects/usb/src/sys/modules/usb2/serial_3g/Makefile#1 add
Differences ...
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#34 (text+ko) ====
@@ -1605,18 +1605,16 @@
* Try to figure out if we have an
* auto-install disk there:
*/
- if (usb2_test_autoinstall(udev, 0) == 0) {
+ if (usb2_test_autoinstall(udev, 0, 0) == 0) {
DPRINTFN(0, "Found possible auto-install "
"disk (trying next config)\n");
config_index++;
goto repeat_set_config;
}
}
- } else if (UGETW(udev->ddesc.idVendor) == USB_VENDOR_HUAWEI) {
- if (usb2_test_huawei(udev, 0) == 0) {
- DPRINTFN(0, "Found Huawei auto-install disk!\n");
- err = USB_ERR_STALLED; /* fake an error */
- }
+ } else if (usb2_test_huawei(udev, &uaa) == 0) {
+ DPRINTFN(0, "Found Huawei auto-install disk!\n");
+ err = USB_ERR_STALLED; /* fake an error */
}
} else {
err = 0; /* set success */
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_msctest.c#10 (text+ko) ====
@@ -36,6 +36,7 @@
#include <dev/usb2/include/usb2_mfunc.h>
#include <dev/usb2/include/usb2_error.h>
#include <dev/usb2/include/usb2_standard.h>
+#include <dev/usb2/include/usb2_devid.h>
#define USB_DEBUG_VAR usb2_debug
@@ -49,6 +50,7 @@
#include <dev/usb2/core/usb2_device.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_util.h>
+#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/include/usb2_mfunc.h>
#include <dev/usb2/include/usb2_error.h>
@@ -474,7 +476,8 @@
* Else: Not an auto install disk.
*------------------------------------------------------------------------*/
usb2_error_t
-usb2_test_autoinstall(struct usb2_device *udev, uint8_t iface_index)
+usb2_test_autoinstall(struct usb2_device *udev, uint8_t iface_index,
+ uint8_t do_eject)
{
struct usb2_interface *iface;
struct usb2_interface_descriptor *id;
@@ -546,8 +549,26 @@
sid_type = sc->buffer[0] & 0x1F;
if (sid_type == 0x05) {
/* CD-ROM */
- /* XXX could investigate more */
- return (0);
+ if (do_eject) {
+ /* 0: opcode: SCSI START/STOP */
+ sc->cbw.CBWCDB[0] = 0x1b;
+ /* 1: byte2: Not immediate */
+ sc->cbw.CBWCDB[1] = 0x00;
+ /* 2..3: reserved */
+ sc->cbw.CBWCDB[2] = 0x00;
+ sc->cbw.CBWCDB[3] = 0x00;
+ /* 4: Load/Eject command */
+ sc->cbw.CBWCDB[4] = 0x02;
+ /* 5: control */
+ sc->cbw.CBWCDB[5] = 0x00;
+ err = bbb_command_start(sc, DIR_OUT, 0,
+ NULL, 0, 6, USB_MS_HZ);
+
+ DPRINTFN(0, "Eject CD command "
+ "status: %s\n", usb2_errstr(err));
+ }
+ err = 0;
+ goto done;
}
} else if (--timeout) {
usb2_pause_mtx(&sc->mtx, USB_MS_HZ);
@@ -566,28 +587,136 @@
}
/*
- * Huawei Exxx radio devices have a built in flash disk which is their
- * default power up configuration. This allows the device to carry its
- * own installation software.
- *
- * Instead of following the USB spec, and create multiple
- * configuration descriptors for this, the devices expects the driver
- * to send UF_DEVICE_REMOTE_WAKEUP to endpoint 2 to reset the device,
- * so it reprobes, now with the radio exposed.
+ * NOTE: The entries marked with XXX should be checked for the correct
+ * speed indication to set the buffer sizes.
*/
+static const struct usb2_device_id u3g_devs[] = {
+ /* OEM: Option */
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAXHSUPA, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
+ /* OEM: Qualcomm, Inc. */
+ {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
+ /* OEM: Huawei */
+ {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, U3GINFO(U3GSP_HSDPA, U3GFL_HUAWEI_INIT))},
+ {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220, U3GINFO(U3GSP_HSPA, U3GFL_HUAWEI_INIT))},
+ /* OEM: Novatel */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_DELL, USB_PRODUCT_DELL_U740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ /* OEM: Merlin */
+ {USB_VPI(USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ /* OEM: Sierra Wireless: */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ /* Sierra TruInstaller device ID */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL, U3GINFO(U3GSP_UMTS, U3GFL_SIERRA_INIT))},
+};
+
+static void
+u3g_sierra_init(struct usb2_device *udev)
+{
+ struct usb2_device_request req;
+
+ DPRINTFN(0, "\n");
+
+ req.bmRequestType = UT_VENDOR;
+ req.bRequest = UR_SET_INTERFACE;
+ USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
+ USETW(req.wIndex, UHF_PORT_CONNECTION);
+ USETW(req.wLength, 0);
+
+ if (usb2_do_request_flags(udev, NULL, &req,
+ NULL, 0, NULL, USB_MS_HZ)) {
+ /* ignore any errors */
+ }
+ return;
+}
+
+static void
+u3g_huawei_init(struct usb2_device *udev)
+{
+ struct usb2_device_request req;
+ DPRINTFN(0, "\n");
+
+ req.bmRequestType = UT_WRITE_DEVICE;
+ req.bRequest = UR_SET_FEATURE;
+ USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
+ USETW(req.wIndex, UHF_PORT_SUSPEND);
+ USETW(req.wLength, 0);
+
+ if (usb2_do_request_flags(udev, NULL, &req,
+ NULL, 0, NULL, USB_MS_HZ)) {
+ /* ignore any errors */
+ }
+ return;
+}
+
+int
+usb2_lookup_huawei(struct usb2_attach_arg *uaa)
+{
+ /* Calling the lookup function will also set the driver info! */
+ return (usb2_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa));
+}
+
+/*
+ * The following function 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.
+ */
usb2_error_t
-usb2_test_huawei(struct usb2_device *udev, uint8_t iface_index)
+usb2_test_huawei(struct usb2_device *udev, struct usb2_attach_arg *uaa)
{
- struct usb2_device_request req;
struct usb2_interface *iface;
struct usb2_interface_descriptor *id;
- usb2_error_t err;
+ uint32_t flags;
if (udev == NULL) {
return (USB_ERR_INVAL);
}
- iface = usb2_get_iface(udev, iface_index);
+ iface = usb2_get_iface(udev, 0);
if (iface == NULL) {
return (USB_ERR_INVAL);
}
@@ -598,15 +727,21 @@
if (id->bInterfaceClass != UICLASS_MASS) {
return (USB_ERR_INVAL);
}
- /* Bend it like Beckham */
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
- USETW(req.wIndex, 2);
- USETW(req.wLength, 0);
+ if (usb2_lookup_huawei(uaa)) {
+ /* no device match */
+ return (USB_ERR_INVAL);
+ }
+ flags = USB_GET_DRIVER_INFO(uaa);
- /* We get error at return, but it works */
- err = usb2_do_request_flags(udev, NULL, &req, NULL, 0, NULL, 1 * USB_MS_HZ);
-
+ if (flags & U3GFL_HUAWEI_INIT) {
+ u3g_huawei_init(udev);
+ } else if (flags & U3GFL_SCSI_EJECT) {
+ return (usb2_test_autoinstall(udev, 0, 1));
+ } else if (flags & U3GFL_SIERRA_INIT) {
+ u3g_sierra_init(udev);
+ } else {
+ /* no quirks */
+ return (USB_ERR_INVAL);
+ }
return (0); /* success */
}
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_msctest.h#6 (text+ko) ====
@@ -27,7 +27,30 @@
#ifndef _USB2_MSCTEST_H_
#define _USB2_MSCTEST_H_
-usb2_error_t usb2_test_autoinstall(struct usb2_device *udev, uint8_t iface_index);
-usb2_error_t usb2_test_huawei(struct usb2_device *udev, uint8_t iface_index);
+usb2_error_t usb2_test_autoinstall(struct usb2_device *udev, uint8_t iface_index, uint8_t do_eject);
+usb2_error_t usb2_test_huawei(struct usb2_device *udev, struct usb2_attach_arg *uaa);
+int usb2_lookup_huawei(struct usb2_attach_arg *uaa);
+
+/* Huawei specific defines */
+
+#define U3GINFO(flag,speed) ((flag)|((speed) * 256))
+#define U3G_GET_SPEED(uaa) (USB_GET_DRIVER_INFO(uaa) / 256)
+
+#define U3GFL_NONE 0x00
+#define U3GFL_HUAWEI_INIT 0x01 /* Requires init command (Huawei
+ * cards) */
+#define U3GFL_SCSI_EJECT 0x02 /* Requires SCSI eject command
+ * (Novatel) */
+#define U3GFL_SIERRA_INIT 0x04 /* Requires init command (Sierra
+ * cards) */
+
+#define U3GSP_GPRS 0
+#define U3GSP_EDGE 1
+#define U3GSP_CDMA 2
+#define U3GSP_UMTS 3
+#define U3GSP_HSDPA 4
+#define U3GSP_HSUPA 5
+#define U3GSP_HSPA 6
+#define U3GSP_MAX 7
#endif /* _USB2_MSCTEST_H_ */
==== //depot/projects/usb/src/sys/modules/usb2/Makefile#5 (text+ko) ====
@@ -57,6 +57,7 @@
SUBDIR += quirk
SUBDIR += scanner
SUBDIR += serial
+SUBDIR += serial_3g
SUBDIR += serial_ark
SUBDIR += serial_bsa
SUBDIR += serial_bser
More information about the p4-projects
mailing list