aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2005-04-22 18:07:02 -0400
committerGreg KH <gregkh@suse.de>2005-04-22 18:07:02 -0400
commitf3fae6ed6aafe71826e03876ad3d4e1d3f238ec8 (patch)
tree9c85c51031ae67ef9e8448a57ba4037d95899ccc /drivers/usb
parent7ea13c9c0e40d24c5f45a3a6bee8a2a39bfb1df4 (diff)
[PATCH] USB: better usbnet zaurus/mdlm/... fix
This is a somewhat more comprehensive fix for the problem of devices like the newer Zaurii ... or in this case some Motorola cell phones. To recap, the problem's root cause is that these devices aren't using standard USB class specifications for their network links, and so far we've had to add lots of device-specific driver entries. The vendor fix abuses the CDC MDLM descriptors (they _could_ have conformed to the spec, but didn't) and defines a "Belcarra firmware" pseudo-class. This patch recognizes that pseudo-class by the GUIDs in those descriptors, and handles the devices that just use the Zaurus framing. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/net/usbnet.c166
1 files changed, 135 insertions, 31 deletions
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 0eefc14449aa..1748159e462e 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * USB Networking Links 2 * USB Networking Links
3 * Copyright (C) 2000-2003 by David Brownell <dbrownell@users.sourceforge.net> 3 * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
4 * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz> 4 * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
5 * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> 5 * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
6 * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net> 6 * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
@@ -2657,7 +2657,7 @@ static const struct driver_info blob_info = {
2657 * All known Zaurii lie about their standards conformance. Most lie by 2657 * All known Zaurii lie about their standards conformance. Most lie by
2658 * saying they support CDC Ethernet. Some lie and say they support CDC 2658 * saying they support CDC Ethernet. Some lie and say they support CDC
2659 * MDLM (as if for access to cell phone modems). Someone, please beat 2659 * MDLM (as if for access to cell phone modems). Someone, please beat
2660 * on Sharp for a while with a cluestick. 2660 * on Sharp (and other such vendors) for a while with a cluestick.
2661 * 2661 *
2662 *-------------------------------------------------------------------------*/ 2662 *-------------------------------------------------------------------------*/
2663 2663
@@ -2710,13 +2710,6 @@ static const struct driver_info zaurus_pxa_info = {
2710}; 2710};
2711#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info) 2711#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
2712 2712
2713static const struct driver_info zaurus_pxa_mdlm_info = {
2714 .description = "Sharp Zaurus, PXA-255 based",
2715 .flags = FLAG_FRAMING_Z,
2716 .check_connect = always_connected,
2717 .tx_fixup = zaurus_tx_fixup,
2718};
2719
2720static const struct driver_info olympus_mxl_info = { 2713static const struct driver_info olympus_mxl_info = {
2721 .description = "Olympus R1000", 2714 .description = "Olympus R1000",
2722 .flags = FLAG_FRAMING_Z, 2715 .flags = FLAG_FRAMING_Z,
@@ -2727,6 +2720,133 @@ static const struct driver_info olympus_mxl_info = {
2727}; 2720};
2728#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info) 2721#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
2729 2722
2723
2724/* Some more recent products using Lineo/Belcarra code will wrongly claim
2725 * CDC MDLM conformance. They aren't conformant: data endpoints live
2726 * in the control interface, there's no data interface, and it's not used
2727 * to talk to a cell phone radio. But at least we can detect these two
2728 * pseudo-classes, rather than growing this product list with entries for
2729 * each new nonconformant product (sigh).
2730 */
2731static const u8 safe_guid[16] = {
2732 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
2733 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
2734};
2735static const u8 blan_guid[16] = {
2736 0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
2737 0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
2738};
2739
2740static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
2741{
2742 u8 *buf = intf->cur_altsetting->extra;
2743 int len = intf->cur_altsetting->extralen;
2744 struct usb_cdc_mdlm_desc *desc = NULL;
2745 struct usb_cdc_mdlm_detail_desc *detail = NULL;
2746
2747 while (len > 3) {
2748 if (buf [1] != USB_DT_CS_INTERFACE)
2749 goto next_desc;
2750
2751 /* use bDescriptorSubType, and just verify that we get a
2752 * "BLAN" (or "SAFE") descriptor.
2753 */
2754 switch (buf [2]) {
2755 case USB_CDC_MDLM_TYPE:
2756 if (desc) {
2757 dev_dbg (&intf->dev, "extra MDLM\n");
2758 goto bad_desc;
2759 }
2760 desc = (void *) buf;
2761 if (desc->bLength != sizeof *desc) {
2762 dev_dbg (&intf->dev, "MDLM len %u\n",
2763 desc->bLength);
2764 goto bad_desc;
2765 }
2766 /* expect bcdVersion 1.0, ignore */
2767 if (memcmp(&desc->bGUID, blan_guid, 16)
2768 || memcmp(&desc->bGUID, blan_guid, 16) ) {
2769 /* hey, this one might _really_ be MDLM! */
2770 dev_dbg (&intf->dev, "MDLM guid\n");
2771 goto bad_desc;
2772 }
2773 break;
2774 case USB_CDC_MDLM_DETAIL_TYPE:
2775 if (detail) {
2776 dev_dbg (&intf->dev, "extra MDLM detail\n");
2777 goto bad_desc;
2778 }
2779 detail = (void *) buf;
2780 switch (detail->bGuidDescriptorType) {
2781 case 0: /* "SAFE" */
2782 if (detail->bLength != (sizeof *detail + 2))
2783 goto bad_detail;
2784 break;
2785 case 1: /* "BLAN" */
2786 if (detail->bLength != (sizeof *detail + 3))
2787 goto bad_detail;
2788 break;
2789 default:
2790 goto bad_detail;
2791 }
2792
2793 /* assuming we either noticed BLAN already, or will
2794 * find it soon, there are some data bytes here:
2795 * - bmNetworkCapabilities (unused)
2796 * - bmDataCapabilities (bits, see below)
2797 * - bPad (ignored, for PADAFTER -- BLAN-only)
2798 * bits are:
2799 * - 0x01 -- Zaurus framing (add CRC)
2800 * - 0x02 -- PADBEFORE
2801 * - 0x04 -- PADAFTER
2802 * - 0x08 -- "fermat" packet mangling (for hw bugs)
2803 */
2804 if (detail->bDetailData[1] != 0x01) {
2805 /* bmDataCapabilites == 0 would be fine too,
2806 * but framing is minidriver-coupled for now.
2807 */
2808bad_detail:
2809 dev_dbg (&intf->dev,
2810 "bad MDLM detail, %d %d %d\n",
2811 detail->bLength,
2812 detail->bDetailData[0],
2813 detail->bDetailData[2]);
2814 goto bad_desc;
2815 }
2816 break;
2817 }
2818next_desc:
2819 len -= buf [0]; /* bLength */
2820 buf += buf [0];
2821 }
2822
2823 if (!desc || !detail) {
2824 dev_dbg (&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
2825 desc ? "" : "func ",
2826 detail ? "" : "detail ");
2827 goto bad_desc;
2828 }
2829
2830 /* There's probably a CDC Ethernet descriptor there, but we can't
2831 * rely on the Ethernet address it provides since not all vendors
2832 * bother to make it unique. Likewise there's no point in tracking
2833 * of the CDC event notifications.
2834 */
2835 return get_endpoints (dev, intf);
2836
2837bad_desc:
2838 dev_info (&dev->udev->dev, "unsupported MDLM descriptors\n");
2839 return -ENODEV;
2840}
2841
2842static const struct driver_info bogus_mdlm_info = {
2843 .description = "pseudo-MDLM (BLAN) device",
2844 .flags = FLAG_FRAMING_Z,
2845 .check_connect = always_connected,
2846 .tx_fixup = zaurus_tx_fixup,
2847 .bind = blan_mdlm_bind,
2848};
2849
2730#else 2850#else
2731 2851
2732/* blacklist all those devices */ 2852/* blacklist all those devices */
@@ -4029,30 +4149,14 @@ static const struct usb_device_id products [] = {
4029}, 4149},
4030 4150
4031#ifdef CONFIG_USB_ZAURUS 4151#ifdef CONFIG_USB_ZAURUS
4032 /* at least some (reports vary) PXA units have very different 4152 /* At least some (reports vary) PXA units have very different lies
4033 * lies about their standards support: they claim to be cell 4153 * about their standards support: they claim to be cell phones with
4034 * phones giving direct radio access (which they aren't). 4154 * direct access to their radios. (They don't conform to CDC MDLM.)
4035 */ 4155 */
4036{ 4156{
4037 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 4157 USB_INTERFACE_INFO (USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
4038 | USB_DEVICE_ID_MATCH_DEVICE, 4158 USB_CDC_PROTO_NONE),
4039 .idVendor = 0x04DD, 4159 .driver_info = (unsigned long) &bogus_mdlm_info,
4040 /* Sharp ROM v1.32 */
4041 .idProduct = 0x8006, /* SL-5600 */
4042 .bInterfaceClass = USB_CLASS_COMM,
4043 .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM,
4044 .bInterfaceProtocol = USB_CDC_PROTO_NONE,
4045 .driver_info = (unsigned long) &zaurus_pxa_mdlm_info,
4046}, {
4047 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4048 | USB_DEVICE_ID_MATCH_DEVICE,
4049 .idVendor = 0x04DD,
4050 /* reported with some C860 units */
4051 .idProduct = 0x9031, /* C-860 */
4052 .bInterfaceClass = USB_CLASS_COMM,
4053 .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM,
4054 .bInterfaceProtocol = USB_CDC_PROTO_NONE,
4055 .driver_info = (unsigned long) &zaurus_pxa_mdlm_info,
4056}, 4160},
4057#endif 4161#endif
4058 4162