diff options
author | thompsa <thompsa@FreeBSD.org> | 2010-01-06 22:14:05 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2010-01-06 22:14:05 +0000 |
commit | f9e6c6a249caaf137a522b43d20cd40c4d8611c3 (patch) | |
tree | 54c711c0bb9a6b4a61ebef1a9c10d5d4a4a96c58 /sys/dev/usb/serial | |
parent | c6572afc18dd829baa4b852e6c8478d4f3d10095 (diff) | |
download | FreeBSD-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.c | 231 |
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: |