diff options
Diffstat (limited to 'drivers/usb/gadget')
| -rw-r--r-- | drivers/usb/gadget/Kconfig | 31 | ||||
| -rw-r--r-- | drivers/usb/gadget/amd5536udc.c | 56 | ||||
| -rw-r--r-- | drivers/usb/gadget/at91_udc.c | 1 | ||||
| -rw-r--r-- | drivers/usb/gadget/audio.c | 24 | ||||
| -rw-r--r-- | drivers/usb/gadget/composite.c | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 5 | ||||
| -rw-r--r-- | drivers/usb/gadget/ether.c | 31 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_audio.c | 97 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_eem.c | 562 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_rndis.c | 15 | ||||
| -rw-r--r-- | drivers/usb/gadget/fsl_qe_udc.c | 4 | ||||
| -rw-r--r-- | drivers/usb/gadget/gmidi.c | 8 | ||||
| -rw-r--r-- | drivers/usb/gadget/pxa25x_udc.c | 49 | ||||
| -rw-r--r-- | drivers/usb/gadget/pxa25x_udc.h | 1 | ||||
| -rw-r--r-- | drivers/usb/gadget/rndis.c | 13 | ||||
| -rw-r--r-- | drivers/usb/gadget/rndis.h | 3 | ||||
| -rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 6 | ||||
| -rw-r--r-- | drivers/usb/gadget/s3c2410_udc.c | 3 | ||||
| -rw-r--r-- | drivers/usb/gadget/u_audio.c | 10 | ||||
| -rw-r--r-- | drivers/usb/gadget/u_ether.c | 85 | ||||
| -rw-r--r-- | drivers/usb/gadget/u_ether.h | 12 | ||||
| -rw-r--r-- | drivers/usb/gadget/u_serial.c | 1 |
22 files changed, 860 insertions, 159 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 9f986b417c5b..33351312327f 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -124,7 +124,7 @@ choice | |||
| 124 | 124 | ||
| 125 | config USB_GADGET_AT91 | 125 | config USB_GADGET_AT91 |
| 126 | boolean "Atmel AT91 USB Device Port" | 126 | boolean "Atmel AT91 USB Device Port" |
| 127 | depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 | 127 | depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 && !ARCH_AT91SAM9G45 |
| 128 | select USB_GADGET_SELECTED | 128 | select USB_GADGET_SELECTED |
| 129 | help | 129 | help |
| 130 | Many Atmel AT91 processors (such as the AT91RM2000) have a | 130 | Many Atmel AT91 processors (such as the AT91RM2000) have a |
| @@ -143,7 +143,7 @@ config USB_AT91 | |||
| 143 | config USB_GADGET_ATMEL_USBA | 143 | config USB_GADGET_ATMEL_USBA |
| 144 | boolean "Atmel USBA" | 144 | boolean "Atmel USBA" |
| 145 | select USB_GADGET_DUALSPEED | 145 | select USB_GADGET_DUALSPEED |
| 146 | depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL | 146 | depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 |
| 147 | help | 147 | help |
| 148 | USBA is the integrated high-speed USB Device controller on | 148 | USBA is the integrated high-speed USB Device controller on |
| 149 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. | 149 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. |
| @@ -627,9 +627,10 @@ config USB_AUDIO | |||
| 627 | config USB_ETH | 627 | config USB_ETH |
| 628 | tristate "Ethernet Gadget (with CDC Ethernet support)" | 628 | tristate "Ethernet Gadget (with CDC Ethernet support)" |
| 629 | depends on NET | 629 | depends on NET |
| 630 | select CRC32 | ||
| 630 | help | 631 | help |
| 631 | This driver implements Ethernet style communication, in either | 632 | This driver implements Ethernet style communication, in one of |
| 632 | of two ways: | 633 | several ways: |
| 633 | 634 | ||
| 634 | - The "Communication Device Class" (CDC) Ethernet Control Model. | 635 | - The "Communication Device Class" (CDC) Ethernet Control Model. |
| 635 | That protocol is often avoided with pure Ethernet adapters, in | 636 | That protocol is often avoided with pure Ethernet adapters, in |
| @@ -639,7 +640,11 @@ config USB_ETH | |||
| 639 | - On hardware can't implement that protocol, a simple CDC subset | 640 | - On hardware can't implement that protocol, a simple CDC subset |
| 640 | is used, placing fewer demands on USB. | 641 | is used, placing fewer demands on USB. |
| 641 | 642 | ||
| 642 | RNDIS support is a third option, more demanding than that subset. | 643 | - CDC Ethernet Emulation Model (EEM) is a newer standard that has |
| 644 | a simpler interface that can be used by more USB hardware. | ||
| 645 | |||
| 646 | RNDIS support is an additional option, more demanding than than | ||
| 647 | subset. | ||
| 643 | 648 | ||
| 644 | Within the USB device, this gadget driver exposes a network device | 649 | Within the USB device, this gadget driver exposes a network device |
| 645 | "usbX", where X depends on what other networking devices you have. | 650 | "usbX", where X depends on what other networking devices you have. |
| @@ -672,6 +677,22 @@ config USB_ETH_RNDIS | |||
| 672 | XP, you'll need to download drivers from Microsoft's website; a URL | 677 | XP, you'll need to download drivers from Microsoft's website; a URL |
| 673 | is given in comments found in that info file. | 678 | is given in comments found in that info file. |
| 674 | 679 | ||
| 680 | config USB_ETH_EEM | ||
| 681 | bool "Ethernet Emulation Model (EEM) support" | ||
| 682 | depends on USB_ETH | ||
| 683 | default n | ||
| 684 | help | ||
| 685 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM | ||
| 686 | and therefore can be supported by more hardware. Technically ECM and | ||
| 687 | EEM are designed for different applications. The ECM model extends | ||
| 688 | the network interface to the target (e.g. a USB cable modem), and the | ||
| 689 | EEM model is for mobile devices to communicate with hosts using | ||
| 690 | ethernet over USB. For Linux gadgets, however, the interface with | ||
| 691 | the host is the same (a usbX device), so the differences are minimal. | ||
| 692 | |||
| 693 | If you say "y" here, the Ethernet gadget driver will use the EEM | ||
| 694 | protocol rather than ECM. If unsure, say "n". | ||
| 695 | |||
| 675 | config USB_GADGETFS | 696 | config USB_GADGETFS |
| 676 | tristate "Gadget Filesystem (EXPERIMENTAL)" | 697 | tristate "Gadget Filesystem (EXPERIMENTAL)" |
| 677 | depends on EXPERIMENTAL | 698 | depends on EXPERIMENTAL |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 77352ccc245e..d5b65962dd36 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
| @@ -2378,40 +2378,34 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) | |||
| 2378 | if (!ep->cancel_transfer && !list_empty(&ep->queue)) { | 2378 | if (!ep->cancel_transfer && !list_empty(&ep->queue)) { |
| 2379 | req = list_entry(ep->queue.next, | 2379 | req = list_entry(ep->queue.next, |
| 2380 | struct udc_request, queue); | 2380 | struct udc_request, queue); |
| 2381 | if (req) { | 2381 | /* |
| 2382 | /* | 2382 | * length bytes transfered |
| 2383 | * length bytes transfered | 2383 | * check dma done of last desc. in PPBDU mode |
| 2384 | * check dma done of last desc. in PPBDU mode | 2384 | */ |
| 2385 | */ | 2385 | if (use_dma_ppb_du) { |
| 2386 | if (use_dma_ppb_du) { | 2386 | td = udc_get_last_dma_desc(req); |
| 2387 | td = udc_get_last_dma_desc(req); | 2387 | if (td) { |
| 2388 | if (td) { | 2388 | dma_done = |
| 2389 | dma_done = | 2389 | AMD_GETBITS(td->status, |
| 2390 | AMD_GETBITS(td->status, | 2390 | UDC_DMA_IN_STS_BS); |
| 2391 | UDC_DMA_IN_STS_BS); | 2391 | /* don't care DMA done */ |
| 2392 | /* don't care DMA done */ | ||
| 2393 | req->req.actual = | ||
| 2394 | req->req.length; | ||
| 2395 | } | ||
| 2396 | } else { | ||
| 2397 | /* assume all bytes transferred */ | ||
| 2398 | req->req.actual = req->req.length; | 2392 | req->req.actual = req->req.length; |
| 2399 | } | 2393 | } |
| 2394 | } else { | ||
| 2395 | /* assume all bytes transferred */ | ||
| 2396 | req->req.actual = req->req.length; | ||
| 2397 | } | ||
| 2400 | 2398 | ||
| 2401 | if (req->req.actual == req->req.length) { | 2399 | if (req->req.actual == req->req.length) { |
| 2402 | /* complete req */ | 2400 | /* complete req */ |
| 2403 | complete_req(ep, req, 0); | 2401 | complete_req(ep, req, 0); |
| 2404 | req->dma_going = 0; | 2402 | req->dma_going = 0; |
| 2405 | /* further request available ? */ | 2403 | /* further request available ? */ |
| 2406 | if (list_empty(&ep->queue)) { | 2404 | if (list_empty(&ep->queue)) { |
| 2407 | /* disable interrupt */ | 2405 | /* disable interrupt */ |
| 2408 | tmp = readl( | 2406 | tmp = readl(&dev->regs->ep_irqmsk); |
| 2409 | &dev->regs->ep_irqmsk); | 2407 | tmp |= AMD_BIT(ep->num); |
| 2410 | tmp |= AMD_BIT(ep->num); | 2408 | writel(tmp, &dev->regs->ep_irqmsk); |
| 2411 | writel(tmp, | ||
| 2412 | &dev->regs->ep_irqmsk); | ||
| 2413 | } | ||
| 2414 | |||
| 2415 | } | 2409 | } |
| 2416 | } | 2410 | } |
| 2417 | } | 2411 | } |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 72bae8f39d81..66450a1abc22 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
| @@ -1754,7 +1754,6 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
| 1754 | IRQF_DISABLED, driver_name, udc)) { | 1754 | IRQF_DISABLED, driver_name, udc)) { |
| 1755 | DBG("request vbus irq %d failed\n", | 1755 | DBG("request vbus irq %d failed\n", |
| 1756 | udc->board.vbus_pin); | 1756 | udc->board.vbus_pin); |
| 1757 | free_irq(udc->udp_irq, udc); | ||
| 1758 | retval = -EBUSY; | 1757 | retval = -EBUSY; |
| 1759 | goto fail3; | 1758 | goto fail3; |
| 1760 | } | 1759 | } |
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 9f80f4e970bd..a3a0f4a27ef0 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c | |||
| @@ -106,20 +106,20 @@ static int audio_set_endpoint_req(struct usb_configuration *c, | |||
| 106 | ctrl->bRequest, w_value, len, ep); | 106 | ctrl->bRequest, w_value, len, ep); |
| 107 | 107 | ||
| 108 | switch (ctrl->bRequest) { | 108 | switch (ctrl->bRequest) { |
| 109 | case SET_CUR: | 109 | case UAC_SET_CUR: |
| 110 | value = 0; | 110 | value = 0; |
| 111 | break; | 111 | break; |
| 112 | 112 | ||
| 113 | case SET_MIN: | 113 | case UAC_SET_MIN: |
| 114 | break; | 114 | break; |
| 115 | 115 | ||
| 116 | case SET_MAX: | 116 | case UAC_SET_MAX: |
| 117 | break; | 117 | break; |
| 118 | 118 | ||
| 119 | case SET_RES: | 119 | case UAC_SET_RES: |
| 120 | break; | 120 | break; |
| 121 | 121 | ||
| 122 | case SET_MEM: | 122 | case UAC_SET_MEM: |
| 123 | break; | 123 | break; |
| 124 | 124 | ||
| 125 | default: | 125 | default: |
| @@ -142,13 +142,13 @@ static int audio_get_endpoint_req(struct usb_configuration *c, | |||
| 142 | ctrl->bRequest, w_value, len, ep); | 142 | ctrl->bRequest, w_value, len, ep); |
| 143 | 143 | ||
| 144 | switch (ctrl->bRequest) { | 144 | switch (ctrl->bRequest) { |
| 145 | case GET_CUR: | 145 | case UAC_GET_CUR: |
| 146 | case GET_MIN: | 146 | case UAC_GET_MIN: |
| 147 | case GET_MAX: | 147 | case UAC_GET_MAX: |
| 148 | case GET_RES: | 148 | case UAC_GET_RES: |
| 149 | value = 3; | 149 | value = 3; |
| 150 | break; | 150 | break; |
| 151 | case GET_MEM: | 151 | case UAC_GET_MEM: |
| 152 | break; | 152 | break; |
| 153 | default: | 153 | default: |
| 154 | break; | 154 | break; |
| @@ -171,11 +171,11 @@ audio_setup(struct usb_configuration *c, const struct usb_ctrlrequest *ctrl) | |||
| 171 | * Audio class messages; interface activation uses set_alt(). | 171 | * Audio class messages; interface activation uses set_alt(). |
| 172 | */ | 172 | */ |
| 173 | switch (ctrl->bRequestType) { | 173 | switch (ctrl->bRequestType) { |
| 174 | case USB_AUDIO_SET_ENDPOINT: | 174 | case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: |
| 175 | value = audio_set_endpoint_req(c, ctrl); | 175 | value = audio_set_endpoint_req(c, ctrl); |
| 176 | break; | 176 | break; |
| 177 | 177 | ||
| 178 | case USB_AUDIO_GET_ENDPOINT: | 178 | case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: |
| 179 | value = audio_get_endpoint_req(c, ctrl); | 179 | value = audio_get_endpoint_req(c, ctrl); |
| 180 | break; | 180 | break; |
| 181 | 181 | ||
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 59e85234fa0a..d05397ec8a18 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
| @@ -602,7 +602,7 @@ static int get_string(struct usb_composite_dev *cdev, | |||
| 602 | } | 602 | } |
| 603 | } | 603 | } |
| 604 | 604 | ||
| 605 | for (len = 0; s->wData[len] && len <= 126; len++) | 605 | for (len = 0; len <= 126 && s->wData[len]; len++) |
| 606 | continue; | 606 | continue; |
| 607 | if (!len) | 607 | if (!len) |
| 608 | return -EINVAL; | 608 | return -EINVAL; |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index a56b24d305f8..5e0966485188 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
| @@ -1306,11 +1306,6 @@ restart: | |||
| 1306 | setup = *(struct usb_ctrlrequest*) urb->setup_packet; | 1306 | setup = *(struct usb_ctrlrequest*) urb->setup_packet; |
| 1307 | w_index = le16_to_cpu(setup.wIndex); | 1307 | w_index = le16_to_cpu(setup.wIndex); |
| 1308 | w_value = le16_to_cpu(setup.wValue); | 1308 | w_value = le16_to_cpu(setup.wValue); |
| 1309 | if (le16_to_cpu(setup.wLength) != | ||
| 1310 | urb->transfer_buffer_length) { | ||
| 1311 | status = -EOVERFLOW; | ||
| 1312 | goto return_urb; | ||
| 1313 | } | ||
| 1314 | 1309 | ||
| 1315 | /* paranoia, in case of stale queued data */ | 1310 | /* paranoia, in case of stale queued data */ |
| 1316 | list_for_each_entry (req, &ep->queue, queue) { | 1311 | list_for_each_entry (req, &ep->queue, queue) { |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index bd102f5052ba..f37de283d0ab 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
| @@ -61,6 +61,11 @@ | |||
| 61 | * simpler, Microsoft pushes their own approach: RNDIS. The published | 61 | * simpler, Microsoft pushes their own approach: RNDIS. The published |
| 62 | * RNDIS specs are ambiguous and appear to be incomplete, and are also | 62 | * RNDIS specs are ambiguous and appear to be incomplete, and are also |
| 63 | * needlessly complex. They borrow more from CDC ACM than CDC ECM. | 63 | * needlessly complex. They borrow more from CDC ACM than CDC ECM. |
| 64 | * | ||
| 65 | * While CDC ECM, CDC Subset, and RNDIS are designed to extend the ethernet | ||
| 66 | * interface to the target, CDC EEM was designed to use ethernet over the USB | ||
| 67 | * link between the host and target. CDC EEM is implemented as an alternative | ||
| 68 | * to those other protocols when that communication model is more appropriate | ||
| 64 | */ | 69 | */ |
| 65 | 70 | ||
| 66 | #define DRIVER_DESC "Ethernet Gadget" | 71 | #define DRIVER_DESC "Ethernet Gadget" |
| @@ -114,6 +119,7 @@ static inline bool has_rndis(void) | |||
| 114 | #include "f_rndis.c" | 119 | #include "f_rndis.c" |
| 115 | #include "rndis.c" | 120 | #include "rndis.c" |
| 116 | #endif | 121 | #endif |
| 122 | #include "f_eem.c" | ||
| 117 | #include "u_ether.c" | 123 | #include "u_ether.c" |
| 118 | 124 | ||
| 119 | /*-------------------------------------------------------------------------*/ | 125 | /*-------------------------------------------------------------------------*/ |
| @@ -150,6 +156,10 @@ static inline bool has_rndis(void) | |||
| 150 | #define RNDIS_VENDOR_NUM 0x0525 /* NetChip */ | 156 | #define RNDIS_VENDOR_NUM 0x0525 /* NetChip */ |
| 151 | #define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ | 157 | #define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ |
| 152 | 158 | ||
| 159 | /* For EEM gadgets */ | ||
| 160 | #define EEM_VENDOR_NUM 0x0525 /* INVALID - NEEDS TO BE ALLOCATED */ | ||
| 161 | #define EEM_PRODUCT_NUM 0xa4a1 /* INVALID - NEEDS TO BE ALLOCATED */ | ||
| 162 | |||
| 153 | /*-------------------------------------------------------------------------*/ | 163 | /*-------------------------------------------------------------------------*/ |
| 154 | 164 | ||
| 155 | static struct usb_device_descriptor device_desc = { | 165 | static struct usb_device_descriptor device_desc = { |
| @@ -246,8 +256,16 @@ static struct usb_configuration rndis_config_driver = { | |||
| 246 | 256 | ||
| 247 | /*-------------------------------------------------------------------------*/ | 257 | /*-------------------------------------------------------------------------*/ |
| 248 | 258 | ||
| 259 | #ifdef CONFIG_USB_ETH_EEM | ||
| 260 | static int use_eem = 1; | ||
| 261 | #else | ||
| 262 | static int use_eem; | ||
| 263 | #endif | ||
| 264 | module_param(use_eem, bool, 0); | ||
| 265 | MODULE_PARM_DESC(use_eem, "use CDC EEM mode"); | ||
| 266 | |||
| 249 | /* | 267 | /* |
| 250 | * We _always_ have an ECM or CDC Subset configuration. | 268 | * We _always_ have an ECM, CDC Subset, or EEM configuration. |
| 251 | */ | 269 | */ |
| 252 | static int __init eth_do_config(struct usb_configuration *c) | 270 | static int __init eth_do_config(struct usb_configuration *c) |
| 253 | { | 271 | { |
| @@ -258,7 +276,9 @@ static int __init eth_do_config(struct usb_configuration *c) | |||
| 258 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 276 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
| 259 | } | 277 | } |
| 260 | 278 | ||
| 261 | if (can_support_ecm(c->cdev->gadget)) | 279 | if (use_eem) |
| 280 | return eem_bind_config(c); | ||
| 281 | else if (can_support_ecm(c->cdev->gadget)) | ||
| 262 | return ecm_bind_config(c, hostaddr); | 282 | return ecm_bind_config(c, hostaddr); |
| 263 | else | 283 | else |
| 264 | return geth_bind_config(c, hostaddr); | 284 | return geth_bind_config(c, hostaddr); |
| @@ -286,7 +306,12 @@ static int __init eth_bind(struct usb_composite_dev *cdev) | |||
| 286 | return status; | 306 | return status; |
| 287 | 307 | ||
| 288 | /* set up main config label and device descriptor */ | 308 | /* set up main config label and device descriptor */ |
| 289 | if (can_support_ecm(cdev->gadget)) { | 309 | if (use_eem) { |
| 310 | /* EEM */ | ||
| 311 | eth_config_driver.label = "CDC Ethernet (EEM)"; | ||
| 312 | device_desc.idVendor = cpu_to_le16(EEM_VENDOR_NUM); | ||
| 313 | device_desc.idProduct = cpu_to_le16(EEM_PRODUCT_NUM); | ||
| 314 | } else if (can_support_ecm(cdev->gadget)) { | ||
| 290 | /* ECM */ | 315 | /* ECM */ |
| 291 | eth_config_driver.label = "CDC Ethernet (ECM)"; | 316 | eth_config_driver.label = "CDC Ethernet (ECM)"; |
| 292 | } else { | 317 | } else { |
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 66527ba2d2ea..98e9bb977291 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c | |||
| @@ -28,6 +28,9 @@ static int audio_buf_size = 48000; | |||
| 28 | module_param(audio_buf_size, int, S_IRUGO); | 28 | module_param(audio_buf_size, int, S_IRUGO); |
| 29 | MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); | 29 | MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); |
| 30 | 30 | ||
| 31 | static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); | ||
| 32 | static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); | ||
| 33 | |||
| 31 | /* | 34 | /* |
| 32 | * DESCRIPTORS ... most are static, but strings and full | 35 | * DESCRIPTORS ... most are static, but strings and full |
| 33 | * configuration descriptors are built on demand. | 36 | * configuration descriptors are built on demand. |
| @@ -50,16 +53,16 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = { | |||
| 50 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, | 53 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, |
| 51 | }; | 54 | }; |
| 52 | 55 | ||
| 53 | DECLARE_USB_AC_HEADER_DESCRIPTOR(2); | 56 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); |
| 54 | 57 | ||
| 55 | #define USB_DT_AC_HEADER_LENGH USB_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) | 58 | #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) |
| 56 | /* B.3.2 Class-Specific AC Interface Descriptor */ | 59 | /* B.3.2 Class-Specific AC Interface Descriptor */ |
| 57 | static struct usb_ac_header_descriptor_2 ac_header_desc = { | 60 | static struct uac_ac_header_descriptor_2 ac_header_desc = { |
| 58 | .bLength = USB_DT_AC_HEADER_LENGH, | 61 | .bLength = UAC_DT_AC_HEADER_LENGTH, |
| 59 | .bDescriptorType = USB_DT_CS_INTERFACE, | 62 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 60 | .bDescriptorSubtype = HEADER, | 63 | .bDescriptorSubtype = UAC_HEADER, |
| 61 | .bcdADC = __constant_cpu_to_le16(0x0100), | 64 | .bcdADC = __constant_cpu_to_le16(0x0100), |
| 62 | .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_LENGH), | 65 | .wTotalLength = __constant_cpu_to_le16(UAC_DT_AC_HEADER_LENGTH), |
| 63 | .bInCollection = F_AUDIO_NUM_INTERFACES, | 66 | .bInCollection = F_AUDIO_NUM_INTERFACES, |
| 64 | .baInterfaceNr = { | 67 | .baInterfaceNr = { |
| 65 | [0] = F_AUDIO_AC_INTERFACE, | 68 | [0] = F_AUDIO_AC_INTERFACE, |
| @@ -68,33 +71,33 @@ static struct usb_ac_header_descriptor_2 ac_header_desc = { | |||
| 68 | }; | 71 | }; |
| 69 | 72 | ||
| 70 | #define INPUT_TERMINAL_ID 1 | 73 | #define INPUT_TERMINAL_ID 1 |
| 71 | static struct usb_input_terminal_descriptor input_terminal_desc = { | 74 | static struct uac_input_terminal_descriptor input_terminal_desc = { |
| 72 | .bLength = USB_DT_AC_INPUT_TERMINAL_SIZE, | 75 | .bLength = UAC_DT_INPUT_TERMINAL_SIZE, |
| 73 | .bDescriptorType = USB_DT_CS_INTERFACE, | 76 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 74 | .bDescriptorSubtype = INPUT_TERMINAL, | 77 | .bDescriptorSubtype = UAC_INPUT_TERMINAL, |
| 75 | .bTerminalID = INPUT_TERMINAL_ID, | 78 | .bTerminalID = INPUT_TERMINAL_ID, |
| 76 | .wTerminalType = USB_AC_TERMINAL_STREAMING, | 79 | .wTerminalType = UAC_TERMINAL_STREAMING, |
| 77 | .bAssocTerminal = 0, | 80 | .bAssocTerminal = 0, |
| 78 | .wChannelConfig = 0x3, | 81 | .wChannelConfig = 0x3, |
| 79 | }; | 82 | }; |
| 80 | 83 | ||
| 81 | DECLARE_USB_AC_FEATURE_UNIT_DESCRIPTOR(0); | 84 | DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); |
| 82 | 85 | ||
| 83 | #define FEATURE_UNIT_ID 2 | 86 | #define FEATURE_UNIT_ID 2 |
| 84 | static struct usb_ac_feature_unit_descriptor_0 feature_unit_desc = { | 87 | static struct uac_feature_unit_descriptor_0 feature_unit_desc = { |
| 85 | .bLength = USB_DT_AC_FEATURE_UNIT_SIZE(0), | 88 | .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), |
| 86 | .bDescriptorType = USB_DT_CS_INTERFACE, | 89 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 87 | .bDescriptorSubtype = FEATURE_UNIT, | 90 | .bDescriptorSubtype = UAC_FEATURE_UNIT, |
| 88 | .bUnitID = FEATURE_UNIT_ID, | 91 | .bUnitID = FEATURE_UNIT_ID, |
| 89 | .bSourceID = INPUT_TERMINAL_ID, | 92 | .bSourceID = INPUT_TERMINAL_ID, |
| 90 | .bControlSize = 2, | 93 | .bControlSize = 2, |
| 91 | .bmaControls[0] = (FU_MUTE | FU_VOLUME), | 94 | .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME), |
| 92 | }; | 95 | }; |
| 93 | 96 | ||
| 94 | static struct usb_audio_control mute_control = { | 97 | static struct usb_audio_control mute_control = { |
| 95 | .list = LIST_HEAD_INIT(mute_control.list), | 98 | .list = LIST_HEAD_INIT(mute_control.list), |
| 96 | .name = "Mute Control", | 99 | .name = "Mute Control", |
| 97 | .type = MUTE_CONTROL, | 100 | .type = UAC_MUTE_CONTROL, |
| 98 | /* Todo: add real Mute control code */ | 101 | /* Todo: add real Mute control code */ |
| 99 | .set = generic_set_cmd, | 102 | .set = generic_set_cmd, |
| 100 | .get = generic_get_cmd, | 103 | .get = generic_get_cmd, |
| @@ -103,7 +106,7 @@ static struct usb_audio_control mute_control = { | |||
| 103 | static struct usb_audio_control volume_control = { | 106 | static struct usb_audio_control volume_control = { |
| 104 | .list = LIST_HEAD_INIT(volume_control.list), | 107 | .list = LIST_HEAD_INIT(volume_control.list), |
| 105 | .name = "Volume Control", | 108 | .name = "Volume Control", |
| 106 | .type = VOLUME_CONTROL, | 109 | .type = UAC_VOLUME_CONTROL, |
| 107 | /* Todo: add real Volume control code */ | 110 | /* Todo: add real Volume control code */ |
| 108 | .set = generic_set_cmd, | 111 | .set = generic_set_cmd, |
| 109 | .get = generic_get_cmd, | 112 | .get = generic_get_cmd, |
| @@ -113,17 +116,17 @@ static struct usb_audio_control_selector feature_unit = { | |||
| 113 | .list = LIST_HEAD_INIT(feature_unit.list), | 116 | .list = LIST_HEAD_INIT(feature_unit.list), |
| 114 | .id = FEATURE_UNIT_ID, | 117 | .id = FEATURE_UNIT_ID, |
| 115 | .name = "Mute & Volume Control", | 118 | .name = "Mute & Volume Control", |
| 116 | .type = FEATURE_UNIT, | 119 | .type = UAC_FEATURE_UNIT, |
| 117 | .desc = (struct usb_descriptor_header *)&feature_unit_desc, | 120 | .desc = (struct usb_descriptor_header *)&feature_unit_desc, |
| 118 | }; | 121 | }; |
| 119 | 122 | ||
| 120 | #define OUTPUT_TERMINAL_ID 3 | 123 | #define OUTPUT_TERMINAL_ID 3 |
| 121 | static struct usb_output_terminal_descriptor output_terminal_desc = { | 124 | static struct uac_output_terminal_descriptor output_terminal_desc = { |
| 122 | .bLength = USB_DT_AC_OUTPUT_TERMINAL_SIZE, | 125 | .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, |
| 123 | .bDescriptorType = USB_DT_CS_INTERFACE, | 126 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 124 | .bDescriptorSubtype = OUTPUT_TERMINAL, | 127 | .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, |
| 125 | .bTerminalID = OUTPUT_TERMINAL_ID, | 128 | .bTerminalID = OUTPUT_TERMINAL_ID, |
| 126 | .wTerminalType = USB_AC_OUTPUT_TERMINAL_SPEAKER, | 129 | .wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER, |
| 127 | .bAssocTerminal = FEATURE_UNIT_ID, | 130 | .bAssocTerminal = FEATURE_UNIT_ID, |
| 128 | .bSourceID = FEATURE_UNIT_ID, | 131 | .bSourceID = FEATURE_UNIT_ID, |
| 129 | }; | 132 | }; |
| @@ -148,22 +151,22 @@ static struct usb_interface_descriptor as_interface_alt_1_desc = { | |||
| 148 | }; | 151 | }; |
| 149 | 152 | ||
| 150 | /* B.4.2 Class-Specific AS Interface Descriptor */ | 153 | /* B.4.2 Class-Specific AS Interface Descriptor */ |
| 151 | static struct usb_as_header_descriptor as_header_desc = { | 154 | static struct uac_as_header_descriptor as_header_desc = { |
| 152 | .bLength = USB_DT_AS_HEADER_SIZE, | 155 | .bLength = UAC_DT_AS_HEADER_SIZE, |
| 153 | .bDescriptorType = USB_DT_CS_INTERFACE, | 156 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 154 | .bDescriptorSubtype = AS_GENERAL, | 157 | .bDescriptorSubtype = UAC_AS_GENERAL, |
| 155 | .bTerminalLink = INPUT_TERMINAL_ID, | 158 | .bTerminalLink = INPUT_TERMINAL_ID, |
| 156 | .bDelay = 1, | 159 | .bDelay = 1, |
| 157 | .wFormatTag = USB_AS_AUDIO_FORMAT_TYPE_I_PCM, | 160 | .wFormatTag = UAC_FORMAT_TYPE_I_PCM, |
| 158 | }; | 161 | }; |
| 159 | 162 | ||
| 160 | DECLARE_USB_AS_FORMAT_TYPE_I_DISCRETE_DESC(1); | 163 | DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); |
| 161 | 164 | ||
| 162 | static struct usb_as_formate_type_i_discrete_descriptor_1 as_type_i_desc = { | 165 | static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { |
| 163 | .bLength = USB_AS_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), | 166 | .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), |
| 164 | .bDescriptorType = USB_DT_CS_INTERFACE, | 167 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 165 | .bDescriptorSubtype = FORMAT_TYPE, | 168 | .bDescriptorSubtype = UAC_FORMAT_TYPE, |
| 166 | .bFormatType = USB_AS_FORMAT_TYPE_I, | 169 | .bFormatType = UAC_FORMAT_TYPE_I, |
| 167 | .bSubframeSize = 2, | 170 | .bSubframeSize = 2, |
| 168 | .bBitResolution = 16, | 171 | .bBitResolution = 16, |
| 169 | .bSamFreqType = 1, | 172 | .bSamFreqType = 1, |
| @@ -174,17 +177,17 @@ static struct usb_endpoint_descriptor as_out_ep_desc __initdata = { | |||
| 174 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | 177 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, |
| 175 | .bDescriptorType = USB_DT_ENDPOINT, | 178 | .bDescriptorType = USB_DT_ENDPOINT, |
| 176 | .bEndpointAddress = USB_DIR_OUT, | 179 | .bEndpointAddress = USB_DIR_OUT, |
| 177 | .bmAttributes = USB_AS_ENDPOINT_ADAPTIVE | 180 | .bmAttributes = USB_ENDPOINT_SYNC_ADAPTIVE |
| 178 | | USB_ENDPOINT_XFER_ISOC, | 181 | | USB_ENDPOINT_XFER_ISOC, |
| 179 | .wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE), | 182 | .wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE), |
| 180 | .bInterval = 4, | 183 | .bInterval = 4, |
| 181 | }; | 184 | }; |
| 182 | 185 | ||
| 183 | /* Class-specific AS ISO OUT Endpoint Descriptor */ | 186 | /* Class-specific AS ISO OUT Endpoint Descriptor */ |
| 184 | static struct usb_as_iso_endpoint_descriptor as_iso_out_desc __initdata = { | 187 | static struct uac_iso_endpoint_descriptor as_iso_out_desc __initdata = { |
| 185 | .bLength = USB_AS_ISO_ENDPOINT_DESC_SIZE, | 188 | .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, |
| 186 | .bDescriptorType = USB_DT_CS_ENDPOINT, | 189 | .bDescriptorType = USB_DT_CS_ENDPOINT, |
| 187 | .bDescriptorSubtype = EP_GENERAL, | 190 | .bDescriptorSubtype = UAC_EP_GENERAL, |
| 188 | .bmAttributes = 1, | 191 | .bmAttributes = 1, |
| 189 | .bLockDelayUnits = 1, | 192 | .bLockDelayUnits = 1, |
| 190 | .wLockDelay = __constant_cpu_to_le16(1), | 193 | .wLockDelay = __constant_cpu_to_le16(1), |
| @@ -456,11 +459,11 @@ f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | |||
| 456 | * Audio class messages; interface activation uses set_alt(). | 459 | * Audio class messages; interface activation uses set_alt(). |
| 457 | */ | 460 | */ |
| 458 | switch (ctrl->bRequestType) { | 461 | switch (ctrl->bRequestType) { |
| 459 | case USB_AUDIO_SET_INTF: | 462 | case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: |
| 460 | value = audio_set_intf_req(f, ctrl); | 463 | value = audio_set_intf_req(f, ctrl); |
| 461 | break; | 464 | break; |
| 462 | 465 | ||
| 463 | case USB_AUDIO_GET_INTF: | 466 | case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: |
| 464 | value = audio_get_intf_req(f, ctrl); | 467 | value = audio_get_intf_req(f, ctrl); |
| 465 | break; | 468 | break; |
| 466 | 469 | ||
| @@ -632,6 +635,18 @@ f_audio_unbind(struct usb_configuration *c, struct usb_function *f) | |||
| 632 | 635 | ||
| 633 | /*-------------------------------------------------------------------------*/ | 636 | /*-------------------------------------------------------------------------*/ |
| 634 | 637 | ||
| 638 | static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) | ||
| 639 | { | ||
| 640 | con->data[cmd] = value; | ||
| 641 | |||
| 642 | return 0; | ||
| 643 | } | ||
| 644 | |||
| 645 | static int generic_get_cmd(struct usb_audio_control *con, u8 cmd) | ||
| 646 | { | ||
| 647 | return con->data[cmd]; | ||
| 648 | } | ||
| 649 | |||
| 635 | /* Todo: add more control selecotor dynamically */ | 650 | /* Todo: add more control selecotor dynamically */ |
| 636 | int __init control_selector_init(struct f_audio *audio) | 651 | int __init control_selector_init(struct f_audio *audio) |
| 637 | { | 652 | { |
| @@ -642,10 +657,10 @@ int __init control_selector_init(struct f_audio *audio) | |||
| 642 | list_add(&mute_control.list, &feature_unit.control); | 657 | list_add(&mute_control.list, &feature_unit.control); |
| 643 | list_add(&volume_control.list, &feature_unit.control); | 658 | list_add(&volume_control.list, &feature_unit.control); |
| 644 | 659 | ||
| 645 | volume_control.data[_CUR] = 0xffc0; | 660 | volume_control.data[UAC__CUR] = 0xffc0; |
| 646 | volume_control.data[_MIN] = 0xe3a0; | 661 | volume_control.data[UAC__MIN] = 0xe3a0; |
| 647 | volume_control.data[_MAX] = 0xfff0; | 662 | volume_control.data[UAC__MAX] = 0xfff0; |
| 648 | volume_control.data[_RES] = 0x0030; | 663 | volume_control.data[UAC__RES] = 0x0030; |
| 649 | 664 | ||
| 650 | return 0; | 665 | return 0; |
| 651 | } | 666 | } |
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c new file mode 100644 index 000000000000..0a577d5694fd --- /dev/null +++ b/drivers/usb/gadget/f_eem.c | |||
| @@ -0,0 +1,562 @@ | |||
| 1 | /* | ||
| 2 | * f_eem.c -- USB CDC Ethernet (EEM) link function driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003-2005,2008 David Brownell | ||
| 5 | * Copyright (C) 2008 Nokia Corporation | ||
| 6 | * Copyright (C) 2009 EF Johnson Technologies | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <linux/device.h> | ||
| 25 | #include <linux/etherdevice.h> | ||
| 26 | #include <linux/crc32.h> | ||
| 27 | |||
| 28 | #include "u_ether.h" | ||
| 29 | |||
| 30 | #define EEM_HLEN 2 | ||
| 31 | |||
| 32 | /* | ||
| 33 | * This function is a "CDC Ethernet Emulation Model" (CDC EEM) | ||
| 34 | * Ethernet link. | ||
| 35 | */ | ||
| 36 | |||
| 37 | struct eem_ep_descs { | ||
| 38 | struct usb_endpoint_descriptor *in; | ||
| 39 | struct usb_endpoint_descriptor *out; | ||
| 40 | }; | ||
| 41 | |||
| 42 | struct f_eem { | ||
| 43 | struct gether port; | ||
| 44 | u8 ctrl_id; | ||
| 45 | |||
| 46 | struct eem_ep_descs fs; | ||
| 47 | struct eem_ep_descs hs; | ||
| 48 | }; | ||
| 49 | |||
| 50 | static inline struct f_eem *func_to_eem(struct usb_function *f) | ||
| 51 | { | ||
| 52 | return container_of(f, struct f_eem, port.func); | ||
| 53 | } | ||
| 54 | |||
| 55 | /*-------------------------------------------------------------------------*/ | ||
| 56 | |||
| 57 | /* interface descriptor: */ | ||
| 58 | |||
| 59 | static struct usb_interface_descriptor eem_intf __initdata = { | ||
| 60 | .bLength = sizeof eem_intf, | ||
| 61 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 62 | |||
| 63 | /* .bInterfaceNumber = DYNAMIC */ | ||
| 64 | .bNumEndpoints = 2, | ||
| 65 | .bInterfaceClass = USB_CLASS_COMM, | ||
| 66 | .bInterfaceSubClass = USB_CDC_SUBCLASS_EEM, | ||
| 67 | .bInterfaceProtocol = USB_CDC_PROTO_EEM, | ||
| 68 | /* .iInterface = DYNAMIC */ | ||
| 69 | }; | ||
| 70 | |||
| 71 | /* full speed support: */ | ||
| 72 | |||
| 73 | static struct usb_endpoint_descriptor eem_fs_in_desc __initdata = { | ||
| 74 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 75 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 76 | |||
| 77 | .bEndpointAddress = USB_DIR_IN, | ||
| 78 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 79 | }; | ||
| 80 | |||
| 81 | static struct usb_endpoint_descriptor eem_fs_out_desc __initdata = { | ||
| 82 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 83 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 84 | |||
| 85 | .bEndpointAddress = USB_DIR_OUT, | ||
| 86 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 87 | }; | ||
| 88 | |||
| 89 | static struct usb_descriptor_header *eem_fs_function[] __initdata = { | ||
| 90 | /* CDC EEM control descriptors */ | ||
| 91 | (struct usb_descriptor_header *) &eem_intf, | ||
| 92 | (struct usb_descriptor_header *) &eem_fs_in_desc, | ||
| 93 | (struct usb_descriptor_header *) &eem_fs_out_desc, | ||
| 94 | NULL, | ||
| 95 | }; | ||
| 96 | |||
| 97 | /* high speed support: */ | ||
| 98 | |||
| 99 | static struct usb_endpoint_descriptor eem_hs_in_desc __initdata = { | ||
| 100 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 101 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 102 | |||
| 103 | .bEndpointAddress = USB_DIR_IN, | ||
| 104 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 105 | .wMaxPacketSize = cpu_to_le16(512), | ||
| 106 | }; | ||
| 107 | |||
| 108 | static struct usb_endpoint_descriptor eem_hs_out_desc __initdata = { | ||
| 109 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 110 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 111 | |||
| 112 | .bEndpointAddress = USB_DIR_OUT, | ||
| 113 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 114 | .wMaxPacketSize = cpu_to_le16(512), | ||
| 115 | }; | ||
| 116 | |||
| 117 | static struct usb_descriptor_header *eem_hs_function[] __initdata = { | ||
| 118 | /* CDC EEM control descriptors */ | ||
| 119 | (struct usb_descriptor_header *) &eem_intf, | ||
| 120 | (struct usb_descriptor_header *) &eem_hs_in_desc, | ||
| 121 | (struct usb_descriptor_header *) &eem_hs_out_desc, | ||
| 122 | NULL, | ||
| 123 | }; | ||
| 124 | |||
| 125 | /* string descriptors: */ | ||
| 126 | |||
| 127 | static struct usb_string eem_string_defs[] = { | ||
| 128 | [0].s = "CDC Ethernet Emulation Model (EEM)", | ||
| 129 | { } /* end of list */ | ||
| 130 | }; | ||
| 131 | |||
| 132 | static struct usb_gadget_strings eem_string_table = { | ||
| 133 | .language = 0x0409, /* en-us */ | ||
| 134 | .strings = eem_string_defs, | ||
| 135 | }; | ||
| 136 | |||
| 137 | static struct usb_gadget_strings *eem_strings[] = { | ||
| 138 | &eem_string_table, | ||
| 139 | NULL, | ||
| 140 | }; | ||
| 141 | |||
| 142 | /*-------------------------------------------------------------------------*/ | ||
| 143 | |||
| 144 | static int eem_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | ||
| 145 | { | ||
| 146 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 147 | int value = -EOPNOTSUPP; | ||
| 148 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
| 149 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 150 | u16 w_length = le16_to_cpu(ctrl->wLength); | ||
| 151 | |||
| 152 | DBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", | ||
| 153 | ctrl->bRequestType, ctrl->bRequest, | ||
| 154 | w_value, w_index, w_length); | ||
| 155 | |||
| 156 | /* device either stalls (value < 0) or reports success */ | ||
| 157 | return value; | ||
| 158 | } | ||
| 159 | |||
| 160 | |||
| 161 | static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | ||
| 162 | { | ||
| 163 | struct f_eem *eem = func_to_eem(f); | ||
| 164 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 165 | struct net_device *net; | ||
| 166 | |||
| 167 | /* we know alt == 0, so this is an activation or a reset */ | ||
| 168 | if (alt != 0) | ||
| 169 | goto fail; | ||
| 170 | |||
| 171 | if (intf == eem->ctrl_id) { | ||
| 172 | |||
| 173 | if (eem->port.in_ep->driver_data) { | ||
| 174 | DBG(cdev, "reset eem\n"); | ||
| 175 | gether_disconnect(&eem->port); | ||
| 176 | } | ||
| 177 | |||
| 178 | if (!eem->port.in) { | ||
| 179 | DBG(cdev, "init eem\n"); | ||
| 180 | eem->port.in = ep_choose(cdev->gadget, | ||
| 181 | eem->hs.in, eem->fs.in); | ||
| 182 | eem->port.out = ep_choose(cdev->gadget, | ||
| 183 | eem->hs.out, eem->fs.out); | ||
| 184 | } | ||
| 185 | |||
| 186 | /* zlps should not occur because zero-length EEM packets | ||
| 187 | * will be inserted in those cases where they would occur | ||
| 188 | */ | ||
| 189 | eem->port.is_zlp_ok = 1; | ||
| 190 | eem->port.cdc_filter = DEFAULT_FILTER; | ||
| 191 | DBG(cdev, "activate eem\n"); | ||
| 192 | net = gether_connect(&eem->port); | ||
| 193 | if (IS_ERR(net)) | ||
| 194 | return PTR_ERR(net); | ||
| 195 | } else | ||
| 196 | goto fail; | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | fail: | ||
| 200 | return -EINVAL; | ||
| 201 | } | ||
| 202 | |||
| 203 | static void eem_disable(struct usb_function *f) | ||
| 204 | { | ||
| 205 | struct f_eem *eem = func_to_eem(f); | ||
| 206 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 207 | |||
| 208 | DBG(cdev, "eem deactivated\n"); | ||
| 209 | |||
| 210 | if (eem->port.in_ep->driver_data) | ||
| 211 | gether_disconnect(&eem->port); | ||
| 212 | } | ||
| 213 | |||
| 214 | /*-------------------------------------------------------------------------*/ | ||
| 215 | |||
| 216 | /* EEM function driver setup/binding */ | ||
| 217 | |||
| 218 | static int __init | ||
| 219 | eem_bind(struct usb_configuration *c, struct usb_function *f) | ||
| 220 | { | ||
| 221 | struct usb_composite_dev *cdev = c->cdev; | ||
| 222 | struct f_eem *eem = func_to_eem(f); | ||
| 223 | int status; | ||
| 224 | struct usb_ep *ep; | ||
| 225 | |||
| 226 | /* allocate instance-specific interface IDs */ | ||
| 227 | status = usb_interface_id(c, f); | ||
| 228 | if (status < 0) | ||
| 229 | goto fail; | ||
| 230 | eem->ctrl_id = status; | ||
| 231 | eem_intf.bInterfaceNumber = status; | ||
| 232 | |||
| 233 | status = -ENODEV; | ||
| 234 | |||
| 235 | /* allocate instance-specific endpoints */ | ||
| 236 | ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_in_desc); | ||
| 237 | if (!ep) | ||
| 238 | goto fail; | ||
| 239 | eem->port.in_ep = ep; | ||
| 240 | ep->driver_data = cdev; /* claim */ | ||
| 241 | |||
| 242 | ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc); | ||
| 243 | if (!ep) | ||
| 244 | goto fail; | ||
| 245 | eem->port.out_ep = ep; | ||
| 246 | ep->driver_data = cdev; /* claim */ | ||
| 247 | |||
| 248 | status = -ENOMEM; | ||
| 249 | |||
| 250 | /* copy descriptors, and track endpoint copies */ | ||
| 251 | f->descriptors = usb_copy_descriptors(eem_fs_function); | ||
| 252 | if (!f->descriptors) | ||
| 253 | goto fail; | ||
| 254 | |||
| 255 | eem->fs.in = usb_find_endpoint(eem_fs_function, | ||
| 256 | f->descriptors, &eem_fs_in_desc); | ||
| 257 | eem->fs.out = usb_find_endpoint(eem_fs_function, | ||
| 258 | f->descriptors, &eem_fs_out_desc); | ||
| 259 | |||
| 260 | /* support all relevant hardware speeds... we expect that when | ||
| 261 | * hardware is dual speed, all bulk-capable endpoints work at | ||
| 262 | * both speeds | ||
| 263 | */ | ||
| 264 | if (gadget_is_dualspeed(c->cdev->gadget)) { | ||
| 265 | eem_hs_in_desc.bEndpointAddress = | ||
| 266 | eem_fs_in_desc.bEndpointAddress; | ||
| 267 | eem_hs_out_desc.bEndpointAddress = | ||
| 268 | eem_fs_out_desc.bEndpointAddress; | ||
| 269 | |||
| 270 | /* copy descriptors, and track endpoint copies */ | ||
| 271 | f->hs_descriptors = usb_copy_descriptors(eem_hs_function); | ||
| 272 | if (!f->hs_descriptors) | ||
| 273 | goto fail; | ||
| 274 | |||
| 275 | eem->hs.in = usb_find_endpoint(eem_hs_function, | ||
| 276 | f->hs_descriptors, &eem_hs_in_desc); | ||
| 277 | eem->hs.out = usb_find_endpoint(eem_hs_function, | ||
| 278 | f->hs_descriptors, &eem_hs_out_desc); | ||
| 279 | } | ||
| 280 | |||
| 281 | DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n", | ||
| 282 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||
| 283 | eem->port.in_ep->name, eem->port.out_ep->name); | ||
| 284 | return 0; | ||
| 285 | |||
| 286 | fail: | ||
| 287 | if (f->descriptors) | ||
| 288 | usb_free_descriptors(f->descriptors); | ||
| 289 | |||
| 290 | /* we might as well release our claims on endpoints */ | ||
| 291 | if (eem->port.out) | ||
| 292 | eem->port.out_ep->driver_data = NULL; | ||
| 293 | if (eem->port.in) | ||
| 294 | eem->port.in_ep->driver_data = NULL; | ||
| 295 | |||
| 296 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | ||
| 297 | |||
| 298 | return status; | ||
| 299 | } | ||
| 300 | |||
| 301 | static void | ||
| 302 | eem_unbind(struct usb_configuration *c, struct usb_function *f) | ||
| 303 | { | ||
| 304 | struct f_eem *eem = func_to_eem(f); | ||
| 305 | |||
| 306 | DBG(c->cdev, "eem unbind\n"); | ||
| 307 | |||
| 308 | if (gadget_is_dualspeed(c->cdev->gadget)) | ||
| 309 | usb_free_descriptors(f->hs_descriptors); | ||
| 310 | usb_free_descriptors(f->descriptors); | ||
| 311 | kfree(eem); | ||
| 312 | } | ||
| 313 | |||
| 314 | static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 315 | { | ||
| 316 | } | ||
| 317 | |||
| 318 | /* | ||
| 319 | * Add the EEM header and ethernet checksum. | ||
| 320 | * We currently do not attempt to put multiple ethernet frames | ||
| 321 | * into a single USB transfer | ||
| 322 | */ | ||
| 323 | static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb) | ||
| 324 | { | ||
| 325 | struct sk_buff *skb2 = NULL; | ||
| 326 | struct usb_ep *in = port->in_ep; | ||
| 327 | int padlen = 0; | ||
| 328 | u16 len = skb->len; | ||
| 329 | |||
| 330 | if (!skb_cloned(skb)) { | ||
| 331 | int headroom = skb_headroom(skb); | ||
| 332 | int tailroom = skb_tailroom(skb); | ||
| 333 | |||
| 334 | /* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0, | ||
| 335 | * stick two bytes of zero-length EEM packet on the end. | ||
| 336 | */ | ||
| 337 | if (((len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) == 0) | ||
| 338 | padlen += 2; | ||
| 339 | |||
| 340 | if ((tailroom >= (ETH_FCS_LEN + padlen)) && | ||
| 341 | (headroom >= EEM_HLEN)) | ||
| 342 | goto done; | ||
| 343 | } | ||
| 344 | |||
| 345 | skb2 = skb_copy_expand(skb, EEM_HLEN, ETH_FCS_LEN + padlen, GFP_ATOMIC); | ||
| 346 | dev_kfree_skb_any(skb); | ||
| 347 | skb = skb2; | ||
| 348 | if (!skb) | ||
| 349 | return skb; | ||
| 350 | |||
| 351 | done: | ||
| 352 | /* use the "no CRC" option */ | ||
| 353 | put_unaligned_be32(0xdeadbeef, skb_put(skb, 4)); | ||
| 354 | |||
| 355 | /* EEM packet header format: | ||
| 356 | * b0..13: length of ethernet frame | ||
| 357 | * b14: bmCRC (0 == sentinel CRC) | ||
| 358 | * b15: bmType (0 == data) | ||
| 359 | */ | ||
| 360 | len = skb->len; | ||
| 361 | put_unaligned_le16((len & 0x3FFF) | BIT(14), skb_push(skb, 2)); | ||
| 362 | |||
| 363 | /* add a zero-length EEM packet, if needed */ | ||
| 364 | if (padlen) | ||
| 365 | put_unaligned_le16(0, skb_put(skb, 2)); | ||
| 366 | |||
| 367 | return skb; | ||
| 368 | } | ||
| 369 | |||
| 370 | /* | ||
| 371 | * Remove the EEM header. Note that there can be many EEM packets in a single | ||
| 372 | * USB transfer, so we need to break them out and handle them independently. | ||
| 373 | */ | ||
| 374 | static int eem_unwrap(struct gether *port, | ||
| 375 | struct sk_buff *skb, | ||
| 376 | struct sk_buff_head *list) | ||
| 377 | { | ||
| 378 | struct usb_composite_dev *cdev = port->func.config->cdev; | ||
| 379 | int status = 0; | ||
| 380 | |||
| 381 | do { | ||
| 382 | struct sk_buff *skb2; | ||
| 383 | u16 header; | ||
| 384 | u16 len = 0; | ||
| 385 | |||
| 386 | if (skb->len < EEM_HLEN) { | ||
| 387 | status = -EINVAL; | ||
| 388 | DBG(cdev, "invalid EEM header\n"); | ||
| 389 | goto error; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* remove the EEM header */ | ||
| 393 | header = get_unaligned_le16(skb->data); | ||
| 394 | skb_pull(skb, EEM_HLEN); | ||
| 395 | |||
| 396 | /* EEM packet header format: | ||
| 397 | * b0..14: EEM type dependent (data or command) | ||
| 398 | * b15: bmType (0 == data, 1 == command) | ||
| 399 | */ | ||
| 400 | if (header & BIT(15)) { | ||
| 401 | struct usb_request *req = cdev->req; | ||
| 402 | u16 bmEEMCmd; | ||
| 403 | |||
| 404 | /* EEM command packet format: | ||
| 405 | * b0..10: bmEEMCmdParam | ||
| 406 | * b11..13: bmEEMCmd | ||
| 407 | * b14: reserved (must be zero) | ||
| 408 | * b15: bmType (1 == command) | ||
| 409 | */ | ||
| 410 | if (header & BIT(14)) | ||
| 411 | continue; | ||
| 412 | |||
| 413 | bmEEMCmd = (header >> 11) & 0x7; | ||
| 414 | switch (bmEEMCmd) { | ||
| 415 | case 0: /* echo */ | ||
| 416 | len = header & 0x7FF; | ||
| 417 | if (skb->len < len) { | ||
| 418 | status = -EOVERFLOW; | ||
| 419 | goto error; | ||
| 420 | } | ||
| 421 | |||
| 422 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
| 423 | if (unlikely(!skb2)) { | ||
| 424 | DBG(cdev, "EEM echo response error\n"); | ||
| 425 | goto next; | ||
| 426 | } | ||
| 427 | skb_trim(skb2, len); | ||
| 428 | put_unaligned_le16(BIT(15) | BIT(11) | len, | ||
| 429 | skb_push(skb2, 2)); | ||
| 430 | skb_copy_bits(skb, 0, req->buf, skb->len); | ||
| 431 | req->length = skb->len; | ||
| 432 | req->complete = eem_cmd_complete; | ||
| 433 | req->zero = 1; | ||
| 434 | if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) | ||
| 435 | DBG(cdev, "echo response queue fail\n"); | ||
| 436 | break; | ||
| 437 | |||
| 438 | case 1: /* echo response */ | ||
| 439 | case 2: /* suspend hint */ | ||
| 440 | case 3: /* response hint */ | ||
| 441 | case 4: /* response complete hint */ | ||
| 442 | case 5: /* tickle */ | ||
| 443 | default: /* reserved */ | ||
| 444 | continue; | ||
| 445 | } | ||
| 446 | } else { | ||
| 447 | u32 crc, crc2; | ||
| 448 | struct sk_buff *skb3; | ||
| 449 | |||
| 450 | /* check for zero-length EEM packet */ | ||
| 451 | if (header == 0) | ||
| 452 | continue; | ||
| 453 | |||
| 454 | /* EEM data packet format: | ||
| 455 | * b0..13: length of ethernet frame | ||
| 456 | * b14: bmCRC (0 == sentinel, 1 == calculated) | ||
| 457 | * b15: bmType (0 == data) | ||
| 458 | */ | ||
| 459 | len = header & 0x3FFF; | ||
| 460 | if ((skb->len < len) | ||
| 461 | || (len < (ETH_HLEN + ETH_FCS_LEN))) { | ||
| 462 | status = -EINVAL; | ||
| 463 | goto error; | ||
| 464 | } | ||
| 465 | |||
| 466 | /* validate CRC */ | ||
| 467 | crc = get_unaligned_le32(skb->data + len - ETH_FCS_LEN); | ||
| 468 | if (header & BIT(14)) { | ||
| 469 | crc = get_unaligned_le32(skb->data + len | ||
| 470 | - ETH_FCS_LEN); | ||
| 471 | crc2 = ~crc32_le(~0, | ||
| 472 | skb->data, | ||
| 473 | skb->len - ETH_FCS_LEN); | ||
| 474 | } else { | ||
| 475 | crc = get_unaligned_be32(skb->data + len | ||
| 476 | - ETH_FCS_LEN); | ||
| 477 | crc2 = 0xdeadbeef; | ||
| 478 | } | ||
| 479 | if (crc != crc2) { | ||
| 480 | DBG(cdev, "invalid EEM CRC\n"); | ||
| 481 | goto next; | ||
| 482 | } | ||
| 483 | |||
| 484 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
| 485 | if (unlikely(!skb2)) { | ||
| 486 | DBG(cdev, "unable to unframe EEM packet\n"); | ||
| 487 | continue; | ||
| 488 | } | ||
| 489 | skb_trim(skb2, len - ETH_FCS_LEN); | ||
| 490 | |||
| 491 | skb3 = skb_copy_expand(skb2, | ||
| 492 | NET_IP_ALIGN, | ||
| 493 | 0, | ||
| 494 | GFP_ATOMIC); | ||
| 495 | if (unlikely(!skb3)) { | ||
| 496 | DBG(cdev, "unable to realign EEM packet\n"); | ||
| 497 | dev_kfree_skb_any(skb2); | ||
| 498 | continue; | ||
| 499 | } | ||
| 500 | dev_kfree_skb_any(skb2); | ||
| 501 | skb_queue_tail(list, skb3); | ||
| 502 | } | ||
| 503 | next: | ||
| 504 | skb_pull(skb, len); | ||
| 505 | } while (skb->len); | ||
| 506 | |||
| 507 | error: | ||
| 508 | dev_kfree_skb_any(skb); | ||
| 509 | return status; | ||
| 510 | } | ||
| 511 | |||
| 512 | /** | ||
| 513 | * eem_bind_config - add CDC Ethernet (EEM) network link to a configuration | ||
| 514 | * @c: the configuration to support the network link | ||
| 515 | * Context: single threaded during gadget setup | ||
| 516 | * | ||
| 517 | * Returns zero on success, else negative errno. | ||
| 518 | * | ||
| 519 | * Caller must have called @gether_setup(). Caller is also responsible | ||
| 520 | * for calling @gether_cleanup() before module unload. | ||
| 521 | */ | ||
| 522 | int __init eem_bind_config(struct usb_configuration *c) | ||
| 523 | { | ||
| 524 | struct f_eem *eem; | ||
| 525 | int status; | ||
| 526 | |||
| 527 | /* maybe allocate device-global string IDs */ | ||
| 528 | if (eem_string_defs[0].id == 0) { | ||
| 529 | |||
| 530 | /* control interface label */ | ||
| 531 | status = usb_string_id(c->cdev); | ||
| 532 | if (status < 0) | ||
| 533 | return status; | ||
| 534 | eem_string_defs[0].id = status; | ||
| 535 | eem_intf.iInterface = status; | ||
| 536 | } | ||
| 537 | |||
| 538 | /* allocate and initialize one new instance */ | ||
| 539 | eem = kzalloc(sizeof *eem, GFP_KERNEL); | ||
| 540 | if (!eem) | ||
| 541 | return -ENOMEM; | ||
| 542 | |||
| 543 | eem->port.cdc_filter = DEFAULT_FILTER; | ||
| 544 | |||
| 545 | eem->port.func.name = "cdc_eem"; | ||
| 546 | eem->port.func.strings = eem_strings; | ||
| 547 | /* descriptors are per-instance copies */ | ||
| 548 | eem->port.func.bind = eem_bind; | ||
| 549 | eem->port.func.unbind = eem_unbind; | ||
| 550 | eem->port.func.set_alt = eem_set_alt; | ||
| 551 | eem->port.func.setup = eem_setup; | ||
| 552 | eem->port.func.disable = eem_disable; | ||
| 553 | eem->port.wrap = eem_wrap; | ||
| 554 | eem->port.unwrap = eem_unwrap; | ||
| 555 | eem->port.header_len = EEM_HLEN; | ||
| 556 | |||
| 557 | status = usb_add_function(c, &eem->port.func); | ||
| 558 | if (status) | ||
| 559 | kfree(eem); | ||
| 560 | return status; | ||
| 561 | } | ||
| 562 | |||
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 424a37c5773f..c9966cc07d3a 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
| @@ -286,12 +286,17 @@ static struct usb_gadget_strings *rndis_strings[] = { | |||
| 286 | 286 | ||
| 287 | /*-------------------------------------------------------------------------*/ | 287 | /*-------------------------------------------------------------------------*/ |
| 288 | 288 | ||
| 289 | static struct sk_buff *rndis_add_header(struct sk_buff *skb) | 289 | static struct sk_buff *rndis_add_header(struct gether *port, |
| 290 | struct sk_buff *skb) | ||
| 290 | { | 291 | { |
| 291 | skb = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type)); | 292 | struct sk_buff *skb2; |
| 292 | if (skb) | 293 | |
| 293 | rndis_add_hdr(skb); | 294 | skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type)); |
| 294 | return skb; | 295 | if (skb2) |
| 296 | rndis_add_hdr(skb2); | ||
| 297 | |||
| 298 | dev_kfree_skb_any(skb); | ||
| 299 | return skb2; | ||
| 295 | } | 300 | } |
| 296 | 301 | ||
| 297 | static void rndis_response_available(void *_rndis) | 302 | static void rndis_response_available(void *_rndis) |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index d701bf4698d2..7881f12413c4 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
| @@ -2751,6 +2751,10 @@ static int __devexit qe_udc_remove(struct of_device *ofdev) | |||
| 2751 | /*-------------------------------------------------------------------------*/ | 2751 | /*-------------------------------------------------------------------------*/ |
| 2752 | static struct of_device_id __devinitdata qe_udc_match[] = { | 2752 | static struct of_device_id __devinitdata qe_udc_match[] = { |
| 2753 | { | 2753 | { |
| 2754 | .compatible = "fsl,mpc8323-qe-usb", | ||
| 2755 | .data = (void *)PORT_QE, | ||
| 2756 | }, | ||
| 2757 | { | ||
| 2754 | .compatible = "fsl,mpc8360-qe-usb", | 2758 | .compatible = "fsl,mpc8360-qe-usb", |
| 2755 | .data = (void *)PORT_QE, | 2759 | .data = (void *)PORT_QE, |
| 2756 | }, | 2760 | }, |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index b9312dc6e041..d0b1e836f0e0 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
| @@ -191,7 +191,7 @@ module_param(qlen, uint, S_IRUGO); | |||
| 191 | #define GMIDI_MS_INTERFACE 1 | 191 | #define GMIDI_MS_INTERFACE 1 |
| 192 | #define GMIDI_NUM_INTERFACES 2 | 192 | #define GMIDI_NUM_INTERFACES 2 |
| 193 | 193 | ||
| 194 | DECLARE_USB_AC_HEADER_DESCRIPTOR(1); | 194 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); |
| 195 | DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); | 195 | DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); |
| 196 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1); | 196 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1); |
| 197 | 197 | ||
| @@ -237,12 +237,12 @@ static const struct usb_interface_descriptor ac_interface_desc = { | |||
| 237 | }; | 237 | }; |
| 238 | 238 | ||
| 239 | /* B.3.2 Class-Specific AC Interface Descriptor */ | 239 | /* B.3.2 Class-Specific AC Interface Descriptor */ |
| 240 | static const struct usb_ac_header_descriptor_1 ac_header_desc = { | 240 | static const struct uac_ac_header_descriptor_1 ac_header_desc = { |
| 241 | .bLength = USB_DT_AC_HEADER_SIZE(1), | 241 | .bLength = UAC_DT_AC_HEADER_SIZE(1), |
| 242 | .bDescriptorType = USB_DT_CS_INTERFACE, | 242 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 243 | .bDescriptorSubtype = USB_MS_HEADER, | 243 | .bDescriptorSubtype = USB_MS_HEADER, |
| 244 | .bcdADC = cpu_to_le16(0x0100), | 244 | .bcdADC = cpu_to_le16(0x0100), |
| 245 | .wTotalLength = cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)), | 245 | .wTotalLength = cpu_to_le16(UAC_DT_AC_HEADER_SIZE(1)), |
| 246 | .bInCollection = 1, | 246 | .bInCollection = 1, |
| 247 | .baInterfaceNr = { | 247 | .baInterfaceNr = { |
| 248 | [0] = GMIDI_MS_INTERFACE, | 248 | [0] = GMIDI_MS_INTERFACE, |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index ed21e263f832..e6fedbd5a654 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | 56 | ||
| 57 | #include <linux/usb/ch9.h> | 57 | #include <linux/usb/ch9.h> |
| 58 | #include <linux/usb/gadget.h> | 58 | #include <linux/usb/gadget.h> |
| 59 | #include <linux/usb/otg.h> | ||
| 59 | 60 | ||
| 60 | /* | 61 | /* |
| 61 | * This driver is PXA25x only. Grab the right register definitions. | 62 | * This driver is PXA25x only. Grab the right register definitions. |
| @@ -1008,15 +1009,27 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
| 1008 | return 0; | 1009 | return 0; |
| 1009 | } | 1010 | } |
| 1010 | 1011 | ||
| 1012 | /* boards may consume current from VBUS, up to 100-500mA based on config. | ||
| 1013 | * the 500uA suspend ceiling means that exclusively vbus-powered PXA designs | ||
| 1014 | * violate USB specs. | ||
| 1015 | */ | ||
| 1016 | static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | ||
| 1017 | { | ||
| 1018 | struct pxa25x_udc *udc; | ||
| 1019 | |||
| 1020 | udc = container_of(_gadget, struct pxa25x_udc, gadget); | ||
| 1021 | |||
| 1022 | if (udc->transceiver) | ||
| 1023 | return otg_set_power(udc->transceiver, mA); | ||
| 1024 | return -EOPNOTSUPP; | ||
| 1025 | } | ||
| 1026 | |||
| 1011 | static const struct usb_gadget_ops pxa25x_udc_ops = { | 1027 | static const struct usb_gadget_ops pxa25x_udc_ops = { |
| 1012 | .get_frame = pxa25x_udc_get_frame, | 1028 | .get_frame = pxa25x_udc_get_frame, |
| 1013 | .wakeup = pxa25x_udc_wakeup, | 1029 | .wakeup = pxa25x_udc_wakeup, |
| 1014 | .vbus_session = pxa25x_udc_vbus_session, | 1030 | .vbus_session = pxa25x_udc_vbus_session, |
| 1015 | .pullup = pxa25x_udc_pullup, | 1031 | .pullup = pxa25x_udc_pullup, |
| 1016 | 1032 | .vbus_draw = pxa25x_udc_vbus_draw, | |
| 1017 | // .vbus_draw ... boards may consume current from VBUS, up to | ||
| 1018 | // 100-500mA based on config. the 500uA suspend ceiling means | ||
| 1019 | // that exclusively vbus-powered PXA designs violate USB specs. | ||
| 1020 | }; | 1033 | }; |
| 1021 | 1034 | ||
| 1022 | /*-------------------------------------------------------------------------*/ | 1035 | /*-------------------------------------------------------------------------*/ |
| @@ -1303,9 +1316,23 @@ fail: | |||
| 1303 | * for set_configuration as well as eventual disconnect. | 1316 | * for set_configuration as well as eventual disconnect. |
| 1304 | */ | 1317 | */ |
| 1305 | DMSG("registered gadget driver '%s'\n", driver->driver.name); | 1318 | DMSG("registered gadget driver '%s'\n", driver->driver.name); |
| 1319 | |||
| 1320 | /* connect to bus through transceiver */ | ||
| 1321 | if (dev->transceiver) { | ||
| 1322 | retval = otg_set_peripheral(dev->transceiver, &dev->gadget); | ||
| 1323 | if (retval) { | ||
| 1324 | DMSG("can't bind to transceiver\n"); | ||
| 1325 | if (driver->unbind) | ||
| 1326 | driver->unbind(&dev->gadget); | ||
| 1327 | goto bind_fail; | ||
| 1328 | } | ||
| 1329 | } | ||
| 1330 | |||
| 1306 | pullup(dev); | 1331 | pullup(dev); |
| 1307 | dump_state(dev); | 1332 | dump_state(dev); |
| 1308 | return 0; | 1333 | return 0; |
| 1334 | bind_fail: | ||
| 1335 | return retval; | ||
| 1309 | } | 1336 | } |
| 1310 | EXPORT_SYMBOL(usb_gadget_register_driver); | 1337 | EXPORT_SYMBOL(usb_gadget_register_driver); |
| 1311 | 1338 | ||
| @@ -1351,6 +1378,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1351 | stop_activity(dev, driver); | 1378 | stop_activity(dev, driver); |
| 1352 | local_irq_enable(); | 1379 | local_irq_enable(); |
| 1353 | 1380 | ||
| 1381 | if (dev->transceiver) | ||
| 1382 | (void) otg_set_peripheral(dev->transceiver, NULL); | ||
| 1383 | |||
| 1354 | driver->unbind(&dev->gadget); | 1384 | driver->unbind(&dev->gadget); |
| 1355 | dev->gadget.dev.driver = NULL; | 1385 | dev->gadget.dev.driver = NULL; |
| 1356 | dev->driver = NULL; | 1386 | dev->driver = NULL; |
| @@ -2162,6 +2192,8 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
| 2162 | dev->dev = &pdev->dev; | 2192 | dev->dev = &pdev->dev; |
| 2163 | dev->mach = pdev->dev.platform_data; | 2193 | dev->mach = pdev->dev.platform_data; |
| 2164 | 2194 | ||
| 2195 | dev->transceiver = otg_get_transceiver(); | ||
| 2196 | |||
| 2165 | if (gpio_is_valid(dev->mach->gpio_vbus)) { | 2197 | if (gpio_is_valid(dev->mach->gpio_vbus)) { |
| 2166 | if ((retval = gpio_request(dev->mach->gpio_vbus, | 2198 | if ((retval = gpio_request(dev->mach->gpio_vbus, |
| 2167 | "pxa25x_udc GPIO VBUS"))) { | 2199 | "pxa25x_udc GPIO VBUS"))) { |
| @@ -2264,6 +2296,10 @@ lubbock_fail0: | |||
| 2264 | if (gpio_is_valid(dev->mach->gpio_vbus)) | 2296 | if (gpio_is_valid(dev->mach->gpio_vbus)) |
| 2265 | gpio_free(dev->mach->gpio_vbus); | 2297 | gpio_free(dev->mach->gpio_vbus); |
| 2266 | err_gpio_vbus: | 2298 | err_gpio_vbus: |
| 2299 | if (dev->transceiver) { | ||
| 2300 | otg_put_transceiver(dev->transceiver); | ||
| 2301 | dev->transceiver = NULL; | ||
| 2302 | } | ||
| 2267 | clk_put(dev->clk); | 2303 | clk_put(dev->clk); |
| 2268 | err_clk: | 2304 | err_clk: |
| 2269 | return retval; | 2305 | return retval; |
| @@ -2305,6 +2341,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) | |||
| 2305 | 2341 | ||
| 2306 | clk_put(dev->clk); | 2342 | clk_put(dev->clk); |
| 2307 | 2343 | ||
| 2344 | if (dev->transceiver) { | ||
| 2345 | otg_put_transceiver(dev->transceiver); | ||
| 2346 | dev->transceiver = NULL; | ||
| 2347 | } | ||
| 2348 | |||
| 2308 | platform_set_drvdata(pdev, NULL); | 2349 | platform_set_drvdata(pdev, NULL); |
| 2309 | the_controller = NULL; | 2350 | the_controller = NULL; |
| 2310 | return 0; | 2351 | return 0; |
diff --git a/drivers/usb/gadget/pxa25x_udc.h b/drivers/usb/gadget/pxa25x_udc.h index 1d51aa21e6eb..f572c5617462 100644 --- a/drivers/usb/gadget/pxa25x_udc.h +++ b/drivers/usb/gadget/pxa25x_udc.h | |||
| @@ -128,6 +128,7 @@ struct pxa25x_udc { | |||
| 128 | struct device *dev; | 128 | struct device *dev; |
| 129 | struct clk *clk; | 129 | struct clk *clk; |
| 130 | struct pxa2xx_udc_mach_info *mach; | 130 | struct pxa2xx_udc_mach_info *mach; |
| 131 | struct otg_transceiver *transceiver; | ||
| 131 | u64 dma_mask; | 132 | u64 dma_mask; |
| 132 | struct pxa25x_ep ep [PXA_UDC_NUM_ENDPOINTS]; | 133 | struct pxa25x_ep ep [PXA_UDC_NUM_ENDPOINTS]; |
| 133 | 134 | ||
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index ca41b0b5afb3..48267bc0b2e0 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
| @@ -1022,22 +1022,29 @@ static rndis_resp_t *rndis_add_response (int configNr, u32 length) | |||
| 1022 | return r; | 1022 | return r; |
| 1023 | } | 1023 | } |
| 1024 | 1024 | ||
| 1025 | int rndis_rm_hdr(struct sk_buff *skb) | 1025 | int rndis_rm_hdr(struct gether *port, |
| 1026 | struct sk_buff *skb, | ||
| 1027 | struct sk_buff_head *list) | ||
| 1026 | { | 1028 | { |
| 1027 | /* tmp points to a struct rndis_packet_msg_type */ | 1029 | /* tmp points to a struct rndis_packet_msg_type */ |
| 1028 | __le32 *tmp = (void *) skb->data; | 1030 | __le32 *tmp = (void *) skb->data; |
| 1029 | 1031 | ||
| 1030 | /* MessageType, MessageLength */ | 1032 | /* MessageType, MessageLength */ |
| 1031 | if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG) | 1033 | if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG) |
| 1032 | != get_unaligned(tmp++)) | 1034 | != get_unaligned(tmp++)) { |
| 1035 | dev_kfree_skb_any(skb); | ||
| 1033 | return -EINVAL; | 1036 | return -EINVAL; |
| 1037 | } | ||
| 1034 | tmp++; | 1038 | tmp++; |
| 1035 | 1039 | ||
| 1036 | /* DataOffset, DataLength */ | 1040 | /* DataOffset, DataLength */ |
| 1037 | if (!skb_pull(skb, get_unaligned_le32(tmp++) + 8)) | 1041 | if (!skb_pull(skb, get_unaligned_le32(tmp++) + 8)) { |
| 1042 | dev_kfree_skb_any(skb); | ||
| 1038 | return -EOVERFLOW; | 1043 | return -EOVERFLOW; |
| 1044 | } | ||
| 1039 | skb_trim(skb, get_unaligned_le32(tmp++)); | 1045 | skb_trim(skb, get_unaligned_le32(tmp++)); |
| 1040 | 1046 | ||
| 1047 | skb_queue_tail(list, skb); | ||
| 1041 | return 0; | 1048 | return 0; |
| 1042 | } | 1049 | } |
| 1043 | 1050 | ||
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h index aac61dfe0f03..c236aaa9dcd1 100644 --- a/drivers/usb/gadget/rndis.h +++ b/drivers/usb/gadget/rndis.h | |||
| @@ -251,7 +251,8 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, | |||
| 251 | const char *vendorDescr); | 251 | const char *vendorDescr); |
| 252 | int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed); | 252 | int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed); |
| 253 | void rndis_add_hdr (struct sk_buff *skb); | 253 | void rndis_add_hdr (struct sk_buff *skb); |
| 254 | int rndis_rm_hdr (struct sk_buff *skb); | 254 | int rndis_rm_hdr(struct gether *port, struct sk_buff *skb, |
| 255 | struct sk_buff_head *list); | ||
| 255 | u8 *rndis_get_next_response (int configNr, u32 *length); | 256 | u8 *rndis_get_next_response (int configNr, u32 *length); |
| 256 | void rndis_free_response (int configNr, u8 *buf); | 257 | void rndis_free_response (int configNr, u8 *buf); |
| 257 | 258 | ||
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 50c71aae2cc2..4b5dbd0127f5 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
| @@ -2392,7 +2392,7 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) | |||
| 2392 | grstctl = readl(hsotg->regs + S3C_GRSTCTL); | 2392 | grstctl = readl(hsotg->regs + S3C_GRSTCTL); |
| 2393 | } while (!(grstctl & S3C_GRSTCTL_CSftRst) && timeout-- > 0); | 2393 | } while (!(grstctl & S3C_GRSTCTL_CSftRst) && timeout-- > 0); |
| 2394 | 2394 | ||
| 2395 | if (!grstctl & S3C_GRSTCTL_CSftRst) { | 2395 | if (!(grstctl & S3C_GRSTCTL_CSftRst)) { |
| 2396 | dev_err(hsotg->dev, "Failed to get CSftRst asserted\n"); | 2396 | dev_err(hsotg->dev, "Failed to get CSftRst asserted\n"); |
| 2397 | return -EINVAL; | 2397 | return -EINVAL; |
| 2398 | } | 2398 | } |
| @@ -2514,8 +2514,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
| 2514 | * DMA mode we may need this. */ | 2514 | * DMA mode we may need this. */ |
| 2515 | writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk | | 2515 | writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk | |
| 2516 | S3C_DOEPMSK_EPDisbldMsk | | 2516 | S3C_DOEPMSK_EPDisbldMsk | |
| 2517 | using_dma(hsotg) ? (S3C_DIEPMSK_XferComplMsk | | 2517 | (using_dma(hsotg) ? (S3C_DIEPMSK_XferComplMsk | |
| 2518 | S3C_DIEPMSK_TimeOUTMsk) : 0, | 2518 | S3C_DIEPMSK_TimeOUTMsk) : 0), |
| 2519 | hsotg->regs + S3C_DOEPMSK); | 2519 | hsotg->regs + S3C_DOEPMSK); |
| 2520 | 2520 | ||
| 2521 | writel(0, hsotg->regs + S3C_DAINTMSK); | 2521 | writel(0, hsotg->regs + S3C_DAINTMSK); |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index a9b452fe6221..d5f4c1d45c97 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
| @@ -1703,8 +1703,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1703 | dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n", | 1703 | dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n", |
| 1704 | driver->driver.name); | 1704 | driver->driver.name); |
| 1705 | 1705 | ||
| 1706 | if (driver->disconnect) | 1706 | driver->unbind(&udc->gadget); |
| 1707 | driver->disconnect(&udc->gadget); | ||
| 1708 | 1707 | ||
| 1709 | device_del(&udc->gadget.dev); | 1708 | device_del(&udc->gadget.dev); |
| 1710 | udc->driver = NULL; | 1709 | udc->driver = NULL; |
diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c index 0f3d22fc030e..b5200d551458 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_audio.c | |||
| @@ -253,11 +253,13 @@ static int gaudio_open_snd_dev(struct gaudio *card) | |||
| 253 | snd->filp = filp_open(fn_cap, O_RDONLY, 0); | 253 | snd->filp = filp_open(fn_cap, O_RDONLY, 0); |
| 254 | if (IS_ERR(snd->filp)) { | 254 | if (IS_ERR(snd->filp)) { |
| 255 | ERROR(card, "No such PCM capture device: %s\n", fn_cap); | 255 | ERROR(card, "No such PCM capture device: %s\n", fn_cap); |
| 256 | snd->filp = NULL; | 256 | snd->substream = NULL; |
| 257 | snd->card = NULL; | ||
| 258 | } else { | ||
| 259 | pcm_file = snd->filp->private_data; | ||
| 260 | snd->substream = pcm_file->substream; | ||
| 261 | snd->card = card; | ||
| 257 | } | 262 | } |
| 258 | pcm_file = snd->filp->private_data; | ||
| 259 | snd->substream = pcm_file->substream; | ||
| 260 | snd->card = card; | ||
| 261 | 263 | ||
| 262 | return 0; | 264 | return 0; |
| 263 | } | 265 | } |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index c66521953917..f8751ff863cd 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
| @@ -37,8 +37,9 @@ | |||
| 37 | * one (!) network link through the USB gadget stack, normally "usb0". | 37 | * one (!) network link through the USB gadget stack, normally "usb0". |
| 38 | * | 38 | * |
| 39 | * The control and data models are handled by the function driver which | 39 | * The control and data models are handled by the function driver which |
| 40 | * connects to this code; such as CDC Ethernet, "CDC Subset", or RNDIS. | 40 | * connects to this code; such as CDC Ethernet (ECM or EEM), |
| 41 | * That includes all descriptor and endpoint management. | 41 | * "CDC Subset", or RNDIS. That includes all descriptor and endpoint |
| 42 | * management. | ||
| 42 | * | 43 | * |
| 43 | * Link level addressing is handled by this component using module | 44 | * Link level addressing is handled by this component using module |
| 44 | * parameters; if no such parameters are provided, random link level | 45 | * parameters; if no such parameters are provided, random link level |
| @@ -68,9 +69,13 @@ struct eth_dev { | |||
| 68 | struct list_head tx_reqs, rx_reqs; | 69 | struct list_head tx_reqs, rx_reqs; |
| 69 | atomic_t tx_qlen; | 70 | atomic_t tx_qlen; |
| 70 | 71 | ||
| 72 | struct sk_buff_head rx_frames; | ||
| 73 | |||
| 71 | unsigned header_len; | 74 | unsigned header_len; |
| 72 | struct sk_buff *(*wrap)(struct sk_buff *skb); | 75 | struct sk_buff *(*wrap)(struct gether *, struct sk_buff *skb); |
| 73 | int (*unwrap)(struct sk_buff *skb); | 76 | int (*unwrap)(struct gether *, |
| 77 | struct sk_buff *skb, | ||
| 78 | struct sk_buff_head *list); | ||
| 74 | 79 | ||
| 75 | struct work_struct work; | 80 | struct work_struct work; |
| 76 | 81 | ||
| @@ -269,7 +274,7 @@ enomem: | |||
| 269 | 274 | ||
| 270 | static void rx_complete(struct usb_ep *ep, struct usb_request *req) | 275 | static void rx_complete(struct usb_ep *ep, struct usb_request *req) |
| 271 | { | 276 | { |
| 272 | struct sk_buff *skb = req->context; | 277 | struct sk_buff *skb = req->context, *skb2; |
| 273 | struct eth_dev *dev = ep->driver_data; | 278 | struct eth_dev *dev = ep->driver_data; |
| 274 | int status = req->status; | 279 | int status = req->status; |
| 275 | 280 | ||
| @@ -278,26 +283,47 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 278 | /* normal completion */ | 283 | /* normal completion */ |
| 279 | case 0: | 284 | case 0: |
| 280 | skb_put(skb, req->actual); | 285 | skb_put(skb, req->actual); |
| 281 | if (dev->unwrap) | ||
| 282 | status = dev->unwrap(skb); | ||
| 283 | if (status < 0 | ||
| 284 | || ETH_HLEN > skb->len | ||
| 285 | || skb->len > ETH_FRAME_LEN) { | ||
| 286 | dev->net->stats.rx_errors++; | ||
| 287 | dev->net->stats.rx_length_errors++; | ||
| 288 | DBG(dev, "rx length %d\n", skb->len); | ||
| 289 | break; | ||
| 290 | } | ||
| 291 | 286 | ||
| 292 | skb->protocol = eth_type_trans(skb, dev->net); | 287 | if (dev->unwrap) { |
| 293 | dev->net->stats.rx_packets++; | 288 | unsigned long flags; |
| 294 | dev->net->stats.rx_bytes += skb->len; | ||
| 295 | 289 | ||
| 296 | /* no buffer copies needed, unless hardware can't | 290 | spin_lock_irqsave(&dev->lock, flags); |
| 297 | * use skb buffers. | 291 | if (dev->port_usb) { |
| 298 | */ | 292 | status = dev->unwrap(dev->port_usb, |
| 299 | status = netif_rx(skb); | 293 | skb, |
| 294 | &dev->rx_frames); | ||
| 295 | } else { | ||
| 296 | dev_kfree_skb_any(skb); | ||
| 297 | status = -ENOTCONN; | ||
| 298 | } | ||
| 299 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 300 | } else { | ||
| 301 | skb_queue_tail(&dev->rx_frames, skb); | ||
| 302 | } | ||
| 300 | skb = NULL; | 303 | skb = NULL; |
| 304 | |||
| 305 | skb2 = skb_dequeue(&dev->rx_frames); | ||
| 306 | while (skb2) { | ||
| 307 | if (status < 0 | ||
| 308 | || ETH_HLEN > skb2->len | ||
| 309 | || skb2->len > ETH_FRAME_LEN) { | ||
| 310 | dev->net->stats.rx_errors++; | ||
| 311 | dev->net->stats.rx_length_errors++; | ||
| 312 | DBG(dev, "rx length %d\n", skb2->len); | ||
| 313 | dev_kfree_skb_any(skb2); | ||
| 314 | goto next_frame; | ||
| 315 | } | ||
| 316 | skb2->protocol = eth_type_trans(skb2, dev->net); | ||
| 317 | dev->net->stats.rx_packets++; | ||
| 318 | dev->net->stats.rx_bytes += skb2->len; | ||
| 319 | |||
| 320 | /* no buffer copies needed, unless hardware can't | ||
| 321 | * use skb buffers. | ||
| 322 | */ | ||
| 323 | status = netif_rx(skb2); | ||
| 324 | next_frame: | ||
| 325 | skb2 = skb_dequeue(&dev->rx_frames); | ||
| 326 | } | ||
| 301 | break; | 327 | break; |
| 302 | 328 | ||
| 303 | /* software-driven interface shutdown */ | 329 | /* software-driven interface shutdown */ |
| @@ -537,14 +563,15 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
| 537 | * or there's not enough space for extra headers we need | 563 | * or there's not enough space for extra headers we need |
| 538 | */ | 564 | */ |
| 539 | if (dev->wrap) { | 565 | if (dev->wrap) { |
| 540 | struct sk_buff *skb_new; | 566 | unsigned long flags; |
| 541 | 567 | ||
| 542 | skb_new = dev->wrap(skb); | 568 | spin_lock_irqsave(&dev->lock, flags); |
| 543 | if (!skb_new) | 569 | if (dev->port_usb) |
| 570 | skb = dev->wrap(dev->port_usb, skb); | ||
| 571 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 572 | if (!skb) | ||
| 544 | goto drop; | 573 | goto drop; |
| 545 | 574 | ||
| 546 | dev_kfree_skb_any(skb); | ||
| 547 | skb = skb_new; | ||
| 548 | length = skb->len; | 575 | length = skb->len; |
| 549 | } | 576 | } |
| 550 | req->buf = skb->data; | 577 | req->buf = skb->data; |
| @@ -578,9 +605,9 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
| 578 | } | 605 | } |
| 579 | 606 | ||
| 580 | if (retval) { | 607 | if (retval) { |
| 608 | dev_kfree_skb_any(skb); | ||
| 581 | drop: | 609 | drop: |
| 582 | dev->net->stats.tx_dropped++; | 610 | dev->net->stats.tx_dropped++; |
| 583 | dev_kfree_skb_any(skb); | ||
| 584 | spin_lock_irqsave(&dev->req_lock, flags); | 611 | spin_lock_irqsave(&dev->req_lock, flags); |
| 585 | if (list_empty(&dev->tx_reqs)) | 612 | if (list_empty(&dev->tx_reqs)) |
| 586 | netif_start_queue(net); | 613 | netif_start_queue(net); |
| @@ -753,6 +780,8 @@ int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) | |||
| 753 | INIT_LIST_HEAD(&dev->tx_reqs); | 780 | INIT_LIST_HEAD(&dev->tx_reqs); |
| 754 | INIT_LIST_HEAD(&dev->rx_reqs); | 781 | INIT_LIST_HEAD(&dev->rx_reqs); |
| 755 | 782 | ||
| 783 | skb_queue_head_init(&dev->rx_frames); | ||
| 784 | |||
| 756 | /* network device setup */ | 785 | /* network device setup */ |
| 757 | dev->net = net; | 786 | dev->net = net; |
| 758 | strcpy(net->name, "usb%d"); | 787 | strcpy(net->name, "usb%d"); |
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h index 0d1f7ae3b071..91b39ffdf6ea 100644 --- a/drivers/usb/gadget/u_ether.h +++ b/drivers/usb/gadget/u_ether.h | |||
| @@ -60,12 +60,13 @@ struct gether { | |||
| 60 | 60 | ||
| 61 | u16 cdc_filter; | 61 | u16 cdc_filter; |
| 62 | 62 | ||
| 63 | /* hooks for added framing, as needed for RNDIS and EEM. | 63 | /* hooks for added framing, as needed for RNDIS and EEM. */ |
| 64 | * we currently don't support multiple frames per SKB. | ||
| 65 | */ | ||
| 66 | u32 header_len; | 64 | u32 header_len; |
| 67 | struct sk_buff *(*wrap)(struct sk_buff *skb); | 65 | struct sk_buff *(*wrap)(struct gether *port, |
| 68 | int (*unwrap)(struct sk_buff *skb); | 66 | struct sk_buff *skb); |
| 67 | int (*unwrap)(struct gether *port, | ||
| 68 | struct sk_buff *skb, | ||
| 69 | struct sk_buff_head *list); | ||
| 69 | 70 | ||
| 70 | /* called on network open/close */ | 71 | /* called on network open/close */ |
| 71 | void (*open)(struct gether *); | 72 | void (*open)(struct gether *); |
| @@ -109,6 +110,7 @@ static inline bool can_support_ecm(struct usb_gadget *gadget) | |||
| 109 | /* each configuration may bind one instance of an ethernet link */ | 110 | /* each configuration may bind one instance of an ethernet link */ |
| 110 | int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); | 111 | int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); |
| 111 | int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); | 112 | int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); |
| 113 | int eem_bind_config(struct usb_configuration *c); | ||
| 112 | 114 | ||
| 113 | #ifdef CONFIG_USB_ETH_RNDIS | 115 | #ifdef CONFIG_USB_ETH_RNDIS |
| 114 | 116 | ||
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index fc6e709f45b1..adf8260c3a6a 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
| @@ -1114,7 +1114,6 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count) | |||
| 1114 | /* export the driver ... */ | 1114 | /* export the driver ... */ |
| 1115 | status = tty_register_driver(gs_tty_driver); | 1115 | status = tty_register_driver(gs_tty_driver); |
| 1116 | if (status) { | 1116 | if (status) { |
| 1117 | put_tty_driver(gs_tty_driver); | ||
| 1118 | pr_err("%s: cannot register, err %d\n", | 1117 | pr_err("%s: cannot register, err %d\n", |
| 1119 | __func__, status); | 1118 | __func__, status); |
| 1120 | goto fail; | 1119 | goto fail; |
