summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/serial
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2010-01-06 22:14:05 +0000
committerthompsa <thompsa@FreeBSD.org>2010-01-06 22:14:05 +0000
commitf9e6c6a249caaf137a522b43d20cd40c4d8611c3 (patch)
tree54c711c0bb9a6b4a61ebef1a9c10d5d4a4a96c58 /sys/dev/usb/serial
parentc6572afc18dd829baa4b852e6c8478d4f3d10095 (diff)
downloadFreeBSD-src-f9e6c6a249caaf137a522b43d20cd40c4d8611c3.zip
FreeBSD-src-f9e6c6a249caaf137a522b43d20cd40c4d8611c3.tar.gz
Improve u3g device ejecting by providing additional methods for the eject
command in the usb_msctest routines, as well as a general tidyup. This now properly ejects the ZTE MF636, Option Gi0322 and Novatel MC950D devices I have on my desk.
Diffstat (limited to 'sys/dev/usb/serial')
-rw-r--r--sys/dev/usb/serial/u3g.c231
1 files changed, 126 insertions, 105 deletions
diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 5b61948..5d2c81c 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -86,10 +86,14 @@ SYSCTL_INT(_hw_usb_u3g, OID_AUTO, debug, CTLFLAG_RW,
#define U3GSP_HSPA 6
#define U3GSP_MAX 7
-#define U3GFL_HUAWEI_INIT 0x0001 /* Init command required */
-#define U3GFL_SCSI_EJECT 0x0002 /* SCSI eject command required */
-#define U3GFL_SIERRA_INIT 0x0004 /* Init command required */
-#define U3GFL_SAEL_M460_INIT 0x0008 /* Init device */
+#define U3GINIT_HUAWEI 1 /* Requires Huawei init command */
+#define U3GINIT_SIERRA 2 /* Requires Sierra init command */
+#define U3GINIT_SCSIEJECT 3 /* Requires SCSI eject command */
+#define U3GINIT_REZERO 4 /* Requires SCSI rezero command */
+#define U3GINIT_ZTESTOR 5 /* Requires ZTE SCSI command */
+#define U3GINIT_CMOTECH 6 /* Requires CMOTECH SCSI command */
+#define U3GINIT_WAIT 7 /* Device reappears after a delay */
+#define U3GINIT_SAEL_M460 8 /* Requires vendor init */
enum {
U3G_BULK_WR,
@@ -192,6 +196,7 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(ANYDATA, ADU_E100X, 0),
U3G_DEV(AXESSTEL, DATAMODEM, 0),
U3G_DEV(CMOTECH, CDMA_MODEM1, 0),
+ U3G_DEV(CMOTECH, CGU628, U3GINIT_CMOTECH),
U3G_DEV(DELL, U5500, 0),
U3G_DEV(DELL, U5505, 0),
U3G_DEV(DELL, U5510, 0),
@@ -211,73 +216,73 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(DLINK3, DWM652, 0),
U3G_DEV(HP, EV2200, 0),
U3G_DEV(HP, HS2300, 0),
- U3G_DEV(HUAWEI, E1401, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1402, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1403, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1404, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1405, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1406, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1407, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1408, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1409, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E140A, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E140B, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E140D, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E140E, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E140F, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1410, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1411, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1412, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1413, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1414, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1415, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1416, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1417, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1418, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1419, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E141A, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E141B, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E141C, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E141D, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E141E, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E141F, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1420, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1421, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1422, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1423, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1424, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1425, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1426, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1427, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1428, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1429, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E142A, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E142B, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E142C, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E142D, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E142E, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E142F, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1430, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1431, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1432, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1433, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1434, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1435, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1436, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1437, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1438, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E1439, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E143A, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E143B, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E143C, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E143D, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E143E, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E143F, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E14AC, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E180V, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E220, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, E220BIS, U3GFL_HUAWEI_INIT),
- U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT),
+ U3G_DEV(HUAWEI, E1401, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1402, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1403, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1404, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1405, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1406, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1407, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1408, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1409, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E140A, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E140B, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E140D, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E140E, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E140F, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1410, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1411, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1412, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1413, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1414, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1415, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1416, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1417, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1418, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1419, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E141A, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E141B, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E141C, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E141D, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E141E, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E141F, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1420, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1421, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1422, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1423, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1424, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1425, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1426, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1427, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1428, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1429, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E142A, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E142B, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E142C, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E142D, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E142E, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E142F, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1430, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1431, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1432, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1433, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1434, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1435, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1436, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1437, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1438, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E1439, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E143A, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E143B, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E143C, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E143D, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E143E, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E143F, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E14AC, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E180V, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI),
+ U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI),
U3G_DEV(KYOCERA2, CDMA_MSM_K, 0),
U3G_DEV(KYOCERA2, KPC680, 0),
U3G_DEV(MERLIN, V620, 0),
@@ -294,7 +299,7 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(NOVATEL, U727_2, 0),
U3G_DEV(NOVATEL, U740, 0),
U3G_DEV(NOVATEL, U740_2, 0),
- U3G_DEV(NOVATEL, U760, U3GFL_SCSI_EJECT),
+ U3G_DEV(NOVATEL, U760, U3GINIT_SCSIEJECT),
U3G_DEV(NOVATEL, U870, 0),
U3G_DEV(NOVATEL, V620, 0),
U3G_DEV(NOVATEL, V640, 0),
@@ -338,7 +343,7 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(QUALCOMMINC, AC2726, 0),
U3G_DEV(QUALCOMMINC, AC8700, 0),
U3G_DEV(QUALCOMMINC, AC8710, 0),
- U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT),
+ U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GINIT_SCSIEJECT),
U3G_DEV(QUALCOMMINC, E0002, 0),
U3G_DEV(QUALCOMMINC, E0003, 0),
U3G_DEV(QUALCOMMINC, E0004, 0),
@@ -405,7 +410,6 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(QUALCOMMINC, E2003, 0),
U3G_DEV(QUALCOMMINC, MF626, 0),
U3G_DEV(QUALCOMMINC, MF628, 0),
- U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT),
U3G_DEV(QUANTA, GKE, 0),
U3G_DEV(QUANTA, GLE, 0),
U3G_DEV(QUANTA, GLX, 0),
@@ -466,7 +470,7 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(SIERRA, MINI5725, 0),
U3G_DEV(SIERRA, T11, 0),
U3G_DEV(SIERRA, T598, 0),
- U3G_DEV(SILABS, SAEL, U3GFL_SAEL_M460_INIT),
+ U3G_DEV(SILABS, SAEL, U3GINIT_SAEL_M460),
U3G_DEV(STELERA, C105, 0),
U3G_DEV(STELERA, E1003, 0),
U3G_DEV(STELERA, E1004, 0),
@@ -492,12 +496,14 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(TOSHIBA, HSDPA, 0),
U3G_DEV(YISO, C893, 0),
/* Autoinstallers */
- U3G_DEV(NOVATEL, ZEROCD, U3GFL_SCSI_EJECT),
- U3G_DEV(SIERRA, TRUINSTALL, U3GFL_SIERRA_INIT),
+ U3G_DEV(NOVATEL, ZEROCD, U3GINIT_SCSIEJECT),
+ U3G_DEV(OPTION, GTICON322, U3GINIT_REZERO),
+ U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GINIT_ZTESTOR),
+ U3G_DEV(SIERRA, TRUINSTALL, U3GINIT_SIERRA),
#undef U3G_DEV
};
-static void
+static int
u3g_sierra_init(struct usb_device *udev)
{
struct usb_device_request req;
@@ -512,10 +518,10 @@ u3g_sierra_init(struct usb_device *udev)
NULL, 0, NULL, USB_MS_HZ)) {
/* ignore any errors */
}
- return;
+ return (0);
}
-static void
+static int
u3g_huawei_init(struct usb_device *udev)
{
struct usb_device_request req;
@@ -530,7 +536,7 @@ u3g_huawei_init(struct usb_device *udev)
NULL, 0, NULL, USB_MS_HZ)) {
/* ignore any errors */
}
- return;
+ return (0);
}
static void
@@ -625,7 +631,7 @@ u3g_test_autoinst(void *arg, struct usb_device *udev,
{
struct usb_interface *iface;
struct usb_interface_descriptor *id;
- uint32_t flags;
+ int error;
if (uaa->dev_state != UAA_DEV_READY)
return;
@@ -636,25 +642,41 @@ u3g_test_autoinst(void *arg, struct usb_device *udev,
id = iface->idesc;
if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
return;
- if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa)) {
- /* no device match */
- return;
+ if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa))
+ return; /* no device match */
+
+ switch (USB_GET_DRIVER_INFO(uaa)) {
+ case U3GINIT_HUAWEI:
+ error = u3g_huawei_init(udev);
+ break;
+ case U3GINIT_SCSIEJECT:
+ error = usb_msc_eject(udev, 0, MSC_EJECT_STOPUNIT);
+ break;
+ case U3GINIT_REZERO:
+ error = usb_msc_eject(udev, 0, MSC_EJECT_REZERO);
+ break;
+ case U3GINIT_ZTESTOR:
+ error = usb_msc_eject(udev, 0, MSC_EJECT_ZTESTOR);
+ break;
+ case U3GINIT_CMOTECH:
+ error = usb_msc_eject(udev, 0, MSC_EJECT_CMOTECH);
+ break;
+ case U3GINIT_SIERRA:
+ error = u3g_sierra_init(udev);
+ break;
+ case U3GINIT_WAIT:
+ /* Just pretend we ejected, the card will timeout */
+ error = 0;
+ break;
+ default:
+ /* no 3G eject quirks */
+ error = EOPNOTSUPP;
+ break;
}
- flags = USB_GET_DRIVER_INFO(uaa);
-
- if (flags & U3GFL_HUAWEI_INIT) {
- u3g_huawei_init(udev);
- } else if (flags & U3GFL_SCSI_EJECT) {
- if (usb_test_autoinstall(udev, 0, 1) != 0)
- return;
- } else if (flags & U3GFL_SIERRA_INIT) {
- u3g_sierra_init(udev);
- } else {
- /* no quirks */
- return;
+ if (error == 0) {
+ /* success, mark the udev as disappearing */
+ uaa->dev_state = UAA_DEV_EJECTING;
}
- uaa->dev_state = UAA_DEV_EJECTING;
- return; /* success */
}
static int
@@ -701,15 +723,14 @@ u3g_attach(device_t dev)
struct usb_interface *iface;
struct usb_interface_descriptor *id;
uint32_t iface_valid;
- int error, flags, nports;
+ int error, type, nports;
int ep, n;
uint8_t i;
DPRINTF("sc=%p\n", sc);
- flags = USB_GET_DRIVER_INFO(uaa);
-
- if (flags & U3GFL_SAEL_M460_INIT)
+ type = USB_GET_DRIVER_INFO(uaa);
+ if (type == U3GINIT_SAEL_M460)
u3g_sael_m460_init(uaa->device);
/* copy in USB config */
@@ -781,8 +802,8 @@ u3g_attach(device_t dev)
DPRINTF("ucom_attach failed\n");
goto detach;
}
- if (sc->sc_numports > 1)
- device_printf(dev, "Found %u ports.\n", sc->sc_numports);
+ device_printf(dev, "Found %u port%s.\n", sc->sc_numports,
+ sc->sc_numports > 1 ? "s":"");
return (0);
detach:
OpenPOWER on IntegriCloud