Date: Wed, 19 Nov 2008 19:15:24 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 153231 for review Message-ID: <200811191915.mAJJFOYI052681@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=153231 Change 153231 by hselasky@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811191915.mAJJFOYI052681>