diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/ether.c | 141 |
1 files changed, 54 insertions, 87 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index f70055473a00..ff244f42723f 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -19,41 +19,19 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | /* #define VERBOSE_DEBUG */ | ||
22 | 23 | ||
23 | // #define DEBUG 1 | ||
24 | // #define VERBOSE | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
28 | #include <linux/delay.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/errno.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/timer.h> | ||
34 | #include <linux/list.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | #include <linux/utsname.h> | 25 | #include <linux/utsname.h> |
37 | #include <linux/device.h> | 26 | #include <linux/device.h> |
38 | #include <linux/moduleparam.h> | ||
39 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
40 | 28 | #include <linux/etherdevice.h> | |
41 | #include <asm/byteorder.h> | 29 | #include <linux/ethtool.h> |
42 | #include <asm/io.h> | ||
43 | #include <asm/irq.h> | ||
44 | #include <asm/system.h> | ||
45 | #include <asm/uaccess.h> | ||
46 | #include <asm/unaligned.h> | ||
47 | 30 | ||
48 | #include <linux/usb/ch9.h> | 31 | #include <linux/usb/ch9.h> |
49 | #include <linux/usb/cdc.h> | 32 | #include <linux/usb/cdc.h> |
50 | #include <linux/usb_gadget.h> | 33 | #include <linux/usb_gadget.h> |
51 | 34 | ||
52 | #include <linux/random.h> | ||
53 | #include <linux/netdevice.h> | ||
54 | #include <linux/etherdevice.h> | ||
55 | #include <linux/ethtool.h> | ||
56 | |||
57 | #include "gadget_chips.h" | 35 | #include "gadget_chips.h" |
58 | 36 | ||
59 | /*-------------------------------------------------------------------------*/ | 37 | /*-------------------------------------------------------------------------*/ |
@@ -356,15 +334,15 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR); | |||
356 | #define qlen(gadget) \ | 334 | #define qlen(gadget) \ |
357 | (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1)) | 335 | (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1)) |
358 | 336 | ||
359 | /* also defer IRQs on highspeed TX */ | ||
360 | #define TX_DELAY qmult | ||
361 | |||
362 | static inline int BITRATE(struct usb_gadget *g) | 337 | static inline int BITRATE(struct usb_gadget *g) |
363 | { | 338 | { |
364 | return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS; | 339 | return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS; |
365 | } | 340 | } |
366 | 341 | ||
367 | #else /* full speed (low speed doesn't do bulk) */ | 342 | #else /* full speed (low speed doesn't do bulk) */ |
343 | |||
344 | #define qmult 1 | ||
345 | |||
368 | #define DEVSPEED USB_SPEED_FULL | 346 | #define DEVSPEED USB_SPEED_FULL |
369 | 347 | ||
370 | #define qlen(gadget) DEFAULT_QLEN | 348 | #define qlen(gadget) DEFAULT_QLEN |
@@ -390,7 +368,7 @@ static inline int BITRATE(struct usb_gadget *g) | |||
390 | do { } while (0) | 368 | do { } while (0) |
391 | #endif /* DEBUG */ | 369 | #endif /* DEBUG */ |
392 | 370 | ||
393 | #ifdef VERBOSE | 371 | #ifdef VERBOSE_DEBUG |
394 | #define VDEBUG DEBUG | 372 | #define VDEBUG DEBUG |
395 | #else | 373 | #else |
396 | #define VDEBUG(dev,fmt,args...) \ | 374 | #define VDEBUG(dev,fmt,args...) \ |
@@ -830,8 +808,6 @@ static const struct usb_descriptor_header *fs_rndis_function [] = { | |||
830 | }; | 808 | }; |
831 | #endif | 809 | #endif |
832 | 810 | ||
833 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
834 | |||
835 | /* | 811 | /* |
836 | * usb 2.0 devices need to expose both high speed and full speed | 812 | * usb 2.0 devices need to expose both high speed and full speed |
837 | * descriptors, unless they only run at full speed. | 813 | * descriptors, unless they only run at full speed. |
@@ -934,18 +910,15 @@ static const struct usb_descriptor_header *hs_rndis_function [] = { | |||
934 | 910 | ||
935 | 911 | ||
936 | /* maxpacket and other transfer characteristics vary by speed. */ | 912 | /* maxpacket and other transfer characteristics vary by speed. */ |
937 | #define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs)) | 913 | static inline struct usb_endpoint_descriptor * |
938 | 914 | ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, | |
939 | #else | 915 | struct usb_endpoint_descriptor *fs) |
940 | |||
941 | /* if there's no high speed support, maxpacket doesn't change. */ | ||
942 | #define ep_desc(g,hs,fs) (((void)(g)), (fs)) | ||
943 | |||
944 | static inline void __init hs_subset_descriptors(void) | ||
945 | { | 916 | { |
917 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
918 | return hs; | ||
919 | return fs; | ||
946 | } | 920 | } |
947 | 921 | ||
948 | #endif /* !CONFIG_USB_GADGET_DUALSPEED */ | ||
949 | 922 | ||
950 | /*-------------------------------------------------------------------------*/ | 923 | /*-------------------------------------------------------------------------*/ |
951 | 924 | ||
@@ -989,22 +962,19 @@ static struct usb_gadget_strings stringtab = { | |||
989 | * complications: class descriptors, and an altsetting. | 962 | * complications: class descriptors, and an altsetting. |
990 | */ | 963 | */ |
991 | static int | 964 | static int |
992 | config_buf (enum usb_device_speed speed, | 965 | config_buf(struct usb_gadget *g, u8 *buf, u8 type, unsigned index, int is_otg) |
993 | u8 *buf, u8 type, | ||
994 | unsigned index, int is_otg) | ||
995 | { | 966 | { |
996 | int len; | 967 | int len; |
997 | const struct usb_config_descriptor *config; | 968 | const struct usb_config_descriptor *config; |
998 | const struct usb_descriptor_header **function; | 969 | const struct usb_descriptor_header **function; |
999 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 970 | int hs = 0; |
1000 | int hs = (speed == USB_SPEED_HIGH); | ||
1001 | 971 | ||
1002 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 972 | if (gadget_is_dualspeed(g)) { |
1003 | hs = !hs; | 973 | hs = (g->speed == USB_SPEED_HIGH); |
974 | if (type == USB_DT_OTHER_SPEED_CONFIG) | ||
975 | hs = !hs; | ||
976 | } | ||
1004 | #define which_fn(t) (hs ? hs_ ## t ## _function : fs_ ## t ## _function) | 977 | #define which_fn(t) (hs ? hs_ ## t ## _function : fs_ ## t ## _function) |
1005 | #else | ||
1006 | #define which_fn(t) (fs_ ## t ## _function) | ||
1007 | #endif | ||
1008 | 978 | ||
1009 | if (index >= device_desc.bNumConfigurations) | 979 | if (index >= device_desc.bNumConfigurations) |
1010 | return -EINVAL; | 980 | return -EINVAL; |
@@ -1217,7 +1187,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags) | |||
1217 | if (number) | 1187 | if (number) |
1218 | eth_reset_config (dev); | 1188 | eth_reset_config (dev); |
1219 | usb_gadget_vbus_draw(dev->gadget, | 1189 | usb_gadget_vbus_draw(dev->gadget, |
1220 | dev->gadget->is_otg ? 8 : 100); | 1190 | gadget_is_otg(dev->gadget) ? 8 : 100); |
1221 | } else { | 1191 | } else { |
1222 | char *speed; | 1192 | char *speed; |
1223 | unsigned power; | 1193 | unsigned power; |
@@ -1399,24 +1369,22 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1399 | value = min (wLength, (u16) sizeof device_desc); | 1369 | value = min (wLength, (u16) sizeof device_desc); |
1400 | memcpy (req->buf, &device_desc, value); | 1370 | memcpy (req->buf, &device_desc, value); |
1401 | break; | 1371 | break; |
1402 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1403 | case USB_DT_DEVICE_QUALIFIER: | 1372 | case USB_DT_DEVICE_QUALIFIER: |
1404 | if (!gadget->is_dualspeed) | 1373 | if (!gadget_is_dualspeed(gadget)) |
1405 | break; | 1374 | break; |
1406 | value = min (wLength, (u16) sizeof dev_qualifier); | 1375 | value = min (wLength, (u16) sizeof dev_qualifier); |
1407 | memcpy (req->buf, &dev_qualifier, value); | 1376 | memcpy (req->buf, &dev_qualifier, value); |
1408 | break; | 1377 | break; |
1409 | 1378 | ||
1410 | case USB_DT_OTHER_SPEED_CONFIG: | 1379 | case USB_DT_OTHER_SPEED_CONFIG: |
1411 | if (!gadget->is_dualspeed) | 1380 | if (!gadget_is_dualspeed(gadget)) |
1412 | break; | 1381 | break; |
1413 | // FALLTHROUGH | 1382 | // FALLTHROUGH |
1414 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1415 | case USB_DT_CONFIG: | 1383 | case USB_DT_CONFIG: |
1416 | value = config_buf (gadget->speed, req->buf, | 1384 | value = config_buf(gadget, req->buf, |
1417 | wValue >> 8, | 1385 | wValue >> 8, |
1418 | wValue & 0xff, | 1386 | wValue & 0xff, |
1419 | gadget->is_otg); | 1387 | gadget_is_otg(gadget)); |
1420 | if (value >= 0) | 1388 | if (value >= 0) |
1421 | value = min (wLength, (u16) value); | 1389 | value = min (wLength, (u16) value); |
1422 | break; | 1390 | break; |
@@ -1585,12 +1553,12 @@ done_set_intf: | |||
1585 | && rndis_control_intf.bInterfaceNumber | 1553 | && rndis_control_intf.bInterfaceNumber |
1586 | == wIndex) { | 1554 | == wIndex) { |
1587 | u8 *buf; | 1555 | u8 *buf; |
1556 | u32 n; | ||
1588 | 1557 | ||
1589 | /* return the result */ | 1558 | /* return the result */ |
1590 | buf = rndis_get_next_response (dev->rndis_config, | 1559 | buf = rndis_get_next_response(dev->rndis_config, &n); |
1591 | &value); | ||
1592 | if (buf) { | 1560 | if (buf) { |
1593 | memcpy (req->buf, buf, value); | 1561 | memcpy(req->buf, buf, n); |
1594 | req->complete = rndis_response_complete; | 1562 | req->complete = rndis_response_complete; |
1595 | rndis_free_response(dev->rndis_config, buf); | 1563 | rndis_free_response(dev->rndis_config, buf); |
1596 | } | 1564 | } |
@@ -2026,12 +1994,11 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) | |||
2026 | 1994 | ||
2027 | req->length = length; | 1995 | req->length = length; |
2028 | 1996 | ||
2029 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
2030 | /* throttle highspeed IRQ rate back slightly */ | 1997 | /* throttle highspeed IRQ rate back slightly */ |
2031 | req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) | 1998 | if (gadget_is_dualspeed(dev->gadget)) |
2032 | ? ((atomic_read (&dev->tx_qlen) % TX_DELAY) != 0) | 1999 | req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) |
2033 | : 0; | 2000 | ? ((atomic_read(&dev->tx_qlen) % qmult) != 0) |
2034 | #endif | 2001 | : 0; |
2035 | 2002 | ||
2036 | retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); | 2003 | retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); |
2037 | switch (retval) { | 2004 | switch (retval) { |
@@ -2188,8 +2155,7 @@ static int eth_stop (struct net_device *net) | |||
2188 | } | 2155 | } |
2189 | 2156 | ||
2190 | if (rndis_active(dev)) { | 2157 | if (rndis_active(dev)) { |
2191 | rndis_set_param_medium (dev->rndis_config, | 2158 | rndis_set_param_medium(dev->rndis_config, NDIS_MEDIUM_802_3, 0); |
2192 | NDIS_MEDIUM_802_3, 0); | ||
2193 | (void) rndis_signal_disconnect (dev->rndis_config); | 2159 | (void) rndis_signal_disconnect (dev->rndis_config); |
2194 | } | 2160 | } |
2195 | 2161 | ||
@@ -2443,26 +2409,28 @@ autoconf_fail: | |||
2443 | if (rndis) | 2409 | if (rndis) |
2444 | device_desc.bNumConfigurations = 2; | 2410 | device_desc.bNumConfigurations = 2; |
2445 | 2411 | ||
2446 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 2412 | if (gadget_is_dualspeed(gadget)) { |
2447 | if (rndis) | 2413 | if (rndis) |
2448 | dev_qualifier.bNumConfigurations = 2; | 2414 | dev_qualifier.bNumConfigurations = 2; |
2449 | else if (!cdc) | 2415 | else if (!cdc) |
2450 | dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 2416 | dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC; |
2451 | 2417 | ||
2452 | /* assumes ep0 uses the same value for both speeds ... */ | 2418 | /* assumes ep0 uses the same value for both speeds ... */ |
2453 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; | 2419 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; |
2454 | 2420 | ||
2455 | /* and that all endpoints are dual-speed */ | 2421 | /* and that all endpoints are dual-speed */ |
2456 | hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; | 2422 | hs_source_desc.bEndpointAddress = |
2457 | hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; | 2423 | fs_source_desc.bEndpointAddress; |
2424 | hs_sink_desc.bEndpointAddress = | ||
2425 | fs_sink_desc.bEndpointAddress; | ||
2458 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | 2426 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) |
2459 | if (status_ep) | 2427 | if (status_ep) |
2460 | hs_status_desc.bEndpointAddress = | 2428 | hs_status_desc.bEndpointAddress = |
2461 | fs_status_desc.bEndpointAddress; | 2429 | fs_status_desc.bEndpointAddress; |
2462 | #endif | 2430 | #endif |
2463 | #endif /* DUALSPEED */ | 2431 | } |
2464 | 2432 | ||
2465 | if (gadget->is_otg) { | 2433 | if (gadget_is_otg(gadget)) { |
2466 | otg_descriptor.bmAttributes |= USB_OTG_HNP, | 2434 | otg_descriptor.bmAttributes |= USB_OTG_HNP, |
2467 | eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 2435 | eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
2468 | eth_config.bMaxPower = 4; | 2436 | eth_config.bMaxPower = 4; |
@@ -2598,12 +2566,11 @@ fail0: | |||
2598 | if (rndis_set_param_dev (dev->rndis_config, dev->net, | 2566 | if (rndis_set_param_dev (dev->rndis_config, dev->net, |
2599 | &dev->stats, &dev->cdc_filter)) | 2567 | &dev->stats, &dev->cdc_filter)) |
2600 | goto fail0; | 2568 | goto fail0; |
2601 | if (rndis_set_param_vendor (dev->rndis_config, vendorID, | 2569 | if (rndis_set_param_vendor(dev->rndis_config, vendorID, |
2602 | manufacturer)) | 2570 | manufacturer)) |
2603 | goto fail0; | 2571 | goto fail0; |
2604 | if (rndis_set_param_medium (dev->rndis_config, | 2572 | if (rndis_set_param_medium(dev->rndis_config, |
2605 | NDIS_MEDIUM_802_3, | 2573 | NDIS_MEDIUM_802_3, 0)) |
2606 | 0)) | ||
2607 | goto fail0; | 2574 | goto fail0; |
2608 | INFO (dev, "RNDIS ready\n"); | 2575 | INFO (dev, "RNDIS ready\n"); |
2609 | } | 2576 | } |