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