diff options
Diffstat (limited to 'drivers/usb')
54 files changed, 5838 insertions, 134 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index e0cad4418085..cf1b19bca306 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -92,6 +92,8 @@ source "drivers/usb/storage/Kconfig" | |||
92 | 92 | ||
93 | source "drivers/usb/image/Kconfig" | 93 | source "drivers/usb/image/Kconfig" |
94 | 94 | ||
95 | source "drivers/usb/usbip/Kconfig" | ||
96 | |||
95 | endif | 97 | endif |
96 | 98 | ||
97 | source "drivers/usb/musb/Kconfig" | 99 | source "drivers/usb/musb/Kconfig" |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 3cba892b83a2..d7be71778059 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -60,3 +60,5 @@ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ | |||
60 | obj-$(CONFIG_USB_GADGET) += gadget/ | 60 | obj-$(CONFIG_USB_GADGET) += gadget/ |
61 | 61 | ||
62 | obj-$(CONFIG_USB_COMMON) += common/ | 62 | obj-$(CONFIG_USB_COMMON) += common/ |
63 | |||
64 | obj-$(CONFIG_USBIP_CORE) += usbip/ | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8a4dcbc7a75f..46f5161c7891 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1728,8 +1728,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1728 | * - Change autosuspend delay of hub can avoid unnecessary auto | 1728 | * - Change autosuspend delay of hub can avoid unnecessary auto |
1729 | * suspend timer for hub, also may decrease power consumption | 1729 | * suspend timer for hub, also may decrease power consumption |
1730 | * of USB bus. | 1730 | * of USB bus. |
1731 | * | ||
1732 | * - If user has indicated to prevent autosuspend by passing | ||
1733 | * usbcore.autosuspend = -1 then keep autosuspend disabled. | ||
1731 | */ | 1734 | */ |
1732 | pm_runtime_set_autosuspend_delay(&hdev->dev, 0); | 1735 | #ifdef CONFIG_PM_RUNTIME |
1736 | if (hdev->dev.power.autosuspend_delay >= 0) | ||
1737 | pm_runtime_set_autosuspend_delay(&hdev->dev, 0); | ||
1738 | #endif | ||
1733 | 1739 | ||
1734 | /* | 1740 | /* |
1735 | * Hubs have proper suspend/resume support, except for root hubs | 1741 | * Hubs have proper suspend/resume support, except for root hubs |
@@ -2107,8 +2113,8 @@ void usb_disconnect(struct usb_device **pdev) | |||
2107 | { | 2113 | { |
2108 | struct usb_port *port_dev = NULL; | 2114 | struct usb_port *port_dev = NULL; |
2109 | struct usb_device *udev = *pdev; | 2115 | struct usb_device *udev = *pdev; |
2110 | struct usb_hub *hub; | 2116 | struct usb_hub *hub = NULL; |
2111 | int port1; | 2117 | int port1 = 1; |
2112 | 2118 | ||
2113 | /* mark the device as inactive, so any further urb submissions for | 2119 | /* mark the device as inactive, so any further urb submissions for |
2114 | * this device (and any of its children) will fail immediately. | 2120 | * this device (and any of its children) will fail immediately. |
@@ -4631,9 +4637,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, | |||
4631 | if (status != -ENODEV && | 4637 | if (status != -ENODEV && |
4632 | port1 != unreliable_port && | 4638 | port1 != unreliable_port && |
4633 | printk_ratelimit()) | 4639 | printk_ratelimit()) |
4634 | dev_err(&udev->dev, "connect-debounce failed, port %d disabled\n", | 4640 | dev_err(&port_dev->dev, "connect-debounce failed\n"); |
4635 | port1); | ||
4636 | |||
4637 | portstatus &= ~USB_PORT_STAT_CONNECTION; | 4641 | portstatus &= ~USB_PORT_STAT_CONNECTION; |
4638 | unreliable_port = port1; | 4642 | unreliable_port = port1; |
4639 | } else { | 4643 | } else { |
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 0ba9c335b584..7c9618e916e2 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -1901,7 +1901,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
1901 | static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) | 1901 | static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) |
1902 | { | 1902 | { |
1903 | u32 dsts = readl(hsotg->regs + DSTS); | 1903 | u32 dsts = readl(hsotg->regs + DSTS); |
1904 | int ep0_mps = 0, ep_mps; | 1904 | int ep0_mps = 0, ep_mps = 8; |
1905 | 1905 | ||
1906 | /* | 1906 | /* |
1907 | * This should signal the finish of the enumeration phase | 1907 | * This should signal the finish of the enumeration phase |
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index ef4936ff626c..9dcfbe7cd5f5 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
@@ -425,7 +425,7 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) | |||
425 | 425 | ||
426 | static int dwc3_omap_extcon_register(struct dwc3_omap *omap) | 426 | static int dwc3_omap_extcon_register(struct dwc3_omap *omap) |
427 | { | 427 | { |
428 | u32 ret; | 428 | int ret; |
429 | struct device_node *node = omap->dev->of_node; | 429 | struct device_node *node = omap->dev->of_node; |
430 | struct extcon_dev *edev; | 430 | struct extcon_dev *edev; |
431 | 431 | ||
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index a186afeaa700..9add915d41f7 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | subdir-ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG | 4 | subdir-ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG |
5 | subdir-ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG | 5 | subdir-ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG |
6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc | 6 | ccflags-y += -Idrivers/usb/gadget/udc |
7 | 7 | ||
8 | obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o | 8 | obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o |
9 | libcomposite-y := usbstring.o config.o epautoconf.o | 9 | libcomposite-y := usbstring.o config.o epautoconf.o |
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 6d91f21b52a6..83ae1065149d 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile | |||
@@ -2,8 +2,8 @@ | |||
2 | # USB peripheral controller drivers | 2 | # USB peripheral controller drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | ccflags-y := -I$(PWD)/drivers/usb/gadget/ | 5 | ccflags-y := -Idrivers/usb/gadget/ |
6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ | 6 | ccflags-y += -Idrivers/usb/gadget/udc/ |
7 | 7 | ||
8 | # USB Functions | 8 | # USB Functions |
9 | usb_f_acm-y := f_acm.o | 9 | usb_f_acm-y := f_acm.o |
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index d50adda913cf..6e6f87656e7b 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c | |||
@@ -1127,10 +1127,7 @@ void gether_disconnect(struct gether *link) | |||
1127 | 1127 | ||
1128 | DBG(dev, "%s\n", __func__); | 1128 | DBG(dev, "%s\n", __func__); |
1129 | 1129 | ||
1130 | netif_tx_lock(dev->net); | ||
1131 | netif_stop_queue(dev->net); | 1130 | netif_stop_queue(dev->net); |
1132 | netif_tx_unlock(dev->net); | ||
1133 | |||
1134 | netif_carrier_off(dev->net); | 1131 | netif_carrier_off(dev->net); |
1135 | 1132 | ||
1136 | /* disable endpoints, forcing (synchronous) completion | 1133 | /* disable endpoints, forcing (synchronous) completion |
diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 71e896d4c5ae..a5eb9a3fbb7a 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c | |||
@@ -195,6 +195,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) | |||
195 | printk(KERN_INFO "Failed to queue request (%d).\n", ret); | 195 | printk(KERN_INFO "Failed to queue request (%d).\n", ret); |
196 | usb_ep_set_halt(ep); | 196 | usb_ep_set_halt(ep); |
197 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 197 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
198 | uvc_queue_cancel(queue, 0); | ||
198 | goto requeue; | 199 | goto requeue; |
199 | } | 200 | } |
200 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 201 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
@@ -281,6 +282,7 @@ error: | |||
281 | static int | 282 | static int |
282 | uvc_video_pump(struct uvc_video *video) | 283 | uvc_video_pump(struct uvc_video *video) |
283 | { | 284 | { |
285 | struct uvc_video_queue *queue = &video->queue; | ||
284 | struct usb_request *req; | 286 | struct usb_request *req; |
285 | struct uvc_buffer *buf; | 287 | struct uvc_buffer *buf; |
286 | unsigned long flags; | 288 | unsigned long flags; |
@@ -322,6 +324,7 @@ uvc_video_pump(struct uvc_video *video) | |||
322 | printk(KERN_INFO "Failed to queue request (%d)\n", ret); | 324 | printk(KERN_INFO "Failed to queue request (%d)\n", ret); |
323 | usb_ep_set_halt(video->ep); | 325 | usb_ep_set_halt(video->ep); |
324 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 326 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
327 | uvc_queue_cancel(queue, 0); | ||
325 | break; | 328 | break; |
326 | } | 329 | } |
327 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 330 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
diff --git a/drivers/usb/gadget/legacy/Makefile b/drivers/usb/gadget/legacy/Makefile index a11aad5635df..edba2d1ee0f3 100644 --- a/drivers/usb/gadget/legacy/Makefile +++ b/drivers/usb/gadget/legacy/Makefile | |||
@@ -2,9 +2,9 @@ | |||
2 | # USB gadget drivers | 2 | # USB gadget drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | ccflags-y := -I$(PWD)/drivers/usb/gadget/ | 5 | ccflags-y := -Idrivers/usb/gadget/ |
6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ | 6 | ccflags-y += -Idrivers/usb/gadget/udc/ |
7 | ccflags-y += -I$(PWD)/drivers/usb/gadget/function/ | 7 | ccflags-y += -Idrivers/usb/gadget/function/ |
8 | 8 | ||
9 | g_zero-y := zero.o | 9 | g_zero-y := zero.o |
10 | g_audio-y := audio.o | 10 | g_audio-y := audio.o |
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 986fc511a2ed..225e385a6160 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c | |||
@@ -222,10 +222,12 @@ static void dbgp_unbind(struct usb_gadget *gadget) | |||
222 | { | 222 | { |
223 | #ifdef CONFIG_USB_G_DBGP_SERIAL | 223 | #ifdef CONFIG_USB_G_DBGP_SERIAL |
224 | kfree(dbgp.serial); | 224 | kfree(dbgp.serial); |
225 | dbgp.serial = NULL; | ||
225 | #endif | 226 | #endif |
226 | if (dbgp.req) { | 227 | if (dbgp.req) { |
227 | kfree(dbgp.req->buf); | 228 | kfree(dbgp.req->buf); |
228 | usb_ep_free_request(gadget->ep0, dbgp.req); | 229 | usb_ep_free_request(gadget->ep0, dbgp.req); |
230 | dbgp.req = NULL; | ||
229 | } | 231 | } |
230 | 232 | ||
231 | gadget->ep0->driver_data = NULL; | 233 | gadget->ep0->driver_data = NULL; |
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 2e4ce7704908..e96077b8bf79 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c | |||
@@ -440,7 +440,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
440 | 440 | ||
441 | value = -ENOMEM; | 441 | value = -ENOMEM; |
442 | kbuf = memdup_user(buf, len); | 442 | kbuf = memdup_user(buf, len); |
443 | if (!kbuf) { | 443 | if (IS_ERR(kbuf)) { |
444 | value = PTR_ERR(kbuf); | 444 | value = PTR_ERR(kbuf); |
445 | goto free1; | 445 | goto free1; |
446 | } | 446 | } |
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 5151f947a4f5..34ebaa68504c 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig | |||
@@ -332,7 +332,7 @@ config USB_GOKU | |||
332 | gadget drivers to also be dynamically linked. | 332 | gadget drivers to also be dynamically linked. |
333 | 333 | ||
334 | config USB_EG20T | 334 | config USB_EG20T |
335 | tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" | 335 | tristate "Intel QUARK X1000/EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" |
336 | depends on PCI | 336 | depends on PCI |
337 | help | 337 | help |
338 | This is a USB device driver for EG20T PCH. | 338 | This is a USB device driver for EG20T PCH. |
@@ -353,6 +353,7 @@ config USB_EG20T | |||
353 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. | 353 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. |
354 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. | 354 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. |
355 | 355 | ||
356 | This driver can be used with Intel's Quark X1000 SOC platform | ||
356 | # | 357 | # |
357 | # LAST -- dummy/emulated controller | 358 | # LAST -- dummy/emulated controller |
358 | # | 359 | # |
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 906e65f0e4fa..c9fe67e29d35 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
@@ -1661,7 +1661,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1661 | if (dma_status) { | 1661 | if (dma_status) { |
1662 | int i; | 1662 | int i; |
1663 | 1663 | ||
1664 | for (i = 1; i < USBA_NR_DMAS; i++) | 1664 | for (i = 1; i <= USBA_NR_DMAS; i++) |
1665 | if (dma_status & (1 << i)) | 1665 | if (dma_status & (1 << i)) |
1666 | usba_dma_irq(udc, &udc->usba_ep[i]); | 1666 | usba_dma_irq(udc, &udc->usba_ep[i]); |
1667 | } | 1667 | } |
diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index d40255f784df..5c5d1adda7eb 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c | |||
@@ -1398,13 +1398,17 @@ static int fusb300_probe(struct platform_device *pdev) | |||
1398 | 1398 | ||
1399 | /* initialize udc */ | 1399 | /* initialize udc */ |
1400 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); | 1400 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); |
1401 | if (fusb300 == NULL) | 1401 | if (fusb300 == NULL) { |
1402 | ret = -ENOMEM; | ||
1402 | goto clean_up; | 1403 | goto clean_up; |
1404 | } | ||
1403 | 1405 | ||
1404 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { | 1406 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { |
1405 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); | 1407 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); |
1406 | if (_ep[i] == NULL) | 1408 | if (_ep[i] == NULL) { |
1409 | ret = -ENOMEM; | ||
1407 | goto clean_up; | 1410 | goto clean_up; |
1411 | } | ||
1408 | fusb300->ep[i] = _ep[i]; | 1412 | fusb300->ep[i] = _ep[i]; |
1409 | } | 1413 | } |
1410 | 1414 | ||
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index eb8c3bedb57a..460d953c91b6 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c | |||
@@ -343,6 +343,7 @@ struct pch_vbus_gpio_data { | |||
343 | * @setup_data: Received setup data | 343 | * @setup_data: Received setup data |
344 | * @phys_addr: of device memory | 344 | * @phys_addr: of device memory |
345 | * @base_addr: for mapped device memory | 345 | * @base_addr: for mapped device memory |
346 | * @bar: Indicates which PCI BAR for USB regs | ||
346 | * @irq: IRQ line for the device | 347 | * @irq: IRQ line for the device |
347 | * @cfg_data: current cfg, intf, and alt in use | 348 | * @cfg_data: current cfg, intf, and alt in use |
348 | * @vbus_gpio: GPIO informaton for detecting VBUS | 349 | * @vbus_gpio: GPIO informaton for detecting VBUS |
@@ -370,14 +371,17 @@ struct pch_udc_dev { | |||
370 | struct usb_ctrlrequest setup_data; | 371 | struct usb_ctrlrequest setup_data; |
371 | unsigned long phys_addr; | 372 | unsigned long phys_addr; |
372 | void __iomem *base_addr; | 373 | void __iomem *base_addr; |
374 | unsigned bar; | ||
373 | unsigned irq; | 375 | unsigned irq; |
374 | struct pch_udc_cfg_data cfg_data; | 376 | struct pch_udc_cfg_data cfg_data; |
375 | struct pch_vbus_gpio_data vbus_gpio; | 377 | struct pch_vbus_gpio_data vbus_gpio; |
376 | }; | 378 | }; |
377 | #define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) | 379 | #define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) |
378 | 380 | ||
381 | #define PCH_UDC_PCI_BAR_QUARK_X1000 0 | ||
379 | #define PCH_UDC_PCI_BAR 1 | 382 | #define PCH_UDC_PCI_BAR 1 |
380 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 | 383 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 |
384 | #define PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC 0x0939 | ||
381 | #define PCI_VENDOR_ID_ROHM 0x10DB | 385 | #define PCI_VENDOR_ID_ROHM 0x10DB |
382 | #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D | 386 | #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D |
383 | #define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 | 387 | #define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 |
@@ -3076,7 +3080,7 @@ static void pch_udc_remove(struct pci_dev *pdev) | |||
3076 | iounmap(dev->base_addr); | 3080 | iounmap(dev->base_addr); |
3077 | if (dev->mem_region) | 3081 | if (dev->mem_region) |
3078 | release_mem_region(dev->phys_addr, | 3082 | release_mem_region(dev->phys_addr, |
3079 | pci_resource_len(pdev, PCH_UDC_PCI_BAR)); | 3083 | pci_resource_len(pdev, dev->bar)); |
3080 | if (dev->active) | 3084 | if (dev->active) |
3081 | pci_disable_device(pdev); | 3085 | pci_disable_device(pdev); |
3082 | kfree(dev); | 3086 | kfree(dev); |
@@ -3144,9 +3148,15 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
3144 | dev->active = 1; | 3148 | dev->active = 1; |
3145 | pci_set_drvdata(pdev, dev); | 3149 | pci_set_drvdata(pdev, dev); |
3146 | 3150 | ||
3151 | /* Determine BAR based on PCI ID */ | ||
3152 | if (id->device == PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC) | ||
3153 | dev->bar = PCH_UDC_PCI_BAR_QUARK_X1000; | ||
3154 | else | ||
3155 | dev->bar = PCH_UDC_PCI_BAR; | ||
3156 | |||
3147 | /* PCI resource allocation */ | 3157 | /* PCI resource allocation */ |
3148 | resource = pci_resource_start(pdev, 1); | 3158 | resource = pci_resource_start(pdev, dev->bar); |
3149 | len = pci_resource_len(pdev, 1); | 3159 | len = pci_resource_len(pdev, dev->bar); |
3150 | 3160 | ||
3151 | if (!request_mem_region(resource, len, KBUILD_MODNAME)) { | 3161 | if (!request_mem_region(resource, len, KBUILD_MODNAME)) { |
3152 | dev_err(&pdev->dev, "%s: pci device used already\n", __func__); | 3162 | dev_err(&pdev->dev, "%s: pci device used already\n", __func__); |
@@ -3212,6 +3222,12 @@ finished: | |||
3212 | 3222 | ||
3213 | static const struct pci_device_id pch_udc_pcidev_id[] = { | 3223 | static const struct pci_device_id pch_udc_pcidev_id[] = { |
3214 | { | 3224 | { |
3225 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
3226 | PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC), | ||
3227 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | ||
3228 | .class_mask = 0xffffffff, | ||
3229 | }, | ||
3230 | { | ||
3215 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EG20T_UDC), | 3231 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EG20T_UDC), |
3216 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | 3232 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, |
3217 | .class_mask = 0xffffffff, | 3233 | .class_mask = 0xffffffff, |
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index 46008421c1ec..de2a8713b428 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c | |||
@@ -1868,8 +1868,8 @@ static int r8a66597_probe(struct platform_device *pdev) | |||
1868 | 1868 | ||
1869 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1869 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1870 | reg = devm_ioremap_resource(&pdev->dev, res); | 1870 | reg = devm_ioremap_resource(&pdev->dev, res); |
1871 | if (!reg) | 1871 | if (IS_ERR(reg)) |
1872 | return -ENODEV; | 1872 | return PTR_ERR(reg); |
1873 | 1873 | ||
1874 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1874 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1875 | irq = ires->start; | 1875 | irq = ires->start; |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index cc305c71ac3d..6130b7574908 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -1230,7 +1230,7 @@ int ehci_hub_control( | |||
1230 | if (selector == EHSET_TEST_SINGLE_STEP_SET_FEATURE) { | 1230 | if (selector == EHSET_TEST_SINGLE_STEP_SET_FEATURE) { |
1231 | spin_unlock_irqrestore(&ehci->lock, flags); | 1231 | spin_unlock_irqrestore(&ehci->lock, flags); |
1232 | retval = ehset_single_step_set_feature(hcd, | 1232 | retval = ehset_single_step_set_feature(hcd, |
1233 | wIndex); | 1233 | wIndex + 1); |
1234 | spin_lock_irqsave(&ehci->lock, flags); | 1234 | spin_lock_irqsave(&ehci->lock, flags); |
1235 | break; | 1235 | break; |
1236 | } | 1236 | } |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 687d36608155..c22a3e15a16e 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -101,6 +101,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
101 | /* AMD PLL quirk */ | 101 | /* AMD PLL quirk */ |
102 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) | 102 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) |
103 | xhci->quirks |= XHCI_AMD_PLL_FIX; | 103 | xhci->quirks |= XHCI_AMD_PLL_FIX; |
104 | |||
105 | if (pdev->vendor == PCI_VENDOR_ID_AMD) | ||
106 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | ||
107 | |||
104 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { | 108 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { |
105 | xhci->quirks |= XHCI_LPM_SUPPORT; | 109 | xhci->quirks |= XHCI_LPM_SUPPORT; |
106 | xhci->quirks |= XHCI_INTEL_HOST; | 110 | xhci->quirks |= XHCI_INTEL_HOST; |
@@ -151,6 +155,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
151 | if (pdev->vendor == PCI_VENDOR_ID_VIA) | 155 | if (pdev->vendor == PCI_VENDOR_ID_VIA) |
152 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 156 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
153 | 157 | ||
158 | /* See https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ | ||
159 | if (pdev->vendor == PCI_VENDOR_ID_VIA && | ||
160 | pdev->device == 0x3432) | ||
161 | xhci->quirks |= XHCI_BROKEN_STREAMS; | ||
162 | |||
154 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 163 | if (xhci->quirks & XHCI_RESET_ON_RESUME) |
155 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, | 164 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, |
156 | "QUIRK: Resetting on resume"); | 165 | "QUIRK: Resetting on resume"); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 60fb52ae864b..abed30b82905 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -364,32 +364,6 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, | |||
364 | } | 364 | } |
365 | } | 365 | } |
366 | 366 | ||
367 | /* | ||
368 | * Find the segment that trb is in. Start searching in start_seg. | ||
369 | * If we must move past a segment that has a link TRB with a toggle cycle state | ||
370 | * bit set, then we will toggle the value pointed at by cycle_state. | ||
371 | */ | ||
372 | static struct xhci_segment *find_trb_seg( | ||
373 | struct xhci_segment *start_seg, | ||
374 | union xhci_trb *trb, int *cycle_state) | ||
375 | { | ||
376 | struct xhci_segment *cur_seg = start_seg; | ||
377 | struct xhci_generic_trb *generic_trb; | ||
378 | |||
379 | while (cur_seg->trbs > trb || | ||
380 | &cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) { | ||
381 | generic_trb = &cur_seg->trbs[TRBS_PER_SEGMENT - 1].generic; | ||
382 | if (generic_trb->field[3] & cpu_to_le32(LINK_TOGGLE)) | ||
383 | *cycle_state ^= 0x1; | ||
384 | cur_seg = cur_seg->next; | ||
385 | if (cur_seg == start_seg) | ||
386 | /* Looped over the entire list. Oops! */ | ||
387 | return NULL; | ||
388 | } | ||
389 | return cur_seg; | ||
390 | } | ||
391 | |||
392 | |||
393 | static struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci, | 367 | static struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci, |
394 | unsigned int slot_id, unsigned int ep_index, | 368 | unsigned int slot_id, unsigned int ep_index, |
395 | unsigned int stream_id) | 369 | unsigned int stream_id) |
@@ -459,9 +433,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, | |||
459 | struct xhci_virt_device *dev = xhci->devs[slot_id]; | 433 | struct xhci_virt_device *dev = xhci->devs[slot_id]; |
460 | struct xhci_virt_ep *ep = &dev->eps[ep_index]; | 434 | struct xhci_virt_ep *ep = &dev->eps[ep_index]; |
461 | struct xhci_ring *ep_ring; | 435 | struct xhci_ring *ep_ring; |
462 | struct xhci_generic_trb *trb; | 436 | struct xhci_segment *new_seg; |
437 | union xhci_trb *new_deq; | ||
463 | dma_addr_t addr; | 438 | dma_addr_t addr; |
464 | u64 hw_dequeue; | 439 | u64 hw_dequeue; |
440 | bool cycle_found = false; | ||
441 | bool td_last_trb_found = false; | ||
465 | 442 | ||
466 | ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, | 443 | ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, |
467 | ep_index, stream_id); | 444 | ep_index, stream_id); |
@@ -486,45 +463,45 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, | |||
486 | hw_dequeue = le64_to_cpu(ep_ctx->deq); | 463 | hw_dequeue = le64_to_cpu(ep_ctx->deq); |
487 | } | 464 | } |
488 | 465 | ||
489 | /* Find virtual address and segment of hardware dequeue pointer */ | 466 | new_seg = ep_ring->deq_seg; |
490 | state->new_deq_seg = ep_ring->deq_seg; | 467 | new_deq = ep_ring->dequeue; |
491 | state->new_deq_ptr = ep_ring->dequeue; | 468 | state->new_cycle_state = hw_dequeue & 0x1; |
492 | while (xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr) | 469 | |
493 | != (dma_addr_t)(hw_dequeue & ~0xf)) { | ||
494 | next_trb(xhci, ep_ring, &state->new_deq_seg, | ||
495 | &state->new_deq_ptr); | ||
496 | if (state->new_deq_ptr == ep_ring->dequeue) { | ||
497 | WARN_ON(1); | ||
498 | return; | ||
499 | } | ||
500 | } | ||
501 | /* | 470 | /* |
502 | * Find cycle state for last_trb, starting at old cycle state of | 471 | * We want to find the pointer, segment and cycle state of the new trb |
503 | * hw_dequeue. If there is only one segment ring, find_trb_seg() will | 472 | * (the one after current TD's last_trb). We know the cycle state at |
504 | * return immediately and cannot toggle the cycle state if this search | 473 | * hw_dequeue, so walk the ring until both hw_dequeue and last_trb are |
505 | * wraps around, so add one more toggle manually in that case. | 474 | * found. |
506 | */ | 475 | */ |
507 | state->new_cycle_state = hw_dequeue & 0x1; | 476 | do { |
508 | if (ep_ring->first_seg == ep_ring->first_seg->next && | 477 | if (!cycle_found && xhci_trb_virt_to_dma(new_seg, new_deq) |
509 | cur_td->last_trb < state->new_deq_ptr) | 478 | == (dma_addr_t)(hw_dequeue & ~0xf)) { |
510 | state->new_cycle_state ^= 0x1; | 479 | cycle_found = true; |
480 | if (td_last_trb_found) | ||
481 | break; | ||
482 | } | ||
483 | if (new_deq == cur_td->last_trb) | ||
484 | td_last_trb_found = true; | ||
511 | 485 | ||
512 | state->new_deq_ptr = cur_td->last_trb; | 486 | if (cycle_found && |
513 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 487 | TRB_TYPE_LINK_LE32(new_deq->generic.field[3]) && |
514 | "Finding segment containing last TRB in TD."); | 488 | new_deq->generic.field[3] & cpu_to_le32(LINK_TOGGLE)) |
515 | state->new_deq_seg = find_trb_seg(state->new_deq_seg, | 489 | state->new_cycle_state ^= 0x1; |
516 | state->new_deq_ptr, &state->new_cycle_state); | 490 | |
517 | if (!state->new_deq_seg) { | 491 | next_trb(xhci, ep_ring, &new_seg, &new_deq); |
518 | WARN_ON(1); | 492 | |
519 | return; | 493 | /* Search wrapped around, bail out */ |
520 | } | 494 | if (new_deq == ep->ring->dequeue) { |
495 | xhci_err(xhci, "Error: Failed finding new dequeue state\n"); | ||
496 | state->new_deq_seg = NULL; | ||
497 | state->new_deq_ptr = NULL; | ||
498 | return; | ||
499 | } | ||
500 | |||
501 | } while (!cycle_found || !td_last_trb_found); | ||
521 | 502 | ||
522 | /* Increment to find next TRB after last_trb. Cycle if appropriate. */ | 503 | state->new_deq_seg = new_seg; |
523 | trb = &state->new_deq_ptr->generic; | 504 | state->new_deq_ptr = new_deq; |
524 | if (TRB_TYPE_LINK_LE32(trb->field[3]) && | ||
525 | (trb->field[3] & cpu_to_le32(LINK_TOGGLE))) | ||
526 | state->new_cycle_state ^= 0x1; | ||
527 | next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); | ||
528 | 505 | ||
529 | /* Don't update the ring cycle state for the producer (us). */ | 506 | /* Don't update the ring cycle state for the producer (us). */ |
530 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 507 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
@@ -2487,7 +2464,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2487 | * last TRB of the previous TD. The command completion handle | 2464 | * last TRB of the previous TD. The command completion handle |
2488 | * will take care the rest. | 2465 | * will take care the rest. |
2489 | */ | 2466 | */ |
2490 | if (!event_seg && trb_comp_code == COMP_STOP_INVAL) { | 2467 | if (!event_seg && (trb_comp_code == COMP_STOP || |
2468 | trb_comp_code == COMP_STOP_INVAL)) { | ||
2491 | ret = 0; | 2469 | ret = 0; |
2492 | goto cleanup; | 2470 | goto cleanup; |
2493 | } | 2471 | } |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b6f21175b872..c020b094fe7d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -2880,6 +2880,9 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, | |||
2880 | ep_index, ep->stopped_stream, ep->stopped_td, | 2880 | ep_index, ep->stopped_stream, ep->stopped_td, |
2881 | &deq_state); | 2881 | &deq_state); |
2882 | 2882 | ||
2883 | if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg) | ||
2884 | return; | ||
2885 | |||
2883 | /* HW with the reset endpoint quirk will use the saved dequeue state to | 2886 | /* HW with the reset endpoint quirk will use the saved dequeue state to |
2884 | * issue a configure endpoint command later. | 2887 | * issue a configure endpoint command later. |
2885 | */ | 2888 | */ |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 06b5d77cd9ad..633caf643122 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -3250,6 +3250,7 @@ static const struct usb_device_id sisusb_table[] = { | |||
3250 | { USB_DEVICE(0x0711, 0x0918) }, | 3250 | { USB_DEVICE(0x0711, 0x0918) }, |
3251 | { USB_DEVICE(0x0711, 0x0920) }, | 3251 | { USB_DEVICE(0x0711, 0x0920) }, |
3252 | { USB_DEVICE(0x0711, 0x0950) }, | 3252 | { USB_DEVICE(0x0711, 0x0950) }, |
3253 | { USB_DEVICE(0x0711, 0x5200) }, | ||
3253 | { USB_DEVICE(0x182d, 0x021c) }, | 3254 | { USB_DEVICE(0x182d, 0x021c) }, |
3254 | { USB_DEVICE(0x182d, 0x0269) }, | 3255 | { USB_DEVICE(0x182d, 0x0269) }, |
3255 | { } | 3256 | { } |
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 9aad00f11bd5..221faed9f074 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c | |||
@@ -96,7 +96,7 @@ static bool ux500_configure_channel(struct dma_channel *channel, | |||
96 | struct musb *musb = ux500_channel->controller->private_data; | 96 | struct musb *musb = ux500_channel->controller->private_data; |
97 | 97 | ||
98 | dev_dbg(musb->controller, | 98 | dev_dbg(musb->controller, |
99 | "packet_sz=%d, mode=%d, dma_addr=0x%llu, len=%d is_tx=%d\n", | 99 | "packet_sz=%d, mode=%d, dma_addr=0x%llx, len=%d is_tx=%d\n", |
100 | packet_sz, mode, (unsigned long long) dma_addr, | 100 | packet_sz, mode, (unsigned long long) dma_addr, |
101 | len, ux500_channel->is_tx); | 101 | len, ux500_channel->is_tx); |
102 | 102 | ||
diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index ea9e705555df..f4b14bd97e14 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c | |||
@@ -260,10 +260,8 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
260 | 260 | ||
261 | gpio_vbus->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), | 261 | gpio_vbus->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), |
262 | GFP_KERNEL); | 262 | GFP_KERNEL); |
263 | if (!gpio_vbus->phy.otg) { | 263 | if (!gpio_vbus->phy.otg) |
264 | kfree(gpio_vbus); | ||
265 | return -ENOMEM; | 264 | return -ENOMEM; |
266 | } | ||
267 | 265 | ||
268 | platform_set_drvdata(pdev, gpio_vbus); | 266 | platform_set_drvdata(pdev, gpio_vbus); |
269 | gpio_vbus->dev = &pdev->dev; | 267 | gpio_vbus->dev = &pdev->dev; |
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index e4108eec5ef4..afc09087ec36 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
@@ -1601,8 +1601,8 @@ static int msm_otg_probe(struct platform_device *pdev) | |||
1601 | */ | 1601 | */ |
1602 | if (motg->phy_number) { | 1602 | if (motg->phy_number) { |
1603 | phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); | 1603 | phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); |
1604 | if (IS_ERR(phy_select)) | 1604 | if (!phy_select) |
1605 | return PTR_ERR(phy_select); | 1605 | return -ENOMEM; |
1606 | /* Enable second PHY with the OTG port */ | 1606 | /* Enable second PHY with the OTG port */ |
1607 | writel(0x1, phy_select); | 1607 | writel(0x1, phy_select); |
1608 | } | 1608 | } |
diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h index 68771bfd1825..80eedd45a20a 100644 --- a/drivers/usb/phy/phy-samsung-usb.h +++ b/drivers/usb/phy/phy-samsung-usb.h | |||
@@ -216,7 +216,7 @@ | |||
216 | 216 | ||
217 | #define EXYNOS5_DRD_PHYPARAM1 (0x20) | 217 | #define EXYNOS5_DRD_PHYPARAM1 (0x20) |
218 | 218 | ||
219 | #define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) | 219 | #define PHYPARAM1_PCS_TXDEEMPH_MASK (0x3f << 0) |
220 | #define PHYPARAM1_PCS_TXDEEMPH (0x1c) | 220 | #define PHYPARAM1_PCS_TXDEEMPH (0x1c) |
221 | 221 | ||
222 | #define EXYNOS5_DRD_PHYTERM (0x24) | 222 | #define EXYNOS5_DRD_PHYTERM (0x24) |
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 6d0f6080eceb..045cd309367a 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c | |||
@@ -232,6 +232,9 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) | |||
232 | phy = __usb_find_phy_dev(dev, &phy_bind_list, index); | 232 | phy = __usb_find_phy_dev(dev, &phy_bind_list, index); |
233 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { | 233 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { |
234 | dev_dbg(dev, "unable to find transceiver\n"); | 234 | dev_dbg(dev, "unable to find transceiver\n"); |
235 | if (!IS_ERR(phy)) | ||
236 | phy = ERR_PTR(-ENODEV); | ||
237 | |||
235 | goto err0; | 238 | goto err0; |
236 | } | 239 | } |
237 | 240 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 216ce3078270..824ea5e7ec8b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -146,6 +146,7 @@ static const struct usb_device_id id_table_combined[] = { | |||
146 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | 146 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, |
147 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | 147 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, |
148 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, | 148 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, |
149 | { USB_DEVICE(FTDI_VID, FTDI_BM_ATOM_NANO_PID) }, | ||
149 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, | 150 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, |
150 | { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, | 151 | { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, |
151 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, | 152 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, |
@@ -934,6 +935,8 @@ static const struct usb_device_id id_table_combined[] = { | |||
934 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, | 935 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, |
935 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, | 936 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, |
936 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) }, | 937 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) }, |
938 | /* ekey Devices */ | ||
939 | { USB_DEVICE(FTDI_VID, FTDI_EKEY_CONV_USB_PID) }, | ||
937 | /* Infineon Devices */ | 940 | /* Infineon Devices */ |
938 | { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, | 941 | { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, |
939 | { } /* Terminating entry */ | 942 | { } /* Terminating entry */ |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 1e58d90a0b6c..70b0b1d88ae9 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -42,6 +42,8 @@ | |||
42 | /* www.candapter.com Ewert Energy Systems CANdapter device */ | 42 | /* www.candapter.com Ewert Energy Systems CANdapter device */ |
43 | #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ | 43 | #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ |
44 | 44 | ||
45 | #define FTDI_BM_ATOM_NANO_PID 0xa559 /* Basic Micro ATOM Nano USB2Serial */ | ||
46 | |||
45 | /* | 47 | /* |
46 | * Texas Instruments XDS100v2 JTAG / BeagleBone A3 | 48 | * Texas Instruments XDS100v2 JTAG / BeagleBone A3 |
47 | * http://processors.wiki.ti.com/index.php/XDS100 | 49 | * http://processors.wiki.ti.com/index.php/XDS100 |
@@ -1378,3 +1380,8 @@ | |||
1378 | #define BRAINBOXES_US_160_6_PID 0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */ | 1380 | #define BRAINBOXES_US_160_6_PID 0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */ |
1379 | #define BRAINBOXES_US_160_7_PID 0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */ | 1381 | #define BRAINBOXES_US_160_7_PID 0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */ |
1380 | #define BRAINBOXES_US_160_8_PID 0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */ | 1382 | #define BRAINBOXES_US_160_8_PID 0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */ |
1383 | |||
1384 | /* | ||
1385 | * ekey biometric systems GmbH (http://ekey.net/) | ||
1386 | */ | ||
1387 | #define FTDI_EKEY_CONV_USB_PID 0xCB08 /* Converter USB */ | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a9688940543d..54a8120897a6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -275,8 +275,12 @@ static void option_instat_callback(struct urb *urb); | |||
275 | #define ZTE_PRODUCT_MF622 0x0001 | 275 | #define ZTE_PRODUCT_MF622 0x0001 |
276 | #define ZTE_PRODUCT_MF628 0x0015 | 276 | #define ZTE_PRODUCT_MF628 0x0015 |
277 | #define ZTE_PRODUCT_MF626 0x0031 | 277 | #define ZTE_PRODUCT_MF626 0x0031 |
278 | #define ZTE_PRODUCT_MC2718 0xffe8 | ||
279 | #define ZTE_PRODUCT_AC2726 0xfff1 | 278 | #define ZTE_PRODUCT_AC2726 0xfff1 |
279 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe | ||
280 | #define ZTE_PRODUCT_AC8710T 0xffff | ||
281 | #define ZTE_PRODUCT_MC2718 0xffe8 | ||
282 | #define ZTE_PRODUCT_AD3812 0xffeb | ||
283 | #define ZTE_PRODUCT_MC2716 0xffed | ||
280 | 284 | ||
281 | #define BENQ_VENDOR_ID 0x04a5 | 285 | #define BENQ_VENDOR_ID 0x04a5 |
282 | #define BENQ_PRODUCT_H10 0x4068 | 286 | #define BENQ_PRODUCT_H10 0x4068 |
@@ -494,6 +498,10 @@ static void option_instat_callback(struct urb *urb); | |||
494 | #define INOVIA_VENDOR_ID 0x20a6 | 498 | #define INOVIA_VENDOR_ID 0x20a6 |
495 | #define INOVIA_SEW858 0x1105 | 499 | #define INOVIA_SEW858 0x1105 |
496 | 500 | ||
501 | /* VIA Telecom */ | ||
502 | #define VIATELECOM_VENDOR_ID 0x15eb | ||
503 | #define VIATELECOM_PRODUCT_CDS7 0x0001 | ||
504 | |||
497 | /* some devices interfaces need special handling due to a number of reasons */ | 505 | /* some devices interfaces need special handling due to a number of reasons */ |
498 | enum option_blacklist_reason { | 506 | enum option_blacklist_reason { |
499 | OPTION_BLACKLIST_NONE = 0, | 507 | OPTION_BLACKLIST_NONE = 0, |
@@ -527,10 +535,18 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = { | |||
527 | .reserved = BIT(4), | 535 | .reserved = BIT(4), |
528 | }; | 536 | }; |
529 | 537 | ||
538 | static const struct option_blacklist_info zte_ad3812_z_blacklist = { | ||
539 | .sendsetup = BIT(0) | BIT(1) | BIT(2), | ||
540 | }; | ||
541 | |||
530 | static const struct option_blacklist_info zte_mc2718_z_blacklist = { | 542 | static const struct option_blacklist_info zte_mc2718_z_blacklist = { |
531 | .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), | 543 | .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), |
532 | }; | 544 | }; |
533 | 545 | ||
546 | static const struct option_blacklist_info zte_mc2716_z_blacklist = { | ||
547 | .sendsetup = BIT(1) | BIT(2) | BIT(3), | ||
548 | }; | ||
549 | |||
534 | static const struct option_blacklist_info huawei_cdc12_blacklist = { | 550 | static const struct option_blacklist_info huawei_cdc12_blacklist = { |
535 | .reserved = BIT(1) | BIT(2), | 551 | .reserved = BIT(1) | BIT(2), |
536 | }; | 552 | }; |
@@ -1070,6 +1086,7 @@ static const struct usb_device_id option_ids[] = { | |||
1070 | { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) }, | 1086 | { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) }, |
1071 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, | 1087 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, |
1072 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | 1088 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, |
1089 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ | ||
1073 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 1090 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
1074 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ | 1091 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ |
1075 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ | 1092 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ |
@@ -1544,13 +1561,18 @@ static const struct usb_device_id option_ids[] = { | |||
1544 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, | 1561 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, |
1545 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, | 1562 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, |
1546 | 1563 | ||
1547 | /* NOTE: most ZTE CDMA devices should be driven by zte_ev, not option */ | 1564 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, |
1565 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | ||
1566 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, | ||
1548 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), | 1567 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), |
1549 | .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, | 1568 | .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, |
1569 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), | ||
1570 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, | ||
1571 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), | ||
1572 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, | ||
1550 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, | 1573 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, |
1551 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, | 1574 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, |
1552 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, | 1575 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, |
1553 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | ||
1554 | 1576 | ||
1555 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 1577 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
1556 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 1578 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
@@ -1724,6 +1746,7 @@ static const struct usb_device_id option_ids[] = { | |||
1724 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ | 1746 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ |
1725 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ | 1747 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ |
1726 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, | 1748 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, |
1749 | { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, | ||
1727 | { } /* Terminating entry */ | 1750 | { } /* Terminating entry */ |
1728 | }; | 1751 | }; |
1729 | MODULE_DEVICE_TABLE(usb, option_ids); | 1752 | MODULE_DEVICE_TABLE(usb, option_ids); |
@@ -1916,6 +1939,8 @@ static void option_instat_callback(struct urb *urb) | |||
1916 | dev_dbg(dev, "%s: type %x req %x\n", __func__, | 1939 | dev_dbg(dev, "%s: type %x req %x\n", __func__, |
1917 | req_pkt->bRequestType, req_pkt->bRequest); | 1940 | req_pkt->bRequestType, req_pkt->bRequest); |
1918 | } | 1941 | } |
1942 | } else if (status == -ENOENT || status == -ESHUTDOWN) { | ||
1943 | dev_dbg(dev, "%s: urb stopped: %d\n", __func__, status); | ||
1919 | } else | 1944 | } else |
1920 | dev_err(dev, "%s: error %d\n", __func__, status); | 1945 | dev_err(dev, "%s: error %d\n", __func__, status); |
1921 | 1946 | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index b3d5a35c0d4b..e9bad928039f 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -45,6 +45,7 @@ static const struct usb_device_id id_table[] = { | |||
45 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) }, | 45 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) }, |
46 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, | 46 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, |
47 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, | 47 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, |
48 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ZTEK) }, | ||
48 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, | 49 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, |
49 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, | 50 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, |
50 | { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, | 51 | { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 42bc082896ac..71fd9da1d6e7 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define PL2303_PRODUCT_ID_GPRS 0x0609 | 22 | #define PL2303_PRODUCT_ID_GPRS 0x0609 |
23 | #define PL2303_PRODUCT_ID_HCR331 0x331a | 23 | #define PL2303_PRODUCT_ID_HCR331 0x331a |
24 | #define PL2303_PRODUCT_ID_MOTOROLA 0x0307 | 24 | #define PL2303_PRODUCT_ID_MOTOROLA 0x0307 |
25 | #define PL2303_PRODUCT_ID_ZTEK 0xe1f1 | ||
25 | 26 | ||
26 | #define ATEN_VENDOR_ID 0x0557 | 27 | #define ATEN_VENDOR_ID 0x0557 |
27 | #define ATEN_VENDOR_ID2 0x0547 | 28 | #define ATEN_VENDOR_ID2 0x0547 |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 02de3110fe94..475723c006f9 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -764,29 +764,39 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
764 | if (usb_endpoint_is_bulk_in(endpoint)) { | 764 | if (usb_endpoint_is_bulk_in(endpoint)) { |
765 | /* we found a bulk in endpoint */ | 765 | /* we found a bulk in endpoint */ |
766 | dev_dbg(ddev, "found bulk in on endpoint %d\n", i); | 766 | dev_dbg(ddev, "found bulk in on endpoint %d\n", i); |
767 | bulk_in_endpoint[num_bulk_in] = endpoint; | 767 | if (num_bulk_in < MAX_NUM_PORTS) { |
768 | ++num_bulk_in; | 768 | bulk_in_endpoint[num_bulk_in] = endpoint; |
769 | ++num_bulk_in; | ||
770 | } | ||
769 | } | 771 | } |
770 | 772 | ||
771 | if (usb_endpoint_is_bulk_out(endpoint)) { | 773 | if (usb_endpoint_is_bulk_out(endpoint)) { |
772 | /* we found a bulk out endpoint */ | 774 | /* we found a bulk out endpoint */ |
773 | dev_dbg(ddev, "found bulk out on endpoint %d\n", i); | 775 | dev_dbg(ddev, "found bulk out on endpoint %d\n", i); |
774 | bulk_out_endpoint[num_bulk_out] = endpoint; | 776 | if (num_bulk_out < MAX_NUM_PORTS) { |
775 | ++num_bulk_out; | 777 | bulk_out_endpoint[num_bulk_out] = endpoint; |
778 | ++num_bulk_out; | ||
779 | } | ||
776 | } | 780 | } |
777 | 781 | ||
778 | if (usb_endpoint_is_int_in(endpoint)) { | 782 | if (usb_endpoint_is_int_in(endpoint)) { |
779 | /* we found a interrupt in endpoint */ | 783 | /* we found a interrupt in endpoint */ |
780 | dev_dbg(ddev, "found interrupt in on endpoint %d\n", i); | 784 | dev_dbg(ddev, "found interrupt in on endpoint %d\n", i); |
781 | interrupt_in_endpoint[num_interrupt_in] = endpoint; | 785 | if (num_interrupt_in < MAX_NUM_PORTS) { |
782 | ++num_interrupt_in; | 786 | interrupt_in_endpoint[num_interrupt_in] = |
787 | endpoint; | ||
788 | ++num_interrupt_in; | ||
789 | } | ||
783 | } | 790 | } |
784 | 791 | ||
785 | if (usb_endpoint_is_int_out(endpoint)) { | 792 | if (usb_endpoint_is_int_out(endpoint)) { |
786 | /* we found an interrupt out endpoint */ | 793 | /* we found an interrupt out endpoint */ |
787 | dev_dbg(ddev, "found interrupt out on endpoint %d\n", i); | 794 | dev_dbg(ddev, "found interrupt out on endpoint %d\n", i); |
788 | interrupt_out_endpoint[num_interrupt_out] = endpoint; | 795 | if (num_interrupt_out < MAX_NUM_PORTS) { |
789 | ++num_interrupt_out; | 796 | interrupt_out_endpoint[num_interrupt_out] = |
797 | endpoint; | ||
798 | ++num_interrupt_out; | ||
799 | } | ||
790 | } | 800 | } |
791 | } | 801 | } |
792 | 802 | ||
@@ -809,8 +819,10 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
809 | if (usb_endpoint_is_int_in(endpoint)) { | 819 | if (usb_endpoint_is_int_in(endpoint)) { |
810 | /* we found a interrupt in endpoint */ | 820 | /* we found a interrupt in endpoint */ |
811 | dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n"); | 821 | dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n"); |
812 | interrupt_in_endpoint[num_interrupt_in] = endpoint; | 822 | if (num_interrupt_in < MAX_NUM_PORTS) { |
813 | ++num_interrupt_in; | 823 | interrupt_in_endpoint[num_interrupt_in] = endpoint; |
824 | ++num_interrupt_in; | ||
825 | } | ||
814 | } | 826 | } |
815 | } | 827 | } |
816 | } | 828 | } |
@@ -850,6 +862,11 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
850 | num_ports = type->num_ports; | 862 | num_ports = type->num_ports; |
851 | } | 863 | } |
852 | 864 | ||
865 | if (num_ports > MAX_NUM_PORTS) { | ||
866 | dev_warn(ddev, "too many ports requested: %d\n", num_ports); | ||
867 | num_ports = MAX_NUM_PORTS; | ||
868 | } | ||
869 | |||
853 | serial->num_ports = num_ports; | 870 | serial->num_ports = num_ports; |
854 | serial->num_bulk_in = num_bulk_in; | 871 | serial->num_bulk_in = num_bulk_in; |
855 | serial->num_bulk_out = num_bulk_out; | 872 | serial->num_bulk_out = num_bulk_out; |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index e62f2dff8b7d..6c3734d2b45a 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -514,6 +514,10 @@ static void command_port_read_callback(struct urb *urb) | |||
514 | dev_dbg(&urb->dev->dev, "%s - command_info is NULL, exiting.\n", __func__); | 514 | dev_dbg(&urb->dev->dev, "%s - command_info is NULL, exiting.\n", __func__); |
515 | return; | 515 | return; |
516 | } | 516 | } |
517 | if (!urb->actual_length) { | ||
518 | dev_dbg(&urb->dev->dev, "%s - empty response, exiting.\n", __func__); | ||
519 | return; | ||
520 | } | ||
517 | if (status) { | 521 | if (status) { |
518 | dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", __func__, status); | 522 | dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", __func__, status); |
519 | if (status != -ENOENT) | 523 | if (status != -ENOENT) |
@@ -534,7 +538,8 @@ static void command_port_read_callback(struct urb *urb) | |||
534 | /* These are unsolicited reports from the firmware, hence no | 538 | /* These are unsolicited reports from the firmware, hence no |
535 | waiting command to wakeup */ | 539 | waiting command to wakeup */ |
536 | dev_dbg(&urb->dev->dev, "%s - event received\n", __func__); | 540 | dev_dbg(&urb->dev->dev, "%s - event received\n", __func__); |
537 | } else if (data[0] == WHITEHEAT_GET_DTR_RTS) { | 541 | } else if ((data[0] == WHITEHEAT_GET_DTR_RTS) && |
542 | (urb->actual_length - 1 <= sizeof(command_info->result_buffer))) { | ||
538 | memcpy(command_info->result_buffer, &data[1], | 543 | memcpy(command_info->result_buffer, &data[1], |
539 | urb->actual_length - 1); | 544 | urb->actual_length - 1); |
540 | command_info->command_finished = WHITEHEAT_CMD_COMPLETE; | 545 | command_info->command_finished = WHITEHEAT_CMD_COMPLETE; |
diff --git a/drivers/usb/serial/zte_ev.c b/drivers/usb/serial/zte_ev.c index e40ab739c4a6..1a132e9e947a 100644 --- a/drivers/usb/serial/zte_ev.c +++ b/drivers/usb/serial/zte_ev.c | |||
@@ -272,28 +272,8 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) | |||
272 | } | 272 | } |
273 | 273 | ||
274 | static const struct usb_device_id id_table[] = { | 274 | static const struct usb_device_id id_table[] = { |
275 | /* AC8710, AC8710T */ | ||
276 | { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) }, | ||
277 | /* AC8700 */ | ||
278 | { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) }, | ||
279 | /* MG880 */ | 275 | /* MG880 */ |
280 | { USB_DEVICE(0x19d2, 0xfffd) }, | 276 | { USB_DEVICE(0x19d2, 0xfffd) }, |
281 | { USB_DEVICE(0x19d2, 0xfffc) }, | ||
282 | { USB_DEVICE(0x19d2, 0xfffb) }, | ||
283 | /* AC8710_V3 */ | ||
284 | { USB_DEVICE(0x19d2, 0xfff6) }, | ||
285 | { USB_DEVICE(0x19d2, 0xfff7) }, | ||
286 | { USB_DEVICE(0x19d2, 0xfff8) }, | ||
287 | { USB_DEVICE(0x19d2, 0xfff9) }, | ||
288 | { USB_DEVICE(0x19d2, 0xffee) }, | ||
289 | /* AC2716, MC2716 */ | ||
290 | { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) }, | ||
291 | /* AD3812 */ | ||
292 | { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) }, | ||
293 | { USB_DEVICE(0x19d2, 0xffec) }, | ||
294 | { USB_DEVICE(0x05C6, 0x3197) }, | ||
295 | { USB_DEVICE(0x05C6, 0x6000) }, | ||
296 | { USB_DEVICE(0x05C6, 0x9008) }, | ||
297 | { }, | 277 | { }, |
298 | }; | 278 | }; |
299 | MODULE_DEVICE_TABLE(usb, id_table); | 279 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 80a5b366255f..7ef99b2f3aaf 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -922,6 +922,12 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, | |||
922 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 922 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
923 | US_FL_FIX_CAPACITY ), | 923 | US_FL_FIX_CAPACITY ), |
924 | 924 | ||
925 | UNUSUAL_DEV( 0x06ca, 0x2003, 0x0100, 0x0100, | ||
926 | "Newer Technology", | ||
927 | "uSCSI", | ||
928 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, | ||
929 | US_FL_SCM_MULT_TARG ), | ||
930 | |||
925 | /* Reported by Adrian Pilchowiec <adi1981@epf.pl> */ | 931 | /* Reported by Adrian Pilchowiec <adi1981@epf.pl> */ |
926 | UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, | 932 | UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, |
927 | "RockChip", | 933 | "RockChip", |
diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig new file mode 100644 index 000000000000..bd99e9e47e50 --- /dev/null +++ b/drivers/usb/usbip/Kconfig | |||
@@ -0,0 +1,41 @@ | |||
1 | config USBIP_CORE | ||
2 | tristate "USB/IP support" | ||
3 | depends on USB && NET | ||
4 | ---help--- | ||
5 | This enables pushing USB packets over IP to allow remote | ||
6 | machines direct access to USB devices. It provides the | ||
7 | USB/IP core that is required by both drivers. | ||
8 | |||
9 | For more details, and to get the userspace utility | ||
10 | programs, please see <http://usbip.sourceforge.net/>. | ||
11 | |||
12 | To compile this as a module, choose M here: the module will | ||
13 | be called usbip-core. | ||
14 | |||
15 | If unsure, say N. | ||
16 | |||
17 | config USBIP_VHCI_HCD | ||
18 | tristate "VHCI hcd" | ||
19 | depends on USBIP_CORE | ||
20 | ---help--- | ||
21 | This enables the USB/IP virtual host controller driver, | ||
22 | which is run on the remote machine. | ||
23 | |||
24 | To compile this driver as a module, choose M here: the | ||
25 | module will be called vhci-hcd. | ||
26 | |||
27 | config USBIP_HOST | ||
28 | tristate "Host driver" | ||
29 | depends on USBIP_CORE | ||
30 | ---help--- | ||
31 | This enables the USB/IP host driver, which is run on the | ||
32 | machine that is sharing the USB devices. | ||
33 | |||
34 | To compile this driver as a module, choose M here: the | ||
35 | module will be called usbip-host. | ||
36 | |||
37 | config USBIP_DEBUG | ||
38 | bool "Debug messages for USB/IP" | ||
39 | depends on USBIP_CORE | ||
40 | ---help--- | ||
41 | This enables the debug messages from the USB/IP drivers. | ||
diff --git a/drivers/usb/usbip/Makefile b/drivers/usb/usbip/Makefile new file mode 100644 index 000000000000..9ecd61545be1 --- /dev/null +++ b/drivers/usb/usbip/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | ccflags-$(CONFIG_USBIP_DEBUG) := -DDEBUG | ||
2 | |||
3 | obj-$(CONFIG_USBIP_CORE) += usbip-core.o | ||
4 | usbip-core-y := usbip_common.o usbip_event.o | ||
5 | |||
6 | obj-$(CONFIG_USBIP_VHCI_HCD) += vhci-hcd.o | ||
7 | vhci-hcd-y := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o | ||
8 | |||
9 | obj-$(CONFIG_USBIP_HOST) += usbip-host.o | ||
10 | usbip-host-y := stub_dev.o stub_main.o stub_rx.o stub_tx.o | ||
diff --git a/drivers/usb/usbip/README b/drivers/usb/usbip/README new file mode 100644 index 000000000000..41a2cf2e77a6 --- /dev/null +++ b/drivers/usb/usbip/README | |||
@@ -0,0 +1,7 @@ | |||
1 | TODO: | ||
2 | - more discussion about the protocol | ||
3 | - testing | ||
4 | - review of the userspace interface | ||
5 | - document the protocol | ||
6 | |||
7 | Please send patches for this code to Greg Kroah-Hartman <greg@kroah.com> | ||
diff --git a/drivers/usb/usbip/stub.h b/drivers/usb/usbip/stub.h new file mode 100644 index 000000000000..266e2b0ce9a8 --- /dev/null +++ b/drivers/usb/usbip/stub.h | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef __USBIP_STUB_H | ||
21 | #define __USBIP_STUB_H | ||
22 | |||
23 | #include <linux/list.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/usb.h> | ||
28 | #include <linux/wait.h> | ||
29 | |||
30 | #define STUB_BUSID_OTHER 0 | ||
31 | #define STUB_BUSID_REMOV 1 | ||
32 | #define STUB_BUSID_ADDED 2 | ||
33 | #define STUB_BUSID_ALLOC 3 | ||
34 | |||
35 | struct stub_device { | ||
36 | struct usb_interface *interface; | ||
37 | struct usb_device *udev; | ||
38 | |||
39 | struct usbip_device ud; | ||
40 | __u32 devid; | ||
41 | |||
42 | /* | ||
43 | * stub_priv preserves private data of each urb. | ||
44 | * It is allocated as stub_priv_cache and assigned to urb->context. | ||
45 | * | ||
46 | * stub_priv is always linked to any one of 3 lists; | ||
47 | * priv_init: linked to this until the comletion of a urb. | ||
48 | * priv_tx : linked to this after the completion of a urb. | ||
49 | * priv_free: linked to this after the sending of the result. | ||
50 | * | ||
51 | * Any of these list operations should be locked by priv_lock. | ||
52 | */ | ||
53 | spinlock_t priv_lock; | ||
54 | struct list_head priv_init; | ||
55 | struct list_head priv_tx; | ||
56 | struct list_head priv_free; | ||
57 | |||
58 | /* see comments for unlinking in stub_rx.c */ | ||
59 | struct list_head unlink_tx; | ||
60 | struct list_head unlink_free; | ||
61 | |||
62 | wait_queue_head_t tx_waitq; | ||
63 | }; | ||
64 | |||
65 | /* private data into urb->priv */ | ||
66 | struct stub_priv { | ||
67 | unsigned long seqnum; | ||
68 | struct list_head list; | ||
69 | struct stub_device *sdev; | ||
70 | struct urb *urb; | ||
71 | |||
72 | int unlinking; | ||
73 | }; | ||
74 | |||
75 | struct stub_unlink { | ||
76 | unsigned long seqnum; | ||
77 | struct list_head list; | ||
78 | __u32 status; | ||
79 | }; | ||
80 | |||
81 | /* same as SYSFS_BUS_ID_SIZE */ | ||
82 | #define BUSID_SIZE 32 | ||
83 | |||
84 | struct bus_id_priv { | ||
85 | char name[BUSID_SIZE]; | ||
86 | char status; | ||
87 | int interf_count; | ||
88 | struct stub_device *sdev; | ||
89 | struct usb_device *udev; | ||
90 | char shutdown_busid; | ||
91 | }; | ||
92 | |||
93 | /* stub_priv is allocated from stub_priv_cache */ | ||
94 | extern struct kmem_cache *stub_priv_cache; | ||
95 | |||
96 | /* stub_dev.c */ | ||
97 | extern struct usb_device_driver stub_driver; | ||
98 | |||
99 | /* stub_main.c */ | ||
100 | struct bus_id_priv *get_busid_priv(const char *busid); | ||
101 | int del_match_busid(char *busid); | ||
102 | void stub_device_cleanup_urbs(struct stub_device *sdev); | ||
103 | |||
104 | /* stub_rx.c */ | ||
105 | int stub_rx_loop(void *data); | ||
106 | |||
107 | /* stub_tx.c */ | ||
108 | void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, | ||
109 | __u32 status); | ||
110 | void stub_complete(struct urb *urb); | ||
111 | int stub_tx_loop(void *data); | ||
112 | |||
113 | #endif /* __USBIP_STUB_H */ | ||
diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c new file mode 100644 index 000000000000..fac20e0434c0 --- /dev/null +++ b/drivers/usb/usbip/stub_dev.c | |||
@@ -0,0 +1,498 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/device.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/kthread.h> | ||
23 | #include <linux/module.h> | ||
24 | |||
25 | #include "usbip_common.h" | ||
26 | #include "stub.h" | ||
27 | |||
28 | /* | ||
29 | * usbip_status shows the status of usbip-host as long as this driver is bound | ||
30 | * to the target device. | ||
31 | */ | ||
32 | static ssize_t usbip_status_show(struct device *dev, | ||
33 | struct device_attribute *attr, char *buf) | ||
34 | { | ||
35 | struct stub_device *sdev = dev_get_drvdata(dev); | ||
36 | int status; | ||
37 | |||
38 | if (!sdev) { | ||
39 | dev_err(dev, "sdev is null\n"); | ||
40 | return -ENODEV; | ||
41 | } | ||
42 | |||
43 | spin_lock_irq(&sdev->ud.lock); | ||
44 | status = sdev->ud.status; | ||
45 | spin_unlock_irq(&sdev->ud.lock); | ||
46 | |||
47 | return snprintf(buf, PAGE_SIZE, "%d\n", status); | ||
48 | } | ||
49 | static DEVICE_ATTR_RO(usbip_status); | ||
50 | |||
51 | /* | ||
52 | * usbip_sockfd gets a socket descriptor of an established TCP connection that | ||
53 | * is used to transfer usbip requests by kernel threads. -1 is a magic number | ||
54 | * by which usbip connection is finished. | ||
55 | */ | ||
56 | static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, | ||
57 | const char *buf, size_t count) | ||
58 | { | ||
59 | struct stub_device *sdev = dev_get_drvdata(dev); | ||
60 | int sockfd = 0; | ||
61 | struct socket *socket; | ||
62 | int rv; | ||
63 | |||
64 | if (!sdev) { | ||
65 | dev_err(dev, "sdev is null\n"); | ||
66 | return -ENODEV; | ||
67 | } | ||
68 | |||
69 | rv = sscanf(buf, "%d", &sockfd); | ||
70 | if (rv != 1) | ||
71 | return -EINVAL; | ||
72 | |||
73 | if (sockfd != -1) { | ||
74 | int err; | ||
75 | |||
76 | dev_info(dev, "stub up\n"); | ||
77 | |||
78 | spin_lock_irq(&sdev->ud.lock); | ||
79 | |||
80 | if (sdev->ud.status != SDEV_ST_AVAILABLE) { | ||
81 | dev_err(dev, "not ready\n"); | ||
82 | goto err; | ||
83 | } | ||
84 | |||
85 | socket = sockfd_lookup(sockfd, &err); | ||
86 | if (!socket) | ||
87 | goto err; | ||
88 | |||
89 | sdev->ud.tcp_socket = socket; | ||
90 | |||
91 | spin_unlock_irq(&sdev->ud.lock); | ||
92 | |||
93 | sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, | ||
94 | "stub_rx"); | ||
95 | sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, | ||
96 | "stub_tx"); | ||
97 | |||
98 | spin_lock_irq(&sdev->ud.lock); | ||
99 | sdev->ud.status = SDEV_ST_USED; | ||
100 | spin_unlock_irq(&sdev->ud.lock); | ||
101 | |||
102 | } else { | ||
103 | dev_info(dev, "stub down\n"); | ||
104 | |||
105 | spin_lock_irq(&sdev->ud.lock); | ||
106 | if (sdev->ud.status != SDEV_ST_USED) | ||
107 | goto err; | ||
108 | |||
109 | spin_unlock_irq(&sdev->ud.lock); | ||
110 | |||
111 | usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN); | ||
112 | } | ||
113 | |||
114 | return count; | ||
115 | |||
116 | err: | ||
117 | spin_unlock_irq(&sdev->ud.lock); | ||
118 | return -EINVAL; | ||
119 | } | ||
120 | static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd); | ||
121 | |||
122 | static int stub_add_files(struct device *dev) | ||
123 | { | ||
124 | int err = 0; | ||
125 | |||
126 | err = device_create_file(dev, &dev_attr_usbip_status); | ||
127 | if (err) | ||
128 | goto err_status; | ||
129 | |||
130 | err = device_create_file(dev, &dev_attr_usbip_sockfd); | ||
131 | if (err) | ||
132 | goto err_sockfd; | ||
133 | |||
134 | err = device_create_file(dev, &dev_attr_usbip_debug); | ||
135 | if (err) | ||
136 | goto err_debug; | ||
137 | |||
138 | return 0; | ||
139 | |||
140 | err_debug: | ||
141 | device_remove_file(dev, &dev_attr_usbip_sockfd); | ||
142 | err_sockfd: | ||
143 | device_remove_file(dev, &dev_attr_usbip_status); | ||
144 | err_status: | ||
145 | return err; | ||
146 | } | ||
147 | |||
148 | static void stub_remove_files(struct device *dev) | ||
149 | { | ||
150 | device_remove_file(dev, &dev_attr_usbip_status); | ||
151 | device_remove_file(dev, &dev_attr_usbip_sockfd); | ||
152 | device_remove_file(dev, &dev_attr_usbip_debug); | ||
153 | } | ||
154 | |||
155 | static void stub_shutdown_connection(struct usbip_device *ud) | ||
156 | { | ||
157 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); | ||
158 | |||
159 | /* | ||
160 | * When removing an exported device, kernel panic sometimes occurred | ||
161 | * and then EIP was sk_wait_data of stub_rx thread. Is this because | ||
162 | * sk_wait_data returned though stub_rx thread was already finished by | ||
163 | * step 1? | ||
164 | */ | ||
165 | if (ud->tcp_socket) { | ||
166 | dev_dbg(&sdev->udev->dev, "shutdown tcp_socket %p\n", | ||
167 | ud->tcp_socket); | ||
168 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); | ||
169 | } | ||
170 | |||
171 | /* 1. stop threads */ | ||
172 | if (ud->tcp_rx) { | ||
173 | kthread_stop_put(ud->tcp_rx); | ||
174 | ud->tcp_rx = NULL; | ||
175 | } | ||
176 | if (ud->tcp_tx) { | ||
177 | kthread_stop_put(ud->tcp_tx); | ||
178 | ud->tcp_tx = NULL; | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * 2. close the socket | ||
183 | * | ||
184 | * tcp_socket is freed after threads are killed so that usbip_xmit does | ||
185 | * not touch NULL socket. | ||
186 | */ | ||
187 | if (ud->tcp_socket) { | ||
188 | sockfd_put(ud->tcp_socket); | ||
189 | ud->tcp_socket = NULL; | ||
190 | } | ||
191 | |||
192 | /* 3. free used data */ | ||
193 | stub_device_cleanup_urbs(sdev); | ||
194 | |||
195 | /* 4. free stub_unlink */ | ||
196 | { | ||
197 | unsigned long flags; | ||
198 | struct stub_unlink *unlink, *tmp; | ||
199 | |||
200 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
201 | list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) { | ||
202 | list_del(&unlink->list); | ||
203 | kfree(unlink); | ||
204 | } | ||
205 | list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, | ||
206 | list) { | ||
207 | list_del(&unlink->list); | ||
208 | kfree(unlink); | ||
209 | } | ||
210 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static void stub_device_reset(struct usbip_device *ud) | ||
215 | { | ||
216 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); | ||
217 | struct usb_device *udev = sdev->udev; | ||
218 | int ret; | ||
219 | |||
220 | dev_dbg(&udev->dev, "device reset"); | ||
221 | |||
222 | ret = usb_lock_device_for_reset(udev, sdev->interface); | ||
223 | if (ret < 0) { | ||
224 | dev_err(&udev->dev, "lock for reset\n"); | ||
225 | spin_lock_irq(&ud->lock); | ||
226 | ud->status = SDEV_ST_ERROR; | ||
227 | spin_unlock_irq(&ud->lock); | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | /* try to reset the device */ | ||
232 | ret = usb_reset_device(udev); | ||
233 | usb_unlock_device(udev); | ||
234 | |||
235 | spin_lock_irq(&ud->lock); | ||
236 | if (ret) { | ||
237 | dev_err(&udev->dev, "device reset\n"); | ||
238 | ud->status = SDEV_ST_ERROR; | ||
239 | } else { | ||
240 | dev_info(&udev->dev, "device reset\n"); | ||
241 | ud->status = SDEV_ST_AVAILABLE; | ||
242 | } | ||
243 | spin_unlock_irq(&ud->lock); | ||
244 | } | ||
245 | |||
246 | static void stub_device_unusable(struct usbip_device *ud) | ||
247 | { | ||
248 | spin_lock_irq(&ud->lock); | ||
249 | ud->status = SDEV_ST_ERROR; | ||
250 | spin_unlock_irq(&ud->lock); | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * stub_device_alloc - allocate a new stub_device struct | ||
255 | * @interface: usb_interface of a new device | ||
256 | * | ||
257 | * Allocates and initializes a new stub_device struct. | ||
258 | */ | ||
259 | static struct stub_device *stub_device_alloc(struct usb_device *udev) | ||
260 | { | ||
261 | struct stub_device *sdev; | ||
262 | int busnum = udev->bus->busnum; | ||
263 | int devnum = udev->devnum; | ||
264 | |||
265 | dev_dbg(&udev->dev, "allocating stub device"); | ||
266 | |||
267 | /* yes, it's a new device */ | ||
268 | sdev = kzalloc(sizeof(struct stub_device), GFP_KERNEL); | ||
269 | if (!sdev) | ||
270 | return NULL; | ||
271 | |||
272 | sdev->udev = usb_get_dev(udev); | ||
273 | |||
274 | /* | ||
275 | * devid is defined with devnum when this driver is first allocated. | ||
276 | * devnum may change later if a device is reset. However, devid never | ||
277 | * changes during a usbip connection. | ||
278 | */ | ||
279 | sdev->devid = (busnum << 16) | devnum; | ||
280 | sdev->ud.side = USBIP_STUB; | ||
281 | sdev->ud.status = SDEV_ST_AVAILABLE; | ||
282 | spin_lock_init(&sdev->ud.lock); | ||
283 | sdev->ud.tcp_socket = NULL; | ||
284 | |||
285 | INIT_LIST_HEAD(&sdev->priv_init); | ||
286 | INIT_LIST_HEAD(&sdev->priv_tx); | ||
287 | INIT_LIST_HEAD(&sdev->priv_free); | ||
288 | INIT_LIST_HEAD(&sdev->unlink_free); | ||
289 | INIT_LIST_HEAD(&sdev->unlink_tx); | ||
290 | spin_lock_init(&sdev->priv_lock); | ||
291 | |||
292 | init_waitqueue_head(&sdev->tx_waitq); | ||
293 | |||
294 | sdev->ud.eh_ops.shutdown = stub_shutdown_connection; | ||
295 | sdev->ud.eh_ops.reset = stub_device_reset; | ||
296 | sdev->ud.eh_ops.unusable = stub_device_unusable; | ||
297 | |||
298 | usbip_start_eh(&sdev->ud); | ||
299 | |||
300 | dev_dbg(&udev->dev, "register new device\n"); | ||
301 | |||
302 | return sdev; | ||
303 | } | ||
304 | |||
305 | static void stub_device_free(struct stub_device *sdev) | ||
306 | { | ||
307 | kfree(sdev); | ||
308 | } | ||
309 | |||
310 | static int stub_probe(struct usb_device *udev) | ||
311 | { | ||
312 | struct stub_device *sdev = NULL; | ||
313 | const char *udev_busid = dev_name(&udev->dev); | ||
314 | int err = 0; | ||
315 | struct bus_id_priv *busid_priv; | ||
316 | int rc; | ||
317 | |||
318 | dev_dbg(&udev->dev, "Enter\n"); | ||
319 | |||
320 | /* check we should claim or not by busid_table */ | ||
321 | busid_priv = get_busid_priv(udev_busid); | ||
322 | if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) || | ||
323 | (busid_priv->status == STUB_BUSID_OTHER)) { | ||
324 | dev_info(&udev->dev, | ||
325 | "%s is not in match_busid table... skip!\n", | ||
326 | udev_busid); | ||
327 | |||
328 | /* | ||
329 | * Return value should be ENODEV or ENOXIO to continue trying | ||
330 | * other matched drivers by the driver core. | ||
331 | * See driver_probe_device() in driver/base/dd.c | ||
332 | */ | ||
333 | return -ENODEV; | ||
334 | } | ||
335 | |||
336 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) { | ||
337 | dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n", | ||
338 | udev_busid); | ||
339 | return -ENODEV; | ||
340 | } | ||
341 | |||
342 | if (!strcmp(udev->bus->bus_name, "vhci_hcd")) { | ||
343 | dev_dbg(&udev->dev, | ||
344 | "%s is attached on vhci_hcd... skip!\n", | ||
345 | udev_busid); | ||
346 | |||
347 | return -ENODEV; | ||
348 | } | ||
349 | |||
350 | /* ok, this is my device */ | ||
351 | sdev = stub_device_alloc(udev); | ||
352 | if (!sdev) | ||
353 | return -ENOMEM; | ||
354 | |||
355 | dev_info(&udev->dev, | ||
356 | "usbip-host: register new device (bus %u dev %u)\n", | ||
357 | udev->bus->busnum, udev->devnum); | ||
358 | |||
359 | busid_priv->shutdown_busid = 0; | ||
360 | |||
361 | /* set private data to usb_device */ | ||
362 | dev_set_drvdata(&udev->dev, sdev); | ||
363 | busid_priv->sdev = sdev; | ||
364 | busid_priv->udev = udev; | ||
365 | |||
366 | /* | ||
367 | * Claim this hub port. | ||
368 | * It doesn't matter what value we pass as owner | ||
369 | * (struct dev_state) as long as it is unique. | ||
370 | */ | ||
371 | rc = usb_hub_claim_port(udev->parent, udev->portnum, | ||
372 | (struct usb_dev_state *) udev); | ||
373 | if (rc) { | ||
374 | dev_dbg(&udev->dev, "unable to claim port\n"); | ||
375 | return rc; | ||
376 | } | ||
377 | |||
378 | err = stub_add_files(&udev->dev); | ||
379 | if (err) { | ||
380 | dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid); | ||
381 | dev_set_drvdata(&udev->dev, NULL); | ||
382 | usb_put_dev(udev); | ||
383 | kthread_stop_put(sdev->ud.eh); | ||
384 | |||
385 | busid_priv->sdev = NULL; | ||
386 | stub_device_free(sdev); | ||
387 | return err; | ||
388 | } | ||
389 | busid_priv->status = STUB_BUSID_ALLOC; | ||
390 | |||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static void shutdown_busid(struct bus_id_priv *busid_priv) | ||
395 | { | ||
396 | if (busid_priv->sdev && !busid_priv->shutdown_busid) { | ||
397 | busid_priv->shutdown_busid = 1; | ||
398 | usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED); | ||
399 | |||
400 | /* wait for the stop of the event handler */ | ||
401 | usbip_stop_eh(&busid_priv->sdev->ud); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * called in usb_disconnect() or usb_deregister() | ||
407 | * but only if actconfig(active configuration) exists | ||
408 | */ | ||
409 | static void stub_disconnect(struct usb_device *udev) | ||
410 | { | ||
411 | struct stub_device *sdev; | ||
412 | const char *udev_busid = dev_name(&udev->dev); | ||
413 | struct bus_id_priv *busid_priv; | ||
414 | int rc; | ||
415 | |||
416 | dev_dbg(&udev->dev, "Enter\n"); | ||
417 | |||
418 | busid_priv = get_busid_priv(udev_busid); | ||
419 | if (!busid_priv) { | ||
420 | BUG(); | ||
421 | return; | ||
422 | } | ||
423 | |||
424 | sdev = dev_get_drvdata(&udev->dev); | ||
425 | |||
426 | /* get stub_device */ | ||
427 | if (!sdev) { | ||
428 | dev_err(&udev->dev, "could not get device"); | ||
429 | return; | ||
430 | } | ||
431 | |||
432 | dev_set_drvdata(&udev->dev, NULL); | ||
433 | |||
434 | /* | ||
435 | * NOTE: rx/tx threads are invoked for each usb_device. | ||
436 | */ | ||
437 | stub_remove_files(&udev->dev); | ||
438 | |||
439 | /* release port */ | ||
440 | rc = usb_hub_release_port(udev->parent, udev->portnum, | ||
441 | (struct usb_dev_state *) udev); | ||
442 | if (rc) { | ||
443 | dev_dbg(&udev->dev, "unable to release port\n"); | ||
444 | return; | ||
445 | } | ||
446 | |||
447 | /* If usb reset is called from event handler */ | ||
448 | if (busid_priv->sdev->ud.eh == current) | ||
449 | return; | ||
450 | |||
451 | /* shutdown the current connection */ | ||
452 | shutdown_busid(busid_priv); | ||
453 | |||
454 | usb_put_dev(sdev->udev); | ||
455 | |||
456 | /* free sdev */ | ||
457 | busid_priv->sdev = NULL; | ||
458 | stub_device_free(sdev); | ||
459 | |||
460 | if (busid_priv->status == STUB_BUSID_ALLOC) { | ||
461 | busid_priv->status = STUB_BUSID_ADDED; | ||
462 | } else { | ||
463 | busid_priv->status = STUB_BUSID_OTHER; | ||
464 | del_match_busid((char *)udev_busid); | ||
465 | } | ||
466 | } | ||
467 | |||
468 | #ifdef CONFIG_PM | ||
469 | |||
470 | /* These functions need usb_port_suspend and usb_port_resume, | ||
471 | * which reside in drivers/usb/core/usb.h. Skip for now. */ | ||
472 | |||
473 | static int stub_suspend(struct usb_device *udev, pm_message_t message) | ||
474 | { | ||
475 | dev_dbg(&udev->dev, "stub_suspend\n"); | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static int stub_resume(struct usb_device *udev, pm_message_t message) | ||
481 | { | ||
482 | dev_dbg(&udev->dev, "stub_resume\n"); | ||
483 | |||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | #endif /* CONFIG_PM */ | ||
488 | |||
489 | struct usb_device_driver stub_driver = { | ||
490 | .name = "usbip-host", | ||
491 | .probe = stub_probe, | ||
492 | .disconnect = stub_disconnect, | ||
493 | #ifdef CONFIG_PM | ||
494 | .suspend = stub_suspend, | ||
495 | .resume = stub_resume, | ||
496 | #endif | ||
497 | .supports_autosuspend = 0, | ||
498 | }; | ||
diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c new file mode 100644 index 000000000000..44ab43fc4fcc --- /dev/null +++ b/drivers/usb/usbip/stub_main.c | |||
@@ -0,0 +1,335 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/string.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/device.h> | ||
23 | |||
24 | #include "usbip_common.h" | ||
25 | #include "stub.h" | ||
26 | |||
27 | #define DRIVER_AUTHOR "Takahiro Hirofuchi" | ||
28 | #define DRIVER_DESC "USB/IP Host Driver" | ||
29 | |||
30 | struct kmem_cache *stub_priv_cache; | ||
31 | /* | ||
32 | * busid_tables defines matching busids that usbip can grab. A user can change | ||
33 | * dynamically what device is locally used and what device is exported to a | ||
34 | * remote host. | ||
35 | */ | ||
36 | #define MAX_BUSID 16 | ||
37 | static struct bus_id_priv busid_table[MAX_BUSID]; | ||
38 | static spinlock_t busid_table_lock; | ||
39 | |||
40 | static void init_busid_table(void) | ||
41 | { | ||
42 | /* | ||
43 | * This also sets the bus_table[i].status to | ||
44 | * STUB_BUSID_OTHER, which is 0. | ||
45 | */ | ||
46 | memset(busid_table, 0, sizeof(busid_table)); | ||
47 | |||
48 | spin_lock_init(&busid_table_lock); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Find the index of the busid by name. | ||
53 | * Must be called with busid_table_lock held. | ||
54 | */ | ||
55 | static int get_busid_idx(const char *busid) | ||
56 | { | ||
57 | int i; | ||
58 | int idx = -1; | ||
59 | |||
60 | for (i = 0; i < MAX_BUSID; i++) | ||
61 | if (busid_table[i].name[0]) | ||
62 | if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { | ||
63 | idx = i; | ||
64 | break; | ||
65 | } | ||
66 | return idx; | ||
67 | } | ||
68 | |||
69 | struct bus_id_priv *get_busid_priv(const char *busid) | ||
70 | { | ||
71 | int idx; | ||
72 | struct bus_id_priv *bid = NULL; | ||
73 | |||
74 | spin_lock(&busid_table_lock); | ||
75 | idx = get_busid_idx(busid); | ||
76 | if (idx >= 0) | ||
77 | bid = &(busid_table[idx]); | ||
78 | spin_unlock(&busid_table_lock); | ||
79 | |||
80 | return bid; | ||
81 | } | ||
82 | |||
83 | static int add_match_busid(char *busid) | ||
84 | { | ||
85 | int i; | ||
86 | int ret = -1; | ||
87 | |||
88 | spin_lock(&busid_table_lock); | ||
89 | /* already registered? */ | ||
90 | if (get_busid_idx(busid) >= 0) { | ||
91 | ret = 0; | ||
92 | goto out; | ||
93 | } | ||
94 | |||
95 | for (i = 0; i < MAX_BUSID; i++) | ||
96 | if (!busid_table[i].name[0]) { | ||
97 | strlcpy(busid_table[i].name, busid, BUSID_SIZE); | ||
98 | if ((busid_table[i].status != STUB_BUSID_ALLOC) && | ||
99 | (busid_table[i].status != STUB_BUSID_REMOV)) | ||
100 | busid_table[i].status = STUB_BUSID_ADDED; | ||
101 | ret = 0; | ||
102 | break; | ||
103 | } | ||
104 | |||
105 | out: | ||
106 | spin_unlock(&busid_table_lock); | ||
107 | |||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | int del_match_busid(char *busid) | ||
112 | { | ||
113 | int idx; | ||
114 | int ret = -1; | ||
115 | |||
116 | spin_lock(&busid_table_lock); | ||
117 | idx = get_busid_idx(busid); | ||
118 | if (idx < 0) | ||
119 | goto out; | ||
120 | |||
121 | /* found */ | ||
122 | ret = 0; | ||
123 | |||
124 | if (busid_table[idx].status == STUB_BUSID_OTHER) | ||
125 | memset(busid_table[idx].name, 0, BUSID_SIZE); | ||
126 | |||
127 | if ((busid_table[idx].status != STUB_BUSID_OTHER) && | ||
128 | (busid_table[idx].status != STUB_BUSID_ADDED)) | ||
129 | busid_table[idx].status = STUB_BUSID_REMOV; | ||
130 | |||
131 | out: | ||
132 | spin_unlock(&busid_table_lock); | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | static ssize_t show_match_busid(struct device_driver *drv, char *buf) | ||
138 | { | ||
139 | int i; | ||
140 | char *out = buf; | ||
141 | |||
142 | spin_lock(&busid_table_lock); | ||
143 | for (i = 0; i < MAX_BUSID; i++) | ||
144 | if (busid_table[i].name[0]) | ||
145 | out += sprintf(out, "%s ", busid_table[i].name); | ||
146 | spin_unlock(&busid_table_lock); | ||
147 | out += sprintf(out, "\n"); | ||
148 | |||
149 | return out - buf; | ||
150 | } | ||
151 | |||
152 | static ssize_t store_match_busid(struct device_driver *dev, const char *buf, | ||
153 | size_t count) | ||
154 | { | ||
155 | int len; | ||
156 | char busid[BUSID_SIZE]; | ||
157 | |||
158 | if (count < 5) | ||
159 | return -EINVAL; | ||
160 | |||
161 | /* busid needs to include \0 termination */ | ||
162 | len = strlcpy(busid, buf + 4, BUSID_SIZE); | ||
163 | if (sizeof(busid) <= len) | ||
164 | return -EINVAL; | ||
165 | |||
166 | if (!strncmp(buf, "add ", 4)) { | ||
167 | if (add_match_busid(busid) < 0) | ||
168 | return -ENOMEM; | ||
169 | |||
170 | pr_debug("add busid %s\n", busid); | ||
171 | return count; | ||
172 | } | ||
173 | |||
174 | if (!strncmp(buf, "del ", 4)) { | ||
175 | if (del_match_busid(busid) < 0) | ||
176 | return -ENODEV; | ||
177 | |||
178 | pr_debug("del busid %s\n", busid); | ||
179 | return count; | ||
180 | } | ||
181 | |||
182 | return -EINVAL; | ||
183 | } | ||
184 | static DRIVER_ATTR(match_busid, S_IRUSR | S_IWUSR, show_match_busid, | ||
185 | store_match_busid); | ||
186 | |||
187 | static ssize_t rebind_store(struct device_driver *dev, const char *buf, | ||
188 | size_t count) | ||
189 | { | ||
190 | int ret; | ||
191 | int len; | ||
192 | struct bus_id_priv *bid; | ||
193 | |||
194 | /* buf length should be less that BUSID_SIZE */ | ||
195 | len = strnlen(buf, BUSID_SIZE); | ||
196 | |||
197 | if (!(len < BUSID_SIZE)) | ||
198 | return -EINVAL; | ||
199 | |||
200 | bid = get_busid_priv(buf); | ||
201 | if (!bid) | ||
202 | return -ENODEV; | ||
203 | |||
204 | ret = device_attach(&bid->udev->dev); | ||
205 | if (ret < 0) { | ||
206 | dev_err(&bid->udev->dev, "rebind failed\n"); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | return count; | ||
211 | } | ||
212 | |||
213 | static DRIVER_ATTR_WO(rebind); | ||
214 | |||
215 | static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead) | ||
216 | { | ||
217 | struct stub_priv *priv, *tmp; | ||
218 | |||
219 | list_for_each_entry_safe(priv, tmp, listhead, list) { | ||
220 | list_del(&priv->list); | ||
221 | return priv; | ||
222 | } | ||
223 | |||
224 | return NULL; | ||
225 | } | ||
226 | |||
227 | static struct stub_priv *stub_priv_pop(struct stub_device *sdev) | ||
228 | { | ||
229 | unsigned long flags; | ||
230 | struct stub_priv *priv; | ||
231 | |||
232 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
233 | |||
234 | priv = stub_priv_pop_from_listhead(&sdev->priv_init); | ||
235 | if (priv) | ||
236 | goto done; | ||
237 | |||
238 | priv = stub_priv_pop_from_listhead(&sdev->priv_tx); | ||
239 | if (priv) | ||
240 | goto done; | ||
241 | |||
242 | priv = stub_priv_pop_from_listhead(&sdev->priv_free); | ||
243 | |||
244 | done: | ||
245 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
246 | |||
247 | return priv; | ||
248 | } | ||
249 | |||
250 | void stub_device_cleanup_urbs(struct stub_device *sdev) | ||
251 | { | ||
252 | struct stub_priv *priv; | ||
253 | struct urb *urb; | ||
254 | |||
255 | dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev); | ||
256 | |||
257 | while ((priv = stub_priv_pop(sdev))) { | ||
258 | urb = priv->urb; | ||
259 | dev_dbg(&sdev->udev->dev, "free urb %p\n", urb); | ||
260 | usb_kill_urb(urb); | ||
261 | |||
262 | kmem_cache_free(stub_priv_cache, priv); | ||
263 | |||
264 | kfree(urb->transfer_buffer); | ||
265 | kfree(urb->setup_packet); | ||
266 | usb_free_urb(urb); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static int __init usbip_host_init(void) | ||
271 | { | ||
272 | int ret; | ||
273 | |||
274 | init_busid_table(); | ||
275 | |||
276 | stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN); | ||
277 | if (!stub_priv_cache) { | ||
278 | pr_err("kmem_cache_create failed\n"); | ||
279 | return -ENOMEM; | ||
280 | } | ||
281 | |||
282 | ret = usb_register_device_driver(&stub_driver, THIS_MODULE); | ||
283 | if (ret) { | ||
284 | pr_err("usb_register failed %d\n", ret); | ||
285 | goto err_usb_register; | ||
286 | } | ||
287 | |||
288 | ret = driver_create_file(&stub_driver.drvwrap.driver, | ||
289 | &driver_attr_match_busid); | ||
290 | if (ret) { | ||
291 | pr_err("driver_create_file failed\n"); | ||
292 | goto err_create_file; | ||
293 | } | ||
294 | |||
295 | ret = driver_create_file(&stub_driver.drvwrap.driver, | ||
296 | &driver_attr_rebind); | ||
297 | if (ret) { | ||
298 | pr_err("driver_create_file failed\n"); | ||
299 | goto err_create_file; | ||
300 | } | ||
301 | |||
302 | pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); | ||
303 | return ret; | ||
304 | |||
305 | err_create_file: | ||
306 | usb_deregister_device_driver(&stub_driver); | ||
307 | err_usb_register: | ||
308 | kmem_cache_destroy(stub_priv_cache); | ||
309 | return ret; | ||
310 | } | ||
311 | |||
312 | static void __exit usbip_host_exit(void) | ||
313 | { | ||
314 | driver_remove_file(&stub_driver.drvwrap.driver, | ||
315 | &driver_attr_match_busid); | ||
316 | |||
317 | driver_remove_file(&stub_driver.drvwrap.driver, | ||
318 | &driver_attr_rebind); | ||
319 | |||
320 | /* | ||
321 | * deregister() calls stub_disconnect() for all devices. Device | ||
322 | * specific data is cleared in stub_disconnect(). | ||
323 | */ | ||
324 | usb_deregister_device_driver(&stub_driver); | ||
325 | |||
326 | kmem_cache_destroy(stub_priv_cache); | ||
327 | } | ||
328 | |||
329 | module_init(usbip_host_init); | ||
330 | module_exit(usbip_host_exit); | ||
331 | |||
332 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
333 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
334 | MODULE_LICENSE("GPL"); | ||
335 | MODULE_VERSION(USBIP_VERSION); | ||
diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c new file mode 100644 index 000000000000..00e475c51a12 --- /dev/null +++ b/drivers/usb/usbip/stub_rx.c | |||
@@ -0,0 +1,594 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <asm/byteorder.h> | ||
21 | #include <linux/kthread.h> | ||
22 | #include <linux/usb.h> | ||
23 | #include <linux/usb/hcd.h> | ||
24 | |||
25 | #include "usbip_common.h" | ||
26 | #include "stub.h" | ||
27 | |||
28 | static int is_clear_halt_cmd(struct urb *urb) | ||
29 | { | ||
30 | struct usb_ctrlrequest *req; | ||
31 | |||
32 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
33 | |||
34 | return (req->bRequest == USB_REQ_CLEAR_FEATURE) && | ||
35 | (req->bRequestType == USB_RECIP_ENDPOINT) && | ||
36 | (req->wValue == USB_ENDPOINT_HALT); | ||
37 | } | ||
38 | |||
39 | static int is_set_interface_cmd(struct urb *urb) | ||
40 | { | ||
41 | struct usb_ctrlrequest *req; | ||
42 | |||
43 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
44 | |||
45 | return (req->bRequest == USB_REQ_SET_INTERFACE) && | ||
46 | (req->bRequestType == USB_RECIP_INTERFACE); | ||
47 | } | ||
48 | |||
49 | static int is_set_configuration_cmd(struct urb *urb) | ||
50 | { | ||
51 | struct usb_ctrlrequest *req; | ||
52 | |||
53 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
54 | |||
55 | return (req->bRequest == USB_REQ_SET_CONFIGURATION) && | ||
56 | (req->bRequestType == USB_RECIP_DEVICE); | ||
57 | } | ||
58 | |||
59 | static int is_reset_device_cmd(struct urb *urb) | ||
60 | { | ||
61 | struct usb_ctrlrequest *req; | ||
62 | __u16 value; | ||
63 | __u16 index; | ||
64 | |||
65 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
66 | value = le16_to_cpu(req->wValue); | ||
67 | index = le16_to_cpu(req->wIndex); | ||
68 | |||
69 | if ((req->bRequest == USB_REQ_SET_FEATURE) && | ||
70 | (req->bRequestType == USB_RT_PORT) && | ||
71 | (value == USB_PORT_FEAT_RESET)) { | ||
72 | usbip_dbg_stub_rx("reset_device_cmd, port %u\n", index); | ||
73 | return 1; | ||
74 | } else | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int tweak_clear_halt_cmd(struct urb *urb) | ||
79 | { | ||
80 | struct usb_ctrlrequest *req; | ||
81 | int target_endp; | ||
82 | int target_dir; | ||
83 | int target_pipe; | ||
84 | int ret; | ||
85 | |||
86 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
87 | |||
88 | /* | ||
89 | * The stalled endpoint is specified in the wIndex value. The endpoint | ||
90 | * of the urb is the target of this clear_halt request (i.e., control | ||
91 | * endpoint). | ||
92 | */ | ||
93 | target_endp = le16_to_cpu(req->wIndex) & 0x000f; | ||
94 | |||
95 | /* the stalled endpoint direction is IN or OUT?. USB_DIR_IN is 0x80. */ | ||
96 | target_dir = le16_to_cpu(req->wIndex) & 0x0080; | ||
97 | |||
98 | if (target_dir) | ||
99 | target_pipe = usb_rcvctrlpipe(urb->dev, target_endp); | ||
100 | else | ||
101 | target_pipe = usb_sndctrlpipe(urb->dev, target_endp); | ||
102 | |||
103 | ret = usb_clear_halt(urb->dev, target_pipe); | ||
104 | if (ret < 0) | ||
105 | dev_err(&urb->dev->dev, | ||
106 | "usb_clear_halt error: devnum %d endp %d ret %d\n", | ||
107 | urb->dev->devnum, target_endp, ret); | ||
108 | else | ||
109 | dev_info(&urb->dev->dev, | ||
110 | "usb_clear_halt done: devnum %d endp %d\n", | ||
111 | urb->dev->devnum, target_endp); | ||
112 | |||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | static int tweak_set_interface_cmd(struct urb *urb) | ||
117 | { | ||
118 | struct usb_ctrlrequest *req; | ||
119 | __u16 alternate; | ||
120 | __u16 interface; | ||
121 | int ret; | ||
122 | |||
123 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
124 | alternate = le16_to_cpu(req->wValue); | ||
125 | interface = le16_to_cpu(req->wIndex); | ||
126 | |||
127 | usbip_dbg_stub_rx("set_interface: inf %u alt %u\n", | ||
128 | interface, alternate); | ||
129 | |||
130 | ret = usb_set_interface(urb->dev, interface, alternate); | ||
131 | if (ret < 0) | ||
132 | dev_err(&urb->dev->dev, | ||
133 | "usb_set_interface error: inf %u alt %u ret %d\n", | ||
134 | interface, alternate, ret); | ||
135 | else | ||
136 | dev_info(&urb->dev->dev, | ||
137 | "usb_set_interface done: inf %u alt %u\n", | ||
138 | interface, alternate); | ||
139 | |||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | static int tweak_set_configuration_cmd(struct urb *urb) | ||
144 | { | ||
145 | struct stub_priv *priv = (struct stub_priv *) urb->context; | ||
146 | struct stub_device *sdev = priv->sdev; | ||
147 | struct usb_ctrlrequest *req; | ||
148 | __u16 config; | ||
149 | int err; | ||
150 | |||
151 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
152 | config = le16_to_cpu(req->wValue); | ||
153 | |||
154 | err = usb_set_configuration(sdev->udev, config); | ||
155 | if (err && err != -ENODEV) | ||
156 | dev_err(&sdev->udev->dev, "can't set config #%d, error %d\n", | ||
157 | config, err); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int tweak_reset_device_cmd(struct urb *urb) | ||
162 | { | ||
163 | struct stub_priv *priv = (struct stub_priv *) urb->context; | ||
164 | struct stub_device *sdev = priv->sdev; | ||
165 | |||
166 | dev_info(&urb->dev->dev, "usb_queue_reset_device\n"); | ||
167 | |||
168 | /* | ||
169 | * With the implementation of pre_reset and post_reset the driver no | ||
170 | * longer unbinds. This allows the use of synchronous reset. | ||
171 | */ | ||
172 | |||
173 | if (usb_lock_device_for_reset(sdev->udev, sdev->interface) < 0) { | ||
174 | dev_err(&urb->dev->dev, "could not obtain lock to reset device\n"); | ||
175 | return 0; | ||
176 | } | ||
177 | usb_reset_device(sdev->udev); | ||
178 | usb_unlock_device(sdev->udev); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * clear_halt, set_interface, and set_configuration require special tricks. | ||
185 | */ | ||
186 | static void tweak_special_requests(struct urb *urb) | ||
187 | { | ||
188 | if (!urb || !urb->setup_packet) | ||
189 | return; | ||
190 | |||
191 | if (usb_pipetype(urb->pipe) != PIPE_CONTROL) | ||
192 | return; | ||
193 | |||
194 | if (is_clear_halt_cmd(urb)) | ||
195 | /* tweak clear_halt */ | ||
196 | tweak_clear_halt_cmd(urb); | ||
197 | |||
198 | else if (is_set_interface_cmd(urb)) | ||
199 | /* tweak set_interface */ | ||
200 | tweak_set_interface_cmd(urb); | ||
201 | |||
202 | else if (is_set_configuration_cmd(urb)) | ||
203 | /* tweak set_configuration */ | ||
204 | tweak_set_configuration_cmd(urb); | ||
205 | |||
206 | else if (is_reset_device_cmd(urb)) | ||
207 | tweak_reset_device_cmd(urb); | ||
208 | else | ||
209 | usbip_dbg_stub_rx("no need to tweak\n"); | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb(). | ||
214 | * By unlinking the urb asynchronously, stub_rx can continuously | ||
215 | * process coming urbs. Even if the urb is unlinked, its completion | ||
216 | * handler will be called and stub_tx will send a return pdu. | ||
217 | * | ||
218 | * See also comments about unlinking strategy in vhci_hcd.c. | ||
219 | */ | ||
220 | static int stub_recv_cmd_unlink(struct stub_device *sdev, | ||
221 | struct usbip_header *pdu) | ||
222 | { | ||
223 | int ret; | ||
224 | unsigned long flags; | ||
225 | struct stub_priv *priv; | ||
226 | |||
227 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
228 | |||
229 | list_for_each_entry(priv, &sdev->priv_init, list) { | ||
230 | if (priv->seqnum != pdu->u.cmd_unlink.seqnum) | ||
231 | continue; | ||
232 | |||
233 | dev_info(&priv->urb->dev->dev, "unlink urb %p\n", | ||
234 | priv->urb); | ||
235 | |||
236 | /* | ||
237 | * This matched urb is not completed yet (i.e., be in | ||
238 | * flight in usb hcd hardware/driver). Now we are | ||
239 | * cancelling it. The unlinking flag means that we are | ||
240 | * now not going to return the normal result pdu of a | ||
241 | * submission request, but going to return a result pdu | ||
242 | * of the unlink request. | ||
243 | */ | ||
244 | priv->unlinking = 1; | ||
245 | |||
246 | /* | ||
247 | * In the case that unlinking flag is on, prev->seqnum | ||
248 | * is changed from the seqnum of the cancelling urb to | ||
249 | * the seqnum of the unlink request. This will be used | ||
250 | * to make the result pdu of the unlink request. | ||
251 | */ | ||
252 | priv->seqnum = pdu->base.seqnum; | ||
253 | |||
254 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
255 | |||
256 | /* | ||
257 | * usb_unlink_urb() is now out of spinlocking to avoid | ||
258 | * spinlock recursion since stub_complete() is | ||
259 | * sometimes called in this context but not in the | ||
260 | * interrupt context. If stub_complete() is executed | ||
261 | * before we call usb_unlink_urb(), usb_unlink_urb() | ||
262 | * will return an error value. In this case, stub_tx | ||
263 | * will return the result pdu of this unlink request | ||
264 | * though submission is completed and actual unlinking | ||
265 | * is not executed. OK? | ||
266 | */ | ||
267 | /* In the above case, urb->status is not -ECONNRESET, | ||
268 | * so a driver in a client host will know the failure | ||
269 | * of the unlink request ? | ||
270 | */ | ||
271 | ret = usb_unlink_urb(priv->urb); | ||
272 | if (ret != -EINPROGRESS) | ||
273 | dev_err(&priv->urb->dev->dev, | ||
274 | "failed to unlink a urb %p, ret %d\n", | ||
275 | priv->urb, ret); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | usbip_dbg_stub_rx("seqnum %d is not pending\n", | ||
281 | pdu->u.cmd_unlink.seqnum); | ||
282 | |||
283 | /* | ||
284 | * The urb of the unlink target is not found in priv_init queue. It was | ||
285 | * already completed and its results is/was going to be sent by a | ||
286 | * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only | ||
287 | * return the completeness of this unlink request to vhci_hcd. | ||
288 | */ | ||
289 | stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0); | ||
290 | |||
291 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int valid_request(struct stub_device *sdev, struct usbip_header *pdu) | ||
297 | { | ||
298 | struct usbip_device *ud = &sdev->ud; | ||
299 | int valid = 0; | ||
300 | |||
301 | if (pdu->base.devid == sdev->devid) { | ||
302 | spin_lock_irq(&ud->lock); | ||
303 | if (ud->status == SDEV_ST_USED) { | ||
304 | /* A request is valid. */ | ||
305 | valid = 1; | ||
306 | } | ||
307 | spin_unlock_irq(&ud->lock); | ||
308 | } | ||
309 | |||
310 | return valid; | ||
311 | } | ||
312 | |||
313 | static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, | ||
314 | struct usbip_header *pdu) | ||
315 | { | ||
316 | struct stub_priv *priv; | ||
317 | struct usbip_device *ud = &sdev->ud; | ||
318 | unsigned long flags; | ||
319 | |||
320 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
321 | |||
322 | priv = kmem_cache_zalloc(stub_priv_cache, GFP_ATOMIC); | ||
323 | if (!priv) { | ||
324 | dev_err(&sdev->interface->dev, "alloc stub_priv\n"); | ||
325 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
326 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | ||
327 | return NULL; | ||
328 | } | ||
329 | |||
330 | priv->seqnum = pdu->base.seqnum; | ||
331 | priv->sdev = sdev; | ||
332 | |||
333 | /* | ||
334 | * After a stub_priv is linked to a list_head, | ||
335 | * our error handler can free allocated data. | ||
336 | */ | ||
337 | list_add_tail(&priv->list, &sdev->priv_init); | ||
338 | |||
339 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
340 | |||
341 | return priv; | ||
342 | } | ||
343 | |||
344 | static int get_pipe(struct stub_device *sdev, int epnum, int dir) | ||
345 | { | ||
346 | struct usb_device *udev = sdev->udev; | ||
347 | struct usb_host_endpoint *ep; | ||
348 | struct usb_endpoint_descriptor *epd = NULL; | ||
349 | |||
350 | if (dir == USBIP_DIR_IN) | ||
351 | ep = udev->ep_in[epnum & 0x7f]; | ||
352 | else | ||
353 | ep = udev->ep_out[epnum & 0x7f]; | ||
354 | if (!ep) { | ||
355 | dev_err(&sdev->interface->dev, "no such endpoint?, %d\n", | ||
356 | epnum); | ||
357 | BUG(); | ||
358 | } | ||
359 | |||
360 | epd = &ep->desc; | ||
361 | if (usb_endpoint_xfer_control(epd)) { | ||
362 | if (dir == USBIP_DIR_OUT) | ||
363 | return usb_sndctrlpipe(udev, epnum); | ||
364 | else | ||
365 | return usb_rcvctrlpipe(udev, epnum); | ||
366 | } | ||
367 | |||
368 | if (usb_endpoint_xfer_bulk(epd)) { | ||
369 | if (dir == USBIP_DIR_OUT) | ||
370 | return usb_sndbulkpipe(udev, epnum); | ||
371 | else | ||
372 | return usb_rcvbulkpipe(udev, epnum); | ||
373 | } | ||
374 | |||
375 | if (usb_endpoint_xfer_int(epd)) { | ||
376 | if (dir == USBIP_DIR_OUT) | ||
377 | return usb_sndintpipe(udev, epnum); | ||
378 | else | ||
379 | return usb_rcvintpipe(udev, epnum); | ||
380 | } | ||
381 | |||
382 | if (usb_endpoint_xfer_isoc(epd)) { | ||
383 | if (dir == USBIP_DIR_OUT) | ||
384 | return usb_sndisocpipe(udev, epnum); | ||
385 | else | ||
386 | return usb_rcvisocpipe(udev, epnum); | ||
387 | } | ||
388 | |||
389 | /* NOT REACHED */ | ||
390 | dev_err(&sdev->interface->dev, "get pipe, epnum %d\n", epnum); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static void masking_bogus_flags(struct urb *urb) | ||
395 | { | ||
396 | int xfertype; | ||
397 | struct usb_device *dev; | ||
398 | struct usb_host_endpoint *ep; | ||
399 | int is_out; | ||
400 | unsigned int allowed; | ||
401 | |||
402 | if (!urb || urb->hcpriv || !urb->complete) | ||
403 | return; | ||
404 | dev = urb->dev; | ||
405 | if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) | ||
406 | return; | ||
407 | |||
408 | ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out) | ||
409 | [usb_pipeendpoint(urb->pipe)]; | ||
410 | if (!ep) | ||
411 | return; | ||
412 | |||
413 | xfertype = usb_endpoint_type(&ep->desc); | ||
414 | if (xfertype == USB_ENDPOINT_XFER_CONTROL) { | ||
415 | struct usb_ctrlrequest *setup = | ||
416 | (struct usb_ctrlrequest *) urb->setup_packet; | ||
417 | |||
418 | if (!setup) | ||
419 | return; | ||
420 | is_out = !(setup->bRequestType & USB_DIR_IN) || | ||
421 | !setup->wLength; | ||
422 | } else { | ||
423 | is_out = usb_endpoint_dir_out(&ep->desc); | ||
424 | } | ||
425 | |||
426 | /* enforce simple/standard policy */ | ||
427 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | | ||
428 | URB_DIR_MASK | URB_FREE_BUFFER); | ||
429 | switch (xfertype) { | ||
430 | case USB_ENDPOINT_XFER_BULK: | ||
431 | if (is_out) | ||
432 | allowed |= URB_ZERO_PACKET; | ||
433 | /* FALLTHROUGH */ | ||
434 | case USB_ENDPOINT_XFER_CONTROL: | ||
435 | allowed |= URB_NO_FSBR; /* only affects UHCI */ | ||
436 | /* FALLTHROUGH */ | ||
437 | default: /* all non-iso endpoints */ | ||
438 | if (!is_out) | ||
439 | allowed |= URB_SHORT_NOT_OK; | ||
440 | break; | ||
441 | case USB_ENDPOINT_XFER_ISOC: | ||
442 | allowed |= URB_ISO_ASAP; | ||
443 | break; | ||
444 | } | ||
445 | urb->transfer_flags &= allowed; | ||
446 | } | ||
447 | |||
448 | static void stub_recv_cmd_submit(struct stub_device *sdev, | ||
449 | struct usbip_header *pdu) | ||
450 | { | ||
451 | int ret; | ||
452 | struct stub_priv *priv; | ||
453 | struct usbip_device *ud = &sdev->ud; | ||
454 | struct usb_device *udev = sdev->udev; | ||
455 | int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); | ||
456 | |||
457 | priv = stub_priv_alloc(sdev, pdu); | ||
458 | if (!priv) | ||
459 | return; | ||
460 | |||
461 | /* setup a urb */ | ||
462 | if (usb_pipeisoc(pipe)) | ||
463 | priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets, | ||
464 | GFP_KERNEL); | ||
465 | else | ||
466 | priv->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
467 | |||
468 | if (!priv->urb) { | ||
469 | dev_err(&sdev->interface->dev, "malloc urb\n"); | ||
470 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | /* allocate urb transfer buffer, if needed */ | ||
475 | if (pdu->u.cmd_submit.transfer_buffer_length > 0) { | ||
476 | priv->urb->transfer_buffer = | ||
477 | kzalloc(pdu->u.cmd_submit.transfer_buffer_length, | ||
478 | GFP_KERNEL); | ||
479 | if (!priv->urb->transfer_buffer) { | ||
480 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | ||
481 | return; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | /* copy urb setup packet */ | ||
486 | priv->urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8, | ||
487 | GFP_KERNEL); | ||
488 | if (!priv->urb->setup_packet) { | ||
489 | dev_err(&sdev->interface->dev, "allocate setup_packet\n"); | ||
490 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | /* set other members from the base header of pdu */ | ||
495 | priv->urb->context = (void *) priv; | ||
496 | priv->urb->dev = udev; | ||
497 | priv->urb->pipe = pipe; | ||
498 | priv->urb->complete = stub_complete; | ||
499 | |||
500 | usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0); | ||
501 | |||
502 | |||
503 | if (usbip_recv_xbuff(ud, priv->urb) < 0) | ||
504 | return; | ||
505 | |||
506 | if (usbip_recv_iso(ud, priv->urb) < 0) | ||
507 | return; | ||
508 | |||
509 | /* no need to submit an intercepted request, but harmless? */ | ||
510 | tweak_special_requests(priv->urb); | ||
511 | |||
512 | masking_bogus_flags(priv->urb); | ||
513 | /* urb is now ready to submit */ | ||
514 | ret = usb_submit_urb(priv->urb, GFP_KERNEL); | ||
515 | |||
516 | if (ret == 0) | ||
517 | usbip_dbg_stub_rx("submit urb ok, seqnum %u\n", | ||
518 | pdu->base.seqnum); | ||
519 | else { | ||
520 | dev_err(&sdev->interface->dev, "submit_urb error, %d\n", ret); | ||
521 | usbip_dump_header(pdu); | ||
522 | usbip_dump_urb(priv->urb); | ||
523 | |||
524 | /* | ||
525 | * Pessimistic. | ||
526 | * This connection will be discarded. | ||
527 | */ | ||
528 | usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT); | ||
529 | } | ||
530 | |||
531 | usbip_dbg_stub_rx("Leave\n"); | ||
532 | } | ||
533 | |||
534 | /* recv a pdu */ | ||
535 | static void stub_rx_pdu(struct usbip_device *ud) | ||
536 | { | ||
537 | int ret; | ||
538 | struct usbip_header pdu; | ||
539 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); | ||
540 | struct device *dev = &sdev->udev->dev; | ||
541 | |||
542 | usbip_dbg_stub_rx("Enter\n"); | ||
543 | |||
544 | memset(&pdu, 0, sizeof(pdu)); | ||
545 | |||
546 | /* receive a pdu header */ | ||
547 | ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu)); | ||
548 | if (ret != sizeof(pdu)) { | ||
549 | dev_err(dev, "recv a header, %d\n", ret); | ||
550 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
551 | return; | ||
552 | } | ||
553 | |||
554 | usbip_header_correct_endian(&pdu, 0); | ||
555 | |||
556 | if (usbip_dbg_flag_stub_rx) | ||
557 | usbip_dump_header(&pdu); | ||
558 | |||
559 | if (!valid_request(sdev, &pdu)) { | ||
560 | dev_err(dev, "recv invalid request\n"); | ||
561 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
562 | return; | ||
563 | } | ||
564 | |||
565 | switch (pdu.base.command) { | ||
566 | case USBIP_CMD_UNLINK: | ||
567 | stub_recv_cmd_unlink(sdev, &pdu); | ||
568 | break; | ||
569 | |||
570 | case USBIP_CMD_SUBMIT: | ||
571 | stub_recv_cmd_submit(sdev, &pdu); | ||
572 | break; | ||
573 | |||
574 | default: | ||
575 | /* NOTREACHED */ | ||
576 | dev_err(dev, "unknown pdu\n"); | ||
577 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
578 | break; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | int stub_rx_loop(void *data) | ||
583 | { | ||
584 | struct usbip_device *ud = data; | ||
585 | |||
586 | while (!kthread_should_stop()) { | ||
587 | if (usbip_event_happened(ud)) | ||
588 | break; | ||
589 | |||
590 | stub_rx_pdu(ud); | ||
591 | } | ||
592 | |||
593 | return 0; | ||
594 | } | ||
diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c new file mode 100644 index 000000000000..dbcabc9dbe0d --- /dev/null +++ b/drivers/usb/usbip/stub_tx.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kthread.h> | ||
21 | #include <linux/socket.h> | ||
22 | |||
23 | #include "usbip_common.h" | ||
24 | #include "stub.h" | ||
25 | |||
26 | static void stub_free_priv_and_urb(struct stub_priv *priv) | ||
27 | { | ||
28 | struct urb *urb = priv->urb; | ||
29 | |||
30 | kfree(urb->setup_packet); | ||
31 | kfree(urb->transfer_buffer); | ||
32 | list_del(&priv->list); | ||
33 | kmem_cache_free(stub_priv_cache, priv); | ||
34 | usb_free_urb(urb); | ||
35 | } | ||
36 | |||
37 | /* be in spin_lock_irqsave(&sdev->priv_lock, flags) */ | ||
38 | void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, | ||
39 | __u32 status) | ||
40 | { | ||
41 | struct stub_unlink *unlink; | ||
42 | |||
43 | unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC); | ||
44 | if (!unlink) { | ||
45 | usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC); | ||
46 | return; | ||
47 | } | ||
48 | |||
49 | unlink->seqnum = seqnum; | ||
50 | unlink->status = status; | ||
51 | |||
52 | list_add_tail(&unlink->list, &sdev->unlink_tx); | ||
53 | } | ||
54 | |||
55 | /** | ||
56 | * stub_complete - completion handler of a usbip urb | ||
57 | * @urb: pointer to the urb completed | ||
58 | * | ||
59 | * When a urb has completed, the USB core driver calls this function mostly in | ||
60 | * the interrupt context. To return the result of a urb, the completed urb is | ||
61 | * linked to the pending list of returning. | ||
62 | * | ||
63 | */ | ||
64 | void stub_complete(struct urb *urb) | ||
65 | { | ||
66 | struct stub_priv *priv = (struct stub_priv *) urb->context; | ||
67 | struct stub_device *sdev = priv->sdev; | ||
68 | unsigned long flags; | ||
69 | |||
70 | usbip_dbg_stub_tx("complete! status %d\n", urb->status); | ||
71 | |||
72 | switch (urb->status) { | ||
73 | case 0: | ||
74 | /* OK */ | ||
75 | break; | ||
76 | case -ENOENT: | ||
77 | dev_info(&urb->dev->dev, | ||
78 | "stopped by a call to usb_kill_urb() because of cleaning up a virtual connection\n"); | ||
79 | return; | ||
80 | case -ECONNRESET: | ||
81 | dev_info(&urb->dev->dev, | ||
82 | "unlinked by a call to usb_unlink_urb()\n"); | ||
83 | break; | ||
84 | case -EPIPE: | ||
85 | dev_info(&urb->dev->dev, "endpoint %d is stalled\n", | ||
86 | usb_pipeendpoint(urb->pipe)); | ||
87 | break; | ||
88 | case -ESHUTDOWN: | ||
89 | dev_info(&urb->dev->dev, "device removed?\n"); | ||
90 | break; | ||
91 | default: | ||
92 | dev_info(&urb->dev->dev, | ||
93 | "urb completion with non-zero status %d\n", | ||
94 | urb->status); | ||
95 | break; | ||
96 | } | ||
97 | |||
98 | /* link a urb to the queue of tx. */ | ||
99 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
100 | if (priv->unlinking) { | ||
101 | stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); | ||
102 | stub_free_priv_and_urb(priv); | ||
103 | } else { | ||
104 | list_move_tail(&priv->list, &sdev->priv_tx); | ||
105 | } | ||
106 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
107 | |||
108 | /* wake up tx_thread */ | ||
109 | wake_up(&sdev->tx_waitq); | ||
110 | } | ||
111 | |||
112 | static inline void setup_base_pdu(struct usbip_header_basic *base, | ||
113 | __u32 command, __u32 seqnum) | ||
114 | { | ||
115 | base->command = command; | ||
116 | base->seqnum = seqnum; | ||
117 | base->devid = 0; | ||
118 | base->ep = 0; | ||
119 | base->direction = 0; | ||
120 | } | ||
121 | |||
122 | static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb) | ||
123 | { | ||
124 | struct stub_priv *priv = (struct stub_priv *) urb->context; | ||
125 | |||
126 | setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum); | ||
127 | usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1); | ||
128 | } | ||
129 | |||
130 | static void setup_ret_unlink_pdu(struct usbip_header *rpdu, | ||
131 | struct stub_unlink *unlink) | ||
132 | { | ||
133 | setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum); | ||
134 | rpdu->u.ret_unlink.status = unlink->status; | ||
135 | } | ||
136 | |||
137 | static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev) | ||
138 | { | ||
139 | unsigned long flags; | ||
140 | struct stub_priv *priv, *tmp; | ||
141 | |||
142 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
143 | |||
144 | list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) { | ||
145 | list_move_tail(&priv->list, &sdev->priv_free); | ||
146 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
147 | return priv; | ||
148 | } | ||
149 | |||
150 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
151 | |||
152 | return NULL; | ||
153 | } | ||
154 | |||
155 | static int stub_send_ret_submit(struct stub_device *sdev) | ||
156 | { | ||
157 | unsigned long flags; | ||
158 | struct stub_priv *priv, *tmp; | ||
159 | |||
160 | struct msghdr msg; | ||
161 | size_t txsize; | ||
162 | |||
163 | size_t total_size = 0; | ||
164 | |||
165 | while ((priv = dequeue_from_priv_tx(sdev)) != NULL) { | ||
166 | int ret; | ||
167 | struct urb *urb = priv->urb; | ||
168 | struct usbip_header pdu_header; | ||
169 | struct usbip_iso_packet_descriptor *iso_buffer = NULL; | ||
170 | struct kvec *iov = NULL; | ||
171 | int iovnum = 0; | ||
172 | |||
173 | txsize = 0; | ||
174 | memset(&pdu_header, 0, sizeof(pdu_header)); | ||
175 | memset(&msg, 0, sizeof(msg)); | ||
176 | |||
177 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) | ||
178 | iovnum = 2 + urb->number_of_packets; | ||
179 | else | ||
180 | iovnum = 2; | ||
181 | |||
182 | iov = kcalloc(iovnum, sizeof(struct kvec), GFP_KERNEL); | ||
183 | |||
184 | if (!iov) { | ||
185 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC); | ||
186 | return -1; | ||
187 | } | ||
188 | |||
189 | iovnum = 0; | ||
190 | |||
191 | /* 1. setup usbip_header */ | ||
192 | setup_ret_submit_pdu(&pdu_header, urb); | ||
193 | usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", | ||
194 | pdu_header.base.seqnum, urb); | ||
195 | usbip_header_correct_endian(&pdu_header, 1); | ||
196 | |||
197 | iov[iovnum].iov_base = &pdu_header; | ||
198 | iov[iovnum].iov_len = sizeof(pdu_header); | ||
199 | iovnum++; | ||
200 | txsize += sizeof(pdu_header); | ||
201 | |||
202 | /* 2. setup transfer buffer */ | ||
203 | if (usb_pipein(urb->pipe) && | ||
204 | usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS && | ||
205 | urb->actual_length > 0) { | ||
206 | iov[iovnum].iov_base = urb->transfer_buffer; | ||
207 | iov[iovnum].iov_len = urb->actual_length; | ||
208 | iovnum++; | ||
209 | txsize += urb->actual_length; | ||
210 | } else if (usb_pipein(urb->pipe) && | ||
211 | usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
212 | /* | ||
213 | * For isochronous packets: actual length is the sum of | ||
214 | * the actual length of the individual, packets, but as | ||
215 | * the packet offsets are not changed there will be | ||
216 | * padding between the packets. To optimally use the | ||
217 | * bandwidth the padding is not transmitted. | ||
218 | */ | ||
219 | |||
220 | int i; | ||
221 | |||
222 | for (i = 0; i < urb->number_of_packets; i++) { | ||
223 | iov[iovnum].iov_base = urb->transfer_buffer + | ||
224 | urb->iso_frame_desc[i].offset; | ||
225 | iov[iovnum].iov_len = | ||
226 | urb->iso_frame_desc[i].actual_length; | ||
227 | iovnum++; | ||
228 | txsize += urb->iso_frame_desc[i].actual_length; | ||
229 | } | ||
230 | |||
231 | if (txsize != sizeof(pdu_header) + urb->actual_length) { | ||
232 | dev_err(&sdev->interface->dev, | ||
233 | "actual length of urb %d does not match iso packet sizes %zu\n", | ||
234 | urb->actual_length, | ||
235 | txsize-sizeof(pdu_header)); | ||
236 | kfree(iov); | ||
237 | usbip_event_add(&sdev->ud, | ||
238 | SDEV_EVENT_ERROR_TCP); | ||
239 | return -1; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | /* 3. setup iso_packet_descriptor */ | ||
244 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
245 | ssize_t len = 0; | ||
246 | |||
247 | iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len); | ||
248 | if (!iso_buffer) { | ||
249 | usbip_event_add(&sdev->ud, | ||
250 | SDEV_EVENT_ERROR_MALLOC); | ||
251 | kfree(iov); | ||
252 | return -1; | ||
253 | } | ||
254 | |||
255 | iov[iovnum].iov_base = iso_buffer; | ||
256 | iov[iovnum].iov_len = len; | ||
257 | txsize += len; | ||
258 | iovnum++; | ||
259 | } | ||
260 | |||
261 | ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, | ||
262 | iov, iovnum, txsize); | ||
263 | if (ret != txsize) { | ||
264 | dev_err(&sdev->interface->dev, | ||
265 | "sendmsg failed!, retval %d for %zd\n", | ||
266 | ret, txsize); | ||
267 | kfree(iov); | ||
268 | kfree(iso_buffer); | ||
269 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); | ||
270 | return -1; | ||
271 | } | ||
272 | |||
273 | kfree(iov); | ||
274 | kfree(iso_buffer); | ||
275 | |||
276 | total_size += txsize; | ||
277 | } | ||
278 | |||
279 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
280 | list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) { | ||
281 | stub_free_priv_and_urb(priv); | ||
282 | } | ||
283 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
284 | |||
285 | return total_size; | ||
286 | } | ||
287 | |||
288 | static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev) | ||
289 | { | ||
290 | unsigned long flags; | ||
291 | struct stub_unlink *unlink, *tmp; | ||
292 | |||
293 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
294 | |||
295 | list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) { | ||
296 | list_move_tail(&unlink->list, &sdev->unlink_free); | ||
297 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
298 | return unlink; | ||
299 | } | ||
300 | |||
301 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
302 | |||
303 | return NULL; | ||
304 | } | ||
305 | |||
306 | static int stub_send_ret_unlink(struct stub_device *sdev) | ||
307 | { | ||
308 | unsigned long flags; | ||
309 | struct stub_unlink *unlink, *tmp; | ||
310 | |||
311 | struct msghdr msg; | ||
312 | struct kvec iov[1]; | ||
313 | size_t txsize; | ||
314 | |||
315 | size_t total_size = 0; | ||
316 | |||
317 | while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) { | ||
318 | int ret; | ||
319 | struct usbip_header pdu_header; | ||
320 | |||
321 | txsize = 0; | ||
322 | memset(&pdu_header, 0, sizeof(pdu_header)); | ||
323 | memset(&msg, 0, sizeof(msg)); | ||
324 | memset(&iov, 0, sizeof(iov)); | ||
325 | |||
326 | usbip_dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum); | ||
327 | |||
328 | /* 1. setup usbip_header */ | ||
329 | setup_ret_unlink_pdu(&pdu_header, unlink); | ||
330 | usbip_header_correct_endian(&pdu_header, 1); | ||
331 | |||
332 | iov[0].iov_base = &pdu_header; | ||
333 | iov[0].iov_len = sizeof(pdu_header); | ||
334 | txsize += sizeof(pdu_header); | ||
335 | |||
336 | ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, | ||
337 | 1, txsize); | ||
338 | if (ret != txsize) { | ||
339 | dev_err(&sdev->interface->dev, | ||
340 | "sendmsg failed!, retval %d for %zd\n", | ||
341 | ret, txsize); | ||
342 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); | ||
343 | return -1; | ||
344 | } | ||
345 | |||
346 | usbip_dbg_stub_tx("send txdata\n"); | ||
347 | total_size += txsize; | ||
348 | } | ||
349 | |||
350 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
351 | |||
352 | list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) { | ||
353 | list_del(&unlink->list); | ||
354 | kfree(unlink); | ||
355 | } | ||
356 | |||
357 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
358 | |||
359 | return total_size; | ||
360 | } | ||
361 | |||
362 | int stub_tx_loop(void *data) | ||
363 | { | ||
364 | struct usbip_device *ud = data; | ||
365 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); | ||
366 | |||
367 | while (!kthread_should_stop()) { | ||
368 | if (usbip_event_happened(ud)) | ||
369 | break; | ||
370 | |||
371 | /* | ||
372 | * send_ret_submit comes earlier than send_ret_unlink. stub_rx | ||
373 | * looks at only priv_init queue. If the completion of a URB is | ||
374 | * earlier than the receive of CMD_UNLINK, priv is moved to | ||
375 | * priv_tx queue and stub_rx does not find the target priv. In | ||
376 | * this case, vhci_rx receives the result of the submit request | ||
377 | * and then receives the result of the unlink request. The | ||
378 | * result of the submit is given back to the usbcore as the | ||
379 | * completion of the unlink request. The request of the | ||
380 | * unlink is ignored. This is ok because a driver who calls | ||
381 | * usb_unlink_urb() understands the unlink was too late by | ||
382 | * getting the status of the given-backed URB which has the | ||
383 | * status of usb_submit_urb(). | ||
384 | */ | ||
385 | if (stub_send_ret_submit(sdev) < 0) | ||
386 | break; | ||
387 | |||
388 | if (stub_send_ret_unlink(sdev) < 0) | ||
389 | break; | ||
390 | |||
391 | wait_event_interruptible(sdev->tx_waitq, | ||
392 | (!list_empty(&sdev->priv_tx) || | ||
393 | !list_empty(&sdev->unlink_tx) || | ||
394 | kthread_should_stop())); | ||
395 | } | ||
396 | |||
397 | return 0; | ||
398 | } | ||
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c new file mode 100644 index 000000000000..facaaf003f19 --- /dev/null +++ b/drivers/usb/usbip/usbip_common.c | |||
@@ -0,0 +1,776 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <asm/byteorder.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/stat.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/moduleparam.h> | ||
28 | #include <net/sock.h> | ||
29 | |||
30 | #include "usbip_common.h" | ||
31 | |||
32 | #define DRIVER_AUTHOR "Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>" | ||
33 | #define DRIVER_DESC "USB/IP Core" | ||
34 | |||
35 | #ifdef CONFIG_USBIP_DEBUG | ||
36 | unsigned long usbip_debug_flag = 0xffffffff; | ||
37 | #else | ||
38 | unsigned long usbip_debug_flag; | ||
39 | #endif | ||
40 | EXPORT_SYMBOL_GPL(usbip_debug_flag); | ||
41 | module_param(usbip_debug_flag, ulong, S_IRUGO|S_IWUSR); | ||
42 | MODULE_PARM_DESC(usbip_debug_flag, "debug flags (defined in usbip_common.h)"); | ||
43 | |||
44 | /* FIXME */ | ||
45 | struct device_attribute dev_attr_usbip_debug; | ||
46 | EXPORT_SYMBOL_GPL(dev_attr_usbip_debug); | ||
47 | |||
48 | static ssize_t usbip_debug_show(struct device *dev, | ||
49 | struct device_attribute *attr, char *buf) | ||
50 | { | ||
51 | return sprintf(buf, "%lx\n", usbip_debug_flag); | ||
52 | } | ||
53 | |||
54 | static ssize_t usbip_debug_store(struct device *dev, | ||
55 | struct device_attribute *attr, const char *buf, | ||
56 | size_t count) | ||
57 | { | ||
58 | if (sscanf(buf, "%lx", &usbip_debug_flag) != 1) | ||
59 | return -EINVAL; | ||
60 | return count; | ||
61 | } | ||
62 | DEVICE_ATTR_RW(usbip_debug); | ||
63 | |||
64 | static void usbip_dump_buffer(char *buff, int bufflen) | ||
65 | { | ||
66 | print_hex_dump(KERN_DEBUG, "usbip-core", DUMP_PREFIX_OFFSET, 16, 4, | ||
67 | buff, bufflen, false); | ||
68 | } | ||
69 | |||
70 | static void usbip_dump_pipe(unsigned int p) | ||
71 | { | ||
72 | unsigned char type = usb_pipetype(p); | ||
73 | unsigned char ep = usb_pipeendpoint(p); | ||
74 | unsigned char dev = usb_pipedevice(p); | ||
75 | unsigned char dir = usb_pipein(p); | ||
76 | |||
77 | pr_debug("dev(%d) ep(%d) [%s] ", dev, ep, dir ? "IN" : "OUT"); | ||
78 | |||
79 | switch (type) { | ||
80 | case PIPE_ISOCHRONOUS: | ||
81 | pr_debug("ISO\n"); | ||
82 | break; | ||
83 | case PIPE_INTERRUPT: | ||
84 | pr_debug("INT\n"); | ||
85 | break; | ||
86 | case PIPE_CONTROL: | ||
87 | pr_debug("CTRL\n"); | ||
88 | break; | ||
89 | case PIPE_BULK: | ||
90 | pr_debug("BULK\n"); | ||
91 | break; | ||
92 | default: | ||
93 | pr_debug("ERR\n"); | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | static void usbip_dump_usb_device(struct usb_device *udev) | ||
99 | { | ||
100 | struct device *dev = &udev->dev; | ||
101 | int i; | ||
102 | |||
103 | dev_dbg(dev, " devnum(%d) devpath(%s) usb speed(%s)", | ||
104 | udev->devnum, udev->devpath, usb_speed_string(udev->speed)); | ||
105 | |||
106 | pr_debug("tt %p, ttport %d\n", udev->tt, udev->ttport); | ||
107 | |||
108 | dev_dbg(dev, " "); | ||
109 | for (i = 0; i < 16; i++) | ||
110 | pr_debug(" %2u", i); | ||
111 | pr_debug("\n"); | ||
112 | |||
113 | dev_dbg(dev, " toggle0(IN) :"); | ||
114 | for (i = 0; i < 16; i++) | ||
115 | pr_debug(" %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0); | ||
116 | pr_debug("\n"); | ||
117 | |||
118 | dev_dbg(dev, " toggle1(OUT):"); | ||
119 | for (i = 0; i < 16; i++) | ||
120 | pr_debug(" %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0); | ||
121 | pr_debug("\n"); | ||
122 | |||
123 | dev_dbg(dev, " epmaxp_in :"); | ||
124 | for (i = 0; i < 16; i++) { | ||
125 | if (udev->ep_in[i]) | ||
126 | pr_debug(" %2u", | ||
127 | le16_to_cpu(udev->ep_in[i]->desc.wMaxPacketSize)); | ||
128 | } | ||
129 | pr_debug("\n"); | ||
130 | |||
131 | dev_dbg(dev, " epmaxp_out :"); | ||
132 | for (i = 0; i < 16; i++) { | ||
133 | if (udev->ep_out[i]) | ||
134 | pr_debug(" %2u", | ||
135 | le16_to_cpu(udev->ep_out[i]->desc.wMaxPacketSize)); | ||
136 | } | ||
137 | pr_debug("\n"); | ||
138 | |||
139 | dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus); | ||
140 | |||
141 | dev_dbg(dev, | ||
142 | "descriptor %p, config %p, actconfig %p, rawdescriptors %p\n", | ||
143 | &udev->descriptor, udev->config, | ||
144 | udev->actconfig, udev->rawdescriptors); | ||
145 | |||
146 | dev_dbg(dev, "have_langid %d, string_langid %d\n", | ||
147 | udev->have_langid, udev->string_langid); | ||
148 | |||
149 | dev_dbg(dev, "maxchild %d\n", udev->maxchild); | ||
150 | } | ||
151 | |||
152 | static void usbip_dump_request_type(__u8 rt) | ||
153 | { | ||
154 | switch (rt & USB_RECIP_MASK) { | ||
155 | case USB_RECIP_DEVICE: | ||
156 | pr_debug("DEVICE"); | ||
157 | break; | ||
158 | case USB_RECIP_INTERFACE: | ||
159 | pr_debug("INTERF"); | ||
160 | break; | ||
161 | case USB_RECIP_ENDPOINT: | ||
162 | pr_debug("ENDPOI"); | ||
163 | break; | ||
164 | case USB_RECIP_OTHER: | ||
165 | pr_debug("OTHER "); | ||
166 | break; | ||
167 | default: | ||
168 | pr_debug("------"); | ||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd) | ||
174 | { | ||
175 | if (!cmd) { | ||
176 | pr_debug(" : null pointer\n"); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | pr_debug(" "); | ||
181 | pr_debug("bRequestType(%02X) bRequest(%02X) wValue(%04X) wIndex(%04X) wLength(%04X) ", | ||
182 | cmd->bRequestType, cmd->bRequest, | ||
183 | cmd->wValue, cmd->wIndex, cmd->wLength); | ||
184 | pr_debug("\n "); | ||
185 | |||
186 | if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | ||
187 | pr_debug("STANDARD "); | ||
188 | switch (cmd->bRequest) { | ||
189 | case USB_REQ_GET_STATUS: | ||
190 | pr_debug("GET_STATUS\n"); | ||
191 | break; | ||
192 | case USB_REQ_CLEAR_FEATURE: | ||
193 | pr_debug("CLEAR_FEAT\n"); | ||
194 | break; | ||
195 | case USB_REQ_SET_FEATURE: | ||
196 | pr_debug("SET_FEAT\n"); | ||
197 | break; | ||
198 | case USB_REQ_SET_ADDRESS: | ||
199 | pr_debug("SET_ADDRRS\n"); | ||
200 | break; | ||
201 | case USB_REQ_GET_DESCRIPTOR: | ||
202 | pr_debug("GET_DESCRI\n"); | ||
203 | break; | ||
204 | case USB_REQ_SET_DESCRIPTOR: | ||
205 | pr_debug("SET_DESCRI\n"); | ||
206 | break; | ||
207 | case USB_REQ_GET_CONFIGURATION: | ||
208 | pr_debug("GET_CONFIG\n"); | ||
209 | break; | ||
210 | case USB_REQ_SET_CONFIGURATION: | ||
211 | pr_debug("SET_CONFIG\n"); | ||
212 | break; | ||
213 | case USB_REQ_GET_INTERFACE: | ||
214 | pr_debug("GET_INTERF\n"); | ||
215 | break; | ||
216 | case USB_REQ_SET_INTERFACE: | ||
217 | pr_debug("SET_INTERF\n"); | ||
218 | break; | ||
219 | case USB_REQ_SYNCH_FRAME: | ||
220 | pr_debug("SYNC_FRAME\n"); | ||
221 | break; | ||
222 | default: | ||
223 | pr_debug("REQ(%02X)\n", cmd->bRequest); | ||
224 | break; | ||
225 | } | ||
226 | usbip_dump_request_type(cmd->bRequestType); | ||
227 | } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { | ||
228 | pr_debug("CLASS\n"); | ||
229 | } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { | ||
230 | pr_debug("VENDOR\n"); | ||
231 | } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED) { | ||
232 | pr_debug("RESERVED\n"); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | void usbip_dump_urb(struct urb *urb) | ||
237 | { | ||
238 | struct device *dev; | ||
239 | |||
240 | if (!urb) { | ||
241 | pr_debug("urb: null pointer!!\n"); | ||
242 | return; | ||
243 | } | ||
244 | |||
245 | if (!urb->dev) { | ||
246 | pr_debug("urb->dev: null pointer!!\n"); | ||
247 | return; | ||
248 | } | ||
249 | |||
250 | dev = &urb->dev->dev; | ||
251 | |||
252 | dev_dbg(dev, " urb :%p\n", urb); | ||
253 | dev_dbg(dev, " dev :%p\n", urb->dev); | ||
254 | |||
255 | usbip_dump_usb_device(urb->dev); | ||
256 | |||
257 | dev_dbg(dev, " pipe :%08x ", urb->pipe); | ||
258 | |||
259 | usbip_dump_pipe(urb->pipe); | ||
260 | |||
261 | dev_dbg(dev, " status :%d\n", urb->status); | ||
262 | dev_dbg(dev, " transfer_flags :%08X\n", urb->transfer_flags); | ||
263 | dev_dbg(dev, " transfer_buffer :%p\n", urb->transfer_buffer); | ||
264 | dev_dbg(dev, " transfer_buffer_length:%d\n", | ||
265 | urb->transfer_buffer_length); | ||
266 | dev_dbg(dev, " actual_length :%d\n", urb->actual_length); | ||
267 | dev_dbg(dev, " setup_packet :%p\n", urb->setup_packet); | ||
268 | |||
269 | if (urb->setup_packet && usb_pipetype(urb->pipe) == PIPE_CONTROL) | ||
270 | usbip_dump_usb_ctrlrequest( | ||
271 | (struct usb_ctrlrequest *)urb->setup_packet); | ||
272 | |||
273 | dev_dbg(dev, " start_frame :%d\n", urb->start_frame); | ||
274 | dev_dbg(dev, " number_of_packets :%d\n", urb->number_of_packets); | ||
275 | dev_dbg(dev, " interval :%d\n", urb->interval); | ||
276 | dev_dbg(dev, " error_count :%d\n", urb->error_count); | ||
277 | dev_dbg(dev, " context :%p\n", urb->context); | ||
278 | dev_dbg(dev, " complete :%p\n", urb->complete); | ||
279 | } | ||
280 | EXPORT_SYMBOL_GPL(usbip_dump_urb); | ||
281 | |||
282 | void usbip_dump_header(struct usbip_header *pdu) | ||
283 | { | ||
284 | pr_debug("BASE: cmd %u seq %u devid %u dir %u ep %u\n", | ||
285 | pdu->base.command, | ||
286 | pdu->base.seqnum, | ||
287 | pdu->base.devid, | ||
288 | pdu->base.direction, | ||
289 | pdu->base.ep); | ||
290 | |||
291 | switch (pdu->base.command) { | ||
292 | case USBIP_CMD_SUBMIT: | ||
293 | pr_debug("USBIP_CMD_SUBMIT: x_flags %u x_len %u sf %u #p %d iv %d\n", | ||
294 | pdu->u.cmd_submit.transfer_flags, | ||
295 | pdu->u.cmd_submit.transfer_buffer_length, | ||
296 | pdu->u.cmd_submit.start_frame, | ||
297 | pdu->u.cmd_submit.number_of_packets, | ||
298 | pdu->u.cmd_submit.interval); | ||
299 | break; | ||
300 | case USBIP_CMD_UNLINK: | ||
301 | pr_debug("USBIP_CMD_UNLINK: seq %u\n", | ||
302 | pdu->u.cmd_unlink.seqnum); | ||
303 | break; | ||
304 | case USBIP_RET_SUBMIT: | ||
305 | pr_debug("USBIP_RET_SUBMIT: st %d al %u sf %d #p %d ec %d\n", | ||
306 | pdu->u.ret_submit.status, | ||
307 | pdu->u.ret_submit.actual_length, | ||
308 | pdu->u.ret_submit.start_frame, | ||
309 | pdu->u.ret_submit.number_of_packets, | ||
310 | pdu->u.ret_submit.error_count); | ||
311 | break; | ||
312 | case USBIP_RET_UNLINK: | ||
313 | pr_debug("USBIP_RET_UNLINK: status %d\n", | ||
314 | pdu->u.ret_unlink.status); | ||
315 | break; | ||
316 | default: | ||
317 | /* NOT REACHED */ | ||
318 | pr_err("unknown command\n"); | ||
319 | break; | ||
320 | } | ||
321 | } | ||
322 | EXPORT_SYMBOL_GPL(usbip_dump_header); | ||
323 | |||
324 | /* Receive data over TCP/IP. */ | ||
325 | int usbip_recv(struct socket *sock, void *buf, int size) | ||
326 | { | ||
327 | int result; | ||
328 | struct msghdr msg; | ||
329 | struct kvec iov; | ||
330 | int total = 0; | ||
331 | |||
332 | /* for blocks of if (usbip_dbg_flag_xmit) */ | ||
333 | char *bp = buf; | ||
334 | int osize = size; | ||
335 | |||
336 | usbip_dbg_xmit("enter\n"); | ||
337 | |||
338 | if (!sock || !buf || !size) { | ||
339 | pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf, | ||
340 | size); | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | |||
344 | do { | ||
345 | sock->sk->sk_allocation = GFP_NOIO; | ||
346 | iov.iov_base = buf; | ||
347 | iov.iov_len = size; | ||
348 | msg.msg_name = NULL; | ||
349 | msg.msg_namelen = 0; | ||
350 | msg.msg_control = NULL; | ||
351 | msg.msg_controllen = 0; | ||
352 | msg.msg_flags = MSG_NOSIGNAL; | ||
353 | |||
354 | result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL); | ||
355 | if (result <= 0) { | ||
356 | pr_debug("receive sock %p buf %p size %u ret %d total %d\n", | ||
357 | sock, buf, size, result, total); | ||
358 | goto err; | ||
359 | } | ||
360 | |||
361 | size -= result; | ||
362 | buf += result; | ||
363 | total += result; | ||
364 | } while (size > 0); | ||
365 | |||
366 | if (usbip_dbg_flag_xmit) { | ||
367 | if (!in_interrupt()) | ||
368 | pr_debug("%-10s:", current->comm); | ||
369 | else | ||
370 | pr_debug("interrupt :"); | ||
371 | |||
372 | pr_debug("receiving....\n"); | ||
373 | usbip_dump_buffer(bp, osize); | ||
374 | pr_debug("received, osize %d ret %d size %d total %d\n", | ||
375 | osize, result, size, total); | ||
376 | } | ||
377 | |||
378 | return total; | ||
379 | |||
380 | err: | ||
381 | return result; | ||
382 | } | ||
383 | EXPORT_SYMBOL_GPL(usbip_recv); | ||
384 | |||
385 | /* there may be more cases to tweak the flags. */ | ||
386 | static unsigned int tweak_transfer_flags(unsigned int flags) | ||
387 | { | ||
388 | flags &= ~URB_NO_TRANSFER_DMA_MAP; | ||
389 | return flags; | ||
390 | } | ||
391 | |||
392 | static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, | ||
393 | int pack) | ||
394 | { | ||
395 | struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit; | ||
396 | |||
397 | /* | ||
398 | * Some members are not still implemented in usbip. I hope this issue | ||
399 | * will be discussed when usbip is ported to other operating systems. | ||
400 | */ | ||
401 | if (pack) { | ||
402 | spdu->transfer_flags = | ||
403 | tweak_transfer_flags(urb->transfer_flags); | ||
404 | spdu->transfer_buffer_length = urb->transfer_buffer_length; | ||
405 | spdu->start_frame = urb->start_frame; | ||
406 | spdu->number_of_packets = urb->number_of_packets; | ||
407 | spdu->interval = urb->interval; | ||
408 | } else { | ||
409 | urb->transfer_flags = spdu->transfer_flags; | ||
410 | urb->transfer_buffer_length = spdu->transfer_buffer_length; | ||
411 | urb->start_frame = spdu->start_frame; | ||
412 | urb->number_of_packets = spdu->number_of_packets; | ||
413 | urb->interval = spdu->interval; | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, | ||
418 | int pack) | ||
419 | { | ||
420 | struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit; | ||
421 | |||
422 | if (pack) { | ||
423 | rpdu->status = urb->status; | ||
424 | rpdu->actual_length = urb->actual_length; | ||
425 | rpdu->start_frame = urb->start_frame; | ||
426 | rpdu->number_of_packets = urb->number_of_packets; | ||
427 | rpdu->error_count = urb->error_count; | ||
428 | } else { | ||
429 | urb->status = rpdu->status; | ||
430 | urb->actual_length = rpdu->actual_length; | ||
431 | urb->start_frame = rpdu->start_frame; | ||
432 | urb->number_of_packets = rpdu->number_of_packets; | ||
433 | urb->error_count = rpdu->error_count; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, | ||
438 | int pack) | ||
439 | { | ||
440 | switch (cmd) { | ||
441 | case USBIP_CMD_SUBMIT: | ||
442 | usbip_pack_cmd_submit(pdu, urb, pack); | ||
443 | break; | ||
444 | case USBIP_RET_SUBMIT: | ||
445 | usbip_pack_ret_submit(pdu, urb, pack); | ||
446 | break; | ||
447 | default: | ||
448 | /* NOT REACHED */ | ||
449 | pr_err("unknown command\n"); | ||
450 | break; | ||
451 | } | ||
452 | } | ||
453 | EXPORT_SYMBOL_GPL(usbip_pack_pdu); | ||
454 | |||
455 | static void correct_endian_basic(struct usbip_header_basic *base, int send) | ||
456 | { | ||
457 | if (send) { | ||
458 | base->command = cpu_to_be32(base->command); | ||
459 | base->seqnum = cpu_to_be32(base->seqnum); | ||
460 | base->devid = cpu_to_be32(base->devid); | ||
461 | base->direction = cpu_to_be32(base->direction); | ||
462 | base->ep = cpu_to_be32(base->ep); | ||
463 | } else { | ||
464 | base->command = be32_to_cpu(base->command); | ||
465 | base->seqnum = be32_to_cpu(base->seqnum); | ||
466 | base->devid = be32_to_cpu(base->devid); | ||
467 | base->direction = be32_to_cpu(base->direction); | ||
468 | base->ep = be32_to_cpu(base->ep); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu, | ||
473 | int send) | ||
474 | { | ||
475 | if (send) { | ||
476 | pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags); | ||
477 | |||
478 | cpu_to_be32s(&pdu->transfer_buffer_length); | ||
479 | cpu_to_be32s(&pdu->start_frame); | ||
480 | cpu_to_be32s(&pdu->number_of_packets); | ||
481 | cpu_to_be32s(&pdu->interval); | ||
482 | } else { | ||
483 | pdu->transfer_flags = be32_to_cpu(pdu->transfer_flags); | ||
484 | |||
485 | be32_to_cpus(&pdu->transfer_buffer_length); | ||
486 | be32_to_cpus(&pdu->start_frame); | ||
487 | be32_to_cpus(&pdu->number_of_packets); | ||
488 | be32_to_cpus(&pdu->interval); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, | ||
493 | int send) | ||
494 | { | ||
495 | if (send) { | ||
496 | cpu_to_be32s(&pdu->status); | ||
497 | cpu_to_be32s(&pdu->actual_length); | ||
498 | cpu_to_be32s(&pdu->start_frame); | ||
499 | cpu_to_be32s(&pdu->number_of_packets); | ||
500 | cpu_to_be32s(&pdu->error_count); | ||
501 | } else { | ||
502 | be32_to_cpus(&pdu->status); | ||
503 | be32_to_cpus(&pdu->actual_length); | ||
504 | be32_to_cpus(&pdu->start_frame); | ||
505 | be32_to_cpus(&pdu->number_of_packets); | ||
506 | be32_to_cpus(&pdu->error_count); | ||
507 | } | ||
508 | } | ||
509 | |||
510 | static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu, | ||
511 | int send) | ||
512 | { | ||
513 | if (send) | ||
514 | pdu->seqnum = cpu_to_be32(pdu->seqnum); | ||
515 | else | ||
516 | pdu->seqnum = be32_to_cpu(pdu->seqnum); | ||
517 | } | ||
518 | |||
519 | static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu, | ||
520 | int send) | ||
521 | { | ||
522 | if (send) | ||
523 | cpu_to_be32s(&pdu->status); | ||
524 | else | ||
525 | be32_to_cpus(&pdu->status); | ||
526 | } | ||
527 | |||
528 | void usbip_header_correct_endian(struct usbip_header *pdu, int send) | ||
529 | { | ||
530 | __u32 cmd = 0; | ||
531 | |||
532 | if (send) | ||
533 | cmd = pdu->base.command; | ||
534 | |||
535 | correct_endian_basic(&pdu->base, send); | ||
536 | |||
537 | if (!send) | ||
538 | cmd = pdu->base.command; | ||
539 | |||
540 | switch (cmd) { | ||
541 | case USBIP_CMD_SUBMIT: | ||
542 | correct_endian_cmd_submit(&pdu->u.cmd_submit, send); | ||
543 | break; | ||
544 | case USBIP_RET_SUBMIT: | ||
545 | correct_endian_ret_submit(&pdu->u.ret_submit, send); | ||
546 | break; | ||
547 | case USBIP_CMD_UNLINK: | ||
548 | correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send); | ||
549 | break; | ||
550 | case USBIP_RET_UNLINK: | ||
551 | correct_endian_ret_unlink(&pdu->u.ret_unlink, send); | ||
552 | break; | ||
553 | default: | ||
554 | /* NOT REACHED */ | ||
555 | pr_err("unknown command\n"); | ||
556 | break; | ||
557 | } | ||
558 | } | ||
559 | EXPORT_SYMBOL_GPL(usbip_header_correct_endian); | ||
560 | |||
561 | static void usbip_iso_packet_correct_endian( | ||
562 | struct usbip_iso_packet_descriptor *iso, int send) | ||
563 | { | ||
564 | /* does not need all members. but copy all simply. */ | ||
565 | if (send) { | ||
566 | iso->offset = cpu_to_be32(iso->offset); | ||
567 | iso->length = cpu_to_be32(iso->length); | ||
568 | iso->status = cpu_to_be32(iso->status); | ||
569 | iso->actual_length = cpu_to_be32(iso->actual_length); | ||
570 | } else { | ||
571 | iso->offset = be32_to_cpu(iso->offset); | ||
572 | iso->length = be32_to_cpu(iso->length); | ||
573 | iso->status = be32_to_cpu(iso->status); | ||
574 | iso->actual_length = be32_to_cpu(iso->actual_length); | ||
575 | } | ||
576 | } | ||
577 | |||
578 | static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso, | ||
579 | struct usb_iso_packet_descriptor *uiso, int pack) | ||
580 | { | ||
581 | if (pack) { | ||
582 | iso->offset = uiso->offset; | ||
583 | iso->length = uiso->length; | ||
584 | iso->status = uiso->status; | ||
585 | iso->actual_length = uiso->actual_length; | ||
586 | } else { | ||
587 | uiso->offset = iso->offset; | ||
588 | uiso->length = iso->length; | ||
589 | uiso->status = iso->status; | ||
590 | uiso->actual_length = iso->actual_length; | ||
591 | } | ||
592 | } | ||
593 | |||
594 | /* must free buffer */ | ||
595 | struct usbip_iso_packet_descriptor* | ||
596 | usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen) | ||
597 | { | ||
598 | struct usbip_iso_packet_descriptor *iso; | ||
599 | int np = urb->number_of_packets; | ||
600 | ssize_t size = np * sizeof(*iso); | ||
601 | int i; | ||
602 | |||
603 | iso = kzalloc(size, GFP_KERNEL); | ||
604 | if (!iso) | ||
605 | return NULL; | ||
606 | |||
607 | for (i = 0; i < np; i++) { | ||
608 | usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 1); | ||
609 | usbip_iso_packet_correct_endian(&iso[i], 1); | ||
610 | } | ||
611 | |||
612 | *bufflen = size; | ||
613 | |||
614 | return iso; | ||
615 | } | ||
616 | EXPORT_SYMBOL_GPL(usbip_alloc_iso_desc_pdu); | ||
617 | |||
618 | /* some members of urb must be substituted before. */ | ||
619 | int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) | ||
620 | { | ||
621 | void *buff; | ||
622 | struct usbip_iso_packet_descriptor *iso; | ||
623 | int np = urb->number_of_packets; | ||
624 | int size = np * sizeof(*iso); | ||
625 | int i; | ||
626 | int ret; | ||
627 | int total_length = 0; | ||
628 | |||
629 | if (!usb_pipeisoc(urb->pipe)) | ||
630 | return 0; | ||
631 | |||
632 | /* my Bluetooth dongle gets ISO URBs which are np = 0 */ | ||
633 | if (np == 0) | ||
634 | return 0; | ||
635 | |||
636 | buff = kzalloc(size, GFP_KERNEL); | ||
637 | if (!buff) | ||
638 | return -ENOMEM; | ||
639 | |||
640 | ret = usbip_recv(ud->tcp_socket, buff, size); | ||
641 | if (ret != size) { | ||
642 | dev_err(&urb->dev->dev, "recv iso_frame_descriptor, %d\n", | ||
643 | ret); | ||
644 | kfree(buff); | ||
645 | |||
646 | if (ud->side == USBIP_STUB) | ||
647 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
648 | else | ||
649 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
650 | |||
651 | return -EPIPE; | ||
652 | } | ||
653 | |||
654 | iso = (struct usbip_iso_packet_descriptor *) buff; | ||
655 | for (i = 0; i < np; i++) { | ||
656 | usbip_iso_packet_correct_endian(&iso[i], 0); | ||
657 | usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 0); | ||
658 | total_length += urb->iso_frame_desc[i].actual_length; | ||
659 | } | ||
660 | |||
661 | kfree(buff); | ||
662 | |||
663 | if (total_length != urb->actual_length) { | ||
664 | dev_err(&urb->dev->dev, | ||
665 | "total length of iso packets %d not equal to actual length of buffer %d\n", | ||
666 | total_length, urb->actual_length); | ||
667 | |||
668 | if (ud->side == USBIP_STUB) | ||
669 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
670 | else | ||
671 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
672 | |||
673 | return -EPIPE; | ||
674 | } | ||
675 | |||
676 | return ret; | ||
677 | } | ||
678 | EXPORT_SYMBOL_GPL(usbip_recv_iso); | ||
679 | |||
680 | /* | ||
681 | * This functions restores the padding which was removed for optimizing | ||
682 | * the bandwidth during transfer over tcp/ip | ||
683 | * | ||
684 | * buffer and iso packets need to be stored and be in propeper endian in urb | ||
685 | * before calling this function | ||
686 | */ | ||
687 | void usbip_pad_iso(struct usbip_device *ud, struct urb *urb) | ||
688 | { | ||
689 | int np = urb->number_of_packets; | ||
690 | int i; | ||
691 | int actualoffset = urb->actual_length; | ||
692 | |||
693 | if (!usb_pipeisoc(urb->pipe)) | ||
694 | return; | ||
695 | |||
696 | /* if no packets or length of data is 0, then nothing to unpack */ | ||
697 | if (np == 0 || urb->actual_length == 0) | ||
698 | return; | ||
699 | |||
700 | /* | ||
701 | * if actual_length is transfer_buffer_length then no padding is | ||
702 | * present. | ||
703 | */ | ||
704 | if (urb->actual_length == urb->transfer_buffer_length) | ||
705 | return; | ||
706 | |||
707 | /* | ||
708 | * loop over all packets from last to first (to prevent overwritting | ||
709 | * memory when padding) and move them into the proper place | ||
710 | */ | ||
711 | for (i = np-1; i > 0; i--) { | ||
712 | actualoffset -= urb->iso_frame_desc[i].actual_length; | ||
713 | memmove(urb->transfer_buffer + urb->iso_frame_desc[i].offset, | ||
714 | urb->transfer_buffer + actualoffset, | ||
715 | urb->iso_frame_desc[i].actual_length); | ||
716 | } | ||
717 | } | ||
718 | EXPORT_SYMBOL_GPL(usbip_pad_iso); | ||
719 | |||
720 | /* some members of urb must be substituted before. */ | ||
721 | int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) | ||
722 | { | ||
723 | int ret; | ||
724 | int size; | ||
725 | |||
726 | if (ud->side == USBIP_STUB) { | ||
727 | /* the direction of urb must be OUT. */ | ||
728 | if (usb_pipein(urb->pipe)) | ||
729 | return 0; | ||
730 | |||
731 | size = urb->transfer_buffer_length; | ||
732 | } else { | ||
733 | /* the direction of urb must be IN. */ | ||
734 | if (usb_pipeout(urb->pipe)) | ||
735 | return 0; | ||
736 | |||
737 | size = urb->actual_length; | ||
738 | } | ||
739 | |||
740 | /* no need to recv xbuff */ | ||
741 | if (!(size > 0)) | ||
742 | return 0; | ||
743 | |||
744 | ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size); | ||
745 | if (ret != size) { | ||
746 | dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret); | ||
747 | if (ud->side == USBIP_STUB) { | ||
748 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
749 | } else { | ||
750 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
751 | return -EPIPE; | ||
752 | } | ||
753 | } | ||
754 | |||
755 | return ret; | ||
756 | } | ||
757 | EXPORT_SYMBOL_GPL(usbip_recv_xbuff); | ||
758 | |||
759 | static int __init usbip_core_init(void) | ||
760 | { | ||
761 | pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); | ||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static void __exit usbip_core_exit(void) | ||
766 | { | ||
767 | return; | ||
768 | } | ||
769 | |||
770 | module_init(usbip_core_init); | ||
771 | module_exit(usbip_core_exit); | ||
772 | |||
773 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
774 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
775 | MODULE_LICENSE("GPL"); | ||
776 | MODULE_VERSION(USBIP_VERSION); | ||
diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h new file mode 100644 index 000000000000..86b08475c254 --- /dev/null +++ b/drivers/usb/usbip/usbip_common.h | |||
@@ -0,0 +1,335 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef __USBIP_COMMON_H | ||
21 | #define __USBIP_COMMON_H | ||
22 | |||
23 | #include <linux/compiler.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/net.h> | ||
27 | #include <linux/printk.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/usb.h> | ||
31 | #include <linux/wait.h> | ||
32 | #include <uapi/linux/usbip.h> | ||
33 | |||
34 | #define USBIP_VERSION "1.0.0" | ||
35 | |||
36 | #undef pr_fmt | ||
37 | |||
38 | #ifdef DEBUG | ||
39 | #define pr_fmt(fmt) KBUILD_MODNAME ": %s:%d: " fmt, __func__, __LINE__ | ||
40 | #else | ||
41 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
42 | #endif | ||
43 | |||
44 | enum { | ||
45 | usbip_debug_xmit = (1 << 0), | ||
46 | usbip_debug_sysfs = (1 << 1), | ||
47 | usbip_debug_urb = (1 << 2), | ||
48 | usbip_debug_eh = (1 << 3), | ||
49 | |||
50 | usbip_debug_stub_cmp = (1 << 8), | ||
51 | usbip_debug_stub_dev = (1 << 9), | ||
52 | usbip_debug_stub_rx = (1 << 10), | ||
53 | usbip_debug_stub_tx = (1 << 11), | ||
54 | |||
55 | usbip_debug_vhci_rh = (1 << 8), | ||
56 | usbip_debug_vhci_hc = (1 << 9), | ||
57 | usbip_debug_vhci_rx = (1 << 10), | ||
58 | usbip_debug_vhci_tx = (1 << 11), | ||
59 | usbip_debug_vhci_sysfs = (1 << 12) | ||
60 | }; | ||
61 | |||
62 | #define usbip_dbg_flag_xmit (usbip_debug_flag & usbip_debug_xmit) | ||
63 | #define usbip_dbg_flag_vhci_rh (usbip_debug_flag & usbip_debug_vhci_rh) | ||
64 | #define usbip_dbg_flag_vhci_hc (usbip_debug_flag & usbip_debug_vhci_hc) | ||
65 | #define usbip_dbg_flag_vhci_rx (usbip_debug_flag & usbip_debug_vhci_rx) | ||
66 | #define usbip_dbg_flag_vhci_tx (usbip_debug_flag & usbip_debug_vhci_tx) | ||
67 | #define usbip_dbg_flag_stub_rx (usbip_debug_flag & usbip_debug_stub_rx) | ||
68 | #define usbip_dbg_flag_stub_tx (usbip_debug_flag & usbip_debug_stub_tx) | ||
69 | #define usbip_dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs) | ||
70 | |||
71 | extern unsigned long usbip_debug_flag; | ||
72 | extern struct device_attribute dev_attr_usbip_debug; | ||
73 | |||
74 | #define usbip_dbg_with_flag(flag, fmt, args...) \ | ||
75 | do { \ | ||
76 | if (flag & usbip_debug_flag) \ | ||
77 | pr_debug(fmt, ##args); \ | ||
78 | } while (0) | ||
79 | |||
80 | #define usbip_dbg_sysfs(fmt, args...) \ | ||
81 | usbip_dbg_with_flag(usbip_debug_sysfs, fmt , ##args) | ||
82 | #define usbip_dbg_xmit(fmt, args...) \ | ||
83 | usbip_dbg_with_flag(usbip_debug_xmit, fmt , ##args) | ||
84 | #define usbip_dbg_urb(fmt, args...) \ | ||
85 | usbip_dbg_with_flag(usbip_debug_urb, fmt , ##args) | ||
86 | #define usbip_dbg_eh(fmt, args...) \ | ||
87 | usbip_dbg_with_flag(usbip_debug_eh, fmt , ##args) | ||
88 | |||
89 | #define usbip_dbg_vhci_rh(fmt, args...) \ | ||
90 | usbip_dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args) | ||
91 | #define usbip_dbg_vhci_hc(fmt, args...) \ | ||
92 | usbip_dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args) | ||
93 | #define usbip_dbg_vhci_rx(fmt, args...) \ | ||
94 | usbip_dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args) | ||
95 | #define usbip_dbg_vhci_tx(fmt, args...) \ | ||
96 | usbip_dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args) | ||
97 | #define usbip_dbg_vhci_sysfs(fmt, args...) \ | ||
98 | usbip_dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args) | ||
99 | |||
100 | #define usbip_dbg_stub_cmp(fmt, args...) \ | ||
101 | usbip_dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args) | ||
102 | #define usbip_dbg_stub_rx(fmt, args...) \ | ||
103 | usbip_dbg_with_flag(usbip_debug_stub_rx, fmt , ##args) | ||
104 | #define usbip_dbg_stub_tx(fmt, args...) \ | ||
105 | usbip_dbg_with_flag(usbip_debug_stub_tx, fmt , ##args) | ||
106 | |||
107 | /* | ||
108 | * USB/IP request headers | ||
109 | * | ||
110 | * Each request is transferred across the network to its counterpart, which | ||
111 | * facilitates the normal USB communication. The values contained in the headers | ||
112 | * are basically the same as in a URB. Currently, four request types are | ||
113 | * defined: | ||
114 | * | ||
115 | * - USBIP_CMD_SUBMIT: a USB request block, corresponds to usb_submit_urb() | ||
116 | * (client to server) | ||
117 | * | ||
118 | * - USBIP_RET_SUBMIT: the result of USBIP_CMD_SUBMIT | ||
119 | * (server to client) | ||
120 | * | ||
121 | * - USBIP_CMD_UNLINK: an unlink request of a pending USBIP_CMD_SUBMIT, | ||
122 | * corresponds to usb_unlink_urb() | ||
123 | * (client to server) | ||
124 | * | ||
125 | * - USBIP_RET_UNLINK: the result of USBIP_CMD_UNLINK | ||
126 | * (server to client) | ||
127 | * | ||
128 | */ | ||
129 | #define USBIP_CMD_SUBMIT 0x0001 | ||
130 | #define USBIP_CMD_UNLINK 0x0002 | ||
131 | #define USBIP_RET_SUBMIT 0x0003 | ||
132 | #define USBIP_RET_UNLINK 0x0004 | ||
133 | |||
134 | #define USBIP_DIR_OUT 0x00 | ||
135 | #define USBIP_DIR_IN 0x01 | ||
136 | |||
137 | /** | ||
138 | * struct usbip_header_basic - data pertinent to every request | ||
139 | * @command: the usbip request type | ||
140 | * @seqnum: sequential number that identifies requests; incremented per | ||
141 | * connection | ||
142 | * @devid: specifies a remote USB device uniquely instead of busnum and devnum; | ||
143 | * in the stub driver, this value is ((busnum << 16) | devnum) | ||
144 | * @direction: direction of the transfer | ||
145 | * @ep: endpoint number | ||
146 | */ | ||
147 | struct usbip_header_basic { | ||
148 | __u32 command; | ||
149 | __u32 seqnum; | ||
150 | __u32 devid; | ||
151 | __u32 direction; | ||
152 | __u32 ep; | ||
153 | } __packed; | ||
154 | |||
155 | /** | ||
156 | * struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header | ||
157 | * @transfer_flags: URB flags | ||
158 | * @transfer_buffer_length: the data size for (in) or (out) transfer | ||
159 | * @start_frame: initial frame for isochronous or interrupt transfers | ||
160 | * @number_of_packets: number of isochronous packets | ||
161 | * @interval: maximum time for the request on the server-side host controller | ||
162 | * @setup: setup data for a control request | ||
163 | */ | ||
164 | struct usbip_header_cmd_submit { | ||
165 | __u32 transfer_flags; | ||
166 | __s32 transfer_buffer_length; | ||
167 | |||
168 | /* it is difficult for usbip to sync frames (reserved only?) */ | ||
169 | __s32 start_frame; | ||
170 | __s32 number_of_packets; | ||
171 | __s32 interval; | ||
172 | |||
173 | unsigned char setup[8]; | ||
174 | } __packed; | ||
175 | |||
176 | /** | ||
177 | * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header | ||
178 | * @status: return status of a non-iso request | ||
179 | * @actual_length: number of bytes transferred | ||
180 | * @start_frame: initial frame for isochronous or interrupt transfers | ||
181 | * @number_of_packets: number of isochronous packets | ||
182 | * @error_count: number of errors for isochronous transfers | ||
183 | */ | ||
184 | struct usbip_header_ret_submit { | ||
185 | __s32 status; | ||
186 | __s32 actual_length; | ||
187 | __s32 start_frame; | ||
188 | __s32 number_of_packets; | ||
189 | __s32 error_count; | ||
190 | } __packed; | ||
191 | |||
192 | /** | ||
193 | * struct usbip_header_cmd_unlink - USBIP_CMD_UNLINK packet header | ||
194 | * @seqnum: the URB seqnum to unlink | ||
195 | */ | ||
196 | struct usbip_header_cmd_unlink { | ||
197 | __u32 seqnum; | ||
198 | } __packed; | ||
199 | |||
200 | /** | ||
201 | * struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header | ||
202 | * @status: return status of the request | ||
203 | */ | ||
204 | struct usbip_header_ret_unlink { | ||
205 | __s32 status; | ||
206 | } __packed; | ||
207 | |||
208 | /** | ||
209 | * struct usbip_header - common header for all usbip packets | ||
210 | * @base: the basic header | ||
211 | * @u: packet type dependent header | ||
212 | */ | ||
213 | struct usbip_header { | ||
214 | struct usbip_header_basic base; | ||
215 | |||
216 | union { | ||
217 | struct usbip_header_cmd_submit cmd_submit; | ||
218 | struct usbip_header_ret_submit ret_submit; | ||
219 | struct usbip_header_cmd_unlink cmd_unlink; | ||
220 | struct usbip_header_ret_unlink ret_unlink; | ||
221 | } u; | ||
222 | } __packed; | ||
223 | |||
224 | /* | ||
225 | * This is the same as usb_iso_packet_descriptor but packed for pdu. | ||
226 | */ | ||
227 | struct usbip_iso_packet_descriptor { | ||
228 | __u32 offset; | ||
229 | __u32 length; /* expected length */ | ||
230 | __u32 actual_length; | ||
231 | __u32 status; | ||
232 | } __packed; | ||
233 | |||
234 | enum usbip_side { | ||
235 | USBIP_VHCI, | ||
236 | USBIP_STUB, | ||
237 | }; | ||
238 | |||
239 | /* event handler */ | ||
240 | #define USBIP_EH_SHUTDOWN (1 << 0) | ||
241 | #define USBIP_EH_BYE (1 << 1) | ||
242 | #define USBIP_EH_RESET (1 << 2) | ||
243 | #define USBIP_EH_UNUSABLE (1 << 3) | ||
244 | |||
245 | #define SDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE) | ||
246 | #define SDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
247 | #define SDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
248 | #define SDEV_EVENT_ERROR_SUBMIT (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
249 | #define SDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) | ||
250 | |||
251 | #define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_BYE) | ||
252 | #define VDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
253 | #define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
254 | #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) | ||
255 | |||
256 | /* a common structure for stub_device and vhci_device */ | ||
257 | struct usbip_device { | ||
258 | enum usbip_side side; | ||
259 | enum usbip_device_status status; | ||
260 | |||
261 | /* lock for status */ | ||
262 | spinlock_t lock; | ||
263 | |||
264 | struct socket *tcp_socket; | ||
265 | |||
266 | struct task_struct *tcp_rx; | ||
267 | struct task_struct *tcp_tx; | ||
268 | |||
269 | unsigned long event; | ||
270 | struct task_struct *eh; | ||
271 | wait_queue_head_t eh_waitq; | ||
272 | |||
273 | struct eh_ops { | ||
274 | void (*shutdown)(struct usbip_device *); | ||
275 | void (*reset)(struct usbip_device *); | ||
276 | void (*unusable)(struct usbip_device *); | ||
277 | } eh_ops; | ||
278 | }; | ||
279 | |||
280 | #define kthread_get_run(threadfn, data, namefmt, ...) \ | ||
281 | ({ \ | ||
282 | struct task_struct *__k \ | ||
283 | = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \ | ||
284 | if (!IS_ERR(__k)) { \ | ||
285 | get_task_struct(__k); \ | ||
286 | wake_up_process(__k); \ | ||
287 | } \ | ||
288 | __k; \ | ||
289 | }) | ||
290 | |||
291 | #define kthread_stop_put(k) \ | ||
292 | do { \ | ||
293 | kthread_stop(k); \ | ||
294 | put_task_struct(k); \ | ||
295 | } while (0) | ||
296 | |||
297 | /* usbip_common.c */ | ||
298 | void usbip_dump_urb(struct urb *purb); | ||
299 | void usbip_dump_header(struct usbip_header *pdu); | ||
300 | |||
301 | int usbip_recv(struct socket *sock, void *buf, int size); | ||
302 | |||
303 | void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, | ||
304 | int pack); | ||
305 | void usbip_header_correct_endian(struct usbip_header *pdu, int send); | ||
306 | |||
307 | struct usbip_iso_packet_descriptor* | ||
308 | usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); | ||
309 | |||
310 | /* some members of urb must be substituted before. */ | ||
311 | int usbip_recv_iso(struct usbip_device *ud, struct urb *urb); | ||
312 | void usbip_pad_iso(struct usbip_device *ud, struct urb *urb); | ||
313 | int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); | ||
314 | |||
315 | /* usbip_event.c */ | ||
316 | int usbip_start_eh(struct usbip_device *ud); | ||
317 | void usbip_stop_eh(struct usbip_device *ud); | ||
318 | void usbip_event_add(struct usbip_device *ud, unsigned long event); | ||
319 | int usbip_event_happened(struct usbip_device *ud); | ||
320 | |||
321 | static inline int interface_to_busnum(struct usb_interface *interface) | ||
322 | { | ||
323 | struct usb_device *udev = interface_to_usbdev(interface); | ||
324 | |||
325 | return udev->bus->busnum; | ||
326 | } | ||
327 | |||
328 | static inline int interface_to_devnum(struct usb_interface *interface) | ||
329 | { | ||
330 | struct usb_device *udev = interface_to_usbdev(interface); | ||
331 | |||
332 | return udev->devnum; | ||
333 | } | ||
334 | |||
335 | #endif /* __USBIP_COMMON_H */ | ||
diff --git a/drivers/usb/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c new file mode 100644 index 000000000000..64933b993d7a --- /dev/null +++ b/drivers/usb/usbip/usbip_event.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kthread.h> | ||
21 | #include <linux/export.h> | ||
22 | |||
23 | #include "usbip_common.h" | ||
24 | |||
25 | static int event_handler(struct usbip_device *ud) | ||
26 | { | ||
27 | usbip_dbg_eh("enter\n"); | ||
28 | |||
29 | /* | ||
30 | * Events are handled by only this thread. | ||
31 | */ | ||
32 | while (usbip_event_happened(ud)) { | ||
33 | usbip_dbg_eh("pending event %lx\n", ud->event); | ||
34 | |||
35 | /* | ||
36 | * NOTE: shutdown must come first. | ||
37 | * Shutdown the device. | ||
38 | */ | ||
39 | if (ud->event & USBIP_EH_SHUTDOWN) { | ||
40 | ud->eh_ops.shutdown(ud); | ||
41 | ud->event &= ~USBIP_EH_SHUTDOWN; | ||
42 | } | ||
43 | |||
44 | /* Reset the device. */ | ||
45 | if (ud->event & USBIP_EH_RESET) { | ||
46 | ud->eh_ops.reset(ud); | ||
47 | ud->event &= ~USBIP_EH_RESET; | ||
48 | } | ||
49 | |||
50 | /* Mark the device as unusable. */ | ||
51 | if (ud->event & USBIP_EH_UNUSABLE) { | ||
52 | ud->eh_ops.unusable(ud); | ||
53 | ud->event &= ~USBIP_EH_UNUSABLE; | ||
54 | } | ||
55 | |||
56 | /* Stop the error handler. */ | ||
57 | if (ud->event & USBIP_EH_BYE) | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int event_handler_loop(void *data) | ||
65 | { | ||
66 | struct usbip_device *ud = data; | ||
67 | |||
68 | while (!kthread_should_stop()) { | ||
69 | wait_event_interruptible(ud->eh_waitq, | ||
70 | usbip_event_happened(ud) || | ||
71 | kthread_should_stop()); | ||
72 | usbip_dbg_eh("wakeup\n"); | ||
73 | |||
74 | if (event_handler(ud) < 0) | ||
75 | break; | ||
76 | } | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | int usbip_start_eh(struct usbip_device *ud) | ||
82 | { | ||
83 | init_waitqueue_head(&ud->eh_waitq); | ||
84 | ud->event = 0; | ||
85 | |||
86 | ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh"); | ||
87 | if (IS_ERR(ud->eh)) { | ||
88 | pr_warn("Unable to start control thread\n"); | ||
89 | return PTR_ERR(ud->eh); | ||
90 | } | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(usbip_start_eh); | ||
95 | |||
96 | void usbip_stop_eh(struct usbip_device *ud) | ||
97 | { | ||
98 | if (ud->eh == current) | ||
99 | return; /* do not wait for myself */ | ||
100 | |||
101 | kthread_stop(ud->eh); | ||
102 | usbip_dbg_eh("usbip_eh has finished\n"); | ||
103 | } | ||
104 | EXPORT_SYMBOL_GPL(usbip_stop_eh); | ||
105 | |||
106 | void usbip_event_add(struct usbip_device *ud, unsigned long event) | ||
107 | { | ||
108 | unsigned long flags; | ||
109 | |||
110 | spin_lock_irqsave(&ud->lock, flags); | ||
111 | ud->event |= event; | ||
112 | wake_up(&ud->eh_waitq); | ||
113 | spin_unlock_irqrestore(&ud->lock, flags); | ||
114 | } | ||
115 | EXPORT_SYMBOL_GPL(usbip_event_add); | ||
116 | |||
117 | int usbip_event_happened(struct usbip_device *ud) | ||
118 | { | ||
119 | int happened = 0; | ||
120 | |||
121 | spin_lock(&ud->lock); | ||
122 | if (ud->event != 0) | ||
123 | happened = 1; | ||
124 | spin_unlock(&ud->lock); | ||
125 | |||
126 | return happened; | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(usbip_event_happened); | ||
diff --git a/drivers/usb/usbip/usbip_protocol.txt b/drivers/usb/usbip/usbip_protocol.txt new file mode 100644 index 000000000000..16b6fe27284c --- /dev/null +++ b/drivers/usb/usbip/usbip_protocol.txt | |||
@@ -0,0 +1,358 @@ | |||
1 | PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! | ||
2 | 28 Jun 2011 | ||
3 | |||
4 | The USB/IP protocol follows a server/client architecture. The server exports the | ||
5 | USB devices and the clients imports them. The device driver for the exported | ||
6 | USB device runs on the client machine. | ||
7 | |||
8 | The client may ask for the list of the exported USB devices. To get the list the | ||
9 | client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST | ||
10 | packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent | ||
11 | in one or more pieces at the low level transport layer). The server sends back | ||
12 | the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the | ||
13 | TCP/IP connection is closed. | ||
14 | |||
15 | virtual host controller usb host | ||
16 | "client" "server" | ||
17 | (imports USB devices) (exports USB devices) | ||
18 | | | | ||
19 | | OP_REQ_DEVLIST | | ||
20 | | ----------------------------------------------> | | ||
21 | | | | ||
22 | | OP_REP_DEVLIST | | ||
23 | | <---------------------------------------------- | | ||
24 | | | | ||
25 | |||
26 | Once the client knows the list of exported USB devices it may decide to use one | ||
27 | of them. First the client opens a TCP/IP connection towards the server and | ||
28 | sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the | ||
29 | import was successful the TCP/IP connection remains open and will be used | ||
30 | to transfer the URB traffic between the client and the server. The client may | ||
31 | send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and | ||
32 | USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the | ||
33 | server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | ||
34 | |||
35 | virtual host controller usb host | ||
36 | "client" "server" | ||
37 | (imports USB devices) (exports USB devices) | ||
38 | | | | ||
39 | | OP_REQ_IMPORT | | ||
40 | | ----------------------------------------------> | | ||
41 | | | | ||
42 | | OP_REP_IMPORT | | ||
43 | | <---------------------------------------------- | | ||
44 | | | | ||
45 | | | | ||
46 | | USBIP_CMD_SUBMIT(seqnum = n) | | ||
47 | | ----------------------------------------------> | | ||
48 | | | | ||
49 | | USBIP_RET_SUBMIT(seqnum = n) | | ||
50 | | <---------------------------------------------- | | ||
51 | | . | | ||
52 | | : | | ||
53 | | | | ||
54 | | USBIP_CMD_SUBMIT(seqnum = m) | | ||
55 | | ----------------------------------------------> | | ||
56 | | | | ||
57 | | USBIP_CMD_SUBMIT(seqnum = m+1) | | ||
58 | | ----------------------------------------------> | | ||
59 | | | | ||
60 | | USBIP_CMD_SUBMIT(seqnum = m+2) | | ||
61 | | ----------------------------------------------> | | ||
62 | | | | ||
63 | | USBIP_RET_SUBMIT(seqnum = m) | | ||
64 | | <---------------------------------------------- | | ||
65 | | | | ||
66 | | USBIP_CMD_SUBMIT(seqnum = m+3) | | ||
67 | | ----------------------------------------------> | | ||
68 | | | | ||
69 | | USBIP_RET_SUBMIT(seqnum = m+1) | | ||
70 | | <---------------------------------------------- | | ||
71 | | | | ||
72 | | USBIP_CMD_SUBMIT(seqnum = m+4) | | ||
73 | | ----------------------------------------------> | | ||
74 | | | | ||
75 | | USBIP_RET_SUBMIT(seqnum = m+2) | | ||
76 | | <---------------------------------------------- | | ||
77 | | . | | ||
78 | | : | | ||
79 | | | | ||
80 | | USBIP_CMD_UNLINK | | ||
81 | | ----------------------------------------------> | | ||
82 | | | | ||
83 | | USBIP_RET_UNLINK | | ||
84 | | <---------------------------------------------- | | ||
85 | | | | ||
86 | |||
87 | The fields are in network (big endian) byte order meaning that the most significant | ||
88 | byte (MSB) is stored at the lowest address. | ||
89 | |||
90 | |||
91 | OP_REQ_DEVLIST: Retrieve the list of exported USB devices. | ||
92 | |||
93 | Offset | Length | Value | Description | ||
94 | -----------+--------+------------+--------------------------------------------------- | ||
95 | 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 | ||
96 | -----------+--------+------------+--------------------------------------------------- | ||
97 | 2 | 2 | 0x8005 | Command code: Retrieve the list of exported USB | ||
98 | | | | devices. | ||
99 | -----------+--------+------------+--------------------------------------------------- | ||
100 | 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 | ||
101 | |||
102 | OP_REP_DEVLIST: Reply with the list of exported USB devices. | ||
103 | |||
104 | Offset | Length | Value | Description | ||
105 | -----------+--------+------------+--------------------------------------------------- | ||
106 | 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0. | ||
107 | -----------+--------+------------+--------------------------------------------------- | ||
108 | 2 | 2 | 0x0005 | Reply code: The list of exported USB devices. | ||
109 | -----------+--------+------------+--------------------------------------------------- | ||
110 | 4 | 4 | 0x00000000 | Status: 0 for OK | ||
111 | -----------+--------+------------+--------------------------------------------------- | ||
112 | 8 | 4 | n | Number of exported devices: 0 means no exported | ||
113 | | | | devices. | ||
114 | -----------+--------+------------+--------------------------------------------------- | ||
115 | 0x0C | | | From now on the exported n devices are described, | ||
116 | | | | if any. If no devices are exported the message | ||
117 | | | | ends with the previous "number of exported | ||
118 | | | | devices" field. | ||
119 | -----------+--------+------------+--------------------------------------------------- | ||
120 | | 256 | | path: Path of the device on the host exporting the | ||
121 | | | | USB device, string closed with zero byte, e.g. | ||
122 | | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" | ||
123 | | | | The unused bytes shall be filled with zero | ||
124 | | | | bytes. | ||
125 | -----------+--------+------------+--------------------------------------------------- | ||
126 | 0x10C | 32 | | busid: Bus ID of the exported device, string | ||
127 | | | | closed with zero byte, e.g. "3-2". The unused | ||
128 | | | | bytes shall be filled with zero bytes. | ||
129 | -----------+--------+------------+--------------------------------------------------- | ||
130 | 0x12C | 4 | | busnum | ||
131 | -----------+--------+------------+--------------------------------------------------- | ||
132 | 0x130 | 4 | | devnum | ||
133 | -----------+--------+------------+--------------------------------------------------- | ||
134 | 0x134 | 4 | | speed | ||
135 | -----------+--------+------------+--------------------------------------------------- | ||
136 | 0x138 | 2 | | idVendor | ||
137 | -----------+--------+------------+--------------------------------------------------- | ||
138 | 0x13A | 2 | | idProduct | ||
139 | -----------+--------+------------+--------------------------------------------------- | ||
140 | 0x13C | 2 | | bcdDevice | ||
141 | -----------+--------+------------+--------------------------------------------------- | ||
142 | 0x13E | 1 | | bDeviceClass | ||
143 | -----------+--------+------------+--------------------------------------------------- | ||
144 | 0x13F | 1 | | bDeviceSubClass | ||
145 | -----------+--------+------------+--------------------------------------------------- | ||
146 | 0x140 | 1 | | bDeviceProtocol | ||
147 | -----------+--------+------------+--------------------------------------------------- | ||
148 | 0x141 | 1 | | bConfigurationValue | ||
149 | -----------+--------+------------+--------------------------------------------------- | ||
150 | 0x142 | 1 | | bNumConfigurations | ||
151 | -----------+--------+------------+--------------------------------------------------- | ||
152 | 0x143 | 1 | | bNumInterfaces | ||
153 | -----------+--------+------------+--------------------------------------------------- | ||
154 | 0x144 | | m_0 | From now on each interface is described, all | ||
155 | | | | together bNumInterfaces times, with the | ||
156 | | | | the following 4 fields: | ||
157 | -----------+--------+------------+--------------------------------------------------- | ||
158 | | 1 | | bInterfaceClass | ||
159 | -----------+--------+------------+--------------------------------------------------- | ||
160 | 0x145 | 1 | | bInterfaceSubClass | ||
161 | -----------+--------+------------+--------------------------------------------------- | ||
162 | 0x146 | 1 | | bInterfaceProtocol | ||
163 | -----------+--------+------------+--------------------------------------------------- | ||
164 | 0x147 | 1 | | padding byte for alignment, shall be set to zero | ||
165 | -----------+--------+------------+--------------------------------------------------- | ||
166 | 0xC + | | | The second exported USB device starts at i=1 | ||
167 | i*0x138 + | | | with the busid field. | ||
168 | m_(i-1)*4 | | | | ||
169 | |||
170 | OP_REQ_IMPORT: Request to import (attach) a remote USB device. | ||
171 | |||
172 | Offset | Length | Value | Description | ||
173 | -----------+--------+------------+--------------------------------------------------- | ||
174 | 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 | ||
175 | -----------+--------+------------+--------------------------------------------------- | ||
176 | 2 | 2 | 0x8003 | Command code: import a remote USB device. | ||
177 | -----------+--------+------------+--------------------------------------------------- | ||
178 | 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 | ||
179 | -----------+--------+------------+--------------------------------------------------- | ||
180 | 8 | 32 | | busid: the busid of the exported device on the | ||
181 | | | | remote host. The possible values are taken | ||
182 | | | | from the message field OP_REP_DEVLIST.busid. | ||
183 | | | | A string closed with zero, the unused bytes | ||
184 | | | | shall be filled with zeros. | ||
185 | -----------+--------+------------+--------------------------------------------------- | ||
186 | |||
187 | OP_REP_IMPORT: Reply to import (attach) a remote USB device. | ||
188 | |||
189 | Offset | Length | Value | Description | ||
190 | -----------+--------+------------+--------------------------------------------------- | ||
191 | 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 | ||
192 | -----------+--------+------------+--------------------------------------------------- | ||
193 | 2 | 2 | 0x0003 | Reply code: Reply to import. | ||
194 | -----------+--------+------------+--------------------------------------------------- | ||
195 | 4 | 4 | 0x00000000 | Status: 0 for OK | ||
196 | | | | 1 for error | ||
197 | -----------+--------+------------+--------------------------------------------------- | ||
198 | 8 | | | From now on comes the details of the imported | ||
199 | | | | device, if the previous status field was OK (0), | ||
200 | | | | otherwise the reply ends with the status field. | ||
201 | -----------+--------+------------+--------------------------------------------------- | ||
202 | | 256 | | path: Path of the device on the host exporting the | ||
203 | | | | USB device, string closed with zero byte, e.g. | ||
204 | | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" | ||
205 | | | | The unused bytes shall be filled with zero | ||
206 | | | | bytes. | ||
207 | -----------+--------+------------+--------------------------------------------------- | ||
208 | 0x108 | 32 | | busid: Bus ID of the exported device, string | ||
209 | | | | closed with zero byte, e.g. "3-2". The unused | ||
210 | | | | bytes shall be filled with zero bytes. | ||
211 | -----------+--------+------------+--------------------------------------------------- | ||
212 | 0x128 | 4 | | busnum | ||
213 | -----------+--------+------------+--------------------------------------------------- | ||
214 | 0x12C | 4 | | devnum | ||
215 | -----------+--------+------------+--------------------------------------------------- | ||
216 | 0x130 | 4 | | speed | ||
217 | -----------+--------+------------+--------------------------------------------------- | ||
218 | 0x134 | 2 | | idVendor | ||
219 | -----------+--------+------------+--------------------------------------------------- | ||
220 | 0x136 | 2 | | idProduct | ||
221 | -----------+--------+------------+--------------------------------------------------- | ||
222 | 0x138 | 2 | | bcdDevice | ||
223 | -----------+--------+------------+--------------------------------------------------- | ||
224 | 0x139 | 1 | | bDeviceClass | ||
225 | -----------+--------+------------+--------------------------------------------------- | ||
226 | 0x13A | 1 | | bDeviceSubClass | ||
227 | -----------+--------+------------+--------------------------------------------------- | ||
228 | 0x13B | 1 | | bDeviceProtocol | ||
229 | -----------+--------+------------+--------------------------------------------------- | ||
230 | 0x13C | 1 | | bConfigurationValue | ||
231 | -----------+--------+------------+--------------------------------------------------- | ||
232 | 0x13D | 1 | | bNumConfigurations | ||
233 | -----------+--------+------------+--------------------------------------------------- | ||
234 | 0x13E | 1 | | bNumInterfaces | ||
235 | |||
236 | USBIP_CMD_SUBMIT: Submit an URB | ||
237 | |||
238 | Offset | Length | Value | Description | ||
239 | -----------+--------+------------+--------------------------------------------------- | ||
240 | 0 | 4 | 0x00000001 | command: Submit an URB | ||
241 | -----------+--------+------------+--------------------------------------------------- | ||
242 | 4 | 4 | | seqnum: the sequence number of the URB to submit | ||
243 | -----------+--------+------------+--------------------------------------------------- | ||
244 | 8 | 4 | | devid | ||
245 | -----------+--------+------------+--------------------------------------------------- | ||
246 | 0xC | 4 | | direction: 0: USBIP_DIR_OUT | ||
247 | | | | 1: USBIP_DIR_IN | ||
248 | -----------+--------+------------+--------------------------------------------------- | ||
249 | 0x10 | 4 | | ep: endpoint number, possible values are: 0...15 | ||
250 | -----------+--------+------------+--------------------------------------------------- | ||
251 | 0x14 | 4 | | transfer_flags: possible values depend on the | ||
252 | | | | URB transfer type, see below | ||
253 | -----------+--------+------------+--------------------------------------------------- | ||
254 | 0x18 | 4 | | transfer_buffer_length | ||
255 | -----------+--------+------------+--------------------------------------------------- | ||
256 | 0x1C | 4 | | start_frame: specify the selected frame to | ||
257 | | | | transmit an ISO frame, ignored if URB_ISO_ASAP | ||
258 | | | | is specified at transfer_flags | ||
259 | -----------+--------+------------+--------------------------------------------------- | ||
260 | 0x20 | 4 | | number_of_packets: number of ISO packets | ||
261 | -----------+--------+------------+--------------------------------------------------- | ||
262 | 0x24 | 4 | | interval: maximum time for the request on the | ||
263 | | | | server-side host controller | ||
264 | -----------+--------+------------+--------------------------------------------------- | ||
265 | 0x28 | 8 | | setup: data bytes for USB setup, filled with | ||
266 | | | | zeros if not used | ||
267 | -----------+--------+------------+--------------------------------------------------- | ||
268 | 0x30 | | | URB data. For ISO transfers the padding between | ||
269 | | | | each ISO packets is not transmitted. | ||
270 | |||
271 | |||
272 | Allowed transfer_flags | value | control | interrupt | bulk | isochronous | ||
273 | -------------------------+------------+---------+-----------+----------+------------- | ||
274 | URB_SHORT_NOT_OK | 0x00000001 | only in | only in | only in | no | ||
275 | URB_ISO_ASAP | 0x00000002 | no | no | no | yes | ||
276 | URB_NO_TRANSFER_DMA_MAP | 0x00000004 | yes | yes | yes | yes | ||
277 | URB_NO_FSBR | 0x00000020 | yes | no | no | no | ||
278 | URB_ZERO_PACKET | 0x00000040 | no | no | only out | no | ||
279 | URB_NO_INTERRUPT | 0x00000080 | yes | yes | yes | yes | ||
280 | URB_FREE_BUFFER | 0x00000100 | yes | yes | yes | yes | ||
281 | URB_DIR_MASK | 0x00000200 | yes | yes | yes | yes | ||
282 | |||
283 | |||
284 | USBIP_RET_SUBMIT: Reply for submitting an URB | ||
285 | |||
286 | Offset | Length | Value | Description | ||
287 | -----------+--------+------------+--------------------------------------------------- | ||
288 | 0 | 4 | 0x00000003 | command | ||
289 | -----------+--------+------------+--------------------------------------------------- | ||
290 | 4 | 4 | | seqnum: URB sequence number | ||
291 | -----------+--------+------------+--------------------------------------------------- | ||
292 | 8 | 4 | | devid | ||
293 | -----------+--------+------------+--------------------------------------------------- | ||
294 | 0xC | 4 | | direction: 0: USBIP_DIR_OUT | ||
295 | | | | 1: USBIP_DIR_IN | ||
296 | -----------+--------+------------+--------------------------------------------------- | ||
297 | 0x10 | 4 | | ep: endpoint number | ||
298 | -----------+--------+------------+--------------------------------------------------- | ||
299 | 0x14 | 4 | | status: zero for successful URB transaction, | ||
300 | | | | otherwise some kind of error happened. | ||
301 | -----------+--------+------------+--------------------------------------------------- | ||
302 | 0x18 | 4 | n | actual_length: number of URB data bytes | ||
303 | -----------+--------+------------+--------------------------------------------------- | ||
304 | 0x1C | 4 | | start_frame: for an ISO frame the actually | ||
305 | | | | selected frame for transmit. | ||
306 | -----------+--------+------------+--------------------------------------------------- | ||
307 | 0x20 | 4 | | number_of_packets | ||
308 | -----------+--------+------------+--------------------------------------------------- | ||
309 | 0x24 | 4 | | error_count | ||
310 | -----------+--------+------------+--------------------------------------------------- | ||
311 | 0x28 | 8 | | setup: data bytes for USB setup, filled with | ||
312 | | | | zeros if not used | ||
313 | -----------+--------+------------+--------------------------------------------------- | ||
314 | 0x30 | n | | URB data bytes. For ISO transfers the padding | ||
315 | | | | between each ISO packets is not transmitted. | ||
316 | |||
317 | USBIP_CMD_UNLINK: Unlink an URB | ||
318 | |||
319 | Offset | Length | Value | Description | ||
320 | -----------+--------+------------+--------------------------------------------------- | ||
321 | 0 | 4 | 0x00000002 | command: URB unlink command | ||
322 | -----------+--------+------------+--------------------------------------------------- | ||
323 | 4 | 4 | | seqnum: URB sequence number to unlink: FIXME: is this so? | ||
324 | -----------+--------+------------+--------------------------------------------------- | ||
325 | 8 | 4 | | devid | ||
326 | -----------+--------+------------+--------------------------------------------------- | ||
327 | 0xC | 4 | | direction: 0: USBIP_DIR_OUT | ||
328 | | | | 1: USBIP_DIR_IN | ||
329 | -----------+--------+------------+--------------------------------------------------- | ||
330 | 0x10 | 4 | | ep: endpoint number: zero | ||
331 | -----------+--------+------------+--------------------------------------------------- | ||
332 | 0x14 | 4 | | seqnum: the URB sequence number given previously | ||
333 | | | | at USBIP_CMD_SUBMIT.seqnum field | ||
334 | -----------+--------+------------+--------------------------------------------------- | ||
335 | 0x30 | n | | URB data bytes. For ISO transfers the padding | ||
336 | | | | between each ISO packets is not transmitted. | ||
337 | |||
338 | USBIP_RET_UNLINK: Reply for URB unlink | ||
339 | |||
340 | Offset | Length | Value | Description | ||
341 | -----------+--------+------------+--------------------------------------------------- | ||
342 | 0 | 4 | 0x00000004 | command: reply for the URB unlink command | ||
343 | -----------+--------+------------+--------------------------------------------------- | ||
344 | 4 | 4 | | seqnum: the unlinked URB sequence number | ||
345 | -----------+--------+------------+--------------------------------------------------- | ||
346 | 8 | 4 | | devid | ||
347 | -----------+--------+------------+--------------------------------------------------- | ||
348 | 0xC | 4 | | direction: 0: USBIP_DIR_OUT | ||
349 | | | | 1: USBIP_DIR_IN | ||
350 | -----------+--------+------------+--------------------------------------------------- | ||
351 | 0x10 | 4 | | ep: endpoint number | ||
352 | -----------+--------+------------+--------------------------------------------------- | ||
353 | 0x14 | 4 | | status: This is the value contained in the | ||
354 | | | | urb->status in the URB completition handler. | ||
355 | | | | FIXME: a better explanation needed. | ||
356 | -----------+--------+------------+--------------------------------------------------- | ||
357 | 0x30 | n | | URB data bytes. For ISO transfers the padding | ||
358 | | | | between each ISO packets is not transmitted. | ||
diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h new file mode 100644 index 000000000000..a863a98a91ce --- /dev/null +++ b/drivers/usb/usbip/vhci.h | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef __USBIP_VHCI_H | ||
12 | #define __USBIP_VHCI_H | ||
13 | |||
14 | #include <linux/device.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/sysfs.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/usb/hcd.h> | ||
21 | #include <linux/wait.h> | ||
22 | |||
23 | struct vhci_device { | ||
24 | struct usb_device *udev; | ||
25 | |||
26 | /* | ||
27 | * devid specifies a remote usb device uniquely instead | ||
28 | * of combination of busnum and devnum. | ||
29 | */ | ||
30 | __u32 devid; | ||
31 | |||
32 | /* speed of a remote device */ | ||
33 | enum usb_device_speed speed; | ||
34 | |||
35 | /* vhci root-hub port to which this device is attached */ | ||
36 | __u32 rhport; | ||
37 | |||
38 | struct usbip_device ud; | ||
39 | |||
40 | /* lock for the below link lists */ | ||
41 | spinlock_t priv_lock; | ||
42 | |||
43 | /* vhci_priv is linked to one of them. */ | ||
44 | struct list_head priv_tx; | ||
45 | struct list_head priv_rx; | ||
46 | |||
47 | /* vhci_unlink is linked to one of them */ | ||
48 | struct list_head unlink_tx; | ||
49 | struct list_head unlink_rx; | ||
50 | |||
51 | /* vhci_tx thread sleeps for this queue */ | ||
52 | wait_queue_head_t waitq_tx; | ||
53 | }; | ||
54 | |||
55 | /* urb->hcpriv, use container_of() */ | ||
56 | struct vhci_priv { | ||
57 | unsigned long seqnum; | ||
58 | struct list_head list; | ||
59 | |||
60 | struct vhci_device *vdev; | ||
61 | struct urb *urb; | ||
62 | }; | ||
63 | |||
64 | struct vhci_unlink { | ||
65 | /* seqnum of this request */ | ||
66 | unsigned long seqnum; | ||
67 | |||
68 | struct list_head list; | ||
69 | |||
70 | /* seqnum of the unlink target */ | ||
71 | unsigned long unlink_seqnum; | ||
72 | }; | ||
73 | |||
74 | /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ | ||
75 | #define VHCI_NPORTS 8 | ||
76 | |||
77 | /* for usb_bus.hcpriv */ | ||
78 | struct vhci_hcd { | ||
79 | spinlock_t lock; | ||
80 | |||
81 | u32 port_status[VHCI_NPORTS]; | ||
82 | |||
83 | unsigned resuming:1; | ||
84 | unsigned long re_timeout; | ||
85 | |||
86 | atomic_t seqnum; | ||
87 | |||
88 | /* | ||
89 | * NOTE: | ||
90 | * wIndex shows the port number and begins from 1. | ||
91 | * But, the index of this array begins from 0. | ||
92 | */ | ||
93 | struct vhci_device vdev[VHCI_NPORTS]; | ||
94 | }; | ||
95 | |||
96 | extern struct vhci_hcd *the_controller; | ||
97 | extern const struct attribute_group dev_attr_group; | ||
98 | |||
99 | /* vhci_hcd.c */ | ||
100 | void rh_port_connect(int rhport, enum usb_device_speed speed); | ||
101 | |||
102 | /* vhci_rx.c */ | ||
103 | struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum); | ||
104 | int vhci_rx_loop(void *data); | ||
105 | |||
106 | /* vhci_tx.c */ | ||
107 | int vhci_tx_loop(void *data); | ||
108 | |||
109 | static inline struct vhci_device *port_to_vdev(__u32 port) | ||
110 | { | ||
111 | return &the_controller->vdev[port]; | ||
112 | } | ||
113 | |||
114 | static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd) | ||
115 | { | ||
116 | return (struct vhci_hcd *) (hcd->hcd_priv); | ||
117 | } | ||
118 | |||
119 | static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci) | ||
120 | { | ||
121 | return container_of((void *) vhci, struct usb_hcd, hcd_priv); | ||
122 | } | ||
123 | |||
124 | static inline struct device *vhci_dev(struct vhci_hcd *vhci) | ||
125 | { | ||
126 | return vhci_to_hcd(vhci)->self.controller; | ||
127 | } | ||
128 | |||
129 | #endif /* __USBIP_VHCI_H */ | ||
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c new file mode 100644 index 000000000000..c02374b6049c --- /dev/null +++ b/drivers/usb/usbip/vhci_hcd.c | |||
@@ -0,0 +1,1171 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/kthread.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #include "usbip_common.h" | ||
29 | #include "vhci.h" | ||
30 | |||
31 | #define DRIVER_AUTHOR "Takahiro Hirofuchi" | ||
32 | #define DRIVER_DESC "USB/IP 'Virtual' Host Controller (VHCI) Driver" | ||
33 | |||
34 | /* | ||
35 | * TODO | ||
36 | * - update root hub emulation | ||
37 | * - move the emulation code to userland ? | ||
38 | * porting to other operating systems | ||
39 | * minimize kernel code | ||
40 | * - add suspend/resume code | ||
41 | * - clean up everything | ||
42 | */ | ||
43 | |||
44 | /* See usb gadget dummy hcd */ | ||
45 | |||
46 | static int vhci_hub_status(struct usb_hcd *hcd, char *buff); | ||
47 | static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
48 | u16 wIndex, char *buff, u16 wLength); | ||
49 | static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | ||
50 | gfp_t mem_flags); | ||
51 | static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); | ||
52 | static int vhci_start(struct usb_hcd *vhci_hcd); | ||
53 | static void vhci_stop(struct usb_hcd *hcd); | ||
54 | static int vhci_get_frame_number(struct usb_hcd *hcd); | ||
55 | |||
56 | static const char driver_name[] = "vhci_hcd"; | ||
57 | static const char driver_desc[] = "USB/IP Virtual Host Controller"; | ||
58 | |||
59 | struct vhci_hcd *the_controller; | ||
60 | |||
61 | static const char * const bit_desc[] = { | ||
62 | "CONNECTION", /*0*/ | ||
63 | "ENABLE", /*1*/ | ||
64 | "SUSPEND", /*2*/ | ||
65 | "OVER_CURRENT", /*3*/ | ||
66 | "RESET", /*4*/ | ||
67 | "R5", /*5*/ | ||
68 | "R6", /*6*/ | ||
69 | "R7", /*7*/ | ||
70 | "POWER", /*8*/ | ||
71 | "LOWSPEED", /*9*/ | ||
72 | "HIGHSPEED", /*10*/ | ||
73 | "PORT_TEST", /*11*/ | ||
74 | "INDICATOR", /*12*/ | ||
75 | "R13", /*13*/ | ||
76 | "R14", /*14*/ | ||
77 | "R15", /*15*/ | ||
78 | "C_CONNECTION", /*16*/ | ||
79 | "C_ENABLE", /*17*/ | ||
80 | "C_SUSPEND", /*18*/ | ||
81 | "C_OVER_CURRENT", /*19*/ | ||
82 | "C_RESET", /*20*/ | ||
83 | "R21", /*21*/ | ||
84 | "R22", /*22*/ | ||
85 | "R23", /*23*/ | ||
86 | "R24", /*24*/ | ||
87 | "R25", /*25*/ | ||
88 | "R26", /*26*/ | ||
89 | "R27", /*27*/ | ||
90 | "R28", /*28*/ | ||
91 | "R29", /*29*/ | ||
92 | "R30", /*30*/ | ||
93 | "R31", /*31*/ | ||
94 | }; | ||
95 | |||
96 | static void dump_port_status_diff(u32 prev_status, u32 new_status) | ||
97 | { | ||
98 | int i = 0; | ||
99 | u32 bit = 1; | ||
100 | |||
101 | pr_debug("status prev -> new: %08x -> %08x\n", prev_status, new_status); | ||
102 | while (bit) { | ||
103 | u32 prev = prev_status & bit; | ||
104 | u32 new = new_status & bit; | ||
105 | char change; | ||
106 | |||
107 | if (!prev && new) | ||
108 | change = '+'; | ||
109 | else if (prev && !new) | ||
110 | change = '-'; | ||
111 | else | ||
112 | change = ' '; | ||
113 | |||
114 | if (prev || new) | ||
115 | pr_debug(" %c%s\n", change, bit_desc[i]); | ||
116 | bit <<= 1; | ||
117 | i++; | ||
118 | } | ||
119 | pr_debug("\n"); | ||
120 | } | ||
121 | |||
122 | void rh_port_connect(int rhport, enum usb_device_speed speed) | ||
123 | { | ||
124 | usbip_dbg_vhci_rh("rh_port_connect %d\n", rhport); | ||
125 | |||
126 | spin_lock(&the_controller->lock); | ||
127 | |||
128 | the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION | ||
129 | | (1 << USB_PORT_FEAT_C_CONNECTION); | ||
130 | |||
131 | switch (speed) { | ||
132 | case USB_SPEED_HIGH: | ||
133 | the_controller->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED; | ||
134 | break; | ||
135 | case USB_SPEED_LOW: | ||
136 | the_controller->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED; | ||
137 | break; | ||
138 | default: | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | spin_unlock(&the_controller->lock); | ||
143 | |||
144 | usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); | ||
145 | } | ||
146 | |||
147 | static void rh_port_disconnect(int rhport) | ||
148 | { | ||
149 | usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport); | ||
150 | |||
151 | spin_lock(&the_controller->lock); | ||
152 | |||
153 | the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION; | ||
154 | the_controller->port_status[rhport] |= | ||
155 | (1 << USB_PORT_FEAT_C_CONNECTION); | ||
156 | |||
157 | spin_unlock(&the_controller->lock); | ||
158 | usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); | ||
159 | } | ||
160 | |||
161 | #define PORT_C_MASK \ | ||
162 | ((USB_PORT_STAT_C_CONNECTION \ | ||
163 | | USB_PORT_STAT_C_ENABLE \ | ||
164 | | USB_PORT_STAT_C_SUSPEND \ | ||
165 | | USB_PORT_STAT_C_OVERCURRENT \ | ||
166 | | USB_PORT_STAT_C_RESET) << 16) | ||
167 | |||
168 | /* | ||
169 | * Returns 0 if the status hasn't changed, or the number of bytes in buf. | ||
170 | * Ports are 0-indexed from the HCD point of view, | ||
171 | * and 1-indexed from the USB core pointer of view. | ||
172 | * | ||
173 | * @buf: a bitmap to show which port status has been changed. | ||
174 | * bit 0: reserved | ||
175 | * bit 1: the status of port 0 has been changed. | ||
176 | * bit 2: the status of port 1 has been changed. | ||
177 | * ... | ||
178 | */ | ||
179 | static int vhci_hub_status(struct usb_hcd *hcd, char *buf) | ||
180 | { | ||
181 | struct vhci_hcd *vhci; | ||
182 | int retval; | ||
183 | int rhport; | ||
184 | int changed = 0; | ||
185 | |||
186 | retval = DIV_ROUND_UP(VHCI_NPORTS + 1, 8); | ||
187 | memset(buf, 0, retval); | ||
188 | |||
189 | vhci = hcd_to_vhci(hcd); | ||
190 | |||
191 | spin_lock(&vhci->lock); | ||
192 | if (!HCD_HW_ACCESSIBLE(hcd)) { | ||
193 | usbip_dbg_vhci_rh("hw accessible flag not on?\n"); | ||
194 | goto done; | ||
195 | } | ||
196 | |||
197 | /* check pseudo status register for each port */ | ||
198 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | ||
199 | if ((vhci->port_status[rhport] & PORT_C_MASK)) { | ||
200 | /* The status of a port has been changed, */ | ||
201 | usbip_dbg_vhci_rh("port %d status changed\n", rhport); | ||
202 | |||
203 | buf[(rhport + 1) / 8] |= 1 << (rhport + 1) % 8; | ||
204 | changed = 1; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | if ((hcd->state == HC_STATE_SUSPENDED) && (changed == 1)) | ||
209 | usb_hcd_resume_root_hub(hcd); | ||
210 | |||
211 | done: | ||
212 | spin_unlock(&vhci->lock); | ||
213 | return changed ? retval : 0; | ||
214 | } | ||
215 | |||
216 | static inline void hub_descriptor(struct usb_hub_descriptor *desc) | ||
217 | { | ||
218 | memset(desc, 0, sizeof(*desc)); | ||
219 | desc->bDescriptorType = 0x29; | ||
220 | desc->bDescLength = 9; | ||
221 | desc->wHubCharacteristics = (__constant_cpu_to_le16(0x0001)); | ||
222 | desc->bNbrPorts = VHCI_NPORTS; | ||
223 | desc->u.hs.DeviceRemovable[0] = 0xff; | ||
224 | desc->u.hs.DeviceRemovable[1] = 0xff; | ||
225 | } | ||
226 | |||
227 | static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
228 | u16 wIndex, char *buf, u16 wLength) | ||
229 | { | ||
230 | struct vhci_hcd *dum; | ||
231 | int retval = 0; | ||
232 | int rhport; | ||
233 | |||
234 | u32 prev_port_status[VHCI_NPORTS]; | ||
235 | |||
236 | if (!HCD_HW_ACCESSIBLE(hcd)) | ||
237 | return -ETIMEDOUT; | ||
238 | |||
239 | /* | ||
240 | * NOTE: | ||
241 | * wIndex shows the port number and begins from 1. | ||
242 | */ | ||
243 | usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, | ||
244 | wIndex); | ||
245 | if (wIndex > VHCI_NPORTS) | ||
246 | pr_err("invalid port number %d\n", wIndex); | ||
247 | rhport = ((__u8)(wIndex & 0x00ff)) - 1; | ||
248 | |||
249 | dum = hcd_to_vhci(hcd); | ||
250 | |||
251 | spin_lock(&dum->lock); | ||
252 | |||
253 | /* store old status and compare now and old later */ | ||
254 | if (usbip_dbg_flag_vhci_rh) { | ||
255 | memcpy(prev_port_status, dum->port_status, | ||
256 | sizeof(prev_port_status)); | ||
257 | } | ||
258 | |||
259 | switch (typeReq) { | ||
260 | case ClearHubFeature: | ||
261 | usbip_dbg_vhci_rh(" ClearHubFeature\n"); | ||
262 | break; | ||
263 | case ClearPortFeature: | ||
264 | switch (wValue) { | ||
265 | case USB_PORT_FEAT_SUSPEND: | ||
266 | if (dum->port_status[rhport] & USB_PORT_STAT_SUSPEND) { | ||
267 | /* 20msec signaling */ | ||
268 | dum->resuming = 1; | ||
269 | dum->re_timeout = | ||
270 | jiffies + msecs_to_jiffies(20); | ||
271 | } | ||
272 | break; | ||
273 | case USB_PORT_FEAT_POWER: | ||
274 | usbip_dbg_vhci_rh( | ||
275 | " ClearPortFeature: USB_PORT_FEAT_POWER\n"); | ||
276 | dum->port_status[rhport] = 0; | ||
277 | dum->resuming = 0; | ||
278 | break; | ||
279 | case USB_PORT_FEAT_C_RESET: | ||
280 | usbip_dbg_vhci_rh( | ||
281 | " ClearPortFeature: USB_PORT_FEAT_C_RESET\n"); | ||
282 | switch (dum->vdev[rhport].speed) { | ||
283 | case USB_SPEED_HIGH: | ||
284 | dum->port_status[rhport] |= | ||
285 | USB_PORT_STAT_HIGH_SPEED; | ||
286 | break; | ||
287 | case USB_SPEED_LOW: | ||
288 | dum->port_status[rhport] |= | ||
289 | USB_PORT_STAT_LOW_SPEED; | ||
290 | break; | ||
291 | default: | ||
292 | break; | ||
293 | } | ||
294 | default: | ||
295 | usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", | ||
296 | wValue); | ||
297 | dum->port_status[rhport] &= ~(1 << wValue); | ||
298 | break; | ||
299 | } | ||
300 | break; | ||
301 | case GetHubDescriptor: | ||
302 | usbip_dbg_vhci_rh(" GetHubDescriptor\n"); | ||
303 | hub_descriptor((struct usb_hub_descriptor *) buf); | ||
304 | break; | ||
305 | case GetHubStatus: | ||
306 | usbip_dbg_vhci_rh(" GetHubStatus\n"); | ||
307 | *(__le32 *) buf = cpu_to_le32(0); | ||
308 | break; | ||
309 | case GetPortStatus: | ||
310 | usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex); | ||
311 | if (wIndex > VHCI_NPORTS || wIndex < 1) { | ||
312 | pr_err("invalid port number %d\n", wIndex); | ||
313 | retval = -EPIPE; | ||
314 | } | ||
315 | |||
316 | /* we do not care about resume. */ | ||
317 | |||
318 | /* whoever resets or resumes must GetPortStatus to | ||
319 | * complete it!! | ||
320 | */ | ||
321 | if (dum->resuming && time_after(jiffies, dum->re_timeout)) { | ||
322 | dum->port_status[rhport] |= | ||
323 | (1 << USB_PORT_FEAT_C_SUSPEND); | ||
324 | dum->port_status[rhport] &= | ||
325 | ~(1 << USB_PORT_FEAT_SUSPEND); | ||
326 | dum->resuming = 0; | ||
327 | dum->re_timeout = 0; | ||
328 | } | ||
329 | |||
330 | if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) != | ||
331 | 0 && time_after(jiffies, dum->re_timeout)) { | ||
332 | dum->port_status[rhport] |= | ||
333 | (1 << USB_PORT_FEAT_C_RESET); | ||
334 | dum->port_status[rhport] &= | ||
335 | ~(1 << USB_PORT_FEAT_RESET); | ||
336 | dum->re_timeout = 0; | ||
337 | |||
338 | if (dum->vdev[rhport].ud.status == | ||
339 | VDEV_ST_NOTASSIGNED) { | ||
340 | usbip_dbg_vhci_rh( | ||
341 | " enable rhport %d (status %u)\n", | ||
342 | rhport, | ||
343 | dum->vdev[rhport].ud.status); | ||
344 | dum->port_status[rhport] |= | ||
345 | USB_PORT_STAT_ENABLE; | ||
346 | } | ||
347 | } | ||
348 | ((__le16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]); | ||
349 | ((__le16 *) buf)[1] = | ||
350 | cpu_to_le16(dum->port_status[rhport] >> 16); | ||
351 | |||
352 | usbip_dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0], | ||
353 | ((u16 *)buf)[1]); | ||
354 | break; | ||
355 | case SetHubFeature: | ||
356 | usbip_dbg_vhci_rh(" SetHubFeature\n"); | ||
357 | retval = -EPIPE; | ||
358 | break; | ||
359 | case SetPortFeature: | ||
360 | switch (wValue) { | ||
361 | case USB_PORT_FEAT_SUSPEND: | ||
362 | usbip_dbg_vhci_rh( | ||
363 | " SetPortFeature: USB_PORT_FEAT_SUSPEND\n"); | ||
364 | break; | ||
365 | case USB_PORT_FEAT_RESET: | ||
366 | usbip_dbg_vhci_rh( | ||
367 | " SetPortFeature: USB_PORT_FEAT_RESET\n"); | ||
368 | /* if it's already running, disconnect first */ | ||
369 | if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) { | ||
370 | dum->port_status[rhport] &= | ||
371 | ~(USB_PORT_STAT_ENABLE | | ||
372 | USB_PORT_STAT_LOW_SPEED | | ||
373 | USB_PORT_STAT_HIGH_SPEED); | ||
374 | /* FIXME test that code path! */ | ||
375 | } | ||
376 | /* 50msec reset signaling */ | ||
377 | dum->re_timeout = jiffies + msecs_to_jiffies(50); | ||
378 | |||
379 | /* FALLTHROUGH */ | ||
380 | default: | ||
381 | usbip_dbg_vhci_rh(" SetPortFeature: default %d\n", | ||
382 | wValue); | ||
383 | dum->port_status[rhport] |= (1 << wValue); | ||
384 | break; | ||
385 | } | ||
386 | break; | ||
387 | |||
388 | default: | ||
389 | pr_err("default: no such request\n"); | ||
390 | |||
391 | /* "protocol stall" on error */ | ||
392 | retval = -EPIPE; | ||
393 | } | ||
394 | |||
395 | if (usbip_dbg_flag_vhci_rh) { | ||
396 | pr_debug("port %d\n", rhport); | ||
397 | /* Only dump valid port status */ | ||
398 | if (rhport >= 0) { | ||
399 | dump_port_status_diff(prev_port_status[rhport], | ||
400 | dum->port_status[rhport]); | ||
401 | } | ||
402 | } | ||
403 | usbip_dbg_vhci_rh(" bye\n"); | ||
404 | |||
405 | spin_unlock(&dum->lock); | ||
406 | |||
407 | return retval; | ||
408 | } | ||
409 | |||
410 | static struct vhci_device *get_vdev(struct usb_device *udev) | ||
411 | { | ||
412 | int i; | ||
413 | |||
414 | if (!udev) | ||
415 | return NULL; | ||
416 | |||
417 | for (i = 0; i < VHCI_NPORTS; i++) | ||
418 | if (the_controller->vdev[i].udev == udev) | ||
419 | return port_to_vdev(i); | ||
420 | |||
421 | return NULL; | ||
422 | } | ||
423 | |||
424 | static void vhci_tx_urb(struct urb *urb) | ||
425 | { | ||
426 | struct vhci_device *vdev = get_vdev(urb->dev); | ||
427 | struct vhci_priv *priv; | ||
428 | |||
429 | if (!vdev) { | ||
430 | pr_err("could not get virtual device"); | ||
431 | return; | ||
432 | } | ||
433 | |||
434 | priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); | ||
435 | if (!priv) { | ||
436 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); | ||
437 | return; | ||
438 | } | ||
439 | |||
440 | spin_lock(&vdev->priv_lock); | ||
441 | |||
442 | priv->seqnum = atomic_inc_return(&the_controller->seqnum); | ||
443 | if (priv->seqnum == 0xffff) | ||
444 | dev_info(&urb->dev->dev, "seqnum max\n"); | ||
445 | |||
446 | priv->vdev = vdev; | ||
447 | priv->urb = urb; | ||
448 | |||
449 | urb->hcpriv = (void *) priv; | ||
450 | |||
451 | list_add_tail(&priv->list, &vdev->priv_tx); | ||
452 | |||
453 | wake_up(&vdev->waitq_tx); | ||
454 | spin_unlock(&vdev->priv_lock); | ||
455 | } | ||
456 | |||
457 | static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | ||
458 | gfp_t mem_flags) | ||
459 | { | ||
460 | struct device *dev = &urb->dev->dev; | ||
461 | int ret = 0; | ||
462 | struct vhci_device *vdev; | ||
463 | |||
464 | usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", | ||
465 | hcd, urb, mem_flags); | ||
466 | |||
467 | /* patch to usb_sg_init() is in 2.5.60 */ | ||
468 | BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); | ||
469 | |||
470 | spin_lock(&the_controller->lock); | ||
471 | |||
472 | if (urb->status != -EINPROGRESS) { | ||
473 | dev_err(dev, "URB already unlinked!, status %d\n", urb->status); | ||
474 | spin_unlock(&the_controller->lock); | ||
475 | return urb->status; | ||
476 | } | ||
477 | |||
478 | vdev = port_to_vdev(urb->dev->portnum-1); | ||
479 | |||
480 | /* refuse enqueue for dead connection */ | ||
481 | spin_lock(&vdev->ud.lock); | ||
482 | if (vdev->ud.status == VDEV_ST_NULL || | ||
483 | vdev->ud.status == VDEV_ST_ERROR) { | ||
484 | dev_err(dev, "enqueue for inactive port %d\n", vdev->rhport); | ||
485 | spin_unlock(&vdev->ud.lock); | ||
486 | spin_unlock(&the_controller->lock); | ||
487 | return -ENODEV; | ||
488 | } | ||
489 | spin_unlock(&vdev->ud.lock); | ||
490 | |||
491 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
492 | if (ret) | ||
493 | goto no_need_unlink; | ||
494 | |||
495 | /* | ||
496 | * The enumeration process is as follows; | ||
497 | * | ||
498 | * 1. Get_Descriptor request to DevAddrs(0) EndPoint(0) | ||
499 | * to get max packet length of default pipe | ||
500 | * | ||
501 | * 2. Set_Address request to DevAddr(0) EndPoint(0) | ||
502 | * | ||
503 | */ | ||
504 | if (usb_pipedevice(urb->pipe) == 0) { | ||
505 | __u8 type = usb_pipetype(urb->pipe); | ||
506 | struct usb_ctrlrequest *ctrlreq = | ||
507 | (struct usb_ctrlrequest *) urb->setup_packet; | ||
508 | |||
509 | if (type != PIPE_CONTROL || !ctrlreq) { | ||
510 | dev_err(dev, "invalid request to devnum 0\n"); | ||
511 | ret = -EINVAL; | ||
512 | goto no_need_xmit; | ||
513 | } | ||
514 | |||
515 | switch (ctrlreq->bRequest) { | ||
516 | case USB_REQ_SET_ADDRESS: | ||
517 | /* set_address may come when a device is reset */ | ||
518 | dev_info(dev, "SetAddress Request (%d) to port %d\n", | ||
519 | ctrlreq->wValue, vdev->rhport); | ||
520 | |||
521 | if (vdev->udev) | ||
522 | usb_put_dev(vdev->udev); | ||
523 | vdev->udev = usb_get_dev(urb->dev); | ||
524 | |||
525 | spin_lock(&vdev->ud.lock); | ||
526 | vdev->ud.status = VDEV_ST_USED; | ||
527 | spin_unlock(&vdev->ud.lock); | ||
528 | |||
529 | if (urb->status == -EINPROGRESS) { | ||
530 | /* This request is successfully completed. */ | ||
531 | /* If not -EINPROGRESS, possibly unlinked. */ | ||
532 | urb->status = 0; | ||
533 | } | ||
534 | |||
535 | goto no_need_xmit; | ||
536 | |||
537 | case USB_REQ_GET_DESCRIPTOR: | ||
538 | if (ctrlreq->wValue == cpu_to_le16(USB_DT_DEVICE << 8)) | ||
539 | usbip_dbg_vhci_hc( | ||
540 | "Not yet?:Get_Descriptor to device 0 (get max pipe size)\n"); | ||
541 | |||
542 | if (vdev->udev) | ||
543 | usb_put_dev(vdev->udev); | ||
544 | vdev->udev = usb_get_dev(urb->dev); | ||
545 | goto out; | ||
546 | |||
547 | default: | ||
548 | /* NOT REACHED */ | ||
549 | dev_err(dev, | ||
550 | "invalid request to devnum 0 bRequest %u, wValue %u\n", | ||
551 | ctrlreq->bRequest, | ||
552 | ctrlreq->wValue); | ||
553 | ret = -EINVAL; | ||
554 | goto no_need_xmit; | ||
555 | } | ||
556 | |||
557 | } | ||
558 | |||
559 | out: | ||
560 | vhci_tx_urb(urb); | ||
561 | spin_unlock(&the_controller->lock); | ||
562 | |||
563 | return 0; | ||
564 | |||
565 | no_need_xmit: | ||
566 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
567 | no_need_unlink: | ||
568 | spin_unlock(&the_controller->lock); | ||
569 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); | ||
570 | return ret; | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | * vhci_rx gives back the urb after receiving the reply of the urb. If an | ||
575 | * unlink pdu is sent or not, vhci_rx receives a normal return pdu and gives | ||
576 | * back its urb. For the driver unlinking the urb, the content of the urb is | ||
577 | * not important, but the calling to its completion handler is important; the | ||
578 | * completion of unlinking is notified by the completion handler. | ||
579 | * | ||
580 | * | ||
581 | * CLIENT SIDE | ||
582 | * | ||
583 | * - When vhci_hcd receives RET_SUBMIT, | ||
584 | * | ||
585 | * - case 1a). the urb of the pdu is not unlinking. | ||
586 | * - normal case | ||
587 | * => just give back the urb | ||
588 | * | ||
589 | * - case 1b). the urb of the pdu is unlinking. | ||
590 | * - usbip.ko will return a reply of the unlinking request. | ||
591 | * => give back the urb now and go to case 2b). | ||
592 | * | ||
593 | * - When vhci_hcd receives RET_UNLINK, | ||
594 | * | ||
595 | * - case 2a). a submit request is still pending in vhci_hcd. | ||
596 | * - urb was really pending in usbip.ko and urb_unlink_urb() was | ||
597 | * completed there. | ||
598 | * => free a pending submit request | ||
599 | * => notify unlink completeness by giving back the urb | ||
600 | * | ||
601 | * - case 2b). a submit request is *not* pending in vhci_hcd. | ||
602 | * - urb was already given back to the core driver. | ||
603 | * => do not give back the urb | ||
604 | * | ||
605 | * | ||
606 | * SERVER SIDE | ||
607 | * | ||
608 | * - When usbip receives CMD_UNLINK, | ||
609 | * | ||
610 | * - case 3a). the urb of the unlink request is now in submission. | ||
611 | * => do usb_unlink_urb(). | ||
612 | * => after the unlink is completed, send RET_UNLINK. | ||
613 | * | ||
614 | * - case 3b). the urb of the unlink request is not in submission. | ||
615 | * - may be already completed or never be received | ||
616 | * => send RET_UNLINK | ||
617 | * | ||
618 | */ | ||
619 | static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | ||
620 | { | ||
621 | struct vhci_priv *priv; | ||
622 | struct vhci_device *vdev; | ||
623 | |||
624 | pr_info("dequeue a urb %p\n", urb); | ||
625 | |||
626 | spin_lock(&the_controller->lock); | ||
627 | |||
628 | priv = urb->hcpriv; | ||
629 | if (!priv) { | ||
630 | /* URB was never linked! or will be soon given back by | ||
631 | * vhci_rx. */ | ||
632 | spin_unlock(&the_controller->lock); | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | { | ||
637 | int ret = 0; | ||
638 | |||
639 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
640 | if (ret) { | ||
641 | spin_unlock(&the_controller->lock); | ||
642 | return ret; | ||
643 | } | ||
644 | } | ||
645 | |||
646 | /* send unlink request here? */ | ||
647 | vdev = priv->vdev; | ||
648 | |||
649 | if (!vdev->ud.tcp_socket) { | ||
650 | /* tcp connection is closed */ | ||
651 | spin_lock(&vdev->priv_lock); | ||
652 | |||
653 | pr_info("device %p seems to be disconnected\n", vdev); | ||
654 | list_del(&priv->list); | ||
655 | kfree(priv); | ||
656 | urb->hcpriv = NULL; | ||
657 | |||
658 | spin_unlock(&vdev->priv_lock); | ||
659 | |||
660 | /* | ||
661 | * If tcp connection is alive, we have sent CMD_UNLINK. | ||
662 | * vhci_rx will receive RET_UNLINK and give back the URB. | ||
663 | * Otherwise, we give back it here. | ||
664 | */ | ||
665 | pr_info("gives back urb %p\n", urb); | ||
666 | |||
667 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
668 | |||
669 | spin_unlock(&the_controller->lock); | ||
670 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | ||
671 | urb->status); | ||
672 | spin_lock(&the_controller->lock); | ||
673 | |||
674 | } else { | ||
675 | /* tcp connection is alive */ | ||
676 | struct vhci_unlink *unlink; | ||
677 | |||
678 | spin_lock(&vdev->priv_lock); | ||
679 | |||
680 | /* setup CMD_UNLINK pdu */ | ||
681 | unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC); | ||
682 | if (!unlink) { | ||
683 | spin_unlock(&vdev->priv_lock); | ||
684 | spin_unlock(&the_controller->lock); | ||
685 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); | ||
686 | return -ENOMEM; | ||
687 | } | ||
688 | |||
689 | unlink->seqnum = atomic_inc_return(&the_controller->seqnum); | ||
690 | if (unlink->seqnum == 0xffff) | ||
691 | pr_info("seqnum max\n"); | ||
692 | |||
693 | unlink->unlink_seqnum = priv->seqnum; | ||
694 | |||
695 | pr_info("device %p seems to be still connected\n", vdev); | ||
696 | |||
697 | /* send cmd_unlink and try to cancel the pending URB in the | ||
698 | * peer */ | ||
699 | list_add_tail(&unlink->list, &vdev->unlink_tx); | ||
700 | wake_up(&vdev->waitq_tx); | ||
701 | |||
702 | spin_unlock(&vdev->priv_lock); | ||
703 | } | ||
704 | |||
705 | spin_unlock(&the_controller->lock); | ||
706 | |||
707 | usbip_dbg_vhci_hc("leave\n"); | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | static void vhci_device_unlink_cleanup(struct vhci_device *vdev) | ||
712 | { | ||
713 | struct vhci_unlink *unlink, *tmp; | ||
714 | |||
715 | spin_lock(&the_controller->lock); | ||
716 | spin_lock(&vdev->priv_lock); | ||
717 | |||
718 | list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { | ||
719 | pr_info("unlink cleanup tx %lu\n", unlink->unlink_seqnum); | ||
720 | list_del(&unlink->list); | ||
721 | kfree(unlink); | ||
722 | } | ||
723 | |||
724 | while (!list_empty(&vdev->unlink_rx)) { | ||
725 | struct urb *urb; | ||
726 | |||
727 | unlink = list_first_entry(&vdev->unlink_rx, struct vhci_unlink, | ||
728 | list); | ||
729 | |||
730 | /* give back URB of unanswered unlink request */ | ||
731 | pr_info("unlink cleanup rx %lu\n", unlink->unlink_seqnum); | ||
732 | |||
733 | urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); | ||
734 | if (!urb) { | ||
735 | pr_info("the urb (seqnum %lu) was already given back\n", | ||
736 | unlink->unlink_seqnum); | ||
737 | list_del(&unlink->list); | ||
738 | kfree(unlink); | ||
739 | continue; | ||
740 | } | ||
741 | |||
742 | urb->status = -ENODEV; | ||
743 | |||
744 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | ||
745 | |||
746 | list_del(&unlink->list); | ||
747 | |||
748 | spin_unlock(&vdev->priv_lock); | ||
749 | spin_unlock(&the_controller->lock); | ||
750 | |||
751 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | ||
752 | urb->status); | ||
753 | |||
754 | spin_lock(&the_controller->lock); | ||
755 | spin_lock(&vdev->priv_lock); | ||
756 | |||
757 | kfree(unlink); | ||
758 | } | ||
759 | |||
760 | spin_unlock(&vdev->priv_lock); | ||
761 | spin_unlock(&the_controller->lock); | ||
762 | } | ||
763 | |||
764 | /* | ||
765 | * The important thing is that only one context begins cleanup. | ||
766 | * This is why error handling and cleanup become simple. | ||
767 | * We do not want to consider race condition as possible. | ||
768 | */ | ||
769 | static void vhci_shutdown_connection(struct usbip_device *ud) | ||
770 | { | ||
771 | struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); | ||
772 | |||
773 | /* need this? see stub_dev.c */ | ||
774 | if (ud->tcp_socket) { | ||
775 | pr_debug("shutdown tcp_socket %p\n", ud->tcp_socket); | ||
776 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); | ||
777 | } | ||
778 | |||
779 | /* kill threads related to this sdev */ | ||
780 | if (vdev->ud.tcp_rx) { | ||
781 | kthread_stop_put(vdev->ud.tcp_rx); | ||
782 | vdev->ud.tcp_rx = NULL; | ||
783 | } | ||
784 | if (vdev->ud.tcp_tx) { | ||
785 | kthread_stop_put(vdev->ud.tcp_tx); | ||
786 | vdev->ud.tcp_tx = NULL; | ||
787 | } | ||
788 | pr_info("stop threads\n"); | ||
789 | |||
790 | /* active connection is closed */ | ||
791 | if (vdev->ud.tcp_socket) { | ||
792 | sockfd_put(vdev->ud.tcp_socket); | ||
793 | vdev->ud.tcp_socket = NULL; | ||
794 | } | ||
795 | pr_info("release socket\n"); | ||
796 | |||
797 | vhci_device_unlink_cleanup(vdev); | ||
798 | |||
799 | /* | ||
800 | * rh_port_disconnect() is a trigger of ... | ||
801 | * usb_disable_device(): | ||
802 | * disable all the endpoints for a USB device. | ||
803 | * usb_disable_endpoint(): | ||
804 | * disable endpoints. pending urbs are unlinked(dequeued). | ||
805 | * | ||
806 | * NOTE: After calling rh_port_disconnect(), the USB device drivers of a | ||
807 | * detached device should release used urbs in a cleanup function (i.e. | ||
808 | * xxx_disconnect()). Therefore, vhci_hcd does not need to release | ||
809 | * pushed urbs and their private data in this function. | ||
810 | * | ||
811 | * NOTE: vhci_dequeue() must be considered carefully. When shutting down | ||
812 | * a connection, vhci_shutdown_connection() expects vhci_dequeue() | ||
813 | * gives back pushed urbs and frees their private data by request of | ||
814 | * the cleanup function of a USB driver. When unlinking a urb with an | ||
815 | * active connection, vhci_dequeue() does not give back the urb which | ||
816 | * is actually given back by vhci_rx after receiving its return pdu. | ||
817 | * | ||
818 | */ | ||
819 | rh_port_disconnect(vdev->rhport); | ||
820 | |||
821 | pr_info("disconnect device\n"); | ||
822 | } | ||
823 | |||
824 | |||
825 | static void vhci_device_reset(struct usbip_device *ud) | ||
826 | { | ||
827 | struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); | ||
828 | |||
829 | spin_lock(&ud->lock); | ||
830 | |||
831 | vdev->speed = 0; | ||
832 | vdev->devid = 0; | ||
833 | |||
834 | if (vdev->udev) | ||
835 | usb_put_dev(vdev->udev); | ||
836 | vdev->udev = NULL; | ||
837 | |||
838 | if (ud->tcp_socket) { | ||
839 | sockfd_put(ud->tcp_socket); | ||
840 | ud->tcp_socket = NULL; | ||
841 | } | ||
842 | ud->status = VDEV_ST_NULL; | ||
843 | |||
844 | spin_unlock(&ud->lock); | ||
845 | } | ||
846 | |||
847 | static void vhci_device_unusable(struct usbip_device *ud) | ||
848 | { | ||
849 | spin_lock(&ud->lock); | ||
850 | ud->status = VDEV_ST_ERROR; | ||
851 | spin_unlock(&ud->lock); | ||
852 | } | ||
853 | |||
854 | static void vhci_device_init(struct vhci_device *vdev) | ||
855 | { | ||
856 | memset(vdev, 0, sizeof(*vdev)); | ||
857 | |||
858 | vdev->ud.side = USBIP_VHCI; | ||
859 | vdev->ud.status = VDEV_ST_NULL; | ||
860 | spin_lock_init(&vdev->ud.lock); | ||
861 | |||
862 | INIT_LIST_HEAD(&vdev->priv_rx); | ||
863 | INIT_LIST_HEAD(&vdev->priv_tx); | ||
864 | INIT_LIST_HEAD(&vdev->unlink_tx); | ||
865 | INIT_LIST_HEAD(&vdev->unlink_rx); | ||
866 | spin_lock_init(&vdev->priv_lock); | ||
867 | |||
868 | init_waitqueue_head(&vdev->waitq_tx); | ||
869 | |||
870 | vdev->ud.eh_ops.shutdown = vhci_shutdown_connection; | ||
871 | vdev->ud.eh_ops.reset = vhci_device_reset; | ||
872 | vdev->ud.eh_ops.unusable = vhci_device_unusable; | ||
873 | |||
874 | usbip_start_eh(&vdev->ud); | ||
875 | } | ||
876 | |||
877 | static int vhci_start(struct usb_hcd *hcd) | ||
878 | { | ||
879 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
880 | int rhport; | ||
881 | int err = 0; | ||
882 | |||
883 | usbip_dbg_vhci_hc("enter vhci_start\n"); | ||
884 | |||
885 | /* initialize private data of usb_hcd */ | ||
886 | |||
887 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | ||
888 | struct vhci_device *vdev = &vhci->vdev[rhport]; | ||
889 | |||
890 | vhci_device_init(vdev); | ||
891 | vdev->rhport = rhport; | ||
892 | } | ||
893 | |||
894 | atomic_set(&vhci->seqnum, 0); | ||
895 | spin_lock_init(&vhci->lock); | ||
896 | |||
897 | hcd->power_budget = 0; /* no limit */ | ||
898 | hcd->uses_new_polling = 1; | ||
899 | |||
900 | /* vhci_hcd is now ready to be controlled through sysfs */ | ||
901 | err = sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group); | ||
902 | if (err) { | ||
903 | pr_err("create sysfs files\n"); | ||
904 | return err; | ||
905 | } | ||
906 | |||
907 | return 0; | ||
908 | } | ||
909 | |||
910 | static void vhci_stop(struct usb_hcd *hcd) | ||
911 | { | ||
912 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
913 | int rhport = 0; | ||
914 | |||
915 | usbip_dbg_vhci_hc("stop VHCI controller\n"); | ||
916 | |||
917 | /* 1. remove the userland interface of vhci_hcd */ | ||
918 | sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group); | ||
919 | |||
920 | /* 2. shutdown all the ports of vhci_hcd */ | ||
921 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | ||
922 | struct vhci_device *vdev = &vhci->vdev[rhport]; | ||
923 | |||
924 | usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED); | ||
925 | usbip_stop_eh(&vdev->ud); | ||
926 | } | ||
927 | } | ||
928 | |||
929 | static int vhci_get_frame_number(struct usb_hcd *hcd) | ||
930 | { | ||
931 | pr_err("Not yet implemented\n"); | ||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | #ifdef CONFIG_PM | ||
936 | |||
937 | /* FIXME: suspend/resume */ | ||
938 | static int vhci_bus_suspend(struct usb_hcd *hcd) | ||
939 | { | ||
940 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
941 | |||
942 | dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); | ||
943 | |||
944 | spin_lock(&vhci->lock); | ||
945 | hcd->state = HC_STATE_SUSPENDED; | ||
946 | spin_unlock(&vhci->lock); | ||
947 | |||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | static int vhci_bus_resume(struct usb_hcd *hcd) | ||
952 | { | ||
953 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
954 | int rc = 0; | ||
955 | |||
956 | dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); | ||
957 | |||
958 | spin_lock(&vhci->lock); | ||
959 | if (!HCD_HW_ACCESSIBLE(hcd)) | ||
960 | rc = -ESHUTDOWN; | ||
961 | else | ||
962 | hcd->state = HC_STATE_RUNNING; | ||
963 | spin_unlock(&vhci->lock); | ||
964 | |||
965 | return rc; | ||
966 | } | ||
967 | |||
968 | #else | ||
969 | |||
970 | #define vhci_bus_suspend NULL | ||
971 | #define vhci_bus_resume NULL | ||
972 | #endif | ||
973 | |||
974 | static struct hc_driver vhci_hc_driver = { | ||
975 | .description = driver_name, | ||
976 | .product_desc = driver_desc, | ||
977 | .hcd_priv_size = sizeof(struct vhci_hcd), | ||
978 | |||
979 | .flags = HCD_USB2, | ||
980 | |||
981 | .start = vhci_start, | ||
982 | .stop = vhci_stop, | ||
983 | |||
984 | .urb_enqueue = vhci_urb_enqueue, | ||
985 | .urb_dequeue = vhci_urb_dequeue, | ||
986 | |||
987 | .get_frame_number = vhci_get_frame_number, | ||
988 | |||
989 | .hub_status_data = vhci_hub_status, | ||
990 | .hub_control = vhci_hub_control, | ||
991 | .bus_suspend = vhci_bus_suspend, | ||
992 | .bus_resume = vhci_bus_resume, | ||
993 | }; | ||
994 | |||
995 | static int vhci_hcd_probe(struct platform_device *pdev) | ||
996 | { | ||
997 | struct usb_hcd *hcd; | ||
998 | int ret; | ||
999 | |||
1000 | usbip_dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id); | ||
1001 | |||
1002 | /* | ||
1003 | * Allocate and initialize hcd. | ||
1004 | * Our private data is also allocated automatically. | ||
1005 | */ | ||
1006 | hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); | ||
1007 | if (!hcd) { | ||
1008 | pr_err("create hcd failed\n"); | ||
1009 | return -ENOMEM; | ||
1010 | } | ||
1011 | hcd->has_tt = 1; | ||
1012 | |||
1013 | /* this is private data for vhci_hcd */ | ||
1014 | the_controller = hcd_to_vhci(hcd); | ||
1015 | |||
1016 | /* | ||
1017 | * Finish generic HCD structure initialization and register. | ||
1018 | * Call the driver's reset() and start() routines. | ||
1019 | */ | ||
1020 | ret = usb_add_hcd(hcd, 0, 0); | ||
1021 | if (ret != 0) { | ||
1022 | pr_err("usb_add_hcd failed %d\n", ret); | ||
1023 | usb_put_hcd(hcd); | ||
1024 | the_controller = NULL; | ||
1025 | return ret; | ||
1026 | } | ||
1027 | |||
1028 | usbip_dbg_vhci_hc("bye\n"); | ||
1029 | return 0; | ||
1030 | } | ||
1031 | |||
1032 | static int vhci_hcd_remove(struct platform_device *pdev) | ||
1033 | { | ||
1034 | struct usb_hcd *hcd; | ||
1035 | |||
1036 | hcd = platform_get_drvdata(pdev); | ||
1037 | if (!hcd) | ||
1038 | return 0; | ||
1039 | |||
1040 | /* | ||
1041 | * Disconnects the root hub, | ||
1042 | * then reverses the effects of usb_add_hcd(), | ||
1043 | * invoking the HCD's stop() methods. | ||
1044 | */ | ||
1045 | usb_remove_hcd(hcd); | ||
1046 | usb_put_hcd(hcd); | ||
1047 | the_controller = NULL; | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1052 | #ifdef CONFIG_PM | ||
1053 | |||
1054 | /* what should happen for USB/IP under suspend/resume? */ | ||
1055 | static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state) | ||
1056 | { | ||
1057 | struct usb_hcd *hcd; | ||
1058 | int rhport = 0; | ||
1059 | int connected = 0; | ||
1060 | int ret = 0; | ||
1061 | |||
1062 | hcd = platform_get_drvdata(pdev); | ||
1063 | |||
1064 | spin_lock(&the_controller->lock); | ||
1065 | |||
1066 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) | ||
1067 | if (the_controller->port_status[rhport] & | ||
1068 | USB_PORT_STAT_CONNECTION) | ||
1069 | connected += 1; | ||
1070 | |||
1071 | spin_unlock(&the_controller->lock); | ||
1072 | |||
1073 | if (connected > 0) { | ||
1074 | dev_info(&pdev->dev, | ||
1075 | "We have %d active connection%s. Do not suspend.\n", | ||
1076 | connected, (connected == 1 ? "" : "s")); | ||
1077 | ret = -EBUSY; | ||
1078 | } else { | ||
1079 | dev_info(&pdev->dev, "suspend vhci_hcd"); | ||
1080 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1081 | } | ||
1082 | |||
1083 | return ret; | ||
1084 | } | ||
1085 | |||
1086 | static int vhci_hcd_resume(struct platform_device *pdev) | ||
1087 | { | ||
1088 | struct usb_hcd *hcd; | ||
1089 | |||
1090 | dev_dbg(&pdev->dev, "%s\n", __func__); | ||
1091 | |||
1092 | hcd = platform_get_drvdata(pdev); | ||
1093 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1094 | usb_hcd_poll_rh_status(hcd); | ||
1095 | |||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1099 | #else | ||
1100 | |||
1101 | #define vhci_hcd_suspend NULL | ||
1102 | #define vhci_hcd_resume NULL | ||
1103 | |||
1104 | #endif | ||
1105 | |||
1106 | static struct platform_driver vhci_driver = { | ||
1107 | .probe = vhci_hcd_probe, | ||
1108 | .remove = vhci_hcd_remove, | ||
1109 | .suspend = vhci_hcd_suspend, | ||
1110 | .resume = vhci_hcd_resume, | ||
1111 | .driver = { | ||
1112 | .name = driver_name, | ||
1113 | .owner = THIS_MODULE, | ||
1114 | }, | ||
1115 | }; | ||
1116 | |||
1117 | /* | ||
1118 | * The VHCI 'device' is 'virtual'; not a real plug&play hardware. | ||
1119 | * We need to add this virtual device as a platform device arbitrarily: | ||
1120 | * 1. platform_device_register() | ||
1121 | */ | ||
1122 | static void the_pdev_release(struct device *dev) | ||
1123 | { | ||
1124 | } | ||
1125 | |||
1126 | static struct platform_device the_pdev = { | ||
1127 | /* should be the same name as driver_name */ | ||
1128 | .name = driver_name, | ||
1129 | .id = -1, | ||
1130 | .dev = { | ||
1131 | .release = the_pdev_release, | ||
1132 | }, | ||
1133 | }; | ||
1134 | |||
1135 | static int __init vhci_hcd_init(void) | ||
1136 | { | ||
1137 | int ret; | ||
1138 | |||
1139 | if (usb_disabled()) | ||
1140 | return -ENODEV; | ||
1141 | |||
1142 | ret = platform_driver_register(&vhci_driver); | ||
1143 | if (ret) | ||
1144 | goto err_driver_register; | ||
1145 | |||
1146 | ret = platform_device_register(&the_pdev); | ||
1147 | if (ret) | ||
1148 | goto err_platform_device_register; | ||
1149 | |||
1150 | pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); | ||
1151 | return ret; | ||
1152 | |||
1153 | err_platform_device_register: | ||
1154 | platform_driver_unregister(&vhci_driver); | ||
1155 | err_driver_register: | ||
1156 | return ret; | ||
1157 | } | ||
1158 | |||
1159 | static void __exit vhci_hcd_exit(void) | ||
1160 | { | ||
1161 | platform_device_unregister(&the_pdev); | ||
1162 | platform_driver_unregister(&vhci_driver); | ||
1163 | } | ||
1164 | |||
1165 | module_init(vhci_hcd_init); | ||
1166 | module_exit(vhci_hcd_exit); | ||
1167 | |||
1168 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
1169 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1170 | MODULE_LICENSE("GPL"); | ||
1171 | MODULE_VERSION(USBIP_VERSION); | ||
diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c new file mode 100644 index 000000000000..00e4a54308e4 --- /dev/null +++ b/drivers/usb/usbip/vhci_rx.c | |||
@@ -0,0 +1,268 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kthread.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include "usbip_common.h" | ||
24 | #include "vhci.h" | ||
25 | |||
26 | /* get URB from transmitted urb queue. caller must hold vdev->priv_lock */ | ||
27 | struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum) | ||
28 | { | ||
29 | struct vhci_priv *priv, *tmp; | ||
30 | struct urb *urb = NULL; | ||
31 | int status; | ||
32 | |||
33 | list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) { | ||
34 | if (priv->seqnum != seqnum) | ||
35 | continue; | ||
36 | |||
37 | urb = priv->urb; | ||
38 | status = urb->status; | ||
39 | |||
40 | usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", | ||
41 | urb, priv, seqnum); | ||
42 | |||
43 | switch (status) { | ||
44 | case -ENOENT: | ||
45 | /* fall through */ | ||
46 | case -ECONNRESET: | ||
47 | dev_info(&urb->dev->dev, | ||
48 | "urb %p was unlinked %ssynchronuously.\n", urb, | ||
49 | status == -ENOENT ? "" : "a"); | ||
50 | break; | ||
51 | case -EINPROGRESS: | ||
52 | /* no info output */ | ||
53 | break; | ||
54 | default: | ||
55 | dev_info(&urb->dev->dev, | ||
56 | "urb %p may be in a error, status %d\n", urb, | ||
57 | status); | ||
58 | } | ||
59 | |||
60 | list_del(&priv->list); | ||
61 | kfree(priv); | ||
62 | urb->hcpriv = NULL; | ||
63 | |||
64 | break; | ||
65 | } | ||
66 | |||
67 | return urb; | ||
68 | } | ||
69 | |||
70 | static void vhci_recv_ret_submit(struct vhci_device *vdev, | ||
71 | struct usbip_header *pdu) | ||
72 | { | ||
73 | struct usbip_device *ud = &vdev->ud; | ||
74 | struct urb *urb; | ||
75 | |||
76 | spin_lock(&vdev->priv_lock); | ||
77 | urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); | ||
78 | spin_unlock(&vdev->priv_lock); | ||
79 | |||
80 | if (!urb) { | ||
81 | pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); | ||
82 | pr_info("max seqnum %d\n", | ||
83 | atomic_read(&the_controller->seqnum)); | ||
84 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
85 | return; | ||
86 | } | ||
87 | |||
88 | /* unpack the pdu to a urb */ | ||
89 | usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0); | ||
90 | |||
91 | /* recv transfer buffer */ | ||
92 | if (usbip_recv_xbuff(ud, urb) < 0) | ||
93 | return; | ||
94 | |||
95 | /* recv iso_packet_descriptor */ | ||
96 | if (usbip_recv_iso(ud, urb) < 0) | ||
97 | return; | ||
98 | |||
99 | /* restore the padding in iso packets */ | ||
100 | usbip_pad_iso(ud, urb); | ||
101 | |||
102 | if (usbip_dbg_flag_vhci_rx) | ||
103 | usbip_dump_urb(urb); | ||
104 | |||
105 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | ||
106 | |||
107 | spin_lock(&the_controller->lock); | ||
108 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | ||
109 | spin_unlock(&the_controller->lock); | ||
110 | |||
111 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); | ||
112 | |||
113 | usbip_dbg_vhci_rx("Leave\n"); | ||
114 | } | ||
115 | |||
116 | static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev, | ||
117 | struct usbip_header *pdu) | ||
118 | { | ||
119 | struct vhci_unlink *unlink, *tmp; | ||
120 | |||
121 | spin_lock(&vdev->priv_lock); | ||
122 | |||
123 | list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) { | ||
124 | pr_info("unlink->seqnum %lu\n", unlink->seqnum); | ||
125 | if (unlink->seqnum == pdu->base.seqnum) { | ||
126 | usbip_dbg_vhci_rx("found pending unlink, %lu\n", | ||
127 | unlink->seqnum); | ||
128 | list_del(&unlink->list); | ||
129 | |||
130 | spin_unlock(&vdev->priv_lock); | ||
131 | return unlink; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | spin_unlock(&vdev->priv_lock); | ||
136 | |||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | static void vhci_recv_ret_unlink(struct vhci_device *vdev, | ||
141 | struct usbip_header *pdu) | ||
142 | { | ||
143 | struct vhci_unlink *unlink; | ||
144 | struct urb *urb; | ||
145 | |||
146 | usbip_dump_header(pdu); | ||
147 | |||
148 | unlink = dequeue_pending_unlink(vdev, pdu); | ||
149 | if (!unlink) { | ||
150 | pr_info("cannot find the pending unlink %u\n", | ||
151 | pdu->base.seqnum); | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | spin_lock(&vdev->priv_lock); | ||
156 | urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); | ||
157 | spin_unlock(&vdev->priv_lock); | ||
158 | |||
159 | if (!urb) { | ||
160 | /* | ||
161 | * I get the result of a unlink request. But, it seems that I | ||
162 | * already received the result of its submit result and gave | ||
163 | * back the URB. | ||
164 | */ | ||
165 | pr_info("the urb (seqnum %d) was already given back\n", | ||
166 | pdu->base.seqnum); | ||
167 | } else { | ||
168 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | ||
169 | |||
170 | /* If unlink is successful, status is -ECONNRESET */ | ||
171 | urb->status = pdu->u.ret_unlink.status; | ||
172 | pr_info("urb->status %d\n", urb->status); | ||
173 | |||
174 | spin_lock(&the_controller->lock); | ||
175 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | ||
176 | spin_unlock(&the_controller->lock); | ||
177 | |||
178 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | ||
179 | urb->status); | ||
180 | } | ||
181 | |||
182 | kfree(unlink); | ||
183 | } | ||
184 | |||
185 | static int vhci_priv_tx_empty(struct vhci_device *vdev) | ||
186 | { | ||
187 | int empty = 0; | ||
188 | |||
189 | spin_lock(&vdev->priv_lock); | ||
190 | empty = list_empty(&vdev->priv_rx); | ||
191 | spin_unlock(&vdev->priv_lock); | ||
192 | |||
193 | return empty; | ||
194 | } | ||
195 | |||
196 | /* recv a pdu */ | ||
197 | static void vhci_rx_pdu(struct usbip_device *ud) | ||
198 | { | ||
199 | int ret; | ||
200 | struct usbip_header pdu; | ||
201 | struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); | ||
202 | |||
203 | usbip_dbg_vhci_rx("Enter\n"); | ||
204 | |||
205 | memset(&pdu, 0, sizeof(pdu)); | ||
206 | |||
207 | /* receive a pdu header */ | ||
208 | ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu)); | ||
209 | if (ret < 0) { | ||
210 | if (ret == -ECONNRESET) | ||
211 | pr_info("connection reset by peer\n"); | ||
212 | else if (ret == -EAGAIN) { | ||
213 | /* ignore if connection was idle */ | ||
214 | if (vhci_priv_tx_empty(vdev)) | ||
215 | return; | ||
216 | pr_info("connection timed out with pending urbs\n"); | ||
217 | } else if (ret != -ERESTARTSYS) | ||
218 | pr_info("xmit failed %d\n", ret); | ||
219 | |||
220 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
221 | return; | ||
222 | } | ||
223 | if (ret == 0) { | ||
224 | pr_info("connection closed"); | ||
225 | usbip_event_add(ud, VDEV_EVENT_DOWN); | ||
226 | return; | ||
227 | } | ||
228 | if (ret != sizeof(pdu)) { | ||
229 | pr_err("received pdu size is %d, should be %d\n", ret, | ||
230 | (unsigned int)sizeof(pdu)); | ||
231 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | usbip_header_correct_endian(&pdu, 0); | ||
236 | |||
237 | if (usbip_dbg_flag_vhci_rx) | ||
238 | usbip_dump_header(&pdu); | ||
239 | |||
240 | switch (pdu.base.command) { | ||
241 | case USBIP_RET_SUBMIT: | ||
242 | vhci_recv_ret_submit(vdev, &pdu); | ||
243 | break; | ||
244 | case USBIP_RET_UNLINK: | ||
245 | vhci_recv_ret_unlink(vdev, &pdu); | ||
246 | break; | ||
247 | default: | ||
248 | /* NOT REACHED */ | ||
249 | pr_err("unknown pdu %u\n", pdu.base.command); | ||
250 | usbip_dump_header(&pdu); | ||
251 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
252 | break; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | int vhci_rx_loop(void *data) | ||
257 | { | ||
258 | struct usbip_device *ud = data; | ||
259 | |||
260 | while (!kthread_should_stop()) { | ||
261 | if (usbip_event_happened(ud)) | ||
262 | break; | ||
263 | |||
264 | vhci_rx_pdu(ud); | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c new file mode 100644 index 000000000000..211f43f67ea2 --- /dev/null +++ b/drivers/usb/usbip/vhci_sysfs.c | |||
@@ -0,0 +1,252 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kthread.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/net.h> | ||
23 | |||
24 | #include "usbip_common.h" | ||
25 | #include "vhci.h" | ||
26 | |||
27 | /* TODO: refine locking ?*/ | ||
28 | |||
29 | /* Sysfs entry to show port status */ | ||
30 | static ssize_t status_show(struct device *dev, struct device_attribute *attr, | ||
31 | char *out) | ||
32 | { | ||
33 | char *s = out; | ||
34 | int i = 0; | ||
35 | |||
36 | BUG_ON(!the_controller || !out); | ||
37 | |||
38 | spin_lock(&the_controller->lock); | ||
39 | |||
40 | /* | ||
41 | * output example: | ||
42 | * prt sta spd dev socket local_busid | ||
43 | * 000 004 000 000 c5a7bb80 1-2.3 | ||
44 | * 001 004 000 000 d8cee980 2-3.4 | ||
45 | * | ||
46 | * IP address can be retrieved from a socket pointer address by looking | ||
47 | * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a | ||
48 | * port number and its peer IP address. | ||
49 | */ | ||
50 | out += sprintf(out, | ||
51 | "prt sta spd bus dev socket local_busid\n"); | ||
52 | |||
53 | for (i = 0; i < VHCI_NPORTS; i++) { | ||
54 | struct vhci_device *vdev = port_to_vdev(i); | ||
55 | |||
56 | spin_lock(&vdev->ud.lock); | ||
57 | out += sprintf(out, "%03u %03u ", i, vdev->ud.status); | ||
58 | |||
59 | if (vdev->ud.status == VDEV_ST_USED) { | ||
60 | out += sprintf(out, "%03u %08x ", | ||
61 | vdev->speed, vdev->devid); | ||
62 | out += sprintf(out, "%16p ", vdev->ud.tcp_socket); | ||
63 | out += sprintf(out, "%s", dev_name(&vdev->udev->dev)); | ||
64 | |||
65 | } else { | ||
66 | out += sprintf(out, "000 000 000 0000000000000000 0-0"); | ||
67 | } | ||
68 | |||
69 | out += sprintf(out, "\n"); | ||
70 | spin_unlock(&vdev->ud.lock); | ||
71 | } | ||
72 | |||
73 | spin_unlock(&the_controller->lock); | ||
74 | |||
75 | return out - s; | ||
76 | } | ||
77 | static DEVICE_ATTR_RO(status); | ||
78 | |||
79 | /* Sysfs entry to shutdown a virtual connection */ | ||
80 | static int vhci_port_disconnect(__u32 rhport) | ||
81 | { | ||
82 | struct vhci_device *vdev; | ||
83 | |||
84 | usbip_dbg_vhci_sysfs("enter\n"); | ||
85 | |||
86 | /* lock */ | ||
87 | spin_lock(&the_controller->lock); | ||
88 | |||
89 | vdev = port_to_vdev(rhport); | ||
90 | |||
91 | spin_lock(&vdev->ud.lock); | ||
92 | if (vdev->ud.status == VDEV_ST_NULL) { | ||
93 | pr_err("not connected %d\n", vdev->ud.status); | ||
94 | |||
95 | /* unlock */ | ||
96 | spin_unlock(&vdev->ud.lock); | ||
97 | spin_unlock(&the_controller->lock); | ||
98 | |||
99 | return -EINVAL; | ||
100 | } | ||
101 | |||
102 | /* unlock */ | ||
103 | spin_unlock(&vdev->ud.lock); | ||
104 | spin_unlock(&the_controller->lock); | ||
105 | |||
106 | usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static ssize_t store_detach(struct device *dev, struct device_attribute *attr, | ||
112 | const char *buf, size_t count) | ||
113 | { | ||
114 | int err; | ||
115 | __u32 rhport = 0; | ||
116 | |||
117 | if (sscanf(buf, "%u", &rhport) != 1) | ||
118 | return -EINVAL; | ||
119 | |||
120 | /* check rhport */ | ||
121 | if (rhport >= VHCI_NPORTS) { | ||
122 | dev_err(dev, "invalid port %u\n", rhport); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | |||
126 | err = vhci_port_disconnect(rhport); | ||
127 | if (err < 0) | ||
128 | return -EINVAL; | ||
129 | |||
130 | usbip_dbg_vhci_sysfs("Leave\n"); | ||
131 | |||
132 | return count; | ||
133 | } | ||
134 | static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach); | ||
135 | |||
136 | /* Sysfs entry to establish a virtual connection */ | ||
137 | static int valid_args(__u32 rhport, enum usb_device_speed speed) | ||
138 | { | ||
139 | /* check rhport */ | ||
140 | if (rhport >= VHCI_NPORTS) { | ||
141 | pr_err("port %u\n", rhport); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | /* check speed */ | ||
146 | switch (speed) { | ||
147 | case USB_SPEED_LOW: | ||
148 | case USB_SPEED_FULL: | ||
149 | case USB_SPEED_HIGH: | ||
150 | case USB_SPEED_WIRELESS: | ||
151 | break; | ||
152 | default: | ||
153 | pr_err("Failed attach request for unsupported USB speed: %s\n", | ||
154 | usb_speed_string(speed)); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * To start a new USB/IP attachment, a userland program needs to setup a TCP | ||
163 | * connection and then write its socket descriptor with remote device | ||
164 | * information into this sysfs file. | ||
165 | * | ||
166 | * A remote device is virtually attached to the root-hub port of @rhport with | ||
167 | * @speed. @devid is embedded into a request to specify the remote device in a | ||
168 | * server host. | ||
169 | * | ||
170 | * write() returns 0 on success, else negative errno. | ||
171 | */ | ||
172 | static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | ||
173 | const char *buf, size_t count) | ||
174 | { | ||
175 | struct vhci_device *vdev; | ||
176 | struct socket *socket; | ||
177 | int sockfd = 0; | ||
178 | __u32 rhport = 0, devid = 0, speed = 0; | ||
179 | int err; | ||
180 | |||
181 | /* | ||
182 | * @rhport: port number of vhci_hcd | ||
183 | * @sockfd: socket descriptor of an established TCP connection | ||
184 | * @devid: unique device identifier in a remote host | ||
185 | * @speed: usb device speed in a remote host | ||
186 | */ | ||
187 | if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 4) | ||
188 | return -EINVAL; | ||
189 | |||
190 | usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n", | ||
191 | rhport, sockfd, devid, speed); | ||
192 | |||
193 | /* check received parameters */ | ||
194 | if (valid_args(rhport, speed) < 0) | ||
195 | return -EINVAL; | ||
196 | |||
197 | /* Extract socket from fd. */ | ||
198 | socket = sockfd_lookup(sockfd, &err); | ||
199 | if (!socket) | ||
200 | return -EINVAL; | ||
201 | |||
202 | /* now need lock until setting vdev status as used */ | ||
203 | |||
204 | /* begin a lock */ | ||
205 | spin_lock(&the_controller->lock); | ||
206 | vdev = port_to_vdev(rhport); | ||
207 | spin_lock(&vdev->ud.lock); | ||
208 | |||
209 | if (vdev->ud.status != VDEV_ST_NULL) { | ||
210 | /* end of the lock */ | ||
211 | spin_unlock(&vdev->ud.lock); | ||
212 | spin_unlock(&the_controller->lock); | ||
213 | |||
214 | sockfd_put(socket); | ||
215 | |||
216 | dev_err(dev, "port %d already used\n", rhport); | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | dev_info(dev, | ||
221 | "rhport(%u) sockfd(%d) devid(%u) speed(%u) speed_str(%s)\n", | ||
222 | rhport, sockfd, devid, speed, usb_speed_string(speed)); | ||
223 | |||
224 | vdev->devid = devid; | ||
225 | vdev->speed = speed; | ||
226 | vdev->ud.tcp_socket = socket; | ||
227 | vdev->ud.status = VDEV_ST_NOTASSIGNED; | ||
228 | |||
229 | spin_unlock(&vdev->ud.lock); | ||
230 | spin_unlock(&the_controller->lock); | ||
231 | /* end the lock */ | ||
232 | |||
233 | vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); | ||
234 | vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); | ||
235 | |||
236 | rh_port_connect(rhport, speed); | ||
237 | |||
238 | return count; | ||
239 | } | ||
240 | static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach); | ||
241 | |||
242 | static struct attribute *dev_attrs[] = { | ||
243 | &dev_attr_status.attr, | ||
244 | &dev_attr_detach.attr, | ||
245 | &dev_attr_attach.attr, | ||
246 | &dev_attr_usbip_debug.attr, | ||
247 | NULL, | ||
248 | }; | ||
249 | |||
250 | const struct attribute_group dev_attr_group = { | ||
251 | .attrs = dev_attrs, | ||
252 | }; | ||
diff --git a/drivers/usb/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c new file mode 100644 index 000000000000..409fd99f3257 --- /dev/null +++ b/drivers/usb/usbip/vhci_tx.c | |||
@@ -0,0 +1,224 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
17 | * USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kthread.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include "usbip_common.h" | ||
24 | #include "vhci.h" | ||
25 | |||
26 | static void setup_cmd_submit_pdu(struct usbip_header *pdup, struct urb *urb) | ||
27 | { | ||
28 | struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv); | ||
29 | struct vhci_device *vdev = priv->vdev; | ||
30 | |||
31 | usbip_dbg_vhci_tx("URB, local devnum %u, remote devid %u\n", | ||
32 | usb_pipedevice(urb->pipe), vdev->devid); | ||
33 | |||
34 | pdup->base.command = USBIP_CMD_SUBMIT; | ||
35 | pdup->base.seqnum = priv->seqnum; | ||
36 | pdup->base.devid = vdev->devid; | ||
37 | pdup->base.direction = usb_pipein(urb->pipe) ? | ||
38 | USBIP_DIR_IN : USBIP_DIR_OUT; | ||
39 | pdup->base.ep = usb_pipeendpoint(urb->pipe); | ||
40 | |||
41 | usbip_pack_pdu(pdup, urb, USBIP_CMD_SUBMIT, 1); | ||
42 | |||
43 | if (urb->setup_packet) | ||
44 | memcpy(pdup->u.cmd_submit.setup, urb->setup_packet, 8); | ||
45 | } | ||
46 | |||
47 | static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev) | ||
48 | { | ||
49 | struct vhci_priv *priv, *tmp; | ||
50 | |||
51 | spin_lock(&vdev->priv_lock); | ||
52 | |||
53 | list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) { | ||
54 | list_move_tail(&priv->list, &vdev->priv_rx); | ||
55 | spin_unlock(&vdev->priv_lock); | ||
56 | return priv; | ||
57 | } | ||
58 | |||
59 | spin_unlock(&vdev->priv_lock); | ||
60 | |||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | static int vhci_send_cmd_submit(struct vhci_device *vdev) | ||
65 | { | ||
66 | struct vhci_priv *priv = NULL; | ||
67 | |||
68 | struct msghdr msg; | ||
69 | struct kvec iov[3]; | ||
70 | size_t txsize; | ||
71 | |||
72 | size_t total_size = 0; | ||
73 | |||
74 | while ((priv = dequeue_from_priv_tx(vdev)) != NULL) { | ||
75 | int ret; | ||
76 | struct urb *urb = priv->urb; | ||
77 | struct usbip_header pdu_header; | ||
78 | struct usbip_iso_packet_descriptor *iso_buffer = NULL; | ||
79 | |||
80 | txsize = 0; | ||
81 | memset(&pdu_header, 0, sizeof(pdu_header)); | ||
82 | memset(&msg, 0, sizeof(msg)); | ||
83 | memset(&iov, 0, sizeof(iov)); | ||
84 | |||
85 | usbip_dbg_vhci_tx("setup txdata urb %p\n", urb); | ||
86 | |||
87 | /* 1. setup usbip_header */ | ||
88 | setup_cmd_submit_pdu(&pdu_header, urb); | ||
89 | usbip_header_correct_endian(&pdu_header, 1); | ||
90 | |||
91 | iov[0].iov_base = &pdu_header; | ||
92 | iov[0].iov_len = sizeof(pdu_header); | ||
93 | txsize += sizeof(pdu_header); | ||
94 | |||
95 | /* 2. setup transfer buffer */ | ||
96 | if (!usb_pipein(urb->pipe) && urb->transfer_buffer_length > 0) { | ||
97 | iov[1].iov_base = urb->transfer_buffer; | ||
98 | iov[1].iov_len = urb->transfer_buffer_length; | ||
99 | txsize += urb->transfer_buffer_length; | ||
100 | } | ||
101 | |||
102 | /* 3. setup iso_packet_descriptor */ | ||
103 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
104 | ssize_t len = 0; | ||
105 | |||
106 | iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len); | ||
107 | if (!iso_buffer) { | ||
108 | usbip_event_add(&vdev->ud, | ||
109 | SDEV_EVENT_ERROR_MALLOC); | ||
110 | return -1; | ||
111 | } | ||
112 | |||
113 | iov[2].iov_base = iso_buffer; | ||
114 | iov[2].iov_len = len; | ||
115 | txsize += len; | ||
116 | } | ||
117 | |||
118 | ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize); | ||
119 | if (ret != txsize) { | ||
120 | pr_err("sendmsg failed!, ret=%d for %zd\n", ret, | ||
121 | txsize); | ||
122 | kfree(iso_buffer); | ||
123 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP); | ||
124 | return -1; | ||
125 | } | ||
126 | |||
127 | kfree(iso_buffer); | ||
128 | usbip_dbg_vhci_tx("send txdata\n"); | ||
129 | |||
130 | total_size += txsize; | ||
131 | } | ||
132 | |||
133 | return total_size; | ||
134 | } | ||
135 | |||
136 | static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev) | ||
137 | { | ||
138 | struct vhci_unlink *unlink, *tmp; | ||
139 | |||
140 | spin_lock(&vdev->priv_lock); | ||
141 | |||
142 | list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { | ||
143 | list_move_tail(&unlink->list, &vdev->unlink_rx); | ||
144 | spin_unlock(&vdev->priv_lock); | ||
145 | return unlink; | ||
146 | } | ||
147 | |||
148 | spin_unlock(&vdev->priv_lock); | ||
149 | |||
150 | return NULL; | ||
151 | } | ||
152 | |||
153 | static int vhci_send_cmd_unlink(struct vhci_device *vdev) | ||
154 | { | ||
155 | struct vhci_unlink *unlink = NULL; | ||
156 | |||
157 | struct msghdr msg; | ||
158 | struct kvec iov[3]; | ||
159 | size_t txsize; | ||
160 | |||
161 | size_t total_size = 0; | ||
162 | |||
163 | while ((unlink = dequeue_from_unlink_tx(vdev)) != NULL) { | ||
164 | int ret; | ||
165 | struct usbip_header pdu_header; | ||
166 | |||
167 | txsize = 0; | ||
168 | memset(&pdu_header, 0, sizeof(pdu_header)); | ||
169 | memset(&msg, 0, sizeof(msg)); | ||
170 | memset(&iov, 0, sizeof(iov)); | ||
171 | |||
172 | usbip_dbg_vhci_tx("setup cmd unlink, %lu\n", unlink->seqnum); | ||
173 | |||
174 | /* 1. setup usbip_header */ | ||
175 | pdu_header.base.command = USBIP_CMD_UNLINK; | ||
176 | pdu_header.base.seqnum = unlink->seqnum; | ||
177 | pdu_header.base.devid = vdev->devid; | ||
178 | pdu_header.base.ep = 0; | ||
179 | pdu_header.u.cmd_unlink.seqnum = unlink->unlink_seqnum; | ||
180 | |||
181 | usbip_header_correct_endian(&pdu_header, 1); | ||
182 | |||
183 | iov[0].iov_base = &pdu_header; | ||
184 | iov[0].iov_len = sizeof(pdu_header); | ||
185 | txsize += sizeof(pdu_header); | ||
186 | |||
187 | ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize); | ||
188 | if (ret != txsize) { | ||
189 | pr_err("sendmsg failed!, ret=%d for %zd\n", ret, | ||
190 | txsize); | ||
191 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP); | ||
192 | return -1; | ||
193 | } | ||
194 | |||
195 | usbip_dbg_vhci_tx("send txdata\n"); | ||
196 | |||
197 | total_size += txsize; | ||
198 | } | ||
199 | |||
200 | return total_size; | ||
201 | } | ||
202 | |||
203 | int vhci_tx_loop(void *data) | ||
204 | { | ||
205 | struct usbip_device *ud = data; | ||
206 | struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); | ||
207 | |||
208 | while (!kthread_should_stop()) { | ||
209 | if (vhci_send_cmd_submit(vdev) < 0) | ||
210 | break; | ||
211 | |||
212 | if (vhci_send_cmd_unlink(vdev) < 0) | ||
213 | break; | ||
214 | |||
215 | wait_event_interruptible(vdev->waitq_tx, | ||
216 | (!list_empty(&vdev->priv_tx) || | ||
217 | !list_empty(&vdev->unlink_tx) || | ||
218 | kthread_should_stop())); | ||
219 | |||
220 | usbip_dbg_vhci_tx("pending urbs ?, now wake up\n"); | ||
221 | } | ||
222 | |||
223 | return 0; | ||
224 | } | ||
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 3e2e4ed20157..e279015be466 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
@@ -2602,6 +2602,7 @@ static void wa_buf_in_cb(struct urb *urb) | |||
2602 | dev = &wa->usb_iface->dev; | 2602 | dev = &wa->usb_iface->dev; |
2603 | --(wa->active_buf_in_urbs); | 2603 | --(wa->active_buf_in_urbs); |
2604 | active_buf_in_urbs = wa->active_buf_in_urbs; | 2604 | active_buf_in_urbs = wa->active_buf_in_urbs; |
2605 | rpipe = xfer->ep->hcpriv; | ||
2605 | 2606 | ||
2606 | if (usb_pipeisoc(xfer->urb->pipe)) { | 2607 | if (usb_pipeisoc(xfer->urb->pipe)) { |
2607 | struct usb_iso_packet_descriptor *iso_frame_desc = | 2608 | struct usb_iso_packet_descriptor *iso_frame_desc = |
@@ -2659,7 +2660,6 @@ static void wa_buf_in_cb(struct urb *urb) | |||
2659 | resubmit_dti = (isoc_data_frame_count == | 2660 | resubmit_dti = (isoc_data_frame_count == |
2660 | urb_frame_count); | 2661 | urb_frame_count); |
2661 | } else if (active_buf_in_urbs == 0) { | 2662 | } else if (active_buf_in_urbs == 0) { |
2662 | rpipe = xfer->ep->hcpriv; | ||
2663 | dev_dbg(dev, | 2663 | dev_dbg(dev, |
2664 | "xfer %p 0x%08X#%u: data in done (%zu bytes)\n", | 2664 | "xfer %p 0x%08X#%u: data in done (%zu bytes)\n", |
2665 | xfer, wa_xfer_id(xfer), seg->index, | 2665 | xfer, wa_xfer_id(xfer), seg->index, |
@@ -2685,7 +2685,6 @@ static void wa_buf_in_cb(struct urb *urb) | |||
2685 | */ | 2685 | */ |
2686 | resubmit_dti = wa->dti_state != WA_DTI_TRANSFER_RESULT_PENDING; | 2686 | resubmit_dti = wa->dti_state != WA_DTI_TRANSFER_RESULT_PENDING; |
2687 | spin_lock_irqsave(&xfer->lock, flags); | 2687 | spin_lock_irqsave(&xfer->lock, flags); |
2688 | rpipe = xfer->ep->hcpriv; | ||
2689 | if (printk_ratelimit()) | 2688 | if (printk_ratelimit()) |
2690 | dev_err(dev, "xfer %p 0x%08X#%u: data in error %d\n", | 2689 | dev_err(dev, "xfer %p 0x%08X#%u: data in error %d\n", |
2691 | xfer, wa_xfer_id(xfer), seg->index, | 2690 | xfer, wa_xfer_id(xfer), seg->index, |