diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-10-03 14:24:46 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-10-03 14:24:46 -0400 |
| commit | 447a8b858e4bda41c394b1bc7fdbc9dc0bdf44f6 (patch) | |
| tree | 676e741f2552c9cb301e1e49c557b92bf8940f55 /drivers/usb | |
| parent | 3049683eafdbbbd7350b0e5ca02a2d8c026a3362 (diff) | |
| parent | 042e1c79166b9250edd8262bea84e1703f27ad2e (diff) | |
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.18.
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/usb/Makefile | 2 | ||||
| -rw-r--r-- | drivers/usb/chipidea/ci_hdrc_imx.c | 3 | ||||
| -rw-r--r-- | drivers/usb/chipidea/debug.c | 4 | ||||
| -rw-r--r-- | drivers/usb/class/usbtmc.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/config.c | 11 | ||||
| -rw-r--r-- | drivers/usb/core/devio.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/driver.c | 7 | ||||
| -rw-r--r-- | drivers/usb/core/hcd-pci.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.c | 4 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 104 | ||||
| -rw-r--r-- | drivers/usb/core/hub.h | 2 | ||||
| -rw-r--r-- | drivers/usb/core/port.c | 21 | ||||
| -rw-r--r-- | drivers/usb/core/quirks.c | 7 | ||||
| -rw-r--r-- | drivers/usb/core/urb.c | 1 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 1 | ||||
| -rw-r--r-- | drivers/usb/dwc2/gadget.c | 14 | ||||
| -rw-r--r-- | drivers/usb/dwc3/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/usb/dwc3/core.c | 51 | ||||
| -rw-r--r-- | drivers/usb/dwc3/core.h | 13 | ||||
| -rw-r--r-- | drivers/usb/dwc3/dwc3-omap.c | 172 | ||||
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 7 | ||||
| -rw-r--r-- | drivers/usb/dwc3/host.c | 14 | ||||
| -rw-r--r-- | drivers/usb/gadget/Kconfig | 824 | ||||
| -rw-r--r-- | drivers/usb/gadget/Makefile | 101 | ||||
| -rw-r--r-- | drivers/usb/gadget/composite.c | 1 | ||||
| -rw-r--r-- | drivers/usb/gadget/configfs.c | 4 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/Makefile | 34 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_acm.c (renamed from drivers/usb/gadget/f_acm.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_ecm.c (renamed from drivers/usb/gadget/f_ecm.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_eem.c (renamed from drivers/usb/gadget/f_eem.c) | 22 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_fs.c (renamed from drivers/usb/gadget/f_fs.c) | 352 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_hid.c (renamed from drivers/usb/gadget/f_hid.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_loopback.c (renamed from drivers/usb/gadget/f_loopback.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_mass_storage.c (renamed from drivers/usb/gadget/f_mass_storage.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_mass_storage.h (renamed from drivers/usb/gadget/f_mass_storage.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_midi.c (renamed from drivers/usb/gadget/f_midi.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_ncm.c (renamed from drivers/usb/gadget/f_ncm.c) | 480 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_obex.c (renamed from drivers/usb/gadget/f_obex.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_phonet.c (renamed from drivers/usb/gadget/f_phonet.c) | 3 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_rndis.c (renamed from drivers/usb/gadget/f_rndis.c) | 4 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_serial.c (renamed from drivers/usb/gadget/f_serial.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_sourcesink.c (renamed from drivers/usb/gadget/f_sourcesink.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_subset.c (renamed from drivers/usb/gadget/f_subset.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_uac1.c (renamed from drivers/usb/gadget/f_uac1.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_uac2.c (renamed from drivers/usb/gadget/f_uac2.c) | 24 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_uvc.c (renamed from drivers/usb/gadget/f_uvc.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_uvc.h (renamed from drivers/usb/gadget/f_uvc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/g_zero.h (renamed from drivers/usb/gadget/g_zero.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/ndis.h (renamed from drivers/usb/gadget/ndis.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/rndis.c (renamed from drivers/usb/gadget/rndis.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/rndis.h (renamed from drivers/usb/gadget/rndis.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/storage_common.c (renamed from drivers/usb/gadget/storage_common.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/storage_common.h (renamed from drivers/usb/gadget/storage_common.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_ecm.h (renamed from drivers/usb/gadget/u_ecm.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_eem.h (renamed from drivers/usb/gadget/u_eem.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_ether.c (renamed from drivers/usb/gadget/u_ether.c) | 22 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_ether.h (renamed from drivers/usb/gadget/u_ether.h) | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_ether_configfs.h (renamed from drivers/usb/gadget/u_ether_configfs.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_fs.h (renamed from drivers/usb/gadget/u_fs.h) | 7 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_gether.h (renamed from drivers/usb/gadget/u_gether.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_ncm.h (renamed from drivers/usb/gadget/u_ncm.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_phonet.h (renamed from drivers/usb/gadget/u_phonet.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_rndis.h (renamed from drivers/usb/gadget/u_rndis.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_serial.c (renamed from drivers/usb/gadget/u_serial.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_serial.h (renamed from drivers/usb/gadget/u_serial.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_uac1.c (renamed from drivers/usb/gadget/u_uac1.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_uac1.h (renamed from drivers/usb/gadget/u_uac1.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/uvc.h (renamed from drivers/usb/gadget/uvc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/uvc_queue.c (renamed from drivers/usb/gadget/uvc_queue.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/uvc_queue.h (renamed from drivers/usb/gadget/uvc_queue.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/uvc_v4l2.c (renamed from drivers/usb/gadget/uvc_v4l2.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/uvc_video.c (renamed from drivers/usb/gadget/uvc_video.c) | 3 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/Kconfig | 475 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/Makefile | 44 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/acm_ms.c (renamed from drivers/usb/gadget/acm_ms.c) | 14 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/audio.c (renamed from drivers/usb/gadget/audio.c) | 12 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/cdc2.c (renamed from drivers/usb/gadget/cdc2.c) | 14 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/dbgp.c (renamed from drivers/usb/gadget/dbgp.c) | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/ether.c (renamed from drivers/usb/gadget/ether.c) | 14 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/g_ffs.c (renamed from drivers/usb/gadget/g_ffs.c) | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/gmidi.c (renamed from drivers/usb/gadget/gmidi.c) | 13 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/hid.c (renamed from drivers/usb/gadget/hid.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/inode.c (renamed from drivers/usb/gadget/inode.c) | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/mass_storage.c (renamed from drivers/usb/gadget/mass_storage.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/multi.c (renamed from drivers/usb/gadget/multi.c) | 13 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/ncm.c (renamed from drivers/usb/gadget/ncm.c) | 14 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/nokia.c (renamed from drivers/usb/gadget/nokia.c) | 12 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/printer.c (renamed from drivers/usb/gadget/printer.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/serial.c (renamed from drivers/usb/gadget/serial.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/tcm_usb_gadget.c (renamed from drivers/usb/gadget/tcm_usb_gadget.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/tcm_usb_gadget.h (renamed from drivers/usb/gadget/tcm_usb_gadget.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/webcam.c (renamed from drivers/usb/gadget/webcam.c) | 15 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/zero.c (renamed from drivers/usb/gadget/zero.c) | 14 | ||||
| -rw-r--r-- | drivers/usb/gadget/net2280.c | 2905 | ||||
| -rw-r--r-- | drivers/usb/gadget/net2280.h | 308 | ||||
| -rw-r--r-- | drivers/usb/gadget/u_os_desc.h | 59 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/Kconfig | 386 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/Makefile | 31 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/amd5536udc.c (renamed from drivers/usb/gadget/amd5536udc.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/amd5536udc.h (renamed from drivers/usb/gadget/amd5536udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/at91_udc.c (renamed from drivers/usb/gadget/at91_udc.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/at91_udc.h (renamed from drivers/usb/gadget/at91_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.c (renamed from drivers/usb/gadget/atmel_usba_udc.c) | 4 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.h (renamed from drivers/usb/gadget/atmel_usba_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/bcm63xx_udc.c (renamed from drivers/usb/gadget/bcm63xx_udc.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/dummy_hcd.c (renamed from drivers/usb/gadget/dummy_hcd.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fotg210-udc.c (renamed from drivers/usb/gadget/fotg210-udc.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fotg210.h (renamed from drivers/usb/gadget/fotg210.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fsl_mxc_udc.c (renamed from drivers/usb/gadget/fsl_mxc_udc.c) | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fsl_qe_udc.c (renamed from drivers/usb/gadget/fsl_qe_udc.c) | 19 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fsl_qe_udc.h (renamed from drivers/usb/gadget/fsl_qe_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fsl_udc_core.c (renamed from drivers/usb/gadget/fsl_udc_core.c) | 19 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fsl_usb2_udc.h (renamed from drivers/usb/gadget/fsl_usb2_udc.h) | 3 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fusb300_udc.c (renamed from drivers/usb/gadget/fusb300_udc.c) | 12 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/fusb300_udc.h (renamed from drivers/usb/gadget/fusb300_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/gadget_chips.h (renamed from drivers/usb/gadget/gadget_chips.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/goku_udc.c (renamed from drivers/usb/gadget/goku_udc.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/goku_udc.h (renamed from drivers/usb/gadget/goku_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/gr_udc.c (renamed from drivers/usb/gadget/gr_udc.c) | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/gr_udc.h (renamed from drivers/usb/gadget/gr_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/lpc32xx_udc.c (renamed from drivers/usb/gadget/lpc32xx_udc.c) | 7 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/m66592-udc.c (renamed from drivers/usb/gadget/m66592-udc.c) | 4 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/m66592-udc.h (renamed from drivers/usb/gadget/m66592-udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/mv_u3d.h (renamed from drivers/usb/gadget/mv_u3d.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/mv_u3d_core.c (renamed from drivers/usb/gadget/mv_u3d_core.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/mv_udc.h (renamed from drivers/usb/gadget/mv_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/mv_udc_core.c (renamed from drivers/usb/gadget/mv_udc_core.c) | 4 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/net2272.c (renamed from drivers/usb/gadget/net2272.c) | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/net2272.h (renamed from drivers/usb/gadget/net2272.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/net2280.c | 3827 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/net2280.h | 403 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/omap_udc.c (renamed from drivers/usb/gadget/omap_udc.c) | 5 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/omap_udc.h (renamed from drivers/usb/gadget/omap_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/pch_udc.c (renamed from drivers/usb/gadget/pch_udc.c) | 22 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/pxa25x_udc.c (renamed from drivers/usb/gadget/pxa25x_udc.c) | 75 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/pxa25x_udc.h (renamed from drivers/usb/gadget/pxa25x_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/pxa27x_udc.c (renamed from drivers/usb/gadget/pxa27x_udc.c) | 6 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/pxa27x_udc.h (renamed from drivers/usb/gadget/pxa27x_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/r8a66597-udc.c (renamed from drivers/usb/gadget/r8a66597-udc.c) | 92 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/r8a66597-udc.h (renamed from drivers/usb/gadget/r8a66597-udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/s3c-hsudc.c (renamed from drivers/usb/gadget/s3c-hsudc.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/s3c2410_udc.c (renamed from drivers/usb/gadget/s3c2410_udc.c) | 8 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/s3c2410_udc.h (renamed from drivers/usb/gadget/s3c2410_udc.h) | 0 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/udc-core.c (renamed from drivers/usb/gadget/udc-core.c) | 0 | ||||
| -rw-r--r-- | drivers/usb/host/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/usb/host/Makefile | 3 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-exynos.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-hub.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-mem.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-msm.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-pci.c | 25 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-spear.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-tegra.c | 67 | ||||
| -rw-r--r-- | drivers/usb/host/fhci-dbg.c | 8 | ||||
| -rw-r--r-- | drivers/usb/host/fotg210-hcd.c | 48 | ||||
| -rw-r--r-- | drivers/usb/host/max3421-hcd.c | 48 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-dbg.c | 9 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-exynos.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-hcd.c | 381 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-hub.c | 11 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-mem.c | 1 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-q.c | 262 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-spear.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ohci.h | 23 | ||||
| -rw-r--r-- | drivers/usb/host/oxu210hp-hcd.c | 48 | ||||
| -rw-r--r-- | drivers/usb/host/uhci-grlib.c | 31 | ||||
| -rw-r--r-- | drivers/usb/host/uhci-hcd.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/uhci-platform.c | 22 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-pci.c | 17 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-plat.c | 52 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-rcar.c | 148 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-rcar.h | 27 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 108 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.c | 163 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.h | 2 | ||||
| -rw-r--r-- | drivers/usb/misc/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/usb/misc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/usb/misc/lvstest.c | 460 | ||||
| -rw-r--r-- | drivers/usb/misc/sisusbvga/sisusb.c | 1 | ||||
| -rw-r--r-- | drivers/usb/misc/usb3503.c | 37 | ||||
| -rw-r--r-- | drivers/usb/musb/blackfin.c | 20 | ||||
| -rw-r--r-- | drivers/usb/musb/davinci.c | 20 | ||||
| -rw-r--r-- | drivers/usb/musb/jz4740.c | 3 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_core.c | 41 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_core.h | 12 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_cppi41.c | 70 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_dma.h | 1 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_dsps.c | 104 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_host.c | 19 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_regs.h | 7 | ||||
| -rw-r--r-- | drivers/usb/musb/tusb6010.c | 16 | ||||
| -rw-r--r-- | drivers/usb/musb/ux500.c | 28 | ||||
| -rw-r--r-- | drivers/usb/musb/ux500_dma.c | 2 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-am335x.c | 12 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-gpio-vbus-usb.c | 49 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-msm-usb.c | 16 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-samsung-usb.h | 2 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-tegra-usb.c | 11 | ||||
| -rw-r--r-- | drivers/usb/phy/phy.c | 5 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/Makefile | 2 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/common.c | 66 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/common.h | 2 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 2 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/pipe.c | 11 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/pipe.h | 1 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/rcar2.c | 77 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/rcar2.h | 4 | ||||
| -rw-r--r-- | drivers/usb/serial/cp210x.c | 3 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 87 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio_ids.h | 20 | ||||
| -rw-r--r-- | drivers/usb/serial/kl5kusb105.c | 30 | ||||
| -rw-r--r-- | drivers/usb/serial/mos7840.c | 5 | ||||
| -rw-r--r-- | drivers/usb/serial/option.c | 31 | ||||
| -rw-r--r-- | drivers/usb/serial/pl2303.c | 1 | ||||
| -rw-r--r-- | drivers/usb/serial/pl2303.h | 1 | ||||
| -rw-r--r-- | drivers/usb/serial/usb-serial.c | 37 | ||||
| -rw-r--r-- | drivers/usb/serial/whiteheat.c | 7 | ||||
| -rw-r--r-- | drivers/usb/serial/zte_ev.c | 20 | ||||
| -rw-r--r-- | drivers/usb/storage/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/usb/storage/ene_ub6250.c | 4 | ||||
| -rw-r--r-- | drivers/usb/storage/sddr09.c | 4 | ||||
| -rw-r--r-- | drivers/usb/storage/uas-detect.h | 40 | ||||
| -rw-r--r-- | drivers/usb/storage/uas.c | 2 | ||||
| -rw-r--r-- | drivers/usb/storage/unusual_devs.h | 6 | ||||
| -rw-r--r-- | drivers/usb/storage/usb.c | 10 | ||||
| -rw-r--r-- | drivers/usb/usbip/Kconfig | 41 | ||||
| -rw-r--r-- | drivers/usb/usbip/Makefile | 10 | ||||
| -rw-r--r-- | drivers/usb/usbip/README | 7 | ||||
| -rw-r--r-- | drivers/usb/usbip/stub.h | 113 | ||||
| -rw-r--r-- | drivers/usb/usbip/stub_dev.c | 498 | ||||
| -rw-r--r-- | drivers/usb/usbip/stub_main.c | 335 | ||||
| -rw-r--r-- | drivers/usb/usbip/stub_rx.c | 594 | ||||
| -rw-r--r-- | drivers/usb/usbip/stub_tx.c | 398 | ||||
| -rw-r--r-- | drivers/usb/usbip/usbip_common.c | 776 | ||||
| -rw-r--r-- | drivers/usb/usbip/usbip_common.h | 335 | ||||
| -rw-r--r-- | drivers/usb/usbip/usbip_event.c | 128 | ||||
| -rw-r--r-- | drivers/usb/usbip/usbip_protocol.txt | 358 | ||||
| -rw-r--r-- | drivers/usb/usbip/vhci.h | 129 | ||||
| -rw-r--r-- | drivers/usb/usbip/vhci_hcd.c | 1171 | ||||
| -rw-r--r-- | drivers/usb/usbip/vhci_rx.c | 268 | ||||
| -rw-r--r-- | drivers/usb/usbip/vhci_sysfs.c | 252 | ||||
| -rw-r--r-- | drivers/usb/usbip/vhci_tx.c | 224 | ||||
| -rw-r--r-- | drivers/usb/wusbcore/wa-xfer.c | 3 |
244 files changed, 14019 insertions, 5773 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/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 2e58f8dfd311..65444b02bd68 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c | |||
| @@ -133,6 +133,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) | |||
| 133 | data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0); | 133 | data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0); |
| 134 | if (IS_ERR(data->phy)) { | 134 | if (IS_ERR(data->phy)) { |
| 135 | ret = PTR_ERR(data->phy); | 135 | ret = PTR_ERR(data->phy); |
| 136 | /* Return -EINVAL if no usbphy is available */ | ||
| 137 | if (ret == -ENODEV) | ||
| 138 | ret = -EINVAL; | ||
| 136 | goto err_clk; | 139 | goto err_clk; |
| 137 | } | 140 | } |
| 138 | 141 | ||
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 7cccab6ff308..795d6538d630 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c | |||
| @@ -208,7 +208,7 @@ static const struct file_operations ci_requests_fops = { | |||
| 208 | .release = single_release, | 208 | .release = single_release, |
| 209 | }; | 209 | }; |
| 210 | 210 | ||
| 211 | int ci_otg_show(struct seq_file *s, void *unused) | 211 | static int ci_otg_show(struct seq_file *s, void *unused) |
| 212 | { | 212 | { |
| 213 | struct ci_hdrc *ci = s->private; | 213 | struct ci_hdrc *ci = s->private; |
| 214 | struct otg_fsm *fsm; | 214 | struct otg_fsm *fsm; |
| @@ -331,7 +331,7 @@ static const struct file_operations ci_role_fops = { | |||
| 331 | .release = single_release, | 331 | .release = single_release, |
| 332 | }; | 332 | }; |
| 333 | 333 | ||
| 334 | int ci_registers_show(struct seq_file *s, void *unused) | 334 | static int ci_registers_show(struct seq_file *s, void *unused) |
| 335 | { | 335 | { |
| 336 | struct ci_hdrc *ci = s->private; | 336 | struct ci_hdrc *ci = s->private; |
| 337 | u32 tmp_reg; | 337 | u32 tmp_reg; |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 103a6e9ee49d..ec978408a2ee 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
| @@ -715,7 +715,7 @@ static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) | |||
| 715 | u8 *buffer; | 715 | u8 *buffer; |
| 716 | int rv; | 716 | int rv; |
| 717 | int n; | 717 | int n; |
| 718 | int actual; | 718 | int actual = 0; |
| 719 | int max_size; | 719 | int max_size; |
| 720 | 720 | ||
| 721 | dev = &data->intf->dev; | 721 | dev = &data->intf->dev; |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 1ab4df1de2da..b2a540b43f97 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
| @@ -199,6 +199,17 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
| 199 | if (n == 0) | 199 | if (n == 0) |
| 200 | n = 9; /* 32 ms = 2^(9-1) uframes */ | 200 | n = 9; /* 32 ms = 2^(9-1) uframes */ |
| 201 | j = 16; | 201 | j = 16; |
| 202 | |||
| 203 | /* | ||
| 204 | * Adjust bInterval for quirked devices. | ||
| 205 | * This quirk fixes bIntervals reported in | ||
| 206 | * linear microframes. | ||
| 207 | */ | ||
| 208 | if (to_usb_device(ddev)->quirks & | ||
| 209 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL) { | ||
| 210 | n = clamp(fls(d->bInterval), i, j); | ||
| 211 | i = j = n; | ||
| 212 | } | ||
| 202 | break; | 213 | break; |
| 203 | default: /* USB_SPEED_FULL or _LOW */ | 214 | default: /* USB_SPEED_FULL or _LOW */ |
| 204 | /* For low-speed, 10 ms is the official minimum. | 215 | /* For low-speed, 10 ms is the official minimum. |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 257876ea03a1..0b59731c3021 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -1509,7 +1509,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
| 1509 | u = (is_in ? URB_DIR_IN : URB_DIR_OUT); | 1509 | u = (is_in ? URB_DIR_IN : URB_DIR_OUT); |
| 1510 | if (uurb->flags & USBDEVFS_URB_ISO_ASAP) | 1510 | if (uurb->flags & USBDEVFS_URB_ISO_ASAP) |
| 1511 | u |= URB_ISO_ASAP; | 1511 | u |= URB_ISO_ASAP; |
| 1512 | if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK) | 1512 | if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK && is_in) |
| 1513 | u |= URB_SHORT_NOT_OK; | 1513 | u |= URB_SHORT_NOT_OK; |
| 1514 | if (uurb->flags & USBDEVFS_URB_NO_FSBR) | 1514 | if (uurb->flags & USBDEVFS_URB_NO_FSBR) |
| 1515 | u |= URB_NO_FSBR; | 1515 | u |= URB_NO_FSBR; |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 4aeb10034de7..9bffd26cea05 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
| @@ -417,10 +417,11 @@ static int usb_unbind_interface(struct device *dev) | |||
| 417 | */ | 417 | */ |
| 418 | lpm_disable_error = usb_unlocked_disable_lpm(udev); | 418 | lpm_disable_error = usb_unlocked_disable_lpm(udev); |
| 419 | 419 | ||
| 420 | /* Terminate all URBs for this interface unless the driver | 420 | /* |
| 421 | * supports "soft" unbinding. | 421 | * Terminate all URBs for this interface unless the driver |
| 422 | * supports "soft" unbinding and the device is still present. | ||
| 422 | */ | 423 | */ |
| 423 | if (!driver->soft_unbind) | 424 | if (!driver->soft_unbind || udev->state == USB_STATE_NOTATTACHED) |
| 424 | usb_disable_interface(udev, intf, false); | 425 | usb_disable_interface(udev, intf, false); |
| 425 | 426 | ||
| 426 | driver->disconnect(intf); | 427 | driver->disconnect(intf); |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 82044b5d6113..efc953119ce2 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
| @@ -380,6 +380,8 @@ void usb_hcd_pci_shutdown(struct pci_dev *dev) | |||
| 380 | if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && | 380 | if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && |
| 381 | hcd->driver->shutdown) { | 381 | hcd->driver->shutdown) { |
| 382 | hcd->driver->shutdown(hcd); | 382 | hcd->driver->shutdown(hcd); |
| 383 | if (usb_hcd_is_primary_hcd(hcd) && hcd->irq > 0) | ||
| 384 | free_irq(hcd->irq, hcd); | ||
| 383 | pci_disable_device(dev); | 385 | pci_disable_device(dev); |
| 384 | } | 386 | } |
| 385 | } | 387 | } |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index bec31e2efb88..487abcfcccd8 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -855,8 +855,6 @@ static ssize_t authorized_default_show(struct device *dev, | |||
| 855 | struct usb_bus *usb_bus = rh_usb_dev->bus; | 855 | struct usb_bus *usb_bus = rh_usb_dev->bus; |
| 856 | struct usb_hcd *usb_hcd; | 856 | struct usb_hcd *usb_hcd; |
| 857 | 857 | ||
| 858 | if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ | ||
| 859 | return -ENODEV; | ||
| 860 | usb_hcd = bus_to_hcd(usb_bus); | 858 | usb_hcd = bus_to_hcd(usb_bus); |
| 861 | return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); | 859 | return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); |
| 862 | } | 860 | } |
| @@ -871,8 +869,6 @@ static ssize_t authorized_default_store(struct device *dev, | |||
| 871 | struct usb_bus *usb_bus = rh_usb_dev->bus; | 869 | struct usb_bus *usb_bus = rh_usb_dev->bus; |
| 872 | struct usb_hcd *usb_hcd; | 870 | struct usb_hcd *usb_hcd; |
| 873 | 871 | ||
| 874 | if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ | ||
| 875 | return -ENODEV; | ||
| 876 | usb_hcd = bus_to_hcd(usb_bus); | 872 | usb_hcd = bus_to_hcd(usb_bus); |
| 877 | result = sscanf(buf, "%u\n", &val); | 873 | result = sscanf(buf, "%u\n", &val); |
| 878 | if (result == 1) { | 874 | if (result == 1) { |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0e950ad8cb25..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. |
| @@ -2606,13 +2612,20 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
| 2606 | /* Is a USB 3.0 port in the Inactive or Compliance Mode state? | 2612 | /* Is a USB 3.0 port in the Inactive or Compliance Mode state? |
| 2607 | * Port worm reset is required to recover | 2613 | * Port worm reset is required to recover |
| 2608 | */ | 2614 | */ |
| 2609 | static bool hub_port_warm_reset_required(struct usb_hub *hub, u16 portstatus) | 2615 | static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1, |
| 2616 | u16 portstatus) | ||
| 2610 | { | 2617 | { |
| 2611 | return hub_is_superspeed(hub->hdev) && | 2618 | u16 link_state; |
| 2612 | (((portstatus & USB_PORT_STAT_LINK_STATE) == | 2619 | |
| 2613 | USB_SS_PORT_LS_SS_INACTIVE) || | 2620 | if (!hub_is_superspeed(hub->hdev)) |
| 2614 | ((portstatus & USB_PORT_STAT_LINK_STATE) == | 2621 | return false; |
| 2615 | USB_SS_PORT_LS_COMP_MOD)) ; | 2622 | |
| 2623 | if (test_bit(port1, hub->warm_reset_bits)) | ||
| 2624 | return true; | ||
| 2625 | |||
| 2626 | link_state = portstatus & USB_PORT_STAT_LINK_STATE; | ||
| 2627 | return link_state == USB_SS_PORT_LS_SS_INACTIVE | ||
| 2628 | || link_state == USB_SS_PORT_LS_COMP_MOD; | ||
| 2616 | } | 2629 | } |
| 2617 | 2630 | ||
| 2618 | static int hub_port_wait_reset(struct usb_hub *hub, int port1, | 2631 | static int hub_port_wait_reset(struct usb_hub *hub, int port1, |
| @@ -2649,7 +2662,7 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, | |||
| 2649 | if ((portstatus & USB_PORT_STAT_RESET)) | 2662 | if ((portstatus & USB_PORT_STAT_RESET)) |
| 2650 | return -EBUSY; | 2663 | return -EBUSY; |
| 2651 | 2664 | ||
| 2652 | if (hub_port_warm_reset_required(hub, portstatus)) | 2665 | if (hub_port_warm_reset_required(hub, port1, portstatus)) |
| 2653 | return -ENOTCONN; | 2666 | return -ENOTCONN; |
| 2654 | 2667 | ||
| 2655 | /* Device went away? */ | 2668 | /* Device went away? */ |
| @@ -2749,9 +2762,10 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
| 2749 | if (status < 0) | 2762 | if (status < 0) |
| 2750 | goto done; | 2763 | goto done; |
| 2751 | 2764 | ||
| 2752 | if (hub_port_warm_reset_required(hub, portstatus)) | 2765 | if (hub_port_warm_reset_required(hub, port1, portstatus)) |
| 2753 | warm = true; | 2766 | warm = true; |
| 2754 | } | 2767 | } |
| 2768 | clear_bit(port1, hub->warm_reset_bits); | ||
| 2755 | 2769 | ||
| 2756 | /* Reset the port */ | 2770 | /* Reset the port */ |
| 2757 | for (i = 0; i < PORT_RESET_TRIES; i++) { | 2771 | for (i = 0; i < PORT_RESET_TRIES; i++) { |
| @@ -2788,7 +2802,8 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
| 2788 | &portstatus, &portchange) < 0) | 2802 | &portstatus, &portchange) < 0) |
| 2789 | goto done; | 2803 | goto done; |
| 2790 | 2804 | ||
| 2791 | if (!hub_port_warm_reset_required(hub, portstatus)) | 2805 | if (!hub_port_warm_reset_required(hub, port1, |
| 2806 | portstatus)) | ||
| 2792 | goto done; | 2807 | goto done; |
| 2793 | 2808 | ||
| 2794 | /* | 2809 | /* |
| @@ -2875,8 +2890,13 @@ static int check_port_resume_type(struct usb_device *udev, | |||
| 2875 | { | 2890 | { |
| 2876 | struct usb_port *port_dev = hub->ports[port1 - 1]; | 2891 | struct usb_port *port_dev = hub->ports[port1 - 1]; |
| 2877 | 2892 | ||
| 2893 | /* Is a warm reset needed to recover the connection? */ | ||
| 2894 | if (status == 0 && udev->reset_resume | ||
| 2895 | && hub_port_warm_reset_required(hub, port1, portstatus)) { | ||
| 2896 | /* pass */; | ||
| 2897 | } | ||
| 2878 | /* Is the device still present? */ | 2898 | /* Is the device still present? */ |
| 2879 | if (status || port_is_suspended(hub, portstatus) || | 2899 | else if (status || port_is_suspended(hub, portstatus) || |
| 2880 | !port_is_power_on(hub, portstatus) || | 2900 | !port_is_power_on(hub, portstatus) || |
| 2881 | !(portstatus & USB_PORT_STAT_CONNECTION)) { | 2901 | !(portstatus & USB_PORT_STAT_CONNECTION)) { |
| 2882 | if (status >= 0) | 2902 | if (status >= 0) |
| @@ -3264,6 +3284,43 @@ static int finish_port_resume(struct usb_device *udev) | |||
| 3264 | } | 3284 | } |
| 3265 | 3285 | ||
| 3266 | /* | 3286 | /* |
| 3287 | * There are some SS USB devices which take longer time for link training. | ||
| 3288 | * XHCI specs 4.19.4 says that when Link training is successful, port | ||
| 3289 | * sets CSC bit to 1. So if SW reads port status before successful link | ||
| 3290 | * training, then it will not find device to be present. | ||
| 3291 | * USB Analyzer log with such buggy devices show that in some cases | ||
| 3292 | * device switch on the RX termination after long delay of host enabling | ||
| 3293 | * the VBUS. In few other cases it has been seen that device fails to | ||
| 3294 | * negotiate link training in first attempt. It has been | ||
| 3295 | * reported till now that few devices take as long as 2000 ms to train | ||
| 3296 | * the link after host enabling its VBUS and termination. Following | ||
| 3297 | * routine implements a 2000 ms timeout for link training. If in a case | ||
| 3298 | * link trains before timeout, loop will exit earlier. | ||
| 3299 | * | ||
| 3300 | * FIXME: If a device was connected before suspend, but was removed | ||
| 3301 | * while system was asleep, then the loop in the following routine will | ||
| 3302 | * only exit at timeout. | ||
| 3303 | * | ||
| 3304 | * This routine should only be called when persist is enabled for a SS | ||
| 3305 | * device. | ||
| 3306 | */ | ||
| 3307 | static int wait_for_ss_port_enable(struct usb_device *udev, | ||
| 3308 | struct usb_hub *hub, int *port1, | ||
| 3309 | u16 *portchange, u16 *portstatus) | ||
| 3310 | { | ||
| 3311 | int status = 0, delay_ms = 0; | ||
| 3312 | |||
| 3313 | while (delay_ms < 2000) { | ||
| 3314 | if (status || *portstatus & USB_PORT_STAT_CONNECTION) | ||
| 3315 | break; | ||
| 3316 | msleep(20); | ||
| 3317 | delay_ms += 20; | ||
| 3318 | status = hub_port_status(hub, *port1, portstatus, portchange); | ||
| 3319 | } | ||
| 3320 | return status; | ||
| 3321 | } | ||
| 3322 | |||
| 3323 | /* | ||
| 3267 | * usb_port_resume - re-activate a suspended usb device's upstream port | 3324 | * usb_port_resume - re-activate a suspended usb device's upstream port |
| 3268 | * @udev: device to re-activate, not a root hub | 3325 | * @udev: device to re-activate, not a root hub |
| 3269 | * Context: must be able to sleep; device not locked; pm locks held | 3326 | * Context: must be able to sleep; device not locked; pm locks held |
| @@ -3359,6 +3416,10 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
| 3359 | } | 3416 | } |
| 3360 | } | 3417 | } |
| 3361 | 3418 | ||
| 3419 | if (udev->persist_enabled && hub_is_superspeed(hub->hdev)) | ||
| 3420 | status = wait_for_ss_port_enable(udev, hub, &port1, &portchange, | ||
| 3421 | &portstatus); | ||
| 3422 | |||
| 3362 | status = check_port_resume_type(udev, | 3423 | status = check_port_resume_type(udev, |
| 3363 | hub, port1, status, portchange, portstatus); | 3424 | hub, port1, status, portchange, portstatus); |
| 3364 | if (status == 0) | 3425 | if (status == 0) |
| @@ -3879,7 +3940,8 @@ int usb_disable_lpm(struct usb_device *udev) | |||
| 3879 | 3940 | ||
| 3880 | if (!udev || !udev->parent || | 3941 | if (!udev || !udev->parent || |
| 3881 | udev->speed != USB_SPEED_SUPER || | 3942 | udev->speed != USB_SPEED_SUPER || |
| 3882 | !udev->lpm_capable) | 3943 | !udev->lpm_capable || |
| 3944 | udev->state < USB_STATE_DEFAULT) | ||
| 3883 | return 0; | 3945 | return 0; |
| 3884 | 3946 | ||
| 3885 | hcd = bus_to_hcd(udev->bus); | 3947 | hcd = bus_to_hcd(udev->bus); |
| @@ -3935,7 +3997,8 @@ void usb_enable_lpm(struct usb_device *udev) | |||
| 3935 | 3997 | ||
| 3936 | if (!udev || !udev->parent || | 3998 | if (!udev || !udev->parent || |
| 3937 | udev->speed != USB_SPEED_SUPER || | 3999 | udev->speed != USB_SPEED_SUPER || |
| 3938 | !udev->lpm_capable) | 4000 | !udev->lpm_capable || |
| 4001 | udev->state < USB_STATE_DEFAULT) | ||
| 3939 | return; | 4002 | return; |
| 3940 | 4003 | ||
| 3941 | udev->lpm_disable_count--; | 4004 | udev->lpm_disable_count--; |
| @@ -4550,6 +4613,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, | |||
| 4550 | struct usb_hcd *hcd = bus_to_hcd(hdev->bus); | 4613 | struct usb_hcd *hcd = bus_to_hcd(hdev->bus); |
| 4551 | struct usb_port *port_dev = hub->ports[port1 - 1]; | 4614 | struct usb_port *port_dev = hub->ports[port1 - 1]; |
| 4552 | struct usb_device *udev = port_dev->child; | 4615 | struct usb_device *udev = port_dev->child; |
| 4616 | static int unreliable_port = -1; | ||
| 4553 | 4617 | ||
| 4554 | /* Disconnect any existing devices under this port */ | 4618 | /* Disconnect any existing devices under this port */ |
| 4555 | if (udev) { | 4619 | if (udev) { |
| @@ -4570,10 +4634,12 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, | |||
| 4570 | USB_PORT_STAT_C_ENABLE)) { | 4634 | USB_PORT_STAT_C_ENABLE)) { |
| 4571 | status = hub_port_debounce_be_stable(hub, port1); | 4635 | status = hub_port_debounce_be_stable(hub, port1); |
| 4572 | if (status < 0) { | 4636 | if (status < 0) { |
| 4573 | if (status != -ENODEV && printk_ratelimit()) | 4637 | if (status != -ENODEV && |
| 4574 | dev_err(&port_dev->dev, | 4638 | port1 != unreliable_port && |
| 4575 | "connect-debounce failed\n"); | 4639 | printk_ratelimit()) |
| 4640 | dev_err(&port_dev->dev, "connect-debounce failed\n"); | ||
| 4576 | portstatus &= ~USB_PORT_STAT_CONNECTION; | 4641 | portstatus &= ~USB_PORT_STAT_CONNECTION; |
| 4642 | unreliable_port = port1; | ||
| 4577 | } else { | 4643 | } else { |
| 4578 | portstatus = status; | 4644 | portstatus = status; |
| 4579 | } | 4645 | } |
| @@ -4889,7 +4955,7 @@ static void port_event(struct usb_hub *hub, int port1) | |||
| 4889 | * Warm reset a USB3 protocol port if it's in | 4955 | * Warm reset a USB3 protocol port if it's in |
| 4890 | * SS.Inactive state. | 4956 | * SS.Inactive state. |
| 4891 | */ | 4957 | */ |
| 4892 | if (hub_port_warm_reset_required(hub, portstatus)) { | 4958 | if (hub_port_warm_reset_required(hub, port1, portstatus)) { |
| 4893 | dev_dbg(&port_dev->dev, "do warm reset\n"); | 4959 | dev_dbg(&port_dev->dev, "do warm reset\n"); |
| 4894 | if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION) | 4960 | if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION) |
| 4895 | || udev->state == USB_STATE_NOTATTACHED) { | 4961 | || udev->state == USB_STATE_NOTATTACHED) { |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 326308e53961..c77d8778af4b 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
| @@ -52,6 +52,8 @@ struct usb_hub { | |||
| 52 | unsigned long power_bits[1]; /* ports that are powered */ | 52 | unsigned long power_bits[1]; /* ports that are powered */ |
| 53 | unsigned long child_usage_bits[1]; /* ports powered on for | 53 | unsigned long child_usage_bits[1]; /* ports powered on for |
| 54 | children */ | 54 | children */ |
| 55 | unsigned long warm_reset_bits[1]; /* ports requesting warm | ||
| 56 | reset recovery */ | ||
| 55 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ | 57 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ |
| 56 | #error event_bits[] is too short! | 58 | #error event_bits[] is too short! |
| 57 | #endif | 59 | #endif |
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index fe1b6d0967e3..cd3f9dc24a06 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c | |||
| @@ -103,16 +103,19 @@ static int usb_port_runtime_resume(struct device *dev) | |||
| 103 | msleep(hub_power_on_good_delay(hub)); | 103 | msleep(hub_power_on_good_delay(hub)); |
| 104 | if (udev && !retval) { | 104 | if (udev && !retval) { |
| 105 | /* | 105 | /* |
| 106 | * Attempt to wait for usb hub port to be reconnected in order | 106 | * Our preference is to simply wait for the port to reconnect, |
| 107 | * to make the resume procedure successful. The device may have | 107 | * as that is the lowest latency method to restart the port. |
| 108 | * disconnected while the port was powered off, so ignore the | 108 | * However, there are cases where toggling port power results in |
| 109 | * return status. | 109 | * the host port and the device port getting out of sync causing |
| 110 | * a link training live lock. Upon timeout, flag the port as | ||
| 111 | * needing warm reset recovery (to be performed later by | ||
| 112 | * usb_port_resume() as requested via usb_wakeup_notification()) | ||
| 110 | */ | 113 | */ |
| 111 | retval = hub_port_debounce_be_connected(hub, port1); | 114 | if (hub_port_debounce_be_connected(hub, port1) < 0) { |
| 112 | if (retval < 0) | 115 | dev_dbg(&port_dev->dev, "reconnect timeout\n"); |
| 113 | dev_dbg(&port_dev->dev, "can't get reconnection after setting port power on, status %d\n", | 116 | if (hub_is_superspeed(hdev)) |
| 114 | retval); | 117 | set_bit(port1, hub->warm_reset_bits); |
| 115 | retval = 0; | 118 | } |
| 116 | 119 | ||
| 117 | /* Force the child awake to revalidate after the power loss. */ | 120 | /* Force the child awake to revalidate after the power loss. */ |
| 118 | if (!test_and_set_bit(port1, hub->child_usage_bits)) { | 121 | if (!test_and_set_bit(port1, hub->child_usage_bits)) { |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 739ee8e8bdfd..bae636e2a1a3 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -145,6 +145,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 145 | /* SKYMEDI USB_DRIVE */ | 145 | /* SKYMEDI USB_DRIVE */ |
| 146 | { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, | 146 | { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 147 | 147 | ||
| 148 | /* Razer - Razer Blade Keyboard */ | ||
| 149 | { USB_DEVICE(0x1532, 0x0116), .driver_info = | ||
| 150 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, | ||
| 151 | |||
| 148 | /* BUILDWIN Photo Frame */ | 152 | /* BUILDWIN Photo Frame */ |
| 149 | { USB_DEVICE(0x1908, 0x1315), .driver_info = | 153 | { USB_DEVICE(0x1908, 0x1315), .driver_info = |
| 150 | USB_QUIRK_HONOR_BNUMINTERFACES }, | 154 | USB_QUIRK_HONOR_BNUMINTERFACES }, |
| @@ -152,6 +156,9 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 152 | /* INTEL VALUE SSD */ | 156 | /* INTEL VALUE SSD */ |
| 153 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, | 157 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 154 | 158 | ||
| 159 | /* USB3503 */ | ||
| 160 | { USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 161 | |||
| 155 | { } /* terminating entry must be last */ | 162 | { } /* terminating entry must be last */ |
| 156 | }; | 163 | }; |
| 157 | 164 | ||
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 991386ceb4ec..c9e8ee81b6b7 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
| @@ -454,6 +454,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
| 454 | URB_FREE_BUFFER); | 454 | URB_FREE_BUFFER); |
| 455 | switch (xfertype) { | 455 | switch (xfertype) { |
| 456 | case USB_ENDPOINT_XFER_BULK: | 456 | case USB_ENDPOINT_XFER_BULK: |
| 457 | case USB_ENDPOINT_XFER_INT: | ||
| 457 | if (is_out) | 458 | if (is_out) |
| 458 | allowed |= URB_ZERO_PACKET; | 459 | allowed |= URB_ZERO_PACKET; |
| 459 | /* FALLTHROUGH */ | 460 | /* FALLTHROUGH */ |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4d1144990d4c..2dd2362198d2 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
| @@ -501,6 +501,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
| 501 | } | 501 | } |
| 502 | return dev; | 502 | return dev; |
| 503 | } | 503 | } |
| 504 | EXPORT_SYMBOL_GPL(usb_alloc_dev); | ||
| 504 | 505 | ||
| 505 | /** | 506 | /** |
| 506 | * usb_get_dev - increments the reference count of the usb device structure | 507 | * usb_get_dev - increments the reference count of the usb device structure |
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index f3c56a2fed5b..7c9618e916e2 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * linux/drivers/usb/gadget/s3c-hsotg.c | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | 2 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. |
| 5 | * http://www.samsung.com | 3 | * http://www.samsung.com |
| 6 | * | 4 | * |
| @@ -1022,7 +1020,8 @@ static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); | |||
| 1022 | * | 1020 | * |
| 1023 | * Set stall for ep0 as response for setup request. | 1021 | * Set stall for ep0 as response for setup request. |
| 1024 | */ | 1022 | */ |
| 1025 | static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg) { | 1023 | static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg) |
| 1024 | { | ||
| 1026 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 1025 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; |
| 1027 | u32 reg; | 1026 | u32 reg; |
| 1028 | u32 ctrl; | 1027 | u32 ctrl; |
| @@ -1902,7 +1901,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
| 1902 | static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) | 1901 | static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) |
| 1903 | { | 1902 | { |
| 1904 | u32 dsts = readl(hsotg->regs + DSTS); | 1903 | u32 dsts = readl(hsotg->regs + DSTS); |
| 1905 | int ep0_mps = 0, ep_mps; | 1904 | int ep0_mps = 0, ep_mps = 8; |
| 1906 | 1905 | ||
| 1907 | /* | 1906 | /* |
| 1908 | * This should signal the finish of the enumeration phase | 1907 | * This should signal the finish of the enumeration phase |
| @@ -1994,7 +1993,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, | |||
| 1994 | s3c_hsotg_complete_request(hsotg, ep, req, | 1993 | s3c_hsotg_complete_request(hsotg, ep, req, |
| 1995 | result); | 1994 | result); |
| 1996 | } | 1995 | } |
| 1997 | if(hsotg->dedicated_fifos) | 1996 | if (hsotg->dedicated_fifos) |
| 1998 | if ((readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4 < 3072) | 1997 | if ((readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4 < 3072) |
| 1999 | s3c_hsotg_txfifo_flush(hsotg, ep->index); | 1998 | s3c_hsotg_txfifo_flush(hsotg, ep->index); |
| 2000 | } | 1999 | } |
| @@ -3390,10 +3389,8 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
| 3390 | int i; | 3389 | int i; |
| 3391 | 3390 | ||
| 3392 | hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); | 3391 | hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); |
| 3393 | if (!hsotg) { | 3392 | if (!hsotg) |
| 3394 | dev_err(dev, "cannot get memory\n"); | ||
| 3395 | return -ENOMEM; | 3393 | return -ENOMEM; |
| 3396 | } | ||
| 3397 | 3394 | ||
| 3398 | /* | 3395 | /* |
| 3399 | * Attempt to find a generic PHY, then look for an old style | 3396 | * Attempt to find a generic PHY, then look for an old style |
| @@ -3512,7 +3509,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
| 3512 | eps = kcalloc(hsotg->num_of_eps + 1, sizeof(struct s3c_hsotg_ep), | 3509 | eps = kcalloc(hsotg->num_of_eps + 1, sizeof(struct s3c_hsotg_ep), |
| 3513 | GFP_KERNEL); | 3510 | GFP_KERNEL); |
| 3514 | if (!eps) { | 3511 | if (!eps) { |
| 3515 | dev_err(dev, "cannot get memory\n"); | ||
| 3516 | ret = -ENOMEM; | 3512 | ret = -ENOMEM; |
| 3517 | goto err_supplies; | 3513 | goto err_supplies; |
| 3518 | } | 3514 | } |
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 261c3b428220..785510a0a0c3 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig | |||
| @@ -93,4 +93,11 @@ config USB_DWC3_VERBOSE | |||
| 93 | help | 93 | help |
| 94 | Say Y here to enable verbose debugging messages on DWC3 Driver. | 94 | Say Y here to enable verbose debugging messages on DWC3 Driver. |
| 95 | 95 | ||
| 96 | config DWC3_HOST_USB3_LPM_ENABLE | ||
| 97 | bool "Enable USB3 LPM Capability" | ||
| 98 | depends on USB_DWC3_HOST=y || USB_DWC3_DUAL_ROLE=y | ||
| 99 | default n | ||
| 100 | help | ||
| 101 | Select this when you want to enable USB3 LPM with dwc3 xhci host. | ||
| 102 | |||
| 96 | endif | 103 | endif |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index eb69eb9f06c8..b769c1faaf03 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
| @@ -386,6 +386,13 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
| 386 | } | 386 | } |
| 387 | dwc->revision = reg; | 387 | dwc->revision = reg; |
| 388 | 388 | ||
| 389 | /* Handle USB2.0-only core configuration */ | ||
| 390 | if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == | ||
| 391 | DWC3_GHWPARAMS3_SSPHY_IFC_DIS) { | ||
| 392 | if (dwc->maximum_speed == USB_SPEED_SUPER) | ||
| 393 | dwc->maximum_speed = USB_SPEED_HIGH; | ||
| 394 | } | ||
| 395 | |||
| 389 | /* issue device SoftReset too */ | 396 | /* issue device SoftReset too */ |
| 390 | timeout = jiffies + msecs_to_jiffies(500); | 397 | timeout = jiffies + msecs_to_jiffies(500); |
| 391 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); | 398 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); |
| @@ -656,6 +663,31 @@ static int dwc3_probe(struct platform_device *pdev) | |||
| 656 | return -ENODEV; | 663 | return -ENODEV; |
| 657 | } | 664 | } |
| 658 | 665 | ||
| 666 | dwc->xhci_resources[0].start = res->start; | ||
| 667 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | ||
| 668 | DWC3_XHCI_REGS_END; | ||
| 669 | dwc->xhci_resources[0].flags = res->flags; | ||
| 670 | dwc->xhci_resources[0].name = res->name; | ||
| 671 | |||
| 672 | res->start += DWC3_GLOBALS_REGS_START; | ||
| 673 | |||
| 674 | /* | ||
| 675 | * Request memory region but exclude xHCI regs, | ||
| 676 | * since it will be requested by the xhci-plat driver. | ||
| 677 | */ | ||
| 678 | regs = devm_ioremap_resource(dev, res); | ||
| 679 | if (IS_ERR(regs)) | ||
| 680 | return PTR_ERR(regs); | ||
| 681 | |||
| 682 | dwc->regs = regs; | ||
| 683 | dwc->regs_size = resource_size(res); | ||
| 684 | /* | ||
| 685 | * restore res->start back to its original value so that, | ||
| 686 | * in case the probe is deferred, we don't end up getting error in | ||
| 687 | * request the memory region the next time probe is called. | ||
| 688 | */ | ||
| 689 | res->start -= DWC3_GLOBALS_REGS_START; | ||
| 690 | |||
| 659 | if (node) { | 691 | if (node) { |
| 660 | dwc->maximum_speed = of_usb_get_maximum_speed(node); | 692 | dwc->maximum_speed = of_usb_get_maximum_speed(node); |
| 661 | 693 | ||
| @@ -676,28 +708,9 @@ static int dwc3_probe(struct platform_device *pdev) | |||
| 676 | if (ret) | 708 | if (ret) |
| 677 | return ret; | 709 | return ret; |
| 678 | 710 | ||
| 679 | dwc->xhci_resources[0].start = res->start; | ||
| 680 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | ||
| 681 | DWC3_XHCI_REGS_END; | ||
| 682 | dwc->xhci_resources[0].flags = res->flags; | ||
| 683 | dwc->xhci_resources[0].name = res->name; | ||
| 684 | |||
| 685 | res->start += DWC3_GLOBALS_REGS_START; | ||
| 686 | |||
| 687 | /* | ||
| 688 | * Request memory region but exclude xHCI regs, | ||
| 689 | * since it will be requested by the xhci-plat driver. | ||
| 690 | */ | ||
| 691 | regs = devm_ioremap_resource(dev, res); | ||
| 692 | if (IS_ERR(regs)) | ||
| 693 | return PTR_ERR(regs); | ||
| 694 | |||
| 695 | spin_lock_init(&dwc->lock); | 711 | spin_lock_init(&dwc->lock); |
| 696 | platform_set_drvdata(pdev, dwc); | 712 | platform_set_drvdata(pdev, dwc); |
| 697 | 713 | ||
| 698 | dwc->regs = regs; | ||
| 699 | dwc->regs_size = resource_size(res); | ||
| 700 | |||
| 701 | dev->dma_mask = dev->parent->dma_mask; | 714 | dev->dma_mask = dev->parent->dma_mask; |
| 702 | dev->dma_parms = dev->parent->dma_parms; | 715 | dev->dma_parms = dev->parent->dma_parms; |
| 703 | dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); | 716 | dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); |
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 57332e3768e4..48fb264065db 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
| @@ -191,6 +191,19 @@ | |||
| 191 | #define DWC3_GHWPARAMS1_PWROPT(n) ((n) << 24) | 191 | #define DWC3_GHWPARAMS1_PWROPT(n) ((n) << 24) |
| 192 | #define DWC3_GHWPARAMS1_PWROPT_MASK DWC3_GHWPARAMS1_PWROPT(3) | 192 | #define DWC3_GHWPARAMS1_PWROPT_MASK DWC3_GHWPARAMS1_PWROPT(3) |
| 193 | 193 | ||
| 194 | /* Global HWPARAMS3 Register */ | ||
| 195 | #define DWC3_GHWPARAMS3_SSPHY_IFC(n) ((n) & 3) | ||
| 196 | #define DWC3_GHWPARAMS3_SSPHY_IFC_DIS 0 | ||
| 197 | #define DWC3_GHWPARAMS3_SSPHY_IFC_ENA 1 | ||
| 198 | #define DWC3_GHWPARAMS3_HSPHY_IFC(n) (((n) & (3 << 2)) >> 2) | ||
| 199 | #define DWC3_GHWPARAMS3_HSPHY_IFC_DIS 0 | ||
| 200 | #define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI 1 | ||
| 201 | #define DWC3_GHWPARAMS3_HSPHY_IFC_ULPI 2 | ||
| 202 | #define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI 3 | ||
| 203 | #define DWC3_GHWPARAMS3_FSPHY_IFC(n) (((n) & (3 << 4)) >> 4) | ||
| 204 | #define DWC3_GHWPARAMS3_FSPHY_IFC_DIS 0 | ||
| 205 | #define DWC3_GHWPARAMS3_FSPHY_IFC_ENA 1 | ||
| 206 | |||
| 194 | /* Global HWPARAMS4 Register */ | 207 | /* Global HWPARAMS4 Register */ |
| 195 | #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) | 208 | #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) |
| 196 | #define DWC3_MAX_HIBER_SCRATCHBUFS 15 | 209 | #define DWC3_MAX_HIBER_SCRATCHBUFS 15 |
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 07a736acd0f2..9dcfbe7cd5f5 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
| @@ -77,10 +77,6 @@ | |||
| 77 | #define USBOTGSS_DEV_EBC_EN 0x0110 | 77 | #define USBOTGSS_DEV_EBC_EN 0x0110 |
| 78 | #define USBOTGSS_DEBUG_OFFSET 0x0600 | 78 | #define USBOTGSS_DEBUG_OFFSET 0x0600 |
| 79 | 79 | ||
| 80 | /* REVISION REGISTER */ | ||
| 81 | #define USBOTGSS_REVISION_XMAJOR(reg) ((reg >> 8) & 0x7) | ||
| 82 | #define USBOTGSS_REVISION_XMAJOR1 1 | ||
| 83 | #define USBOTGSS_REVISION_XMAJOR2 2 | ||
| 84 | /* SYSCONFIG REGISTER */ | 80 | /* SYSCONFIG REGISTER */ |
| 85 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) | 81 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) |
| 86 | 82 | ||
| @@ -129,7 +125,6 @@ struct dwc3_omap { | |||
| 129 | u32 irq_eoi_offset; | 125 | u32 irq_eoi_offset; |
| 130 | u32 debug_offset; | 126 | u32 debug_offset; |
| 131 | u32 irq0_offset; | 127 | u32 irq0_offset; |
| 132 | u32 revision; | ||
| 133 | 128 | ||
| 134 | u32 dma_status:1; | 129 | u32 dma_status:1; |
| 135 | 130 | ||
| @@ -383,6 +378,87 @@ static int dwc3_omap_vbus_notifier(struct notifier_block *nb, | |||
| 383 | return NOTIFY_DONE; | 378 | return NOTIFY_DONE; |
| 384 | } | 379 | } |
| 385 | 380 | ||
| 381 | static void dwc3_omap_map_offset(struct dwc3_omap *omap) | ||
| 382 | { | ||
| 383 | struct device_node *node = omap->dev->of_node; | ||
| 384 | |||
| 385 | /* | ||
| 386 | * Differentiate between OMAP5 and AM437x. | ||
| 387 | * | ||
| 388 | * For OMAP5(ES2.0) and AM437x wrapper revision is same, even | ||
| 389 | * though there are changes in wrapper register offsets. | ||
| 390 | * | ||
| 391 | * Using dt compatible to differentiate AM437x. | ||
| 392 | */ | ||
| 393 | if (of_device_is_compatible(node, "ti,am437x-dwc3")) { | ||
| 394 | omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; | ||
| 395 | omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; | ||
| 396 | omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; | ||
| 397 | omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; | ||
| 398 | omap->debug_offset = USBOTGSS_DEBUG_OFFSET; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) | ||
| 403 | { | ||
| 404 | u32 reg; | ||
| 405 | struct device_node *node = omap->dev->of_node; | ||
| 406 | int utmi_mode = 0; | ||
| 407 | |||
| 408 | reg = dwc3_omap_read_utmi_status(omap); | ||
| 409 | |||
| 410 | of_property_read_u32(node, "utmi-mode", &utmi_mode); | ||
| 411 | |||
| 412 | switch (utmi_mode) { | ||
| 413 | case DWC3_OMAP_UTMI_MODE_SW: | ||
| 414 | reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 415 | break; | ||
| 416 | case DWC3_OMAP_UTMI_MODE_HW: | ||
| 417 | reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 418 | break; | ||
| 419 | default: | ||
| 420 | dev_dbg(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode); | ||
| 421 | } | ||
| 422 | |||
| 423 | dwc3_omap_write_utmi_status(omap, reg); | ||
| 424 | } | ||
| 425 | |||
| 426 | static int dwc3_omap_extcon_register(struct dwc3_omap *omap) | ||
| 427 | { | ||
| 428 | int ret; | ||
| 429 | struct device_node *node = omap->dev->of_node; | ||
| 430 | struct extcon_dev *edev; | ||
| 431 | |||
| 432 | if (of_property_read_bool(node, "extcon")) { | ||
| 433 | edev = extcon_get_edev_by_phandle(omap->dev, 0); | ||
| 434 | if (IS_ERR(edev)) { | ||
| 435 | dev_vdbg(omap->dev, "couldn't get extcon device\n"); | ||
| 436 | return -EPROBE_DEFER; | ||
| 437 | } | ||
| 438 | |||
| 439 | omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier; | ||
| 440 | ret = extcon_register_interest(&omap->extcon_vbus_dev, | ||
| 441 | edev->name, "USB", | ||
| 442 | &omap->vbus_nb); | ||
| 443 | if (ret < 0) | ||
| 444 | dev_vdbg(omap->dev, "failed to register notifier for USB\n"); | ||
| 445 | |||
| 446 | omap->id_nb.notifier_call = dwc3_omap_id_notifier; | ||
| 447 | ret = extcon_register_interest(&omap->extcon_id_dev, | ||
| 448 | edev->name, "USB-HOST", | ||
| 449 | &omap->id_nb); | ||
| 450 | if (ret < 0) | ||
| 451 | dev_vdbg(omap->dev, "failed to register notifier for USB-HOST\n"); | ||
| 452 | |||
| 453 | if (extcon_get_cable_state(edev, "USB") == true) | ||
| 454 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); | ||
| 455 | if (extcon_get_cable_state(edev, "USB-HOST") == true) | ||
| 456 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); | ||
| 457 | } | ||
| 458 | |||
| 459 | return 0; | ||
| 460 | } | ||
| 461 | |||
| 386 | static int dwc3_omap_probe(struct platform_device *pdev) | 462 | static int dwc3_omap_probe(struct platform_device *pdev) |
| 387 | { | 463 | { |
| 388 | struct device_node *node = pdev->dev.of_node; | 464 | struct device_node *node = pdev->dev.of_node; |
| @@ -390,15 +466,11 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
| 390 | struct dwc3_omap *omap; | 466 | struct dwc3_omap *omap; |
| 391 | struct resource *res; | 467 | struct resource *res; |
| 392 | struct device *dev = &pdev->dev; | 468 | struct device *dev = &pdev->dev; |
| 393 | struct extcon_dev *edev; | ||
| 394 | struct regulator *vbus_reg = NULL; | 469 | struct regulator *vbus_reg = NULL; |
| 395 | 470 | ||
| 396 | int ret; | 471 | int ret; |
| 397 | int irq; | 472 | int irq; |
| 398 | 473 | ||
| 399 | int utmi_mode = 0; | ||
| 400 | int x_major; | ||
| 401 | |||
| 402 | u32 reg; | 474 | u32 reg; |
| 403 | 475 | ||
| 404 | void __iomem *base; | 476 | void __iomem *base; |
| @@ -448,58 +520,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
| 448 | goto err0; | 520 | goto err0; |
| 449 | } | 521 | } |
| 450 | 522 | ||
| 451 | reg = dwc3_omap_readl(omap->base, USBOTGSS_REVISION); | 523 | dwc3_omap_map_offset(omap); |
| 452 | omap->revision = reg; | 524 | dwc3_omap_set_utmi_mode(omap); |
| 453 | x_major = USBOTGSS_REVISION_XMAJOR(reg); | ||
| 454 | |||
| 455 | /* Differentiate between OMAP5 and AM437x */ | ||
| 456 | switch (x_major) { | ||
| 457 | case USBOTGSS_REVISION_XMAJOR1: | ||
| 458 | case USBOTGSS_REVISION_XMAJOR2: | ||
| 459 | omap->irq_eoi_offset = 0; | ||
| 460 | omap->irq0_offset = 0; | ||
| 461 | omap->irqmisc_offset = 0; | ||
| 462 | omap->utmi_otg_offset = 0; | ||
| 463 | omap->debug_offset = 0; | ||
| 464 | break; | ||
| 465 | default: | ||
| 466 | /* Default to the latest revision */ | ||
| 467 | omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; | ||
| 468 | omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; | ||
| 469 | omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; | ||
| 470 | omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; | ||
| 471 | omap->debug_offset = USBOTGSS_DEBUG_OFFSET; | ||
| 472 | break; | ||
| 473 | } | ||
| 474 | |||
| 475 | /* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are | ||
| 476 | * changes in wrapper registers, Using dt compatible for aegis | ||
| 477 | */ | ||
| 478 | |||
| 479 | if (of_device_is_compatible(node, "ti,am437x-dwc3")) { | ||
| 480 | omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; | ||
| 481 | omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; | ||
| 482 | omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; | ||
| 483 | omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; | ||
| 484 | omap->debug_offset = USBOTGSS_DEBUG_OFFSET; | ||
| 485 | } | ||
| 486 | |||
| 487 | reg = dwc3_omap_read_utmi_status(omap); | ||
| 488 | |||
| 489 | of_property_read_u32(node, "utmi-mode", &utmi_mode); | ||
| 490 | |||
| 491 | switch (utmi_mode) { | ||
| 492 | case DWC3_OMAP_UTMI_MODE_SW: | ||
| 493 | reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 494 | break; | ||
| 495 | case DWC3_OMAP_UTMI_MODE_HW: | ||
| 496 | reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 497 | break; | ||
| 498 | default: | ||
| 499 | dev_dbg(dev, "UNKNOWN utmi mode %d\n", utmi_mode); | ||
| 500 | } | ||
| 501 | |||
| 502 | dwc3_omap_write_utmi_status(omap, reg); | ||
| 503 | 525 | ||
| 504 | /* check the DMA Status */ | 526 | /* check the DMA Status */ |
| 505 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); | 527 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); |
| @@ -515,31 +537,9 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
| 515 | 537 | ||
| 516 | dwc3_omap_enable_irqs(omap); | 538 | dwc3_omap_enable_irqs(omap); |
| 517 | 539 | ||
| 518 | if (of_property_read_bool(node, "extcon")) { | 540 | ret = dwc3_omap_extcon_register(omap); |
| 519 | edev = extcon_get_edev_by_phandle(dev, 0); | 541 | if (ret < 0) |
| 520 | if (IS_ERR(edev)) { | 542 | goto err2; |
| 521 | dev_vdbg(dev, "couldn't get extcon device\n"); | ||
| 522 | ret = -EPROBE_DEFER; | ||
| 523 | goto err2; | ||
| 524 | } | ||
| 525 | |||
| 526 | omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier; | ||
| 527 | ret = extcon_register_interest(&omap->extcon_vbus_dev, | ||
| 528 | edev->name, "USB", &omap->vbus_nb); | ||
| 529 | if (ret < 0) | ||
| 530 | dev_vdbg(dev, "failed to register notifier for USB\n"); | ||
| 531 | omap->id_nb.notifier_call = dwc3_omap_id_notifier; | ||
| 532 | ret = extcon_register_interest(&omap->extcon_id_dev, edev->name, | ||
| 533 | "USB-HOST", &omap->id_nb); | ||
| 534 | if (ret < 0) | ||
| 535 | dev_vdbg(dev, | ||
| 536 | "failed to register notifier for USB-HOST\n"); | ||
| 537 | |||
| 538 | if (extcon_get_cable_state(edev, "USB") == true) | ||
| 539 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); | ||
| 540 | if (extcon_get_cable_state(edev, "USB-HOST") == true) | ||
| 541 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); | ||
| 542 | } | ||
| 543 | 543 | ||
| 544 | ret = of_platform_populate(node, NULL, NULL, dev); | 544 | ret = of_platform_populate(node, NULL, NULL, dev); |
| 545 | if (ret) { | 545 | if (ret) { |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index dab7927d1009..349cacc577d8 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
| @@ -1971,8 +1971,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
| 1971 | } | 1971 | } |
| 1972 | 1972 | ||
| 1973 | static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, | 1973 | static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, |
| 1974 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event, | 1974 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event) |
| 1975 | int start_new) | ||
| 1976 | { | 1975 | { |
| 1977 | unsigned status = 0; | 1976 | unsigned status = 0; |
| 1978 | int clean_busy; | 1977 | int clean_busy; |
| @@ -2039,7 +2038,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
| 2039 | return; | 2038 | return; |
| 2040 | } | 2039 | } |
| 2041 | 2040 | ||
| 2042 | dwc3_endpoint_transfer_complete(dwc, dep, event, 1); | 2041 | dwc3_endpoint_transfer_complete(dwc, dep, event); |
| 2043 | break; | 2042 | break; |
| 2044 | case DWC3_DEPEVT_XFERINPROGRESS: | 2043 | case DWC3_DEPEVT_XFERINPROGRESS: |
| 2045 | if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 2044 | if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
| @@ -2048,7 +2047,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
| 2048 | return; | 2047 | return; |
| 2049 | } | 2048 | } |
| 2050 | 2049 | ||
| 2051 | dwc3_endpoint_transfer_complete(dwc, dep, event, 0); | 2050 | dwc3_endpoint_transfer_complete(dwc, dep, event); |
| 2052 | break; | 2051 | break; |
| 2053 | case DWC3_DEPEVT_XFERNOTREADY: | 2052 | case DWC3_DEPEVT_XFERNOTREADY: |
| 2054 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 2053 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index 32db328cc769..dcb8ca084598 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c | |||
| @@ -16,12 +16,14 @@ | |||
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/usb/xhci_pdriver.h> | ||
| 19 | 20 | ||
| 20 | #include "core.h" | 21 | #include "core.h" |
| 21 | 22 | ||
| 22 | int dwc3_host_init(struct dwc3 *dwc) | 23 | int dwc3_host_init(struct dwc3 *dwc) |
| 23 | { | 24 | { |
| 24 | struct platform_device *xhci; | 25 | struct platform_device *xhci; |
| 26 | struct usb_xhci_pdata pdata; | ||
| 25 | int ret; | 27 | int ret; |
| 26 | 28 | ||
| 27 | xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO); | 29 | xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO); |
| @@ -46,6 +48,18 @@ int dwc3_host_init(struct dwc3 *dwc) | |||
| 46 | goto err1; | 48 | goto err1; |
| 47 | } | 49 | } |
| 48 | 50 | ||
| 51 | memset(&pdata, 0, sizeof(pdata)); | ||
| 52 | |||
| 53 | #ifdef CONFIG_DWC3_HOST_USB3_LPM_ENABLE | ||
| 54 | pdata.usb3_lpm_capable = 1; | ||
| 55 | #endif | ||
| 56 | |||
| 57 | ret = platform_device_add_data(xhci, &pdata, sizeof(pdata)); | ||
| 58 | if (ret) { | ||
| 59 | dev_err(dwc->dev, "couldn't add platform data to xHCI device\n"); | ||
| 60 | goto err1; | ||
| 61 | } | ||
| 62 | |||
| 49 | ret = platform_device_add(xhci); | 63 | ret = platform_device_add(xhci); |
| 50 | if (ret) { | 64 | if (ret) { |
| 51 | dev_err(dwc->dev, "failed to register xHCI device\n"); | 65 | dev_err(dwc->dev, "failed to register xHCI device\n"); |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index ba18e9c110cc..5c822afb6d70 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -127,368 +127,7 @@ config USB_GADGET_STORAGE_NUM_BUFFERS | |||
| 127 | a module parameter as well. | 127 | a module parameter as well. |
| 128 | If unsure, say 2. | 128 | If unsure, say 2. |
| 129 | 129 | ||
| 130 | # | 130 | source "drivers/usb/gadget/udc/Kconfig" |
| 131 | # USB Peripheral Controller Support | ||
| 132 | # | ||
| 133 | # The order here is alphabetical, except that integrated controllers go | ||
| 134 | # before discrete ones so they will be the initial/default value: | ||
| 135 | # - integrated/SOC controllers first | ||
| 136 | # - licensed IP used in both SOC and discrete versions | ||
| 137 | # - discrete ones (including all PCI-only controllers) | ||
| 138 | # - debug/dummy gadget+hcd is last. | ||
| 139 | # | ||
| 140 | menu "USB Peripheral Controller" | ||
| 141 | |||
| 142 | # | ||
| 143 | # Integrated controllers | ||
| 144 | # | ||
| 145 | |||
| 146 | config USB_AT91 | ||
| 147 | tristate "Atmel AT91 USB Device Port" | ||
| 148 | depends on ARCH_AT91 | ||
| 149 | help | ||
| 150 | Many Atmel AT91 processors (such as the AT91RM2000) have a | ||
| 151 | full speed USB Device Port with support for five configurable | ||
| 152 | endpoints (plus endpoint zero). | ||
| 153 | |||
| 154 | Say "y" to link the driver statically, or "m" to build a | ||
| 155 | dynamically linked module called "at91_udc" and force all | ||
| 156 | gadget drivers to also be dynamically linked. | ||
| 157 | |||
| 158 | config USB_LPC32XX | ||
| 159 | tristate "LPC32XX USB Peripheral Controller" | ||
| 160 | depends on ARCH_LPC32XX && I2C | ||
| 161 | select USB_ISP1301 | ||
| 162 | help | ||
| 163 | This option selects the USB device controller in the LPC32xx SoC. | ||
| 164 | |||
| 165 | Say "y" to link the driver statically, or "m" to build a | ||
| 166 | dynamically linked module called "lpc32xx_udc" and force all | ||
| 167 | gadget drivers to also be dynamically linked. | ||
| 168 | |||
| 169 | config USB_ATMEL_USBA | ||
| 170 | tristate "Atmel USBA" | ||
| 171 | depends on AVR32 || ARCH_AT91 | ||
| 172 | help | ||
| 173 | USBA is the integrated high-speed USB Device controller on | ||
| 174 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. | ||
| 175 | |||
| 176 | config USB_BCM63XX_UDC | ||
| 177 | tristate "Broadcom BCM63xx Peripheral Controller" | ||
| 178 | depends on BCM63XX | ||
| 179 | help | ||
| 180 | Many Broadcom BCM63xx chipsets (such as the BCM6328) have a | ||
| 181 | high speed USB Device Port with support for four fixed endpoints | ||
| 182 | (plus endpoint zero). | ||
| 183 | |||
| 184 | Say "y" to link the driver statically, or "m" to build a | ||
| 185 | dynamically linked module called "bcm63xx_udc". | ||
| 186 | |||
| 187 | config USB_FSL_USB2 | ||
| 188 | tristate "Freescale Highspeed USB DR Peripheral Controller" | ||
| 189 | depends on FSL_SOC || ARCH_MXC | ||
| 190 | select USB_FSL_MPH_DR_OF if OF | ||
| 191 | help | ||
| 192 | Some of Freescale PowerPC and i.MX processors have a High Speed | ||
| 193 | Dual-Role(DR) USB controller, which supports device mode. | ||
| 194 | |||
| 195 | The number of programmable endpoints is different through | ||
| 196 | SOC revisions. | ||
| 197 | |||
| 198 | Say "y" to link the driver statically, or "m" to build a | ||
| 199 | dynamically linked module called "fsl_usb2_udc" and force | ||
| 200 | all gadget drivers to also be dynamically linked. | ||
| 201 | |||
| 202 | config USB_FUSB300 | ||
| 203 | tristate "Faraday FUSB300 USB Peripheral Controller" | ||
| 204 | depends on !PHYS_ADDR_T_64BIT && HAS_DMA | ||
| 205 | help | ||
| 206 | Faraday usb device controller FUSB300 driver | ||
| 207 | |||
| 208 | config USB_FOTG210_UDC | ||
| 209 | depends on HAS_DMA | ||
| 210 | tristate "Faraday FOTG210 USB Peripheral Controller" | ||
| 211 | help | ||
| 212 | Faraday USB2.0 OTG controller which can be configured as | ||
| 213 | high speed or full speed USB device. This driver supppors | ||
| 214 | Bulk Transfer so far. | ||
| 215 | |||
| 216 | Say "y" to link the driver statically, or "m" to build a | ||
| 217 | dynamically linked module called "fotg210_udc". | ||
| 218 | |||
| 219 | config USB_GR_UDC | ||
| 220 | tristate "Aeroflex Gaisler GRUSBDC USB Peripheral Controller Driver" | ||
| 221 | depends on HAS_DMA | ||
| 222 | help | ||
| 223 | Select this to support Aeroflex Gaisler GRUSBDC cores from the GRLIB | ||
| 224 | VHDL IP core library. | ||
| 225 | |||
| 226 | config USB_OMAP | ||
| 227 | tristate "OMAP USB Device Controller" | ||
| 228 | depends on ARCH_OMAP1 | ||
| 229 | depends on ISP1301_OMAP || !(MACH_OMAP_H2 || MACH_OMAP_H3) | ||
| 230 | help | ||
| 231 | Many Texas Instruments OMAP processors have flexible full | ||
| 232 | speed USB device controllers, with support for up to 30 | ||
| 233 | endpoints (plus endpoint zero). This driver supports the | ||
| 234 | controller in the OMAP 1611, and should work with controllers | ||
| 235 | in other OMAP processors too, given minor tweaks. | ||
| 236 | |||
| 237 | Say "y" to link the driver statically, or "m" to build a | ||
| 238 | dynamically linked module called "omap_udc" and force all | ||
| 239 | gadget drivers to also be dynamically linked. | ||
| 240 | |||
| 241 | config USB_PXA25X | ||
| 242 | tristate "PXA 25x or IXP 4xx" | ||
| 243 | depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX | ||
| 244 | help | ||
| 245 | Intel's PXA 25x series XScale ARM-5TE processors include | ||
| 246 | an integrated full speed USB 1.1 device controller. The | ||
| 247 | controller in the IXP 4xx series is register-compatible. | ||
| 248 | |||
| 249 | It has fifteen fixed-function endpoints, as well as endpoint | ||
| 250 | zero (for control transfers). | ||
| 251 | |||
| 252 | Say "y" to link the driver statically, or "m" to build a | ||
| 253 | dynamically linked module called "pxa25x_udc" and force all | ||
| 254 | gadget drivers to also be dynamically linked. | ||
| 255 | |||
| 256 | # if there's only one gadget driver, using only two bulk endpoints, | ||
| 257 | # don't waste memory for the other endpoints | ||
| 258 | config USB_PXA25X_SMALL | ||
| 259 | depends on USB_PXA25X | ||
| 260 | bool | ||
| 261 | default n if USB_ETH_RNDIS | ||
| 262 | default y if USB_ZERO | ||
| 263 | default y if USB_ETH | ||
| 264 | default y if USB_G_SERIAL | ||
| 265 | |||
| 266 | config USB_R8A66597 | ||
| 267 | tristate "Renesas R8A66597 USB Peripheral Controller" | ||
| 268 | depends on HAS_DMA | ||
| 269 | help | ||
| 270 | R8A66597 is a discrete USB host and peripheral controller chip that | ||
| 271 | supports both full and high speed USB 2.0 data transfers. | ||
| 272 | It has nine configurable endpoints, and endpoint zero. | ||
| 273 | |||
| 274 | Say "y" to link the driver statically, or "m" to build a | ||
| 275 | dynamically linked module called "r8a66597_udc" and force all | ||
| 276 | gadget drivers to also be dynamically linked. | ||
| 277 | |||
| 278 | config USB_RENESAS_USBHS_UDC | ||
| 279 | tristate 'Renesas USBHS controller' | ||
| 280 | depends on USB_RENESAS_USBHS | ||
| 281 | help | ||
| 282 | Renesas USBHS is a discrete USB host and peripheral controller chip | ||
| 283 | that supports both full and high speed USB 2.0 data transfers. | ||
| 284 | It has nine or more configurable endpoints, and endpoint zero. | ||
| 285 | |||
| 286 | Say "y" to link the driver statically, or "m" to build a | ||
| 287 | dynamically linked module called "renesas_usbhs" and force all | ||
| 288 | gadget drivers to also be dynamically linked. | ||
| 289 | |||
| 290 | config USB_PXA27X | ||
| 291 | tristate "PXA 27x" | ||
| 292 | help | ||
| 293 | Intel's PXA 27x series XScale ARM v5TE processors include | ||
| 294 | an integrated full speed USB 1.1 device controller. | ||
| 295 | |||
| 296 | It has up to 23 endpoints, as well as endpoint zero (for | ||
| 297 | control transfers). | ||
| 298 | |||
| 299 | Say "y" to link the driver statically, or "m" to build a | ||
| 300 | dynamically linked module called "pxa27x_udc" and force all | ||
| 301 | gadget drivers to also be dynamically linked. | ||
| 302 | |||
| 303 | config USB_S3C2410 | ||
| 304 | tristate "S3C2410 USB Device Controller" | ||
| 305 | depends on ARCH_S3C24XX | ||
| 306 | help | ||
| 307 | Samsung's S3C2410 is an ARM-4 processor with an integrated | ||
| 308 | full speed USB 1.1 device controller. It has 4 configurable | ||
| 309 | endpoints, as well as endpoint zero (for control transfers). | ||
| 310 | |||
| 311 | This driver has been tested on the S3C2410, S3C2412, and | ||
| 312 | S3C2440 processors. | ||
| 313 | |||
| 314 | config USB_S3C2410_DEBUG | ||
| 315 | boolean "S3C2410 udc debug messages" | ||
| 316 | depends on USB_S3C2410 | ||
| 317 | |||
| 318 | config USB_S3C_HSUDC | ||
| 319 | tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" | ||
| 320 | depends on ARCH_S3C24XX | ||
| 321 | help | ||
| 322 | Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC | ||
| 323 | integrated with dual speed USB 2.0 device controller. It has | ||
| 324 | 8 endpoints, as well as endpoint zero. | ||
| 325 | |||
| 326 | This driver has been tested on S3C2416 and S3C2450 processors. | ||
| 327 | |||
| 328 | config USB_MV_UDC | ||
| 329 | tristate "Marvell USB2.0 Device Controller" | ||
| 330 | depends on HAS_DMA | ||
| 331 | help | ||
| 332 | Marvell Socs (including PXA and MMP series) include a high speed | ||
| 333 | USB2.0 OTG controller, which can be configured as high speed or | ||
| 334 | full speed USB peripheral. | ||
| 335 | |||
| 336 | config USB_MV_U3D | ||
| 337 | depends on HAS_DMA | ||
| 338 | tristate "MARVELL PXA2128 USB 3.0 controller" | ||
| 339 | help | ||
| 340 | MARVELL PXA2128 Processor series include a super speed USB3.0 device | ||
| 341 | controller, which support super speed USB peripheral. | ||
| 342 | |||
| 343 | # | ||
| 344 | # Controllers available in both integrated and discrete versions | ||
| 345 | # | ||
| 346 | |||
| 347 | config USB_M66592 | ||
| 348 | tristate "Renesas M66592 USB Peripheral Controller" | ||
| 349 | help | ||
| 350 | M66592 is a discrete USB peripheral controller chip that | ||
| 351 | supports both full and high speed USB 2.0 data transfers. | ||
| 352 | It has seven configurable endpoints, and endpoint zero. | ||
| 353 | |||
| 354 | Say "y" to link the driver statically, or "m" to build a | ||
| 355 | dynamically linked module called "m66592_udc" and force all | ||
| 356 | gadget drivers to also be dynamically linked. | ||
| 357 | |||
| 358 | # | ||
| 359 | # Controllers available only in discrete form (and all PCI controllers) | ||
| 360 | # | ||
| 361 | |||
| 362 | config USB_AMD5536UDC | ||
| 363 | tristate "AMD5536 UDC" | ||
| 364 | depends on PCI | ||
| 365 | help | ||
| 366 | The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. | ||
| 367 | It is a USB Highspeed DMA capable USB device controller. Beside ep0 | ||
| 368 | it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). | ||
| 369 | The UDC port supports OTG operation, and may be used as a host port | ||
| 370 | if it's not being used to implement peripheral or OTG roles. | ||
| 371 | |||
| 372 | Say "y" to link the driver statically, or "m" to build a | ||
| 373 | dynamically linked module called "amd5536udc" and force all | ||
| 374 | gadget drivers to also be dynamically linked. | ||
| 375 | |||
| 376 | config USB_FSL_QE | ||
| 377 | tristate "Freescale QE/CPM USB Device Controller" | ||
| 378 | depends on FSL_SOC && (QUICC_ENGINE || CPM) | ||
| 379 | help | ||
| 380 | Some of Freescale PowerPC processors have a Full Speed | ||
| 381 | QE/CPM2 USB controller, which support device mode with 4 | ||
| 382 | programmable endpoints. This driver supports the | ||
| 383 | controller in the MPC8360 and MPC8272, and should work with | ||
| 384 | controllers having QE or CPM2, given minor tweaks. | ||
| 385 | |||
| 386 | Set CONFIG_USB_GADGET to "m" to build this driver as a | ||
| 387 | dynamically linked module called "fsl_qe_udc". | ||
| 388 | |||
| 389 | config USB_NET2272 | ||
| 390 | tristate "PLX NET2272" | ||
| 391 | help | ||
| 392 | PLX NET2272 is a USB peripheral controller which supports | ||
| 393 | both full and high speed USB 2.0 data transfers. | ||
| 394 | |||
| 395 | It has three configurable endpoints, as well as endpoint zero | ||
| 396 | (for control transfer). | ||
| 397 | Say "y" to link the driver statically, or "m" to build a | ||
| 398 | dynamically linked module called "net2272" and force all | ||
| 399 | gadget drivers to also be dynamically linked. | ||
| 400 | |||
| 401 | config USB_NET2272_DMA | ||
| 402 | boolean "Support external DMA controller" | ||
| 403 | depends on USB_NET2272 && HAS_DMA | ||
| 404 | help | ||
| 405 | The NET2272 part can optionally support an external DMA | ||
| 406 | controller, but your board has to have support in the | ||
| 407 | driver itself. | ||
| 408 | |||
| 409 | If unsure, say "N" here. The driver works fine in PIO mode. | ||
| 410 | |||
| 411 | config USB_NET2280 | ||
| 412 | tristate "NetChip 228x" | ||
| 413 | depends on PCI | ||
| 414 | help | ||
| 415 | NetChip 2280 / 2282 is a PCI based USB peripheral controller which | ||
| 416 | supports both full and high speed USB 2.0 data transfers. | ||
| 417 | |||
| 418 | It has six configurable endpoints, as well as endpoint zero | ||
| 419 | (for control transfers) and several endpoints with dedicated | ||
| 420 | functions. | ||
| 421 | |||
| 422 | Say "y" to link the driver statically, or "m" to build a | ||
| 423 | dynamically linked module called "net2280" and force all | ||
| 424 | gadget drivers to also be dynamically linked. | ||
| 425 | |||
| 426 | config USB_GOKU | ||
| 427 | tristate "Toshiba TC86C001 'Goku-S'" | ||
| 428 | depends on PCI | ||
| 429 | help | ||
| 430 | The Toshiba TC86C001 is a PCI device which includes controllers | ||
| 431 | for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI). | ||
| 432 | |||
| 433 | The device controller has three configurable (bulk or interrupt) | ||
| 434 | endpoints, plus endpoint zero (for control transfers). | ||
| 435 | |||
| 436 | Say "y" to link the driver statically, or "m" to build a | ||
| 437 | dynamically linked module called "goku_udc" and to force all | ||
| 438 | gadget drivers to also be dynamically linked. | ||
| 439 | |||
| 440 | config USB_EG20T | ||
| 441 | tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" | ||
| 442 | depends on PCI | ||
| 443 | help | ||
| 444 | This is a USB device driver for EG20T PCH. | ||
| 445 | EG20T PCH is the platform controller hub that is used in Intel's | ||
| 446 | general embedded platform. EG20T PCH has USB device interface. | ||
| 447 | Using this interface, it is able to access system devices connected | ||
| 448 | to USB device. | ||
| 449 | This driver enables USB device function. | ||
| 450 | USB device is a USB peripheral controller which | ||
| 451 | supports both full and high speed USB 2.0 data transfers. | ||
| 452 | This driver supports both control transfer and bulk transfer modes. | ||
| 453 | This driver dose not support interrupt transfer or isochronous | ||
| 454 | transfer modes. | ||
| 455 | |||
| 456 | This driver also can be used for LAPIS Semiconductor's ML7213 which is | ||
| 457 | for IVI(In-Vehicle Infotainment) use. | ||
| 458 | ML7831 is for general purpose use. | ||
| 459 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. | ||
| 460 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. | ||
| 461 | |||
| 462 | # | ||
| 463 | # LAST -- dummy/emulated controller | ||
| 464 | # | ||
| 465 | |||
| 466 | config USB_DUMMY_HCD | ||
| 467 | tristate "Dummy HCD (DEVELOPMENT)" | ||
| 468 | depends on USB=y || (USB=m && USB_GADGET=m) | ||
| 469 | help | ||
| 470 | This host controller driver emulates USB, looping all data transfer | ||
| 471 | requests back to a USB "gadget driver" in the same host. The host | ||
| 472 | side is the master; the gadget side is the slave. Gadget drivers | ||
| 473 | can be high, full, or low speed; and they have access to endpoints | ||
| 474 | like those from NET2280, PXA2xx, or SA1100 hardware. | ||
| 475 | |||
| 476 | This may help in some stages of creating a driver to embed in a | ||
| 477 | Linux device, since it lets you debug several parts of the gadget | ||
| 478 | driver without its hardware or drivers being involved. | ||
| 479 | |||
| 480 | Since such a gadget side driver needs to interoperate with a host | ||
| 481 | side Linux-USB device driver, this may help to debug both sides | ||
| 482 | of a USB protocol stack. | ||
| 483 | |||
| 484 | Say "y" to link the driver statically, or "m" to build a | ||
| 485 | dynamically linked module called "dummy_hcd" and force all | ||
| 486 | gadget drivers to also be dynamically linked. | ||
| 487 | |||
| 488 | # NOTE: Please keep dummy_hcd LAST so that "real hardware" appears | ||
| 489 | # first and will be selected by default. | ||
| 490 | |||
| 491 | endmenu | ||
| 492 | 131 | ||
| 493 | # | 132 | # |
| 494 | # USB Gadget Drivers | 133 | # USB Gadget Drivers |
| @@ -714,466 +353,7 @@ config USB_CONFIGFS_F_FS | |||
| 714 | implemented in kernel space (for instance Ethernet, serial or | 353 | implemented in kernel space (for instance Ethernet, serial or |
| 715 | mass storage) and other are implemented in user space. | 354 | mass storage) and other are implemented in user space. |
| 716 | 355 | ||
| 717 | config USB_ZERO | 356 | source "drivers/usb/gadget/legacy/Kconfig" |
| 718 | tristate "Gadget Zero (DEVELOPMENT)" | ||
| 719 | select USB_LIBCOMPOSITE | ||
| 720 | select USB_F_SS_LB | ||
| 721 | help | ||
| 722 | Gadget Zero is a two-configuration device. It either sinks and | ||
| 723 | sources bulk data; or it loops back a configurable number of | ||
| 724 | transfers. It also implements control requests, for "chapter 9" | ||
| 725 | conformance. The driver needs only two bulk-capable endpoints, so | ||
| 726 | it can work on top of most device-side usb controllers. It's | ||
| 727 | useful for testing, and is also a working example showing how | ||
| 728 | USB "gadget drivers" can be written. | ||
| 729 | |||
| 730 | Make this be the first driver you try using on top of any new | ||
| 731 | USB peripheral controller driver. Then you can use host-side | ||
| 732 | test software, like the "usbtest" driver, to put your hardware | ||
| 733 | and its driver through a basic set of functional tests. | ||
| 734 | |||
| 735 | Gadget Zero also works with the host-side "usb-skeleton" driver, | ||
| 736 | and with many kinds of host-side test software. You may need | ||
| 737 | to tweak product and vendor IDs before host software knows about | ||
| 738 | this device, and arrange to select an appropriate configuration. | ||
| 739 | |||
| 740 | Say "y" to link the driver statically, or "m" to build a | ||
| 741 | dynamically linked module called "g_zero". | ||
| 742 | |||
| 743 | config USB_ZERO_HNPTEST | ||
| 744 | boolean "HNP Test Device" | ||
| 745 | depends on USB_ZERO && USB_OTG | ||
| 746 | help | ||
| 747 | You can configure this device to enumerate using the device | ||
| 748 | identifiers of the USB-OTG test device. That means that when | ||
| 749 | this gadget connects to another OTG device, with this one using | ||
| 750 | the "B-Peripheral" role, that device will use HNP to let this | ||
| 751 | one serve as the USB host instead (in the "B-Host" role). | ||
| 752 | |||
| 753 | config USB_AUDIO | ||
| 754 | tristate "Audio Gadget" | ||
| 755 | depends on SND | ||
| 756 | select USB_LIBCOMPOSITE | ||
| 757 | select SND_PCM | ||
| 758 | help | ||
| 759 | This Gadget Audio driver is compatible with USB Audio Class | ||
| 760 | specification 2.0. It implements 1 AudioControl interface, | ||
| 761 | 1 AudioStreaming Interface each for USB-OUT and USB-IN. | ||
| 762 | Number of channels, sample rate and sample size can be | ||
| 763 | specified as module parameters. | ||
| 764 | This driver doesn't expect any real Audio codec to be present | ||
| 765 | on the device - the audio streams are simply sinked to and | ||
| 766 | sourced from a virtual ALSA sound card created. The user-space | ||
| 767 | application may choose to do whatever it wants with the data | ||
| 768 | received from the USB Host and choose to provide whatever it | ||
| 769 | wants as audio data to the USB Host. | ||
| 770 | |||
| 771 | Say "y" to link the driver statically, or "m" to build a | ||
| 772 | dynamically linked module called "g_audio". | ||
| 773 | |||
| 774 | config GADGET_UAC1 | ||
| 775 | bool "UAC 1.0 (Legacy)" | ||
| 776 | depends on USB_AUDIO | ||
| 777 | help | ||
| 778 | If you instead want older UAC Spec-1.0 driver that also has audio | ||
| 779 | paths hardwired to the Audio codec chip on-board and doesn't work | ||
| 780 | without one. | ||
| 781 | |||
| 782 | config USB_ETH | ||
| 783 | tristate "Ethernet Gadget (with CDC Ethernet support)" | ||
| 784 | depends on NET | ||
| 785 | select USB_LIBCOMPOSITE | ||
| 786 | select USB_U_ETHER | ||
| 787 | select USB_F_ECM | ||
| 788 | select USB_F_SUBSET | ||
| 789 | select CRC32 | ||
| 790 | help | ||
| 791 | This driver implements Ethernet style communication, in one of | ||
| 792 | several ways: | ||
| 793 | |||
| 794 | - The "Communication Device Class" (CDC) Ethernet Control Model. | ||
| 795 | That protocol is often avoided with pure Ethernet adapters, in | ||
| 796 | favor of simpler vendor-specific hardware, but is widely | ||
| 797 | supported by firmware for smart network devices. | ||
| 798 | |||
| 799 | - On hardware can't implement that protocol, a simple CDC subset | ||
| 800 | is used, placing fewer demands on USB. | ||
| 801 | |||
| 802 | - CDC Ethernet Emulation Model (EEM) is a newer standard that has | ||
| 803 | a simpler interface that can be used by more USB hardware. | ||
| 804 | |||
| 805 | RNDIS support is an additional option, more demanding than than | ||
| 806 | subset. | ||
| 807 | |||
| 808 | Within the USB device, this gadget driver exposes a network device | ||
| 809 | "usbX", where X depends on what other networking devices you have. | ||
| 810 | Treat it like a two-node Ethernet link: host, and gadget. | ||
| 811 | |||
| 812 | The Linux-USB host-side "usbnet" driver interoperates with this | ||
| 813 | driver, so that deep I/O queues can be supported. On 2.4 kernels, | ||
| 814 | use "CDCEther" instead, if you're using the CDC option. That CDC | ||
| 815 | mode should also interoperate with standard CDC Ethernet class | ||
| 816 | drivers on other host operating systems. | ||
| 817 | |||
| 818 | Say "y" to link the driver statically, or "m" to build a | ||
| 819 | dynamically linked module called "g_ether". | ||
| 820 | |||
| 821 | config USB_ETH_RNDIS | ||
| 822 | bool "RNDIS support" | ||
| 823 | depends on USB_ETH | ||
| 824 | select USB_LIBCOMPOSITE | ||
| 825 | select USB_F_RNDIS | ||
| 826 | default y | ||
| 827 | help | ||
| 828 | Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol, | ||
| 829 | and Microsoft provides redistributable binary RNDIS drivers for | ||
| 830 | older versions of Windows. | ||
| 831 | |||
| 832 | If you say "y" here, the Ethernet gadget driver will try to provide | ||
| 833 | a second device configuration, supporting RNDIS to talk to such | ||
| 834 | Microsoft USB hosts. | ||
| 835 | |||
| 836 | To make MS-Windows work with this, use Documentation/usb/linux.inf | ||
| 837 | as the "driver info file". For versions of MS-Windows older than | ||
| 838 | XP, you'll need to download drivers from Microsoft's website; a URL | ||
| 839 | is given in comments found in that info file. | ||
| 840 | |||
| 841 | config USB_ETH_EEM | ||
| 842 | bool "Ethernet Emulation Model (EEM) support" | ||
| 843 | depends on USB_ETH | ||
| 844 | select USB_LIBCOMPOSITE | ||
| 845 | select USB_F_EEM | ||
| 846 | default n | ||
| 847 | help | ||
| 848 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM | ||
| 849 | and therefore can be supported by more hardware. Technically ECM and | ||
| 850 | EEM are designed for different applications. The ECM model extends | ||
| 851 | the network interface to the target (e.g. a USB cable modem), and the | ||
| 852 | EEM model is for mobile devices to communicate with hosts using | ||
| 853 | ethernet over USB. For Linux gadgets, however, the interface with | ||
| 854 | the host is the same (a usbX device), so the differences are minimal. | ||
| 855 | |||
| 856 | If you say "y" here, the Ethernet gadget driver will use the EEM | ||
| 857 | protocol rather than ECM. If unsure, say "n". | ||
| 858 | |||
| 859 | config USB_G_NCM | ||
| 860 | tristate "Network Control Model (NCM) support" | ||
| 861 | depends on NET | ||
| 862 | select USB_LIBCOMPOSITE | ||
| 863 | select USB_U_ETHER | ||
| 864 | select USB_F_NCM | ||
| 865 | select CRC32 | ||
| 866 | help | ||
| 867 | This driver implements USB CDC NCM subclass standard. NCM is | ||
| 868 | an advanced protocol for Ethernet encapsulation, allows grouping | ||
| 869 | of several ethernet frames into one USB transfer and different | ||
| 870 | alignment possibilities. | ||
| 871 | |||
| 872 | Say "y" to link the driver statically, or "m" to build a | ||
| 873 | dynamically linked module called "g_ncm". | ||
| 874 | |||
| 875 | config USB_GADGETFS | ||
| 876 | tristate "Gadget Filesystem" | ||
| 877 | help | ||
| 878 | This driver provides a filesystem based API that lets user mode | ||
| 879 | programs implement a single-configuration USB device, including | ||
| 880 | endpoint I/O and control requests that don't relate to enumeration. | ||
| 881 | All endpoints, transfer speeds, and transfer types supported by | ||
| 882 | the hardware are available, through read() and write() calls. | ||
| 883 | |||
| 884 | Say "y" to link the driver statically, or "m" to build a | ||
| 885 | dynamically linked module called "gadgetfs". | ||
| 886 | |||
| 887 | config USB_FUNCTIONFS | ||
| 888 | tristate "Function Filesystem" | ||
| 889 | select USB_LIBCOMPOSITE | ||
| 890 | select USB_F_FS | ||
| 891 | select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS) | ||
| 892 | help | ||
| 893 | The Function Filesystem (FunctionFS) lets one create USB | ||
| 894 | composite functions in user space in the same way GadgetFS | ||
| 895 | lets one create USB gadgets in user space. This allows creation | ||
| 896 | of composite gadgets such that some of the functions are | ||
| 897 | implemented in kernel space (for instance Ethernet, serial or | ||
| 898 | mass storage) and other are implemented in user space. | ||
| 899 | |||
| 900 | If you say "y" or "m" here you will be able what kind of | ||
| 901 | configurations the gadget will provide. | ||
| 902 | |||
| 903 | Say "y" to link the driver statically, or "m" to build | ||
| 904 | a dynamically linked module called "g_ffs". | ||
| 905 | |||
| 906 | config USB_FUNCTIONFS_ETH | ||
| 907 | bool "Include configuration with CDC ECM (Ethernet)" | ||
| 908 | depends on USB_FUNCTIONFS && NET | ||
| 909 | select USB_U_ETHER | ||
| 910 | select USB_F_ECM | ||
| 911 | select USB_F_SUBSET | ||
| 912 | help | ||
| 913 | Include a configuration with CDC ECM function (Ethernet) and the | ||
| 914 | Function Filesystem. | ||
| 915 | |||
| 916 | config USB_FUNCTIONFS_RNDIS | ||
| 917 | bool "Include configuration with RNDIS (Ethernet)" | ||
| 918 | depends on USB_FUNCTIONFS && NET | ||
| 919 | select USB_U_ETHER | ||
| 920 | select USB_F_RNDIS | ||
| 921 | help | ||
| 922 | Include a configuration with RNDIS function (Ethernet) and the Filesystem. | ||
| 923 | |||
| 924 | config USB_FUNCTIONFS_GENERIC | ||
| 925 | bool "Include 'pure' configuration" | ||
| 926 | depends on USB_FUNCTIONFS | ||
| 927 | help | ||
| 928 | Include a configuration with the Function Filesystem alone with | ||
| 929 | no Ethernet interface. | ||
| 930 | |||
| 931 | config USB_MASS_STORAGE | ||
| 932 | tristate "Mass Storage Gadget" | ||
| 933 | depends on BLOCK | ||
| 934 | select USB_LIBCOMPOSITE | ||
| 935 | select USB_F_MASS_STORAGE | ||
| 936 | help | ||
| 937 | The Mass Storage Gadget acts as a USB Mass Storage disk drive. | ||
| 938 | As its storage repository it can use a regular file or a block | ||
| 939 | device (in much the same way as the "loop" device driver), | ||
| 940 | specified as a module parameter or sysfs option. | ||
| 941 | |||
| 942 | This driver is a replacement for now removed File-backed | ||
| 943 | Storage Gadget (g_file_storage). | ||
| 944 | |||
| 945 | Say "y" to link the driver statically, or "m" to build | ||
| 946 | a dynamically linked module called "g_mass_storage". | ||
| 947 | |||
| 948 | config USB_GADGET_TARGET | ||
| 949 | tristate "USB Gadget Target Fabric Module" | ||
| 950 | depends on TARGET_CORE | ||
| 951 | select USB_LIBCOMPOSITE | ||
| 952 | help | ||
| 953 | This fabric is an USB gadget. Two USB protocols are supported that is | ||
| 954 | BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is | ||
| 955 | advertised on alternative interface 0 (primary) and UAS is on | ||
| 956 | alternative interface 1. Both protocols can work on USB2.0 and USB3.0. | ||
| 957 | UAS utilizes the USB 3.0 feature called streams support. | ||
| 958 | |||
| 959 | config USB_G_SERIAL | ||
| 960 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" | ||
| 961 | depends on TTY | ||
| 962 | select USB_U_SERIAL | ||
| 963 | select USB_F_ACM | ||
| 964 | select USB_F_SERIAL | ||
| 965 | select USB_F_OBEX | ||
| 966 | select USB_LIBCOMPOSITE | ||
| 967 | help | ||
| 968 | The Serial Gadget talks to the Linux-USB generic serial driver. | ||
| 969 | This driver supports a CDC-ACM module option, which can be used | ||
| 970 | to interoperate with MS-Windows hosts or with the Linux-USB | ||
| 971 | "cdc-acm" driver. | ||
| 972 | |||
| 973 | This driver also supports a CDC-OBEX option. You will need a | ||
| 974 | user space OBEX server talking to /dev/ttyGS*, since the kernel | ||
| 975 | itself doesn't implement the OBEX protocol. | ||
| 976 | |||
| 977 | Say "y" to link the driver statically, or "m" to build a | ||
| 978 | dynamically linked module called "g_serial". | ||
| 979 | |||
| 980 | For more information, see Documentation/usb/gadget_serial.txt | ||
| 981 | which includes instructions and a "driver info file" needed to | ||
| 982 | make MS-Windows work with CDC ACM. | ||
| 983 | |||
| 984 | config USB_MIDI_GADGET | ||
| 985 | tristate "MIDI Gadget" | ||
| 986 | depends on SND | ||
| 987 | select USB_LIBCOMPOSITE | ||
| 988 | select SND_RAWMIDI | ||
| 989 | help | ||
| 990 | The MIDI Gadget acts as a USB Audio device, with one MIDI | ||
| 991 | input and one MIDI output. These MIDI jacks appear as | ||
| 992 | a sound "card" in the ALSA sound system. Other MIDI | ||
| 993 | connections can then be made on the gadget system, using | ||
| 994 | ALSA's aconnect utility etc. | ||
| 995 | |||
| 996 | Say "y" to link the driver statically, or "m" to build a | ||
| 997 | dynamically linked module called "g_midi". | ||
| 998 | |||
| 999 | config USB_G_PRINTER | ||
| 1000 | tristate "Printer Gadget" | ||
| 1001 | select USB_LIBCOMPOSITE | ||
| 1002 | help | ||
| 1003 | The Printer Gadget channels data between the USB host and a | ||
| 1004 | userspace program driving the print engine. The user space | ||
| 1005 | program reads and writes the device file /dev/g_printer to | ||
| 1006 | receive or send printer data. It can use ioctl calls to | ||
| 1007 | the device file to get or set printer status. | ||
| 1008 | |||
| 1009 | Say "y" to link the driver statically, or "m" to build a | ||
| 1010 | dynamically linked module called "g_printer". | ||
| 1011 | |||
| 1012 | For more information, see Documentation/usb/gadget_printer.txt | ||
| 1013 | which includes sample code for accessing the device file. | ||
| 1014 | |||
| 1015 | if TTY | ||
| 1016 | |||
| 1017 | config USB_CDC_COMPOSITE | ||
| 1018 | tristate "CDC Composite Device (Ethernet and ACM)" | ||
| 1019 | depends on NET | ||
| 1020 | select USB_LIBCOMPOSITE | ||
| 1021 | select USB_U_SERIAL | ||
| 1022 | select USB_U_ETHER | ||
| 1023 | select USB_F_ACM | ||
| 1024 | select USB_F_ECM | ||
| 1025 | help | ||
| 1026 | This driver provides two functions in one configuration: | ||
| 1027 | a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. | ||
| 1028 | |||
| 1029 | This driver requires four bulk and two interrupt endpoints, | ||
| 1030 | plus the ability to handle altsettings. Not all peripheral | ||
| 1031 | controllers are that capable. | ||
| 1032 | |||
| 1033 | Say "y" to link the driver statically, or "m" to build a | ||
| 1034 | dynamically linked module. | ||
| 1035 | |||
| 1036 | config USB_G_NOKIA | ||
| 1037 | tristate "Nokia composite gadget" | ||
| 1038 | depends on PHONET | ||
| 1039 | select USB_LIBCOMPOSITE | ||
| 1040 | select USB_U_SERIAL | ||
| 1041 | select USB_U_ETHER | ||
| 1042 | select USB_F_ACM | ||
| 1043 | select USB_F_OBEX | ||
| 1044 | select USB_F_PHONET | ||
| 1045 | select USB_F_ECM | ||
| 1046 | help | ||
| 1047 | The Nokia composite gadget provides support for acm, obex | ||
| 1048 | and phonet in only one composite gadget driver. | ||
| 1049 | |||
| 1050 | It's only really useful for N900 hardware. If you're building | ||
| 1051 | a kernel for N900, say Y or M here. If unsure, say N. | ||
| 1052 | |||
| 1053 | config USB_G_ACM_MS | ||
| 1054 | tristate "CDC Composite Device (ACM and mass storage)" | ||
| 1055 | depends on BLOCK | ||
| 1056 | select USB_LIBCOMPOSITE | ||
| 1057 | select USB_U_SERIAL | ||
| 1058 | select USB_F_ACM | ||
| 1059 | select USB_F_MASS_STORAGE | ||
| 1060 | help | ||
| 1061 | This driver provides two functions in one configuration: | ||
| 1062 | a mass storage, and a CDC ACM (serial port) link. | ||
| 1063 | |||
| 1064 | Say "y" to link the driver statically, or "m" to build a | ||
| 1065 | dynamically linked module called "g_acm_ms". | ||
| 1066 | |||
| 1067 | config USB_G_MULTI | ||
| 1068 | tristate "Multifunction Composite Gadget" | ||
| 1069 | depends on BLOCK && NET | ||
| 1070 | select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS | ||
| 1071 | select USB_LIBCOMPOSITE | ||
| 1072 | select USB_U_SERIAL | ||
| 1073 | select USB_U_ETHER | ||
| 1074 | select USB_F_ACM | ||
| 1075 | select USB_F_MASS_STORAGE | ||
| 1076 | help | ||
| 1077 | The Multifunction Composite Gadget provides Ethernet (RNDIS | ||
| 1078 | and/or CDC Ethernet), mass storage and ACM serial link | ||
| 1079 | interfaces. | ||
| 1080 | |||
| 1081 | You will be asked to choose which of the two configurations is | ||
| 1082 | to be available in the gadget. At least one configuration must | ||
| 1083 | be chosen to make the gadget usable. Selecting more than one | ||
| 1084 | configuration will prevent Windows from automatically detecting | ||
| 1085 | the gadget as a composite gadget, so an INF file will be needed to | ||
| 1086 | use the gadget. | ||
| 1087 | |||
| 1088 | Say "y" to link the driver statically, or "m" to build a | ||
| 1089 | dynamically linked module called "g_multi". | ||
| 1090 | |||
| 1091 | config USB_G_MULTI_RNDIS | ||
| 1092 | bool "RNDIS + CDC Serial + Storage configuration" | ||
| 1093 | depends on USB_G_MULTI | ||
| 1094 | select USB_F_RNDIS | ||
| 1095 | default y | ||
| 1096 | help | ||
| 1097 | This option enables a configuration with RNDIS, CDC Serial and | ||
| 1098 | Mass Storage functions available in the Multifunction Composite | ||
| 1099 | Gadget. This is the configuration dedicated for Windows since RNDIS | ||
| 1100 | is Microsoft's protocol. | ||
| 1101 | |||
| 1102 | If unsure, say "y". | ||
| 1103 | |||
| 1104 | config USB_G_MULTI_CDC | ||
| 1105 | bool "CDC Ethernet + CDC Serial + Storage configuration" | ||
| 1106 | depends on USB_G_MULTI | ||
| 1107 | default n | ||
| 1108 | select USB_F_ECM | ||
| 1109 | help | ||
| 1110 | This option enables a configuration with CDC Ethernet (ECM), CDC | ||
| 1111 | Serial and Mass Storage functions available in the Multifunction | ||
| 1112 | Composite Gadget. | ||
| 1113 | |||
| 1114 | If unsure, say "y". | ||
| 1115 | |||
| 1116 | endif # TTY | ||
| 1117 | |||
| 1118 | config USB_G_HID | ||
| 1119 | tristate "HID Gadget" | ||
| 1120 | select USB_LIBCOMPOSITE | ||
| 1121 | help | ||
| 1122 | The HID gadget driver provides generic emulation of USB | ||
| 1123 | Human Interface Devices (HID). | ||
| 1124 | |||
| 1125 | For more information, see Documentation/usb/gadget_hid.txt which | ||
| 1126 | includes sample code for accessing the device files. | ||
| 1127 | |||
| 1128 | Say "y" to link the driver statically, or "m" to build a | ||
| 1129 | dynamically linked module called "g_hid". | ||
| 1130 | |||
| 1131 | # Standalone / single function gadgets | ||
| 1132 | config USB_G_DBGP | ||
| 1133 | tristate "EHCI Debug Device Gadget" | ||
| 1134 | depends on TTY | ||
| 1135 | select USB_LIBCOMPOSITE | ||
| 1136 | help | ||
| 1137 | This gadget emulates an EHCI Debug device. This is useful when you want | ||
| 1138 | to interact with an EHCI Debug Port. | ||
| 1139 | |||
| 1140 | Say "y" to link the driver statically, or "m" to build a | ||
| 1141 | dynamically linked module called "g_dbgp". | ||
| 1142 | |||
| 1143 | if USB_G_DBGP | ||
| 1144 | choice | ||
| 1145 | prompt "EHCI Debug Device mode" | ||
| 1146 | default USB_G_DBGP_SERIAL | ||
| 1147 | |||
| 1148 | config USB_G_DBGP_PRINTK | ||
| 1149 | depends on USB_G_DBGP | ||
| 1150 | bool "printk" | ||
| 1151 | help | ||
| 1152 | Directly printk() received data. No interaction. | ||
| 1153 | |||
| 1154 | config USB_G_DBGP_SERIAL | ||
| 1155 | depends on USB_G_DBGP | ||
| 1156 | select USB_U_SERIAL | ||
| 1157 | bool "serial" | ||
| 1158 | help | ||
| 1159 | Userland can interact using /dev/ttyGSxxx. | ||
| 1160 | endchoice | ||
| 1161 | endif | ||
| 1162 | |||
| 1163 | # put drivers that need isochronous transfer support (for audio | ||
| 1164 | # or video class gadget drivers), or specific hardware, here. | ||
| 1165 | config USB_G_WEBCAM | ||
| 1166 | tristate "USB Webcam Gadget" | ||
| 1167 | depends on VIDEO_DEV | ||
| 1168 | select USB_LIBCOMPOSITE | ||
| 1169 | select VIDEOBUF2_VMALLOC | ||
| 1170 | help | ||
| 1171 | The Webcam Gadget acts as a composite USB Audio and Video Class | ||
| 1172 | device. It provides a userspace API to process UVC control requests | ||
| 1173 | and stream video data to the host. | ||
| 1174 | |||
| 1175 | Say "y" to link the driver statically, or "m" to build a | ||
| 1176 | dynamically linked module called "g_webcam". | ||
| 1177 | 357 | ||
| 1178 | endchoice | 358 | endchoice |
| 1179 | 359 | ||
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 49514ea60a98..9add915d41f7 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
| @@ -1,105 +1,12 @@ | |||
| 1 | # | 1 | # |
| 2 | # USB peripheral controller drivers | 2 | # USB peripheral controller drivers |
| 3 | # | 3 | # |
| 4 | ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG | 4 | subdir-ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG |
| 5 | ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG | 5 | subdir-ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG |
| 6 | ccflags-y += -Idrivers/usb/gadget/udc | ||
| 6 | 7 | ||
| 7 | obj-$(CONFIG_USB_GADGET) += udc-core.o | ||
| 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 |
| 10 | libcomposite-y += composite.o functions.o configfs.o u_f.o | 10 | libcomposite-y += composite.o functions.o configfs.o u_f.o |
| 11 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | ||
| 12 | obj-$(CONFIG_USB_NET2272) += net2272.o | ||
| 13 | obj-$(CONFIG_USB_NET2280) += net2280.o | ||
| 14 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o | ||
| 15 | obj-$(CONFIG_USB_PXA25X) += pxa25x_udc.o | ||
| 16 | obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o | ||
| 17 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | ||
| 18 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | ||
| 19 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o | ||
| 20 | obj-$(CONFIG_USB_AT91) += at91_udc.o | ||
| 21 | obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o | ||
| 22 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o | ||
| 23 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | ||
| 24 | fsl_usb2_udc-y := fsl_udc_core.o | ||
| 25 | fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | ||
| 26 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | ||
| 27 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | ||
| 28 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | ||
| 29 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o | ||
| 30 | obj-$(CONFIG_USB_LPC32XX) += lpc32xx_udc.o | ||
| 31 | obj-$(CONFIG_USB_EG20T) += pch_udc.o | ||
| 32 | obj-$(CONFIG_USB_MV_UDC) += mv_udc.o | ||
| 33 | mv_udc-y := mv_udc_core.o | ||
| 34 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o | ||
| 35 | obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o | ||
| 36 | obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o | ||
| 37 | obj-$(CONFIG_USB_GR_UDC) += gr_udc.o | ||
| 38 | 11 | ||
| 39 | # USB Functions | 12 | obj-$(CONFIG_USB_GADGET) += udc/ function/ legacy/ |
| 40 | usb_f_acm-y := f_acm.o | ||
| 41 | obj-$(CONFIG_USB_F_ACM) += usb_f_acm.o | ||
| 42 | usb_f_ss_lb-y := f_loopback.o f_sourcesink.o | ||
| 43 | obj-$(CONFIG_USB_F_SS_LB) += usb_f_ss_lb.o | ||
| 44 | obj-$(CONFIG_USB_U_SERIAL) += u_serial.o | ||
| 45 | usb_f_serial-y := f_serial.o | ||
| 46 | obj-$(CONFIG_USB_F_SERIAL) += usb_f_serial.o | ||
| 47 | usb_f_obex-y := f_obex.o | ||
| 48 | obj-$(CONFIG_USB_F_OBEX) += usb_f_obex.o | ||
| 49 | obj-$(CONFIG_USB_U_ETHER) += u_ether.o | ||
| 50 | usb_f_ncm-y := f_ncm.o | ||
| 51 | obj-$(CONFIG_USB_F_NCM) += usb_f_ncm.o | ||
| 52 | usb_f_ecm-y := f_ecm.o | ||
| 53 | obj-$(CONFIG_USB_F_ECM) += usb_f_ecm.o | ||
| 54 | usb_f_phonet-y := f_phonet.o | ||
| 55 | obj-$(CONFIG_USB_F_PHONET) += usb_f_phonet.o | ||
| 56 | usb_f_eem-y := f_eem.o | ||
| 57 | obj-$(CONFIG_USB_F_EEM) += usb_f_eem.o | ||
| 58 | usb_f_ecm_subset-y := f_subset.o | ||
| 59 | obj-$(CONFIG_USB_F_SUBSET) += usb_f_ecm_subset.o | ||
| 60 | usb_f_rndis-y := f_rndis.o rndis.o | ||
| 61 | obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o | ||
| 62 | usb_f_mass_storage-y := f_mass_storage.o storage_common.o | ||
| 63 | obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o | ||
| 64 | usb_f_fs-y := f_fs.o | ||
| 65 | obj-$(CONFIG_USB_F_FS) += usb_f_fs.o | ||
| 66 | |||
| 67 | # | ||
| 68 | # USB gadget drivers | ||
| 69 | # | ||
| 70 | g_zero-y := zero.o | ||
| 71 | g_audio-y := audio.o | ||
| 72 | g_ether-y := ether.o | ||
| 73 | g_serial-y := serial.o | ||
| 74 | g_midi-y := gmidi.o | ||
| 75 | gadgetfs-y := inode.o | ||
| 76 | g_mass_storage-y := mass_storage.o | ||
| 77 | g_printer-y := printer.o | ||
| 78 | g_cdc-y := cdc2.o | ||
| 79 | g_multi-y := multi.o | ||
| 80 | g_hid-y := hid.o | ||
| 81 | g_dbgp-y := dbgp.o | ||
| 82 | g_nokia-y := nokia.o | ||
| 83 | g_webcam-y := webcam.o | ||
| 84 | g_ncm-y := ncm.o | ||
| 85 | g_acm_ms-y := acm_ms.o | ||
| 86 | g_tcm_usb_gadget-y := tcm_usb_gadget.o | ||
| 87 | |||
| 88 | obj-$(CONFIG_USB_ZERO) += g_zero.o | ||
| 89 | obj-$(CONFIG_USB_AUDIO) += g_audio.o | ||
| 90 | obj-$(CONFIG_USB_ETH) += g_ether.o | ||
| 91 | obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o | ||
| 92 | obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o | ||
| 93 | obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o | ||
| 94 | obj-$(CONFIG_USB_G_SERIAL) += g_serial.o | ||
| 95 | obj-$(CONFIG_USB_G_PRINTER) += g_printer.o | ||
| 96 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o | ||
| 97 | obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o | ||
| 98 | obj-$(CONFIG_USB_G_HID) += g_hid.o | ||
| 99 | obj-$(CONFIG_USB_G_DBGP) += g_dbgp.o | ||
| 100 | obj-$(CONFIG_USB_G_MULTI) += g_multi.o | ||
| 101 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o | ||
| 102 | obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o | ||
| 103 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o | ||
| 104 | obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o | ||
| 105 | obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o | ||
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f80151932053..6935a822ce2b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
| @@ -1956,6 +1956,7 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) | |||
| 1956 | } | 1956 | } |
| 1957 | if (cdev->req) { | 1957 | if (cdev->req) { |
| 1958 | kfree(cdev->req->buf); | 1958 | kfree(cdev->req->buf); |
| 1959 | usb_ep_dequeue(cdev->gadget->ep0, cdev->req); | ||
| 1959 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); | 1960 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); |
| 1960 | } | 1961 | } |
| 1961 | cdev->next_string_id = 0; | 1962 | cdev->next_string_id = 0; |
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 97142146eead..811c2c7cc269 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c | |||
| @@ -1021,12 +1021,10 @@ static ssize_t ext_prop_data_store(struct usb_os_desc_ext_prop *ext_prop, | |||
| 1021 | 1021 | ||
| 1022 | if (page[len - 1] == '\n' || page[len - 1] == '\0') | 1022 | if (page[len - 1] == '\n' || page[len - 1] == '\0') |
| 1023 | --len; | 1023 | --len; |
| 1024 | new_data = kzalloc(len, GFP_KERNEL); | 1024 | new_data = kmemdup(page, len, GFP_KERNEL); |
| 1025 | if (!new_data) | 1025 | if (!new_data) |
| 1026 | return -ENOMEM; | 1026 | return -ENOMEM; |
| 1027 | 1027 | ||
| 1028 | memcpy(new_data, page, len); | ||
| 1029 | |||
| 1030 | if (desc->opts_mutex) | 1028 | if (desc->opts_mutex) |
| 1031 | mutex_lock(desc->opts_mutex); | 1029 | mutex_lock(desc->opts_mutex); |
| 1032 | kfree(ext_prop->data); | 1030 | kfree(ext_prop->data); |
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile new file mode 100644 index 000000000000..83ae1065149d --- /dev/null +++ b/drivers/usb/gadget/function/Makefile | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | # | ||
| 2 | # USB peripheral controller drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | ccflags-y := -Idrivers/usb/gadget/ | ||
| 6 | ccflags-y += -Idrivers/usb/gadget/udc/ | ||
| 7 | |||
| 8 | # USB Functions | ||
| 9 | usb_f_acm-y := f_acm.o | ||
| 10 | obj-$(CONFIG_USB_F_ACM) += usb_f_acm.o | ||
| 11 | usb_f_ss_lb-y := f_loopback.o f_sourcesink.o | ||
| 12 | obj-$(CONFIG_USB_F_SS_LB) += usb_f_ss_lb.o | ||
| 13 | obj-$(CONFIG_USB_U_SERIAL) += u_serial.o | ||
| 14 | usb_f_serial-y := f_serial.o | ||
| 15 | obj-$(CONFIG_USB_F_SERIAL) += usb_f_serial.o | ||
| 16 | usb_f_obex-y := f_obex.o | ||
| 17 | obj-$(CONFIG_USB_F_OBEX) += usb_f_obex.o | ||
| 18 | obj-$(CONFIG_USB_U_ETHER) += u_ether.o | ||
| 19 | usb_f_ncm-y := f_ncm.o | ||
| 20 | obj-$(CONFIG_USB_F_NCM) += usb_f_ncm.o | ||
| 21 | usb_f_ecm-y := f_ecm.o | ||
| 22 | obj-$(CONFIG_USB_F_ECM) += usb_f_ecm.o | ||
| 23 | usb_f_phonet-y := f_phonet.o | ||
| 24 | obj-$(CONFIG_USB_F_PHONET) += usb_f_phonet.o | ||
| 25 | usb_f_eem-y := f_eem.o | ||
| 26 | obj-$(CONFIG_USB_F_EEM) += usb_f_eem.o | ||
| 27 | usb_f_ecm_subset-y := f_subset.o | ||
| 28 | obj-$(CONFIG_USB_F_SUBSET) += usb_f_ecm_subset.o | ||
| 29 | usb_f_rndis-y := f_rndis.o rndis.o | ||
| 30 | obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o | ||
| 31 | usb_f_mass_storage-y := f_mass_storage.o storage_common.o | ||
| 32 | obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o | ||
| 33 | usb_f_fs-y := f_fs.o | ||
| 34 | obj-$(CONFIG_USB_F_FS) += usb_f_fs.o | ||
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/function/f_acm.c index ab1065afbbd0..ab1065afbbd0 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c | |||
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 798760fa7e70..798760fa7e70 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c | |||
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/function/f_eem.c index d61c11d765d0..4d8b236ea608 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c | |||
| @@ -355,20 +355,18 @@ static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb) | |||
| 355 | int padlen = 0; | 355 | int padlen = 0; |
| 356 | u16 len = skb->len; | 356 | u16 len = skb->len; |
| 357 | 357 | ||
| 358 | if (!skb_cloned(skb)) { | 358 | int headroom = skb_headroom(skb); |
| 359 | int headroom = skb_headroom(skb); | 359 | int tailroom = skb_tailroom(skb); |
| 360 | int tailroom = skb_tailroom(skb); | ||
| 361 | 360 | ||
| 362 | /* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0, | 361 | /* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0, |
| 363 | * stick two bytes of zero-length EEM packet on the end. | 362 | * stick two bytes of zero-length EEM packet on the end. |
| 364 | */ | 363 | */ |
| 365 | if (((len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) == 0) | 364 | if (((len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) == 0) |
| 366 | padlen += 2; | 365 | padlen += 2; |
| 367 | 366 | ||
| 368 | if ((tailroom >= (ETH_FCS_LEN + padlen)) && | 367 | if ((tailroom >= (ETH_FCS_LEN + padlen)) && |
| 369 | (headroom >= EEM_HLEN)) | 368 | (headroom >= EEM_HLEN) && !skb_cloned(skb)) |
| 370 | goto done; | 369 | goto done; |
| 371 | } | ||
| 372 | 370 | ||
| 373 | skb2 = skb_copy_expand(skb, EEM_HLEN, ETH_FCS_LEN + padlen, GFP_ATOMIC); | 371 | skb2 = skb_copy_expand(skb, EEM_HLEN, ETH_FCS_LEN + padlen, GFP_ATOMIC); |
| 374 | dev_kfree_skb_any(skb); | 372 | dev_kfree_skb_any(skb); |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 8598c27c7d43..dc30adf15a01 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #include "u_fs.h" | 35 | #include "u_fs.h" |
| 36 | #include "u_f.h" | 36 | #include "u_f.h" |
| 37 | #include "u_os_desc.h" | ||
| 37 | #include "configfs.h" | 38 | #include "configfs.h" |
| 38 | 39 | ||
| 39 | #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ | 40 | #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ |
| @@ -1646,13 +1647,22 @@ enum ffs_entity_type { | |||
| 1646 | FFS_DESCRIPTOR, FFS_INTERFACE, FFS_STRING, FFS_ENDPOINT | 1647 | FFS_DESCRIPTOR, FFS_INTERFACE, FFS_STRING, FFS_ENDPOINT |
| 1647 | }; | 1648 | }; |
| 1648 | 1649 | ||
| 1650 | enum ffs_os_desc_type { | ||
| 1651 | FFS_OS_DESC, FFS_OS_DESC_EXT_COMPAT, FFS_OS_DESC_EXT_PROP | ||
| 1652 | }; | ||
| 1653 | |||
| 1649 | typedef int (*ffs_entity_callback)(enum ffs_entity_type entity, | 1654 | typedef int (*ffs_entity_callback)(enum ffs_entity_type entity, |
| 1650 | u8 *valuep, | 1655 | u8 *valuep, |
| 1651 | struct usb_descriptor_header *desc, | 1656 | struct usb_descriptor_header *desc, |
| 1652 | void *priv); | 1657 | void *priv); |
| 1653 | 1658 | ||
| 1654 | static int __must_check ffs_do_desc(char *data, unsigned len, | 1659 | typedef int (*ffs_os_desc_callback)(enum ffs_os_desc_type entity, |
| 1655 | ffs_entity_callback entity, void *priv) | 1660 | struct usb_os_desc_header *h, void *data, |
| 1661 | unsigned len, void *priv); | ||
| 1662 | |||
| 1663 | static int __must_check ffs_do_single_desc(char *data, unsigned len, | ||
| 1664 | ffs_entity_callback entity, | ||
| 1665 | void *priv) | ||
| 1656 | { | 1666 | { |
| 1657 | struct usb_descriptor_header *_ds = (void *)data; | 1667 | struct usb_descriptor_header *_ds = (void *)data; |
| 1658 | u8 length; | 1668 | u8 length; |
| @@ -1804,7 +1814,7 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, | |||
| 1804 | if (!data) | 1814 | if (!data) |
| 1805 | return _len - len; | 1815 | return _len - len; |
| 1806 | 1816 | ||
| 1807 | ret = ffs_do_desc(data, len, entity, priv); | 1817 | ret = ffs_do_single_desc(data, len, entity, priv); |
| 1808 | if (unlikely(ret < 0)) { | 1818 | if (unlikely(ret < 0)) { |
| 1809 | pr_debug("%s returns %d\n", __func__, ret); | 1819 | pr_debug("%s returns %d\n", __func__, ret); |
| 1810 | return ret; | 1820 | return ret; |
| @@ -1857,11 +1867,191 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, | |||
| 1857 | return 0; | 1867 | return 0; |
| 1858 | } | 1868 | } |
| 1859 | 1869 | ||
| 1870 | static int __ffs_do_os_desc_header(enum ffs_os_desc_type *next_type, | ||
| 1871 | struct usb_os_desc_header *desc) | ||
| 1872 | { | ||
| 1873 | u16 bcd_version = le16_to_cpu(desc->bcdVersion); | ||
| 1874 | u16 w_index = le16_to_cpu(desc->wIndex); | ||
| 1875 | |||
| 1876 | if (bcd_version != 1) { | ||
| 1877 | pr_vdebug("unsupported os descriptors version: %d", | ||
| 1878 | bcd_version); | ||
| 1879 | return -EINVAL; | ||
| 1880 | } | ||
| 1881 | switch (w_index) { | ||
| 1882 | case 0x4: | ||
| 1883 | *next_type = FFS_OS_DESC_EXT_COMPAT; | ||
| 1884 | break; | ||
| 1885 | case 0x5: | ||
| 1886 | *next_type = FFS_OS_DESC_EXT_PROP; | ||
| 1887 | break; | ||
| 1888 | default: | ||
| 1889 | pr_vdebug("unsupported os descriptor type: %d", w_index); | ||
| 1890 | return -EINVAL; | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | return sizeof(*desc); | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | /* | ||
| 1897 | * Process all extended compatibility/extended property descriptors | ||
| 1898 | * of a feature descriptor | ||
| 1899 | */ | ||
| 1900 | static int __must_check ffs_do_single_os_desc(char *data, unsigned len, | ||
| 1901 | enum ffs_os_desc_type type, | ||
| 1902 | u16 feature_count, | ||
| 1903 | ffs_os_desc_callback entity, | ||
| 1904 | void *priv, | ||
| 1905 | struct usb_os_desc_header *h) | ||
| 1906 | { | ||
| 1907 | int ret; | ||
| 1908 | const unsigned _len = len; | ||
| 1909 | |||
| 1910 | ENTER(); | ||
| 1911 | |||
| 1912 | /* loop over all ext compat/ext prop descriptors */ | ||
| 1913 | while (feature_count--) { | ||
| 1914 | ret = entity(type, h, data, len, priv); | ||
| 1915 | if (unlikely(ret < 0)) { | ||
| 1916 | pr_debug("bad OS descriptor, type: %d\n", type); | ||
| 1917 | return ret; | ||
| 1918 | } | ||
| 1919 | data += ret; | ||
| 1920 | len -= ret; | ||
| 1921 | } | ||
| 1922 | return _len - len; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | /* Process a number of complete Feature Descriptors (Ext Compat or Ext Prop) */ | ||
| 1926 | static int __must_check ffs_do_os_descs(unsigned count, | ||
| 1927 | char *data, unsigned len, | ||
| 1928 | ffs_os_desc_callback entity, void *priv) | ||
| 1929 | { | ||
| 1930 | const unsigned _len = len; | ||
| 1931 | unsigned long num = 0; | ||
| 1932 | |||
| 1933 | ENTER(); | ||
| 1934 | |||
| 1935 | for (num = 0; num < count; ++num) { | ||
| 1936 | int ret; | ||
| 1937 | enum ffs_os_desc_type type; | ||
| 1938 | u16 feature_count; | ||
| 1939 | struct usb_os_desc_header *desc = (void *)data; | ||
| 1940 | |||
| 1941 | if (len < sizeof(*desc)) | ||
| 1942 | return -EINVAL; | ||
| 1943 | |||
| 1944 | /* | ||
| 1945 | * Record "descriptor" entity. | ||
| 1946 | * Process dwLength, bcdVersion, wIndex, get b/wCount. | ||
| 1947 | * Move the data pointer to the beginning of extended | ||
| 1948 | * compatibilities proper or extended properties proper | ||
| 1949 | * portions of the data | ||
| 1950 | */ | ||
| 1951 | if (le32_to_cpu(desc->dwLength) > len) | ||
| 1952 | return -EINVAL; | ||
| 1953 | |||
| 1954 | ret = __ffs_do_os_desc_header(&type, desc); | ||
| 1955 | if (unlikely(ret < 0)) { | ||
| 1956 | pr_debug("entity OS_DESCRIPTOR(%02lx); ret = %d\n", | ||
| 1957 | num, ret); | ||
| 1958 | return ret; | ||
| 1959 | } | ||
| 1960 | /* | ||
| 1961 | * 16-bit hex "?? 00" Little Endian looks like 8-bit hex "??" | ||
| 1962 | */ | ||
| 1963 | feature_count = le16_to_cpu(desc->wCount); | ||
| 1964 | if (type == FFS_OS_DESC_EXT_COMPAT && | ||
| 1965 | (feature_count > 255 || desc->Reserved)) | ||
| 1966 | return -EINVAL; | ||
| 1967 | len -= ret; | ||
| 1968 | data += ret; | ||
| 1969 | |||
| 1970 | /* | ||
| 1971 | * Process all function/property descriptors | ||
| 1972 | * of this Feature Descriptor | ||
| 1973 | */ | ||
| 1974 | ret = ffs_do_single_os_desc(data, len, type, | ||
| 1975 | feature_count, entity, priv, desc); | ||
| 1976 | if (unlikely(ret < 0)) { | ||
| 1977 | pr_debug("%s returns %d\n", __func__, ret); | ||
| 1978 | return ret; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | len -= ret; | ||
| 1982 | data += ret; | ||
| 1983 | } | ||
| 1984 | return _len - len; | ||
| 1985 | } | ||
| 1986 | |||
| 1987 | /** | ||
| 1988 | * Validate contents of the buffer from userspace related to OS descriptors. | ||
| 1989 | */ | ||
| 1990 | static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, | ||
| 1991 | struct usb_os_desc_header *h, void *data, | ||
| 1992 | unsigned len, void *priv) | ||
| 1993 | { | ||
| 1994 | struct ffs_data *ffs = priv; | ||
| 1995 | u8 length; | ||
| 1996 | |||
| 1997 | ENTER(); | ||
| 1998 | |||
| 1999 | switch (type) { | ||
| 2000 | case FFS_OS_DESC_EXT_COMPAT: { | ||
| 2001 | struct usb_ext_compat_desc *d = data; | ||
| 2002 | int i; | ||
| 2003 | |||
| 2004 | if (len < sizeof(*d) || | ||
| 2005 | d->bFirstInterfaceNumber >= ffs->interfaces_count || | ||
| 2006 | d->Reserved1) | ||
| 2007 | return -EINVAL; | ||
| 2008 | for (i = 0; i < ARRAY_SIZE(d->Reserved2); ++i) | ||
| 2009 | if (d->Reserved2[i]) | ||
| 2010 | return -EINVAL; | ||
| 2011 | |||
| 2012 | length = sizeof(struct usb_ext_compat_desc); | ||
| 2013 | } | ||
| 2014 | break; | ||
| 2015 | case FFS_OS_DESC_EXT_PROP: { | ||
| 2016 | struct usb_ext_prop_desc *d = data; | ||
| 2017 | u32 type, pdl; | ||
| 2018 | u16 pnl; | ||
| 2019 | |||
| 2020 | if (len < sizeof(*d) || h->interface >= ffs->interfaces_count) | ||
| 2021 | return -EINVAL; | ||
| 2022 | length = le32_to_cpu(d->dwSize); | ||
| 2023 | type = le32_to_cpu(d->dwPropertyDataType); | ||
| 2024 | if (type < USB_EXT_PROP_UNICODE || | ||
| 2025 | type > USB_EXT_PROP_UNICODE_MULTI) { | ||
| 2026 | pr_vdebug("unsupported os descriptor property type: %d", | ||
| 2027 | type); | ||
| 2028 | return -EINVAL; | ||
| 2029 | } | ||
| 2030 | pnl = le16_to_cpu(d->wPropertyNameLength); | ||
| 2031 | pdl = le32_to_cpu(*(u32 *)((u8 *)data + 10 + pnl)); | ||
| 2032 | if (length != 14 + pnl + pdl) { | ||
| 2033 | pr_vdebug("invalid os descriptor length: %d pnl:%d pdl:%d (descriptor %d)\n", | ||
| 2034 | length, pnl, pdl, type); | ||
| 2035 | return -EINVAL; | ||
| 2036 | } | ||
| 2037 | ++ffs->ms_os_descs_ext_prop_count; | ||
| 2038 | /* property name reported to the host as "WCHAR"s */ | ||
| 2039 | ffs->ms_os_descs_ext_prop_name_len += pnl * 2; | ||
| 2040 | ffs->ms_os_descs_ext_prop_data_len += pdl; | ||
| 2041 | } | ||
| 2042 | break; | ||
| 2043 | default: | ||
| 2044 | pr_vdebug("unknown descriptor: %d\n", type); | ||
| 2045 | return -EINVAL; | ||
| 2046 | } | ||
| 2047 | return length; | ||
| 2048 | } | ||
| 2049 | |||
| 1860 | static int __ffs_data_got_descs(struct ffs_data *ffs, | 2050 | static int __ffs_data_got_descs(struct ffs_data *ffs, |
| 1861 | char *const _data, size_t len) | 2051 | char *const _data, size_t len) |
| 1862 | { | 2052 | { |
| 1863 | char *data = _data, *raw_descs; | 2053 | char *data = _data, *raw_descs; |
| 1864 | unsigned counts[3], flags; | 2054 | unsigned os_descs_count = 0, counts[3], flags; |
| 1865 | int ret = -EINVAL, i; | 2055 | int ret = -EINVAL, i; |
| 1866 | 2056 | ||
| 1867 | ENTER(); | 2057 | ENTER(); |
| @@ -1879,7 +2069,8 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
| 1879 | flags = get_unaligned_le32(data + 8); | 2069 | flags = get_unaligned_le32(data + 8); |
| 1880 | if (flags & ~(FUNCTIONFS_HAS_FS_DESC | | 2070 | if (flags & ~(FUNCTIONFS_HAS_FS_DESC | |
| 1881 | FUNCTIONFS_HAS_HS_DESC | | 2071 | FUNCTIONFS_HAS_HS_DESC | |
| 1882 | FUNCTIONFS_HAS_SS_DESC)) { | 2072 | FUNCTIONFS_HAS_SS_DESC | |
| 2073 | FUNCTIONFS_HAS_MS_OS_DESC)) { | ||
| 1883 | ret = -ENOSYS; | 2074 | ret = -ENOSYS; |
| 1884 | goto error; | 2075 | goto error; |
| 1885 | } | 2076 | } |
| @@ -1902,6 +2093,11 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
| 1902 | len -= 4; | 2093 | len -= 4; |
| 1903 | } | 2094 | } |
| 1904 | } | 2095 | } |
| 2096 | if (flags & (1 << i)) { | ||
| 2097 | os_descs_count = get_unaligned_le32(data); | ||
| 2098 | data += 4; | ||
| 2099 | len -= 4; | ||
| 2100 | }; | ||
| 1905 | 2101 | ||
| 1906 | /* Read descriptors */ | 2102 | /* Read descriptors */ |
| 1907 | raw_descs = data; | 2103 | raw_descs = data; |
| @@ -1915,6 +2111,14 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
| 1915 | data += ret; | 2111 | data += ret; |
| 1916 | len -= ret; | 2112 | len -= ret; |
| 1917 | } | 2113 | } |
| 2114 | if (os_descs_count) { | ||
| 2115 | ret = ffs_do_os_descs(os_descs_count, data, len, | ||
| 2116 | __ffs_data_do_os_desc, ffs); | ||
| 2117 | if (ret < 0) | ||
| 2118 | goto error; | ||
| 2119 | data += ret; | ||
| 2120 | len -= ret; | ||
| 2121 | } | ||
| 1918 | 2122 | ||
| 1919 | if (raw_descs == data || len) { | 2123 | if (raw_descs == data || len) { |
| 1920 | ret = -EINVAL; | 2124 | ret = -EINVAL; |
| @@ -1927,6 +2131,7 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
| 1927 | ffs->fs_descs_count = counts[0]; | 2131 | ffs->fs_descs_count = counts[0]; |
| 1928 | ffs->hs_descs_count = counts[1]; | 2132 | ffs->hs_descs_count = counts[1]; |
| 1929 | ffs->ss_descs_count = counts[2]; | 2133 | ffs->ss_descs_count = counts[2]; |
| 2134 | ffs->ms_os_descs_count = os_descs_count; | ||
| 1930 | 2135 | ||
| 1931 | return 0; | 2136 | return 0; |
| 1932 | 2137 | ||
| @@ -2268,6 +2473,85 @@ static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep, | |||
| 2268 | return 0; | 2473 | return 0; |
| 2269 | } | 2474 | } |
| 2270 | 2475 | ||
| 2476 | static int __ffs_func_bind_do_os_desc(enum ffs_os_desc_type type, | ||
| 2477 | struct usb_os_desc_header *h, void *data, | ||
| 2478 | unsigned len, void *priv) | ||
| 2479 | { | ||
| 2480 | struct ffs_function *func = priv; | ||
| 2481 | u8 length = 0; | ||
| 2482 | |||
| 2483 | switch (type) { | ||
| 2484 | case FFS_OS_DESC_EXT_COMPAT: { | ||
| 2485 | struct usb_ext_compat_desc *desc = data; | ||
| 2486 | struct usb_os_desc_table *t; | ||
| 2487 | |||
| 2488 | t = &func->function.os_desc_table[desc->bFirstInterfaceNumber]; | ||
| 2489 | t->if_id = func->interfaces_nums[desc->bFirstInterfaceNumber]; | ||
| 2490 | memcpy(t->os_desc->ext_compat_id, &desc->CompatibleID, | ||
| 2491 | ARRAY_SIZE(desc->CompatibleID) + | ||
| 2492 | ARRAY_SIZE(desc->SubCompatibleID)); | ||
| 2493 | length = sizeof(*desc); | ||
| 2494 | } | ||
| 2495 | break; | ||
| 2496 | case FFS_OS_DESC_EXT_PROP: { | ||
| 2497 | struct usb_ext_prop_desc *desc = data; | ||
| 2498 | struct usb_os_desc_table *t; | ||
| 2499 | struct usb_os_desc_ext_prop *ext_prop; | ||
| 2500 | char *ext_prop_name; | ||
| 2501 | char *ext_prop_data; | ||
| 2502 | |||
| 2503 | t = &func->function.os_desc_table[h->interface]; | ||
| 2504 | t->if_id = func->interfaces_nums[h->interface]; | ||
| 2505 | |||
| 2506 | ext_prop = func->ffs->ms_os_descs_ext_prop_avail; | ||
| 2507 | func->ffs->ms_os_descs_ext_prop_avail += sizeof(*ext_prop); | ||
| 2508 | |||
| 2509 | ext_prop->type = le32_to_cpu(desc->dwPropertyDataType); | ||
| 2510 | ext_prop->name_len = le16_to_cpu(desc->wPropertyNameLength); | ||
| 2511 | ext_prop->data_len = le32_to_cpu(*(u32 *) | ||
| 2512 | usb_ext_prop_data_len_ptr(data, ext_prop->name_len)); | ||
| 2513 | length = ext_prop->name_len + ext_prop->data_len + 14; | ||
| 2514 | |||
| 2515 | ext_prop_name = func->ffs->ms_os_descs_ext_prop_name_avail; | ||
| 2516 | func->ffs->ms_os_descs_ext_prop_name_avail += | ||
| 2517 | ext_prop->name_len; | ||
| 2518 | |||
| 2519 | ext_prop_data = func->ffs->ms_os_descs_ext_prop_data_avail; | ||
| 2520 | func->ffs->ms_os_descs_ext_prop_data_avail += | ||
| 2521 | ext_prop->data_len; | ||
| 2522 | memcpy(ext_prop_data, | ||
| 2523 | usb_ext_prop_data_ptr(data, ext_prop->name_len), | ||
| 2524 | ext_prop->data_len); | ||
| 2525 | /* unicode data reported to the host as "WCHAR"s */ | ||
| 2526 | switch (ext_prop->type) { | ||
| 2527 | case USB_EXT_PROP_UNICODE: | ||
| 2528 | case USB_EXT_PROP_UNICODE_ENV: | ||
| 2529 | case USB_EXT_PROP_UNICODE_LINK: | ||
| 2530 | case USB_EXT_PROP_UNICODE_MULTI: | ||
| 2531 | ext_prop->data_len *= 2; | ||
| 2532 | break; | ||
| 2533 | } | ||
| 2534 | ext_prop->data = ext_prop_data; | ||
| 2535 | |||
| 2536 | memcpy(ext_prop_name, usb_ext_prop_name_ptr(data), | ||
| 2537 | ext_prop->name_len); | ||
| 2538 | /* property name reported to the host as "WCHAR"s */ | ||
| 2539 | ext_prop->name_len *= 2; | ||
| 2540 | ext_prop->name = ext_prop_name; | ||
| 2541 | |||
| 2542 | t->os_desc->ext_prop_len += | ||
| 2543 | ext_prop->name_len + ext_prop->data_len + 14; | ||
| 2544 | ++t->os_desc->ext_prop_count; | ||
| 2545 | list_add_tail(&ext_prop->entry, &t->os_desc->ext_prop); | ||
| 2546 | } | ||
| 2547 | break; | ||
| 2548 | default: | ||
| 2549 | pr_vdebug("unknown descriptor: %d\n", type); | ||
| 2550 | } | ||
| 2551 | |||
| 2552 | return length; | ||
| 2553 | } | ||
| 2554 | |||
| 2271 | static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f, | 2555 | static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f, |
| 2272 | struct usb_configuration *c) | 2556 | struct usb_configuration *c) |
| 2273 | { | 2557 | { |
| @@ -2329,7 +2613,7 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
| 2329 | const int super = gadget_is_superspeed(func->gadget) && | 2613 | const int super = gadget_is_superspeed(func->gadget) && |
| 2330 | func->ffs->ss_descs_count; | 2614 | func->ffs->ss_descs_count; |
| 2331 | 2615 | ||
| 2332 | int fs_len, hs_len, ret; | 2616 | int fs_len, hs_len, ss_len, ret, i; |
| 2333 | 2617 | ||
| 2334 | /* Make it a single chunk, less management later on */ | 2618 | /* Make it a single chunk, less management later on */ |
| 2335 | vla_group(d); | 2619 | vla_group(d); |
| @@ -2341,6 +2625,18 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
| 2341 | vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs, | 2625 | vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs, |
| 2342 | super ? ffs->ss_descs_count + 1 : 0); | 2626 | super ? ffs->ss_descs_count + 1 : 0); |
| 2343 | vla_item_with_sz(d, short, inums, ffs->interfaces_count); | 2627 | vla_item_with_sz(d, short, inums, ffs->interfaces_count); |
| 2628 | vla_item_with_sz(d, struct usb_os_desc_table, os_desc_table, | ||
| 2629 | c->cdev->use_os_string ? ffs->interfaces_count : 0); | ||
| 2630 | vla_item_with_sz(d, char[16], ext_compat, | ||
| 2631 | c->cdev->use_os_string ? ffs->interfaces_count : 0); | ||
| 2632 | vla_item_with_sz(d, struct usb_os_desc, os_desc, | ||
| 2633 | c->cdev->use_os_string ? ffs->interfaces_count : 0); | ||
| 2634 | vla_item_with_sz(d, struct usb_os_desc_ext_prop, ext_prop, | ||
| 2635 | ffs->ms_os_descs_ext_prop_count); | ||
| 2636 | vla_item_with_sz(d, char, ext_prop_name, | ||
| 2637 | ffs->ms_os_descs_ext_prop_name_len); | ||
| 2638 | vla_item_with_sz(d, char, ext_prop_data, | ||
| 2639 | ffs->ms_os_descs_ext_prop_data_len); | ||
| 2344 | vla_item_with_sz(d, char, raw_descs, ffs->raw_descs_length); | 2640 | vla_item_with_sz(d, char, raw_descs, ffs->raw_descs_length); |
| 2345 | char *vlabuf; | 2641 | char *vlabuf; |
| 2346 | 2642 | ||
| @@ -2351,12 +2647,16 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
| 2351 | return -ENOTSUPP; | 2647 | return -ENOTSUPP; |
| 2352 | 2648 | ||
| 2353 | /* Allocate a single chunk, less management later on */ | 2649 | /* Allocate a single chunk, less management later on */ |
| 2354 | vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL); | 2650 | vlabuf = kzalloc(vla_group_size(d), GFP_KERNEL); |
| 2355 | if (unlikely(!vlabuf)) | 2651 | if (unlikely(!vlabuf)) |
| 2356 | return -ENOMEM; | 2652 | return -ENOMEM; |
| 2357 | 2653 | ||
| 2358 | /* Zero */ | 2654 | ffs->ms_os_descs_ext_prop_avail = vla_ptr(vlabuf, d, ext_prop); |
| 2359 | memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz); | 2655 | ffs->ms_os_descs_ext_prop_name_avail = |
| 2656 | vla_ptr(vlabuf, d, ext_prop_name); | ||
| 2657 | ffs->ms_os_descs_ext_prop_data_avail = | ||
| 2658 | vla_ptr(vlabuf, d, ext_prop_data); | ||
| 2659 | |||
| 2360 | /* Copy descriptors */ | 2660 | /* Copy descriptors */ |
| 2361 | memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs, | 2661 | memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs, |
| 2362 | ffs->raw_descs_length); | 2662 | ffs->raw_descs_length); |
| @@ -2410,12 +2710,16 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
| 2410 | 2710 | ||
| 2411 | if (likely(super)) { | 2711 | if (likely(super)) { |
| 2412 | func->function.ss_descriptors = vla_ptr(vlabuf, d, ss_descs); | 2712 | func->function.ss_descriptors = vla_ptr(vlabuf, d, ss_descs); |
| 2413 | ret = ffs_do_descs(ffs->ss_descs_count, | 2713 | ss_len = ffs_do_descs(ffs->ss_descs_count, |
| 2414 | vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len, | 2714 | vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len, |
| 2415 | d_raw_descs__sz - fs_len - hs_len, | 2715 | d_raw_descs__sz - fs_len - hs_len, |
| 2416 | __ffs_func_bind_do_descs, func); | 2716 | __ffs_func_bind_do_descs, func); |
| 2417 | if (unlikely(ret < 0)) | 2717 | if (unlikely(ss_len < 0)) { |
| 2718 | ret = ss_len; | ||
| 2418 | goto error; | 2719 | goto error; |
| 2720 | } | ||
| 2721 | } else { | ||
| 2722 | ss_len = 0; | ||
| 2419 | } | 2723 | } |
| 2420 | 2724 | ||
| 2421 | /* | 2725 | /* |
| @@ -2431,6 +2735,28 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
| 2431 | if (unlikely(ret < 0)) | 2735 | if (unlikely(ret < 0)) |
| 2432 | goto error; | 2736 | goto error; |
| 2433 | 2737 | ||
| 2738 | func->function.os_desc_table = vla_ptr(vlabuf, d, os_desc_table); | ||
| 2739 | if (c->cdev->use_os_string) | ||
| 2740 | for (i = 0; i < ffs->interfaces_count; ++i) { | ||
| 2741 | struct usb_os_desc *desc; | ||
| 2742 | |||
| 2743 | desc = func->function.os_desc_table[i].os_desc = | ||
| 2744 | vla_ptr(vlabuf, d, os_desc) + | ||
| 2745 | i * sizeof(struct usb_os_desc); | ||
| 2746 | desc->ext_compat_id = | ||
| 2747 | vla_ptr(vlabuf, d, ext_compat) + i * 16; | ||
| 2748 | INIT_LIST_HEAD(&desc->ext_prop); | ||
| 2749 | } | ||
| 2750 | ret = ffs_do_os_descs(ffs->ms_os_descs_count, | ||
| 2751 | vla_ptr(vlabuf, d, raw_descs) + | ||
| 2752 | fs_len + hs_len + ss_len, | ||
| 2753 | d_raw_descs__sz - fs_len - hs_len - ss_len, | ||
| 2754 | __ffs_func_bind_do_os_desc, func); | ||
| 2755 | if (unlikely(ret < 0)) | ||
| 2756 | goto error; | ||
| 2757 | func->function.os_desc_n = | ||
| 2758 | c->cdev->use_os_string ? ffs->interfaces_count : 0; | ||
| 2759 | |||
| 2434 | /* And we're done */ | 2760 | /* And we're done */ |
| 2435 | ffs_event_add(ffs, FUNCTIONFS_BIND); | 2761 | ffs_event_add(ffs, FUNCTIONFS_BIND); |
| 2436 | return 0; | 2762 | return 0; |
| @@ -2901,12 +3227,12 @@ static void *ffs_acquire_dev(const char *dev_name) | |||
| 2901 | 3227 | ||
| 2902 | ffs_dev = _ffs_find_dev(dev_name); | 3228 | ffs_dev = _ffs_find_dev(dev_name); |
| 2903 | if (!ffs_dev) | 3229 | if (!ffs_dev) |
| 2904 | ffs_dev = ERR_PTR(-ENODEV); | 3230 | ffs_dev = ERR_PTR(-ENOENT); |
| 2905 | else if (ffs_dev->mounted) | 3231 | else if (ffs_dev->mounted) |
| 2906 | ffs_dev = ERR_PTR(-EBUSY); | 3232 | ffs_dev = ERR_PTR(-EBUSY); |
| 2907 | else if (ffs_dev->ffs_acquire_dev_callback && | 3233 | else if (ffs_dev->ffs_acquire_dev_callback && |
| 2908 | ffs_dev->ffs_acquire_dev_callback(ffs_dev)) | 3234 | ffs_dev->ffs_acquire_dev_callback(ffs_dev)) |
| 2909 | ffs_dev = ERR_PTR(-ENODEV); | 3235 | ffs_dev = ERR_PTR(-ENOENT); |
| 2910 | else | 3236 | else |
| 2911 | ffs_dev->mounted = true; | 3237 | ffs_dev->mounted = true; |
| 2912 | 3238 | ||
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/function/f_hid.c index a95290a1289f..a95290a1289f 100644 --- a/drivers/usb/gadget/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c | |||
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index 4557cd03f0b1..4557cd03f0b1 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c | |||
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index b96393908860..b96393908860 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c | |||
diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h index b4866fcef30b..b4866fcef30b 100644 --- a/drivers/usb/gadget/f_mass_storage.h +++ b/drivers/usb/gadget/function/f_mass_storage.h | |||
diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 807b31c0edc3..807b31c0edc3 100644 --- a/drivers/usb/gadget/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c | |||
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index a9499fd30792..bcdc882cd415 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c | |||
| @@ -68,6 +68,18 @@ struct f_ncm { | |||
| 68 | * callback and ethernet open/close | 68 | * callback and ethernet open/close |
| 69 | */ | 69 | */ |
| 70 | spinlock_t lock; | 70 | spinlock_t lock; |
| 71 | |||
| 72 | struct net_device *netdev; | ||
| 73 | |||
| 74 | /* For multi-frame NDP TX */ | ||
| 75 | struct sk_buff *skb_tx_data; | ||
| 76 | struct sk_buff *skb_tx_ndp; | ||
| 77 | u16 ndp_dgram_count; | ||
| 78 | bool timer_force_tx; | ||
| 79 | struct tasklet_struct tx_tasklet; | ||
| 80 | struct hrtimer task_timer; | ||
| 81 | |||
| 82 | bool timer_stopping; | ||
| 71 | }; | 83 | }; |
| 72 | 84 | ||
| 73 | static inline struct f_ncm *func_to_ncm(struct usb_function *f) | 85 | static inline struct f_ncm *func_to_ncm(struct usb_function *f) |
| @@ -92,15 +104,20 @@ static inline unsigned ncm_bitrate(struct usb_gadget *g) | |||
| 92 | * If the host can group frames, allow it to do that, 16K is selected, | 104 | * If the host can group frames, allow it to do that, 16K is selected, |
| 93 | * because it's used by default by the current linux host driver | 105 | * because it's used by default by the current linux host driver |
| 94 | */ | 106 | */ |
| 95 | #define NTB_DEFAULT_IN_SIZE USB_CDC_NCM_NTB_MIN_IN_SIZE | 107 | #define NTB_DEFAULT_IN_SIZE 16384 |
| 96 | #define NTB_OUT_SIZE 16384 | 108 | #define NTB_OUT_SIZE 16384 |
| 97 | 109 | ||
| 98 | /* | 110 | /* Allocation for storing the NDP, 32 should suffice for a |
| 99 | * skbs of size less than that will not be aligned | 111 | * 16k packet. This allows a maximum of 32 * 507 Byte packets to |
| 100 | * to NCM's dwNtbInMaxSize to save bus bandwidth | 112 | * be transmitted in a single 16kB skb, though when sending full size |
| 113 | * packets this limit will be plenty. | ||
| 114 | * Smaller packets are not likely to be trying to maximize the | ||
| 115 | * throughput and will be mstly sending smaller infrequent frames. | ||
| 101 | */ | 116 | */ |
| 117 | #define TX_MAX_NUM_DPE 32 | ||
| 102 | 118 | ||
| 103 | #define MAX_TX_NONFIXED (512 * 3) | 119 | /* Delay for the transmit to wait before sending an unfilled NTB frame. */ |
| 120 | #define TX_TIMEOUT_NSECS 300000 | ||
| 104 | 121 | ||
| 105 | #define FORMATS_SUPPORTED (USB_CDC_NCM_NTB16_SUPPORTED | \ | 122 | #define FORMATS_SUPPORTED (USB_CDC_NCM_NTB16_SUPPORTED | \ |
| 106 | USB_CDC_NCM_NTB32_SUPPORTED) | 123 | USB_CDC_NCM_NTB32_SUPPORTED) |
| @@ -355,14 +372,15 @@ struct ndp_parser_opts { | |||
| 355 | u32 ndp_sign; | 372 | u32 ndp_sign; |
| 356 | unsigned nth_size; | 373 | unsigned nth_size; |
| 357 | unsigned ndp_size; | 374 | unsigned ndp_size; |
| 375 | unsigned dpe_size; | ||
| 358 | unsigned ndplen_align; | 376 | unsigned ndplen_align; |
| 359 | /* sizes in u16 units */ | 377 | /* sizes in u16 units */ |
| 360 | unsigned dgram_item_len; /* index or length */ | 378 | unsigned dgram_item_len; /* index or length */ |
| 361 | unsigned block_length; | 379 | unsigned block_length; |
| 362 | unsigned fp_index; | 380 | unsigned ndp_index; |
| 363 | unsigned reserved1; | 381 | unsigned reserved1; |
| 364 | unsigned reserved2; | 382 | unsigned reserved2; |
| 365 | unsigned next_fp_index; | 383 | unsigned next_ndp_index; |
| 366 | }; | 384 | }; |
| 367 | 385 | ||
| 368 | #define INIT_NDP16_OPTS { \ | 386 | #define INIT_NDP16_OPTS { \ |
| @@ -370,13 +388,14 @@ struct ndp_parser_opts { | |||
| 370 | .ndp_sign = USB_CDC_NCM_NDP16_NOCRC_SIGN, \ | 388 | .ndp_sign = USB_CDC_NCM_NDP16_NOCRC_SIGN, \ |
| 371 | .nth_size = sizeof(struct usb_cdc_ncm_nth16), \ | 389 | .nth_size = sizeof(struct usb_cdc_ncm_nth16), \ |
| 372 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \ | 390 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \ |
| 391 | .dpe_size = sizeof(struct usb_cdc_ncm_dpe16), \ | ||
| 373 | .ndplen_align = 4, \ | 392 | .ndplen_align = 4, \ |
| 374 | .dgram_item_len = 1, \ | 393 | .dgram_item_len = 1, \ |
| 375 | .block_length = 1, \ | 394 | .block_length = 1, \ |
| 376 | .fp_index = 1, \ | 395 | .ndp_index = 1, \ |
| 377 | .reserved1 = 0, \ | 396 | .reserved1 = 0, \ |
| 378 | .reserved2 = 0, \ | 397 | .reserved2 = 0, \ |
| 379 | .next_fp_index = 1, \ | 398 | .next_ndp_index = 1, \ |
| 380 | } | 399 | } |
| 381 | 400 | ||
| 382 | 401 | ||
| @@ -385,13 +404,14 @@ struct ndp_parser_opts { | |||
| 385 | .ndp_sign = USB_CDC_NCM_NDP32_NOCRC_SIGN, \ | 404 | .ndp_sign = USB_CDC_NCM_NDP32_NOCRC_SIGN, \ |
| 386 | .nth_size = sizeof(struct usb_cdc_ncm_nth32), \ | 405 | .nth_size = sizeof(struct usb_cdc_ncm_nth32), \ |
| 387 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \ | 406 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \ |
| 407 | .dpe_size = sizeof(struct usb_cdc_ncm_dpe32), \ | ||
| 388 | .ndplen_align = 8, \ | 408 | .ndplen_align = 8, \ |
| 389 | .dgram_item_len = 2, \ | 409 | .dgram_item_len = 2, \ |
| 390 | .block_length = 2, \ | 410 | .block_length = 2, \ |
| 391 | .fp_index = 2, \ | 411 | .ndp_index = 2, \ |
| 392 | .reserved1 = 1, \ | 412 | .reserved1 = 1, \ |
| 393 | .reserved2 = 2, \ | 413 | .reserved2 = 2, \ |
| 394 | .next_fp_index = 2, \ | 414 | .next_ndp_index = 2, \ |
| 395 | } | 415 | } |
| 396 | 416 | ||
| 397 | static const struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS; | 417 | static const struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS; |
| @@ -803,6 +823,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
| 803 | 823 | ||
| 804 | if (ncm->port.in_ep->driver_data) { | 824 | if (ncm->port.in_ep->driver_data) { |
| 805 | DBG(cdev, "reset ncm\n"); | 825 | DBG(cdev, "reset ncm\n"); |
| 826 | ncm->timer_stopping = true; | ||
| 827 | ncm->netdev = NULL; | ||
| 806 | gether_disconnect(&ncm->port); | 828 | gether_disconnect(&ncm->port); |
| 807 | ncm_reset_values(ncm); | 829 | ncm_reset_values(ncm); |
| 808 | } | 830 | } |
| @@ -839,6 +861,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
| 839 | net = gether_connect(&ncm->port); | 861 | net = gether_connect(&ncm->port); |
| 840 | if (IS_ERR(net)) | 862 | if (IS_ERR(net)) |
| 841 | return PTR_ERR(net); | 863 | return PTR_ERR(net); |
| 864 | ncm->netdev = net; | ||
| 865 | ncm->timer_stopping = false; | ||
| 842 | } | 866 | } |
| 843 | 867 | ||
| 844 | spin_lock(&ncm->lock); | 868 | spin_lock(&ncm->lock); |
| @@ -865,95 +889,232 @@ static int ncm_get_alt(struct usb_function *f, unsigned intf) | |||
| 865 | return ncm->port.in_ep->driver_data ? 1 : 0; | 889 | return ncm->port.in_ep->driver_data ? 1 : 0; |
| 866 | } | 890 | } |
| 867 | 891 | ||
| 892 | static struct sk_buff *package_for_tx(struct f_ncm *ncm) | ||
| 893 | { | ||
| 894 | __le16 *ntb_iter; | ||
| 895 | struct sk_buff *skb2 = NULL; | ||
| 896 | unsigned ndp_pad; | ||
| 897 | unsigned ndp_index; | ||
| 898 | unsigned new_len; | ||
| 899 | |||
| 900 | const struct ndp_parser_opts *opts = ncm->parser_opts; | ||
| 901 | const int ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment); | ||
| 902 | const int dgram_idx_len = 2 * 2 * opts->dgram_item_len; | ||
| 903 | |||
| 904 | /* Stop the timer */ | ||
| 905 | hrtimer_try_to_cancel(&ncm->task_timer); | ||
| 906 | |||
| 907 | ndp_pad = ALIGN(ncm->skb_tx_data->len, ndp_align) - | ||
| 908 | ncm->skb_tx_data->len; | ||
| 909 | ndp_index = ncm->skb_tx_data->len + ndp_pad; | ||
| 910 | new_len = ndp_index + dgram_idx_len + ncm->skb_tx_ndp->len; | ||
| 911 | |||
| 912 | /* Set the final BlockLength and wNdpIndex */ | ||
| 913 | ntb_iter = (void *) ncm->skb_tx_data->data; | ||
| 914 | /* Increment pointer to BlockLength */ | ||
| 915 | ntb_iter += 2 + 1 + 1; | ||
| 916 | put_ncm(&ntb_iter, opts->block_length, new_len); | ||
| 917 | put_ncm(&ntb_iter, opts->ndp_index, ndp_index); | ||
| 918 | |||
| 919 | /* Set the final NDP wLength */ | ||
| 920 | new_len = opts->ndp_size + | ||
| 921 | (ncm->ndp_dgram_count * dgram_idx_len); | ||
| 922 | ncm->ndp_dgram_count = 0; | ||
| 923 | /* Increment from start to wLength */ | ||
| 924 | ntb_iter = (void *) ncm->skb_tx_ndp->data; | ||
| 925 | ntb_iter += 2; | ||
| 926 | put_unaligned_le16(new_len, ntb_iter); | ||
| 927 | |||
| 928 | /* Merge the skbs */ | ||
| 929 | swap(skb2, ncm->skb_tx_data); | ||
| 930 | if (ncm->skb_tx_data) { | ||
| 931 | dev_kfree_skb_any(ncm->skb_tx_data); | ||
| 932 | ncm->skb_tx_data = NULL; | ||
| 933 | } | ||
| 934 | |||
| 935 | /* Insert NDP alignment. */ | ||
| 936 | ntb_iter = (void *) skb_put(skb2, ndp_pad); | ||
| 937 | memset(ntb_iter, 0, ndp_pad); | ||
| 938 | |||
| 939 | /* Copy NTB across. */ | ||
| 940 | ntb_iter = (void *) skb_put(skb2, ncm->skb_tx_ndp->len); | ||
| 941 | memcpy(ntb_iter, ncm->skb_tx_ndp->data, ncm->skb_tx_ndp->len); | ||
| 942 | dev_kfree_skb_any(ncm->skb_tx_ndp); | ||
| 943 | ncm->skb_tx_ndp = NULL; | ||
| 944 | |||
| 945 | /* Insert zero'd datagram. */ | ||
| 946 | ntb_iter = (void *) skb_put(skb2, dgram_idx_len); | ||
| 947 | memset(ntb_iter, 0, dgram_idx_len); | ||
| 948 | |||
| 949 | return skb2; | ||
| 950 | } | ||
| 951 | |||
| 868 | static struct sk_buff *ncm_wrap_ntb(struct gether *port, | 952 | static struct sk_buff *ncm_wrap_ntb(struct gether *port, |
| 869 | struct sk_buff *skb) | 953 | struct sk_buff *skb) |
| 870 | { | 954 | { |
| 871 | struct f_ncm *ncm = func_to_ncm(&port->func); | 955 | struct f_ncm *ncm = func_to_ncm(&port->func); |
| 872 | struct sk_buff *skb2; | 956 | struct sk_buff *skb2 = NULL; |
| 873 | int ncb_len = 0; | 957 | int ncb_len = 0; |
| 874 | __le16 *tmp; | 958 | __le16 *ntb_data; |
| 875 | int div; | 959 | __le16 *ntb_ndp; |
| 876 | int rem; | 960 | int dgram_pad; |
| 877 | int pad; | 961 | |
| 878 | int ndp_align; | ||
| 879 | int ndp_pad; | ||
| 880 | unsigned max_size = ncm->port.fixed_in_len; | 962 | unsigned max_size = ncm->port.fixed_in_len; |
| 881 | const struct ndp_parser_opts *opts = ncm->parser_opts; | 963 | const struct ndp_parser_opts *opts = ncm->parser_opts; |
| 882 | unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; | 964 | const int ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment); |
| 883 | 965 | const int div = le16_to_cpu(ntb_parameters.wNdpInDivisor); | |
| 884 | div = le16_to_cpu(ntb_parameters.wNdpInDivisor); | 966 | const int rem = le16_to_cpu(ntb_parameters.wNdpInPayloadRemainder); |
| 885 | rem = le16_to_cpu(ntb_parameters.wNdpInPayloadRemainder); | 967 | const int dgram_idx_len = 2 * 2 * opts->dgram_item_len; |
| 886 | ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment); | ||
| 887 | 968 | ||
| 888 | ncb_len += opts->nth_size; | 969 | if (!skb && !ncm->skb_tx_data) |
| 889 | ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len; | ||
| 890 | ncb_len += ndp_pad; | ||
| 891 | ncb_len += opts->ndp_size; | ||
| 892 | ncb_len += 2 * 2 * opts->dgram_item_len; /* Datagram entry */ | ||
| 893 | ncb_len += 2 * 2 * opts->dgram_item_len; /* Zero datagram entry */ | ||
| 894 | pad = ALIGN(ncb_len, div) + rem - ncb_len; | ||
| 895 | ncb_len += pad; | ||
| 896 | |||
| 897 | if (ncb_len + skb->len + crc_len > max_size) { | ||
| 898 | dev_kfree_skb_any(skb); | ||
| 899 | return NULL; | 970 | return NULL; |
| 900 | } | ||
| 901 | 971 | ||
| 902 | skb2 = skb_copy_expand(skb, ncb_len, | 972 | if (skb) { |
| 903 | max_size - skb->len - ncb_len - crc_len, | 973 | /* Add the CRC if required up front */ |
| 904 | GFP_ATOMIC); | 974 | if (ncm->is_crc) { |
| 905 | dev_kfree_skb_any(skb); | 975 | uint32_t crc; |
| 906 | if (!skb2) | 976 | __le16 *crc_pos; |
| 907 | return NULL; | 977 | |
| 978 | crc = ~crc32_le(~0, | ||
| 979 | skb->data, | ||
| 980 | skb->len); | ||
| 981 | crc_pos = (void *) skb_put(skb, sizeof(uint32_t)); | ||
| 982 | put_unaligned_le32(crc, crc_pos); | ||
| 983 | } | ||
| 908 | 984 | ||
| 909 | skb = skb2; | 985 | /* If the new skb is too big for the current NCM NTB then |
| 986 | * set the current stored skb to be sent now and clear it | ||
| 987 | * ready for new data. | ||
| 988 | * NOTE: Assume maximum align for speed of calculation. | ||
| 989 | */ | ||
| 990 | if (ncm->skb_tx_data | ||
| 991 | && (ncm->ndp_dgram_count >= TX_MAX_NUM_DPE | ||
| 992 | || (ncm->skb_tx_data->len + | ||
| 993 | div + rem + skb->len + | ||
| 994 | ncm->skb_tx_ndp->len + ndp_align + (2 * dgram_idx_len)) | ||
| 995 | > max_size)) { | ||
| 996 | skb2 = package_for_tx(ncm); | ||
| 997 | if (!skb2) | ||
| 998 | goto err; | ||
| 999 | } | ||
| 910 | 1000 | ||
| 911 | tmp = (void *) skb_push(skb, ncb_len); | 1001 | if (!ncm->skb_tx_data) { |
| 912 | memset(tmp, 0, ncb_len); | 1002 | ncb_len = opts->nth_size; |
| 1003 | dgram_pad = ALIGN(ncb_len, div) + rem - ncb_len; | ||
| 1004 | ncb_len += dgram_pad; | ||
| 913 | 1005 | ||
| 914 | put_unaligned_le32(opts->nth_sign, tmp); /* dwSignature */ | 1006 | /* Create a new skb for the NTH and datagrams. */ |
| 915 | tmp += 2; | 1007 | ncm->skb_tx_data = alloc_skb(max_size, GFP_ATOMIC); |
| 916 | /* wHeaderLength */ | 1008 | if (!ncm->skb_tx_data) |
| 917 | put_unaligned_le16(opts->nth_size, tmp++); | 1009 | goto err; |
| 918 | tmp++; /* skip wSequence */ | ||
| 919 | put_ncm(&tmp, opts->block_length, skb->len); /* (d)wBlockLength */ | ||
| 920 | /* (d)wFpIndex */ | ||
| 921 | /* the first pointer is right after the NTH + align */ | ||
| 922 | put_ncm(&tmp, opts->fp_index, opts->nth_size + ndp_pad); | ||
| 923 | 1010 | ||
| 924 | tmp = (void *)tmp + ndp_pad; | 1011 | ntb_data = (void *) skb_put(ncm->skb_tx_data, ncb_len); |
| 1012 | memset(ntb_data, 0, ncb_len); | ||
| 1013 | /* dwSignature */ | ||
| 1014 | put_unaligned_le32(opts->nth_sign, ntb_data); | ||
| 1015 | ntb_data += 2; | ||
| 1016 | /* wHeaderLength */ | ||
| 1017 | put_unaligned_le16(opts->nth_size, ntb_data++); | ||
| 1018 | |||
| 1019 | /* Allocate an skb for storing the NDP, | ||
| 1020 | * TX_MAX_NUM_DPE should easily suffice for a | ||
| 1021 | * 16k packet. | ||
| 1022 | */ | ||
| 1023 | ncm->skb_tx_ndp = alloc_skb((int)(opts->ndp_size | ||
| 1024 | + opts->dpe_size | ||
| 1025 | * TX_MAX_NUM_DPE), | ||
| 1026 | GFP_ATOMIC); | ||
| 1027 | if (!ncm->skb_tx_ndp) | ||
| 1028 | goto err; | ||
| 1029 | ntb_ndp = (void *) skb_put(ncm->skb_tx_ndp, | ||
| 1030 | opts->ndp_size); | ||
| 1031 | memset(ntb_ndp, 0, ncb_len); | ||
| 1032 | /* dwSignature */ | ||
| 1033 | put_unaligned_le32(ncm->ndp_sign, ntb_ndp); | ||
| 1034 | ntb_ndp += 2; | ||
| 925 | 1035 | ||
| 926 | /* NDP */ | 1036 | /* There is always a zeroed entry */ |
| 927 | put_unaligned_le32(ncm->ndp_sign, tmp); /* dwSignature */ | 1037 | ncm->ndp_dgram_count = 1; |
| 928 | tmp += 2; | ||
| 929 | /* wLength */ | ||
| 930 | put_unaligned_le16(ncb_len - opts->nth_size - pad, tmp++); | ||
| 931 | 1038 | ||
| 932 | tmp += opts->reserved1; | 1039 | /* Note: we skip opts->next_ndp_index */ |
| 933 | tmp += opts->next_fp_index; /* skip reserved (d)wNextFpIndex */ | 1040 | } |
| 934 | tmp += opts->reserved2; | ||
| 935 | 1041 | ||
| 936 | if (ncm->is_crc) { | 1042 | /* Delay the timer. */ |
| 937 | uint32_t crc; | 1043 | hrtimer_start(&ncm->task_timer, |
| 1044 | ktime_set(0, TX_TIMEOUT_NSECS), | ||
| 1045 | HRTIMER_MODE_REL); | ||
| 1046 | |||
| 1047 | /* Add the datagram position entries */ | ||
| 1048 | ntb_ndp = (void *) skb_put(ncm->skb_tx_ndp, dgram_idx_len); | ||
| 1049 | memset(ntb_ndp, 0, dgram_idx_len); | ||
| 1050 | |||
| 1051 | ncb_len = ncm->skb_tx_data->len; | ||
| 1052 | dgram_pad = ALIGN(ncb_len, div) + rem - ncb_len; | ||
| 1053 | ncb_len += dgram_pad; | ||
| 1054 | |||
| 1055 | /* (d)wDatagramIndex */ | ||
| 1056 | put_ncm(&ntb_ndp, opts->dgram_item_len, ncb_len); | ||
| 1057 | /* (d)wDatagramLength */ | ||
| 1058 | put_ncm(&ntb_ndp, opts->dgram_item_len, skb->len); | ||
| 1059 | ncm->ndp_dgram_count++; | ||
| 1060 | |||
| 1061 | /* Add the new data to the skb */ | ||
| 1062 | ntb_data = (void *) skb_put(ncm->skb_tx_data, dgram_pad); | ||
| 1063 | memset(ntb_data, 0, dgram_pad); | ||
| 1064 | ntb_data = (void *) skb_put(ncm->skb_tx_data, skb->len); | ||
| 1065 | memcpy(ntb_data, skb->data, skb->len); | ||
| 1066 | dev_kfree_skb_any(skb); | ||
| 1067 | skb = NULL; | ||
| 938 | 1068 | ||
| 939 | crc = ~crc32_le(~0, | 1069 | } else if (ncm->skb_tx_data && ncm->timer_force_tx) { |
| 940 | skb->data + ncb_len, | 1070 | /* If the tx was requested because of a timeout then send */ |
| 941 | skb->len - ncb_len); | 1071 | skb2 = package_for_tx(ncm); |
| 942 | put_unaligned_le32(crc, skb->data + skb->len); | 1072 | if (!skb2) |
| 943 | skb_put(skb, crc_len); | 1073 | goto err; |
| 944 | } | 1074 | } |
| 945 | 1075 | ||
| 946 | /* (d)wDatagramIndex[0] */ | 1076 | return skb2; |
| 947 | put_ncm(&tmp, opts->dgram_item_len, ncb_len); | ||
| 948 | /* (d)wDatagramLength[0] */ | ||
| 949 | put_ncm(&tmp, opts->dgram_item_len, skb->len - ncb_len); | ||
| 950 | /* (d)wDatagramIndex[1] and (d)wDatagramLength[1] already zeroed */ | ||
| 951 | 1077 | ||
| 952 | if (skb->len > MAX_TX_NONFIXED) | 1078 | err: |
| 953 | memset(skb_put(skb, max_size - skb->len), | 1079 | ncm->netdev->stats.tx_dropped++; |
| 954 | 0, max_size - skb->len); | 1080 | |
| 1081 | if (skb) | ||
| 1082 | dev_kfree_skb_any(skb); | ||
| 1083 | if (ncm->skb_tx_data) | ||
| 1084 | dev_kfree_skb_any(ncm->skb_tx_data); | ||
| 1085 | if (ncm->skb_tx_ndp) | ||
| 1086 | dev_kfree_skb_any(ncm->skb_tx_ndp); | ||
| 955 | 1087 | ||
| 956 | return skb; | 1088 | return NULL; |
| 1089 | } | ||
| 1090 | |||
| 1091 | /* | ||
| 1092 | * This transmits the NTB if there are frames waiting. | ||
| 1093 | */ | ||
| 1094 | static void ncm_tx_tasklet(unsigned long data) | ||
| 1095 | { | ||
| 1096 | struct f_ncm *ncm = (void *)data; | ||
| 1097 | |||
| 1098 | if (ncm->timer_stopping) | ||
| 1099 | return; | ||
| 1100 | |||
| 1101 | /* Only send if data is available. */ | ||
| 1102 | if (ncm->skb_tx_data) { | ||
| 1103 | ncm->timer_force_tx = true; | ||
| 1104 | ncm->netdev->netdev_ops->ndo_start_xmit(NULL, ncm->netdev); | ||
| 1105 | ncm->timer_force_tx = false; | ||
| 1106 | } | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | /* | ||
| 1110 | * The transmit should only be run if no skb data has been sent | ||
| 1111 | * for a certain duration. | ||
| 1112 | */ | ||
| 1113 | static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data) | ||
| 1114 | { | ||
| 1115 | struct f_ncm *ncm = container_of(data, struct f_ncm, task_timer); | ||
| 1116 | tasklet_schedule(&ncm->tx_tasklet); | ||
| 1117 | return HRTIMER_NORESTART; | ||
| 957 | } | 1118 | } |
| 958 | 1119 | ||
| 959 | static int ncm_unwrap_ntb(struct gether *port, | 1120 | static int ncm_unwrap_ntb(struct gether *port, |
| @@ -963,6 +1124,7 @@ static int ncm_unwrap_ntb(struct gether *port, | |||
| 963 | struct f_ncm *ncm = func_to_ncm(&port->func); | 1124 | struct f_ncm *ncm = func_to_ncm(&port->func); |
| 964 | __le16 *tmp = (void *) skb->data; | 1125 | __le16 *tmp = (void *) skb->data; |
| 965 | unsigned index, index2; | 1126 | unsigned index, index2; |
| 1127 | int ndp_index; | ||
| 966 | unsigned dg_len, dg_len2; | 1128 | unsigned dg_len, dg_len2; |
| 967 | unsigned ndp_len; | 1129 | unsigned ndp_len; |
| 968 | struct sk_buff *skb2; | 1130 | struct sk_buff *skb2; |
| @@ -995,91 +1157,101 @@ static int ncm_unwrap_ntb(struct gether *port, | |||
| 995 | goto err; | 1157 | goto err; |
| 996 | } | 1158 | } |
| 997 | 1159 | ||
| 998 | index = get_ncm(&tmp, opts->fp_index); | 1160 | ndp_index = get_ncm(&tmp, opts->ndp_index); |
| 999 | /* NCM 3.2 */ | ||
| 1000 | if (((index % 4) != 0) && (index < opts->nth_size)) { | ||
| 1001 | INFO(port->func.config->cdev, "Bad index: %x\n", | ||
| 1002 | index); | ||
| 1003 | goto err; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | /* walk through NDP */ | ||
| 1007 | tmp = ((void *)skb->data) + index; | ||
| 1008 | if (get_unaligned_le32(tmp) != ncm->ndp_sign) { | ||
| 1009 | INFO(port->func.config->cdev, "Wrong NDP SIGN\n"); | ||
| 1010 | goto err; | ||
| 1011 | } | ||
| 1012 | tmp += 2; | ||
| 1013 | |||
| 1014 | ndp_len = get_unaligned_le16(tmp++); | ||
| 1015 | /* | ||
| 1016 | * NCM 3.3.1 | ||
| 1017 | * entry is 2 items | ||
| 1018 | * item size is 16/32 bits, opts->dgram_item_len * 2 bytes | ||
| 1019 | * minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry | ||
| 1020 | */ | ||
| 1021 | if ((ndp_len < opts->ndp_size + 2 * 2 * (opts->dgram_item_len * 2)) | ||
| 1022 | || (ndp_len % opts->ndplen_align != 0)) { | ||
| 1023 | INFO(port->func.config->cdev, "Bad NDP length: %x\n", ndp_len); | ||
| 1024 | goto err; | ||
| 1025 | } | ||
| 1026 | tmp += opts->reserved1; | ||
| 1027 | tmp += opts->next_fp_index; /* skip reserved (d)wNextFpIndex */ | ||
| 1028 | tmp += opts->reserved2; | ||
| 1029 | |||
| 1030 | ndp_len -= opts->ndp_size; | ||
| 1031 | index2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1032 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1033 | dgram_counter = 0; | ||
| 1034 | 1161 | ||
| 1162 | /* Run through all the NDP's in the NTB */ | ||
| 1035 | do { | 1163 | do { |
| 1036 | index = index2; | 1164 | /* NCM 3.2 */ |
| 1037 | dg_len = dg_len2; | 1165 | if (((ndp_index % 4) != 0) && |
| 1038 | if (dg_len < 14 + crc_len) { /* ethernet header + crc */ | 1166 | (ndp_index < opts->nth_size)) { |
| 1039 | INFO(port->func.config->cdev, "Bad dgram length: %x\n", | 1167 | INFO(port->func.config->cdev, "Bad index: %#X\n", |
| 1040 | dg_len); | 1168 | ndp_index); |
| 1041 | goto err; | 1169 | goto err; |
| 1042 | } | 1170 | } |
| 1043 | if (ncm->is_crc) { | 1171 | |
| 1044 | uint32_t crc, crc2; | 1172 | /* walk through NDP */ |
| 1045 | 1173 | tmp = (void *)(skb->data + ndp_index); | |
| 1046 | crc = get_unaligned_le32(skb->data + | 1174 | if (get_unaligned_le32(tmp) != ncm->ndp_sign) { |
| 1047 | index + dg_len - crc_len); | 1175 | INFO(port->func.config->cdev, "Wrong NDP SIGN\n"); |
| 1048 | crc2 = ~crc32_le(~0, | 1176 | goto err; |
| 1049 | skb->data + index, | ||
| 1050 | dg_len - crc_len); | ||
| 1051 | if (crc != crc2) { | ||
| 1052 | INFO(port->func.config->cdev, "Bad CRC\n"); | ||
| 1053 | goto err; | ||
| 1054 | } | ||
| 1055 | } | 1177 | } |
| 1178 | tmp += 2; | ||
| 1056 | 1179 | ||
| 1180 | ndp_len = get_unaligned_le16(tmp++); | ||
| 1181 | /* | ||
| 1182 | * NCM 3.3.1 | ||
| 1183 | * entry is 2 items | ||
| 1184 | * item size is 16/32 bits, opts->dgram_item_len * 2 bytes | ||
| 1185 | * minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry | ||
| 1186 | * Each entry is a dgram index and a dgram length. | ||
| 1187 | */ | ||
| 1188 | if ((ndp_len < opts->ndp_size | ||
| 1189 | + 2 * 2 * (opts->dgram_item_len * 2)) | ||
| 1190 | || (ndp_len % opts->ndplen_align != 0)) { | ||
| 1191 | INFO(port->func.config->cdev, "Bad NDP length: %#X\n", | ||
| 1192 | ndp_len); | ||
| 1193 | goto err; | ||
| 1194 | } | ||
| 1195 | tmp += opts->reserved1; | ||
| 1196 | /* Check for another NDP (d)wNextNdpIndex */ | ||
| 1197 | ndp_index = get_ncm(&tmp, opts->next_ndp_index); | ||
| 1198 | tmp += opts->reserved2; | ||
| 1199 | |||
| 1200 | ndp_len -= opts->ndp_size; | ||
| 1057 | index2 = get_ncm(&tmp, opts->dgram_item_len); | 1201 | index2 = get_ncm(&tmp, opts->dgram_item_len); |
| 1058 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); | 1202 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); |
| 1203 | dgram_counter = 0; | ||
| 1204 | |||
| 1205 | do { | ||
| 1206 | index = index2; | ||
| 1207 | dg_len = dg_len2; | ||
| 1208 | if (dg_len < 14 + crc_len) { /* ethernet hdr + crc */ | ||
| 1209 | INFO(port->func.config->cdev, | ||
| 1210 | "Bad dgram length: %#X\n", dg_len); | ||
| 1211 | goto err; | ||
| 1212 | } | ||
| 1213 | if (ncm->is_crc) { | ||
| 1214 | uint32_t crc, crc2; | ||
| 1215 | |||
| 1216 | crc = get_unaligned_le32(skb->data + | ||
| 1217 | index + dg_len - | ||
| 1218 | crc_len); | ||
| 1219 | crc2 = ~crc32_le(~0, | ||
| 1220 | skb->data + index, | ||
| 1221 | dg_len - crc_len); | ||
| 1222 | if (crc != crc2) { | ||
| 1223 | INFO(port->func.config->cdev, | ||
| 1224 | "Bad CRC\n"); | ||
| 1225 | goto err; | ||
| 1226 | } | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | index2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1230 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1059 | 1231 | ||
| 1060 | if (index2 == 0 || dg_len2 == 0) { | 1232 | /* |
| 1061 | skb2 = skb; | 1233 | * Copy the data into a new skb. |
| 1062 | } else { | 1234 | * This ensures the truesize is correct |
| 1063 | skb2 = skb_clone(skb, GFP_ATOMIC); | 1235 | */ |
| 1236 | skb2 = netdev_alloc_skb_ip_align(ncm->netdev, | ||
| 1237 | dg_len - crc_len); | ||
| 1064 | if (skb2 == NULL) | 1238 | if (skb2 == NULL) |
| 1065 | goto err; | 1239 | goto err; |
| 1066 | } | 1240 | memcpy(skb_put(skb2, dg_len - crc_len), |
| 1241 | skb->data + index, dg_len - crc_len); | ||
| 1067 | 1242 | ||
| 1068 | if (!skb_pull(skb2, index)) { | 1243 | skb_queue_tail(list, skb2); |
| 1069 | ret = -EOVERFLOW; | ||
| 1070 | goto err; | ||
| 1071 | } | ||
| 1072 | 1244 | ||
| 1073 | skb_trim(skb2, dg_len - crc_len); | 1245 | ndp_len -= 2 * (opts->dgram_item_len * 2); |
| 1074 | skb_queue_tail(list, skb2); | ||
| 1075 | 1246 | ||
| 1076 | ndp_len -= 2 * (opts->dgram_item_len * 2); | 1247 | dgram_counter++; |
| 1077 | 1248 | ||
| 1078 | dgram_counter++; | 1249 | if (index2 == 0 || dg_len2 == 0) |
| 1250 | break; | ||
| 1251 | } while (ndp_len > 2 * (opts->dgram_item_len * 2)); | ||
| 1252 | } while (ndp_index); | ||
| 1079 | 1253 | ||
| 1080 | if (index2 == 0 || dg_len2 == 0) | 1254 | dev_kfree_skb_any(skb); |
| 1081 | break; | ||
| 1082 | } while (ndp_len > 2 * (opts->dgram_item_len * 2)); /* zero entry */ | ||
| 1083 | 1255 | ||
| 1084 | VDBG(port->func.config->cdev, | 1256 | VDBG(port->func.config->cdev, |
| 1085 | "Parsed NTB with %d frames\n", dgram_counter); | 1257 | "Parsed NTB with %d frames\n", dgram_counter); |
| @@ -1097,8 +1269,11 @@ static void ncm_disable(struct usb_function *f) | |||
| 1097 | 1269 | ||
| 1098 | DBG(cdev, "ncm deactivated\n"); | 1270 | DBG(cdev, "ncm deactivated\n"); |
| 1099 | 1271 | ||
| 1100 | if (ncm->port.in_ep->driver_data) | 1272 | if (ncm->port.in_ep->driver_data) { |
| 1273 | ncm->timer_stopping = true; | ||
| 1274 | ncm->netdev = NULL; | ||
| 1101 | gether_disconnect(&ncm->port); | 1275 | gether_disconnect(&ncm->port); |
| 1276 | } | ||
| 1102 | 1277 | ||
| 1103 | if (ncm->notify->driver_data) { | 1278 | if (ncm->notify->driver_data) { |
| 1104 | usb_ep_disable(ncm->notify); | 1279 | usb_ep_disable(ncm->notify); |
| @@ -1267,6 +1442,10 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 1267 | ncm->port.open = ncm_open; | 1442 | ncm->port.open = ncm_open; |
| 1268 | ncm->port.close = ncm_close; | 1443 | ncm->port.close = ncm_close; |
| 1269 | 1444 | ||
| 1445 | tasklet_init(&ncm->tx_tasklet, ncm_tx_tasklet, (unsigned long) ncm); | ||
| 1446 | hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
| 1447 | ncm->task_timer.function = ncm_tx_timeout; | ||
| 1448 | |||
| 1270 | DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", | 1449 | DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", |
| 1271 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | 1450 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", |
| 1272 | ncm->port.in_ep->name, ncm->port.out_ep->name, | 1451 | ncm->port.in_ep->name, ncm->port.out_ep->name, |
| @@ -1380,6 +1559,10 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) | |||
| 1380 | 1559 | ||
| 1381 | DBG(c->cdev, "ncm unbind\n"); | 1560 | DBG(c->cdev, "ncm unbind\n"); |
| 1382 | 1561 | ||
| 1562 | hrtimer_cancel(&ncm->task_timer); | ||
| 1563 | tasklet_kill(&ncm->tx_tasklet); | ||
| 1564 | |||
| 1565 | ncm_string_defs[0].id = 0; | ||
| 1383 | usb_free_all_descriptors(f); | 1566 | usb_free_all_descriptors(f); |
| 1384 | 1567 | ||
| 1385 | kfree(ncm->notify_req->buf); | 1568 | kfree(ncm->notify_req->buf); |
| @@ -1416,6 +1599,7 @@ static struct usb_function *ncm_alloc(struct usb_function_instance *fi) | |||
| 1416 | ncm->port.ioport = netdev_priv(opts->net); | 1599 | ncm->port.ioport = netdev_priv(opts->net); |
| 1417 | mutex_unlock(&opts->lock); | 1600 | mutex_unlock(&opts->lock); |
| 1418 | ncm->port.is_fixed = true; | 1601 | ncm->port.is_fixed = true; |
| 1602 | ncm->port.supports_multi_frame = true; | ||
| 1419 | 1603 | ||
| 1420 | ncm->port.func.name = "cdc_network"; | 1604 | ncm->port.func.name = "cdc_network"; |
| 1421 | /* descriptors are per-instance copies */ | 1605 | /* descriptors are per-instance copies */ |
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/function/f_obex.c index aebae1853bce..aebae1853bce 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c | |||
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index f2b781773eed..b9cfc1571d71 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c | |||
| @@ -721,7 +721,8 @@ struct net_device *gphonet_setup_default(void) | |||
| 721 | struct phonet_port *port; | 721 | struct phonet_port *port; |
| 722 | 722 | ||
| 723 | /* Create net device */ | 723 | /* Create net device */ |
| 724 | dev = alloc_netdev(sizeof(*port), "upnlink%d", pn_net_setup); | 724 | dev = alloc_netdev(sizeof(*port), "upnlink%d", NET_NAME_UNKNOWN, |
| 725 | pn_net_setup); | ||
| 725 | if (!dev) | 726 | if (!dev) |
| 726 | return ERR_PTR(-ENOMEM); | 727 | return ERR_PTR(-ENOMEM); |
| 727 | 728 | ||
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 9c41e9515b8e..ddb09dc6d1f2 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c | |||
| @@ -727,6 +727,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 727 | rndis_control_intf.bInterfaceNumber = status; | 727 | rndis_control_intf.bInterfaceNumber = status; |
| 728 | rndis_union_desc.bMasterInterface0 = status; | 728 | rndis_union_desc.bMasterInterface0 = status; |
| 729 | 729 | ||
| 730 | if (cdev->use_os_string) | ||
| 731 | f->os_desc_table[0].if_id = | ||
| 732 | rndis_iad_descriptor.bFirstInterface; | ||
| 733 | |||
| 730 | status = usb_interface_id(c, f); | 734 | status = usb_interface_id(c, f); |
| 731 | if (status < 0) | 735 | if (status < 0) |
| 732 | goto fail; | 736 | goto fail; |
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/function/f_serial.c index 9ecbcbf36a45..9ecbcbf36a45 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c | |||
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index d3cd52db78fe..d3cd52db78fe 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c | |||
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/function/f_subset.c index 1ea8baf33333..1ea8baf33333 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c | |||
diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 2b4c82d84bfc..2b4c82d84bfc 100644 --- a/drivers/usb/gadget/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c | |||
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 6261db4a9910..3ed89ecc8d6d 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c | |||
| @@ -348,14 +348,34 @@ static int uac2_pcm_open(struct snd_pcm_substream *substream) | |||
| 348 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 348 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 349 | spin_lock_init(&uac2->p_prm.lock); | 349 | spin_lock_init(&uac2->p_prm.lock); |
| 350 | runtime->hw.rate_min = p_srate; | 350 | runtime->hw.rate_min = p_srate; |
| 351 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; /* ! p_ssize ! */ | 351 | switch (p_ssize) { |
| 352 | case 3: | ||
| 353 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; | ||
| 354 | break; | ||
| 355 | case 4: | ||
| 356 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; | ||
| 357 | break; | ||
| 358 | default: | ||
| 359 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
| 360 | break; | ||
| 361 | } | ||
| 352 | runtime->hw.channels_min = num_channels(p_chmask); | 362 | runtime->hw.channels_min = num_channels(p_chmask); |
| 353 | runtime->hw.period_bytes_min = 2 * uac2->p_prm.max_psize | 363 | runtime->hw.period_bytes_min = 2 * uac2->p_prm.max_psize |
| 354 | / runtime->hw.periods_min; | 364 | / runtime->hw.periods_min; |
| 355 | } else { | 365 | } else { |
| 356 | spin_lock_init(&uac2->c_prm.lock); | 366 | spin_lock_init(&uac2->c_prm.lock); |
| 357 | runtime->hw.rate_min = c_srate; | 367 | runtime->hw.rate_min = c_srate; |
| 358 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; /* ! c_ssize ! */ | 368 | switch (c_ssize) { |
| 369 | case 3: | ||
| 370 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; | ||
| 371 | break; | ||
| 372 | case 4: | ||
| 373 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; | ||
| 374 | break; | ||
| 375 | default: | ||
| 376 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
| 377 | break; | ||
| 378 | } | ||
| 359 | runtime->hw.channels_min = num_channels(c_chmask); | 379 | runtime->hw.channels_min = num_channels(c_chmask); |
| 360 | runtime->hw.period_bytes_min = 2 * uac2->c_prm.max_psize | 380 | runtime->hw.period_bytes_min = 2 * uac2->c_prm.max_psize |
| 361 | / runtime->hw.periods_min; | 381 | / runtime->hw.periods_min; |
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index e2a1f50bd93c..e2a1f50bd93c 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c | |||
diff --git a/drivers/usb/gadget/f_uvc.h b/drivers/usb/gadget/function/f_uvc.h index ec52752f7326..ec52752f7326 100644 --- a/drivers/usb/gadget/f_uvc.h +++ b/drivers/usb/gadget/function/f_uvc.h | |||
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/function/g_zero.h index 15f180904f8a..15f180904f8a 100644 --- a/drivers/usb/gadget/g_zero.h +++ b/drivers/usb/gadget/function/g_zero.h | |||
diff --git a/drivers/usb/gadget/ndis.h b/drivers/usb/gadget/function/ndis.h index a19f72dec0cd..a19f72dec0cd 100644 --- a/drivers/usb/gadget/ndis.h +++ b/drivers/usb/gadget/function/ndis.h | |||
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/function/rndis.c index 95d2324f6977..95d2324f6977 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/function/rndis.c | |||
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/function/rndis.h index 0f4abb4c3775..0f4abb4c3775 100644 --- a/drivers/usb/gadget/rndis.h +++ b/drivers/usb/gadget/function/rndis.h | |||
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/function/storage_common.c index 648f9e489b39..648f9e489b39 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/function/storage_common.c | |||
diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/function/storage_common.h index 70c891469f57..70c891469f57 100644 --- a/drivers/usb/gadget/storage_common.h +++ b/drivers/usb/gadget/function/storage_common.h | |||
diff --git a/drivers/usb/gadget/u_ecm.h b/drivers/usb/gadget/function/u_ecm.h index 262cc03cc2c0..262cc03cc2c0 100644 --- a/drivers/usb/gadget/u_ecm.h +++ b/drivers/usb/gadget/function/u_ecm.h | |||
diff --git a/drivers/usb/gadget/u_eem.h b/drivers/usb/gadget/function/u_eem.h index e3ae97874c4f..e3ae97874c4f 100644 --- a/drivers/usb/gadget/u_eem.h +++ b/drivers/usb/gadget/function/u_eem.h | |||
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 97b027724ee7..6e6f87656e7b 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c | |||
| @@ -483,7 +483,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
| 483 | struct net_device *net) | 483 | struct net_device *net) |
| 484 | { | 484 | { |
| 485 | struct eth_dev *dev = netdev_priv(net); | 485 | struct eth_dev *dev = netdev_priv(net); |
| 486 | int length = skb->len; | 486 | int length = 0; |
| 487 | int retval; | 487 | int retval; |
| 488 | struct usb_request *req = NULL; | 488 | struct usb_request *req = NULL; |
| 489 | unsigned long flags; | 489 | unsigned long flags; |
| @@ -500,13 +500,13 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
| 500 | } | 500 | } |
| 501 | spin_unlock_irqrestore(&dev->lock, flags); | 501 | spin_unlock_irqrestore(&dev->lock, flags); |
| 502 | 502 | ||
| 503 | if (!in) { | 503 | if (skb && !in) { |
| 504 | dev_kfree_skb_any(skb); | 504 | dev_kfree_skb_any(skb); |
| 505 | return NETDEV_TX_OK; | 505 | return NETDEV_TX_OK; |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | /* apply outgoing CDC or RNDIS filters */ | 508 | /* apply outgoing CDC or RNDIS filters */ |
| 509 | if (!is_promisc(cdc_filter)) { | 509 | if (skb && !is_promisc(cdc_filter)) { |
| 510 | u8 *dest = skb->data; | 510 | u8 *dest = skb->data; |
| 511 | 511 | ||
| 512 | if (is_multicast_ether_addr(dest)) { | 512 | if (is_multicast_ether_addr(dest)) { |
| @@ -557,11 +557,17 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
| 557 | if (dev->port_usb) | 557 | if (dev->port_usb) |
| 558 | skb = dev->wrap(dev->port_usb, skb); | 558 | skb = dev->wrap(dev->port_usb, skb); |
| 559 | spin_unlock_irqrestore(&dev->lock, flags); | 559 | spin_unlock_irqrestore(&dev->lock, flags); |
| 560 | if (!skb) | 560 | if (!skb) { |
| 561 | /* Multi frame CDC protocols may store the frame for | ||
| 562 | * later which is not a dropped frame. | ||
| 563 | */ | ||
| 564 | if (dev->port_usb->supports_multi_frame) | ||
| 565 | goto multiframe; | ||
| 561 | goto drop; | 566 | goto drop; |
| 562 | 567 | } | |
| 563 | length = skb->len; | ||
| 564 | } | 568 | } |
| 569 | |||
| 570 | length = skb->len; | ||
| 565 | req->buf = skb->data; | 571 | req->buf = skb->data; |
| 566 | req->context = skb; | 572 | req->context = skb; |
| 567 | req->complete = tx_complete; | 573 | req->complete = tx_complete; |
| @@ -604,6 +610,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
| 604 | dev_kfree_skb_any(skb); | 610 | dev_kfree_skb_any(skb); |
| 605 | drop: | 611 | drop: |
| 606 | dev->net->stats.tx_dropped++; | 612 | dev->net->stats.tx_dropped++; |
| 613 | multiframe: | ||
| 607 | spin_lock_irqsave(&dev->req_lock, flags); | 614 | spin_lock_irqsave(&dev->req_lock, flags); |
| 608 | if (list_empty(&dev->tx_reqs)) | 615 | if (list_empty(&dev->tx_reqs)) |
| 609 | netif_start_queue(net); | 616 | netif_start_queue(net); |
| @@ -1120,10 +1127,7 @@ void gether_disconnect(struct gether *link) | |||
| 1120 | 1127 | ||
| 1121 | DBG(dev, "%s\n", __func__); | 1128 | DBG(dev, "%s\n", __func__); |
| 1122 | 1129 | ||
| 1123 | netif_tx_lock(dev->net); | ||
| 1124 | netif_stop_queue(dev->net); | 1130 | netif_stop_queue(dev->net); |
| 1125 | netif_tx_unlock(dev->net); | ||
| 1126 | |||
| 1127 | netif_carrier_off(dev->net); | 1131 | netif_carrier_off(dev->net); |
| 1128 | 1132 | ||
| 1129 | /* disable endpoints, forcing (synchronous) completion | 1133 | /* disable endpoints, forcing (synchronous) completion |
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/function/u_ether.h index 0f0290acea7e..334b38947916 100644 --- a/drivers/usb/gadget/u_ether.h +++ b/drivers/usb/gadget/function/u_ether.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/if_ether.h> | 18 | #include <linux/if_ether.h> |
| 19 | #include <linux/usb/composite.h> | 19 | #include <linux/usb/composite.h> |
| 20 | #include <linux/usb/cdc.h> | 20 | #include <linux/usb/cdc.h> |
| 21 | #include <linux/netdevice.h> | ||
| 21 | 22 | ||
| 22 | #include "gadget_chips.h" | 23 | #include "gadget_chips.h" |
| 23 | 24 | ||
| @@ -74,6 +75,7 @@ struct gether { | |||
| 74 | bool is_fixed; | 75 | bool is_fixed; |
| 75 | u32 fixed_out_len; | 76 | u32 fixed_out_len; |
| 76 | u32 fixed_in_len; | 77 | u32 fixed_in_len; |
| 78 | bool supports_multi_frame; | ||
| 77 | struct sk_buff *(*wrap)(struct gether *port, | 79 | struct sk_buff *(*wrap)(struct gether *port, |
| 78 | struct sk_buff *skb); | 80 | struct sk_buff *skb); |
| 79 | int (*unwrap)(struct gether *port, | 81 | int (*unwrap)(struct gether *port, |
diff --git a/drivers/usb/gadget/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index bcbd30146cfd..bcbd30146cfd 100644 --- a/drivers/usb/gadget/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h | |||
diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/function/u_fs.h index bf0ba375d459..63d6e71569c1 100644 --- a/drivers/usb/gadget/u_fs.h +++ b/drivers/usb/gadget/function/u_fs.h | |||
| @@ -216,6 +216,13 @@ struct ffs_data { | |||
| 216 | unsigned fs_descs_count; | 216 | unsigned fs_descs_count; |
| 217 | unsigned hs_descs_count; | 217 | unsigned hs_descs_count; |
| 218 | unsigned ss_descs_count; | 218 | unsigned ss_descs_count; |
| 219 | unsigned ms_os_descs_count; | ||
| 220 | unsigned ms_os_descs_ext_prop_count; | ||
| 221 | unsigned ms_os_descs_ext_prop_name_len; | ||
| 222 | unsigned ms_os_descs_ext_prop_data_len; | ||
| 223 | void *ms_os_descs_ext_prop_avail; | ||
| 224 | void *ms_os_descs_ext_prop_name_avail; | ||
| 225 | void *ms_os_descs_ext_prop_data_avail; | ||
| 219 | 226 | ||
| 220 | unsigned short strings_count; | 227 | unsigned short strings_count; |
| 221 | unsigned short interfaces_count; | 228 | unsigned short interfaces_count; |
diff --git a/drivers/usb/gadget/u_gether.h b/drivers/usb/gadget/function/u_gether.h index d4078426ba5d..d4078426ba5d 100644 --- a/drivers/usb/gadget/u_gether.h +++ b/drivers/usb/gadget/function/u_gether.h | |||
diff --git a/drivers/usb/gadget/u_ncm.h b/drivers/usb/gadget/function/u_ncm.h index ce0f3a78ca13..ce0f3a78ca13 100644 --- a/drivers/usb/gadget/u_ncm.h +++ b/drivers/usb/gadget/function/u_ncm.h | |||
diff --git a/drivers/usb/gadget/u_phonet.h b/drivers/usb/gadget/function/u_phonet.h index 98ced18779ea..98ced18779ea 100644 --- a/drivers/usb/gadget/u_phonet.h +++ b/drivers/usb/gadget/function/u_phonet.h | |||
diff --git a/drivers/usb/gadget/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h index e902aa42a297..e902aa42a297 100644 --- a/drivers/usb/gadget/u_rndis.h +++ b/drivers/usb/gadget/function/u_rndis.h | |||
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/function/u_serial.c index ad0aca812002..ad0aca812002 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c | |||
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/function/u_serial.h index c20210c0babd..c20210c0babd 100644 --- a/drivers/usb/gadget/u_serial.h +++ b/drivers/usb/gadget/function/u_serial.h | |||
diff --git a/drivers/usb/gadget/u_uac1.c b/drivers/usb/gadget/function/u_uac1.c index 7a55fea43430..7a55fea43430 100644 --- a/drivers/usb/gadget/u_uac1.c +++ b/drivers/usb/gadget/function/u_uac1.c | |||
diff --git a/drivers/usb/gadget/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index 18c2e729faf6..18c2e729faf6 100644 --- a/drivers/usb/gadget/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h | |||
diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/function/uvc.h index 7a9111de8054..7a9111de8054 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/function/uvc.h | |||
diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 1c29bc954db9..1c29bc954db9 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c | |||
diff --git a/drivers/usb/gadget/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index 8e76ce982f1e..8e76ce982f1e 100644 --- a/drivers/usb/gadget/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h | |||
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index ad48e81155e2..ad48e81155e2 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c | |||
diff --git a/drivers/usb/gadget/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 71e896d4c5ae..a5eb9a3fbb7a 100644 --- a/drivers/usb/gadget/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/Kconfig b/drivers/usb/gadget/legacy/Kconfig new file mode 100644 index 000000000000..aa376f006333 --- /dev/null +++ b/drivers/usb/gadget/legacy/Kconfig | |||
| @@ -0,0 +1,475 @@ | |||
| 1 | # | ||
| 2 | # USB Gadget support on a system involves | ||
| 3 | # (a) a peripheral controller, and | ||
| 4 | # (b) the gadget driver using it. | ||
| 5 | # | ||
| 6 | # NOTE: Gadget support ** DOES NOT ** depend on host-side CONFIG_USB !! | ||
| 7 | # | ||
| 8 | # - Host systems (like PCs) need CONFIG_USB (with "A" jacks). | ||
| 9 | # - Peripherals (like PDAs) need CONFIG_USB_GADGET (with "B" jacks). | ||
| 10 | # - Some systems have both kinds of controllers. | ||
| 11 | # | ||
| 12 | # With help from a special transceiver and a "Mini-AB" jack, systems with | ||
| 13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). | ||
| 14 | # | ||
| 15 | |||
| 16 | config USB_ZERO | ||
| 17 | tristate "Gadget Zero (DEVELOPMENT)" | ||
| 18 | select USB_LIBCOMPOSITE | ||
| 19 | select USB_F_SS_LB | ||
| 20 | help | ||
| 21 | Gadget Zero is a two-configuration device. It either sinks and | ||
| 22 | sources bulk data; or it loops back a configurable number of | ||
| 23 | transfers. It also implements control requests, for "chapter 9" | ||
| 24 | conformance. The driver needs only two bulk-capable endpoints, so | ||
| 25 | it can work on top of most device-side usb controllers. It's | ||
| 26 | useful for testing, and is also a working example showing how | ||
| 27 | USB "gadget drivers" can be written. | ||
| 28 | |||
| 29 | Make this be the first driver you try using on top of any new | ||
| 30 | USB peripheral controller driver. Then you can use host-side | ||
| 31 | test software, like the "usbtest" driver, to put your hardware | ||
| 32 | and its driver through a basic set of functional tests. | ||
| 33 | |||
| 34 | Gadget Zero also works with the host-side "usb-skeleton" driver, | ||
| 35 | and with many kinds of host-side test software. You may need | ||
| 36 | to tweak product and vendor IDs before host software knows about | ||
| 37 | this device, and arrange to select an appropriate configuration. | ||
| 38 | |||
| 39 | Say "y" to link the driver statically, or "m" to build a | ||
| 40 | dynamically linked module called "g_zero". | ||
| 41 | |||
| 42 | config USB_ZERO_HNPTEST | ||
| 43 | boolean "HNP Test Device" | ||
| 44 | depends on USB_ZERO && USB_OTG | ||
| 45 | help | ||
| 46 | You can configure this device to enumerate using the device | ||
| 47 | identifiers of the USB-OTG test device. That means that when | ||
| 48 | this gadget connects to another OTG device, with this one using | ||
| 49 | the "B-Peripheral" role, that device will use HNP to let this | ||
| 50 | one serve as the USB host instead (in the "B-Host" role). | ||
| 51 | |||
| 52 | config USB_AUDIO | ||
| 53 | tristate "Audio Gadget" | ||
| 54 | depends on SND | ||
| 55 | select USB_LIBCOMPOSITE | ||
| 56 | select SND_PCM | ||
| 57 | help | ||
| 58 | This Gadget Audio driver is compatible with USB Audio Class | ||
| 59 | specification 2.0. It implements 1 AudioControl interface, | ||
| 60 | 1 AudioStreaming Interface each for USB-OUT and USB-IN. | ||
| 61 | Number of channels, sample rate and sample size can be | ||
| 62 | specified as module parameters. | ||
| 63 | This driver doesn't expect any real Audio codec to be present | ||
| 64 | on the device - the audio streams are simply sinked to and | ||
| 65 | sourced from a virtual ALSA sound card created. The user-space | ||
| 66 | application may choose to do whatever it wants with the data | ||
| 67 | received from the USB Host and choose to provide whatever it | ||
| 68 | wants as audio data to the USB Host. | ||
| 69 | |||
| 70 | Say "y" to link the driver statically, or "m" to build a | ||
| 71 | dynamically linked module called "g_audio". | ||
| 72 | |||
| 73 | config GADGET_UAC1 | ||
| 74 | bool "UAC 1.0 (Legacy)" | ||
| 75 | depends on USB_AUDIO | ||
| 76 | help | ||
| 77 | If you instead want older UAC Spec-1.0 driver that also has audio | ||
| 78 | paths hardwired to the Audio codec chip on-board and doesn't work | ||
| 79 | without one. | ||
| 80 | |||
| 81 | config USB_ETH | ||
| 82 | tristate "Ethernet Gadget (with CDC Ethernet support)" | ||
| 83 | depends on NET | ||
| 84 | select USB_LIBCOMPOSITE | ||
| 85 | select USB_U_ETHER | ||
| 86 | select USB_F_ECM | ||
| 87 | select USB_F_SUBSET | ||
| 88 | select CRC32 | ||
| 89 | help | ||
| 90 | This driver implements Ethernet style communication, in one of | ||
| 91 | several ways: | ||
| 92 | |||
| 93 | - The "Communication Device Class" (CDC) Ethernet Control Model. | ||
| 94 | That protocol is often avoided with pure Ethernet adapters, in | ||
| 95 | favor of simpler vendor-specific hardware, but is widely | ||
| 96 | supported by firmware for smart network devices. | ||
| 97 | |||
| 98 | - On hardware can't implement that protocol, a simple CDC subset | ||
| 99 | is used, placing fewer demands on USB. | ||
| 100 | |||
| 101 | - CDC Ethernet Emulation Model (EEM) is a newer standard that has | ||
| 102 | a simpler interface that can be used by more USB hardware. | ||
| 103 | |||
| 104 | RNDIS support is an additional option, more demanding than than | ||
| 105 | subset. | ||
| 106 | |||
| 107 | Within the USB device, this gadget driver exposes a network device | ||
| 108 | "usbX", where X depends on what other networking devices you have. | ||
| 109 | Treat it like a two-node Ethernet link: host, and gadget. | ||
| 110 | |||
| 111 | The Linux-USB host-side "usbnet" driver interoperates with this | ||
| 112 | driver, so that deep I/O queues can be supported. On 2.4 kernels, | ||
| 113 | use "CDCEther" instead, if you're using the CDC option. That CDC | ||
| 114 | mode should also interoperate with standard CDC Ethernet class | ||
| 115 | drivers on other host operating systems. | ||
| 116 | |||
| 117 | Say "y" to link the driver statically, or "m" to build a | ||
| 118 | dynamically linked module called "g_ether". | ||
| 119 | |||
| 120 | config USB_ETH_RNDIS | ||
| 121 | bool "RNDIS support" | ||
| 122 | depends on USB_ETH | ||
| 123 | select USB_LIBCOMPOSITE | ||
| 124 | select USB_F_RNDIS | ||
| 125 | default y | ||
| 126 | help | ||
| 127 | Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol, | ||
| 128 | and Microsoft provides redistributable binary RNDIS drivers for | ||
| 129 | older versions of Windows. | ||
| 130 | |||
| 131 | If you say "y" here, the Ethernet gadget driver will try to provide | ||
| 132 | a second device configuration, supporting RNDIS to talk to such | ||
| 133 | Microsoft USB hosts. | ||
| 134 | |||
| 135 | To make MS-Windows work with this, use Documentation/usb/linux.inf | ||
| 136 | as the "driver info file". For versions of MS-Windows older than | ||
| 137 | XP, you'll need to download drivers from Microsoft's website; a URL | ||
| 138 | is given in comments found in that info file. | ||
| 139 | |||
| 140 | config USB_ETH_EEM | ||
| 141 | bool "Ethernet Emulation Model (EEM) support" | ||
| 142 | depends on USB_ETH | ||
| 143 | select USB_LIBCOMPOSITE | ||
| 144 | select USB_F_EEM | ||
| 145 | default n | ||
| 146 | help | ||
| 147 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM | ||
| 148 | and therefore can be supported by more hardware. Technically ECM and | ||
| 149 | EEM are designed for different applications. The ECM model extends | ||
| 150 | the network interface to the target (e.g. a USB cable modem), and the | ||
| 151 | EEM model is for mobile devices to communicate with hosts using | ||
| 152 | ethernet over USB. For Linux gadgets, however, the interface with | ||
| 153 | the host is the same (a usbX device), so the differences are minimal. | ||
| 154 | |||
| 155 | If you say "y" here, the Ethernet gadget driver will use the EEM | ||
| 156 | protocol rather than ECM. If unsure, say "n". | ||
| 157 | |||
| 158 | config USB_G_NCM | ||
| 159 | tristate "Network Control Model (NCM) support" | ||
| 160 | depends on NET | ||
| 161 | select USB_LIBCOMPOSITE | ||
| 162 | select USB_U_ETHER | ||
| 163 | select USB_F_NCM | ||
| 164 | select CRC32 | ||
| 165 | help | ||
| 166 | This driver implements USB CDC NCM subclass standard. NCM is | ||
| 167 | an advanced protocol for Ethernet encapsulation, allows grouping | ||
| 168 | of several ethernet frames into one USB transfer and different | ||
| 169 | alignment possibilities. | ||
| 170 | |||
| 171 | Say "y" to link the driver statically, or "m" to build a | ||
| 172 | dynamically linked module called "g_ncm". | ||
| 173 | |||
| 174 | config USB_GADGETFS | ||
| 175 | tristate "Gadget Filesystem" | ||
| 176 | help | ||
| 177 | This driver provides a filesystem based API that lets user mode | ||
| 178 | programs implement a single-configuration USB device, including | ||
| 179 | endpoint I/O and control requests that don't relate to enumeration. | ||
| 180 | All endpoints, transfer speeds, and transfer types supported by | ||
| 181 | the hardware are available, through read() and write() calls. | ||
| 182 | |||
| 183 | Say "y" to link the driver statically, or "m" to build a | ||
| 184 | dynamically linked module called "gadgetfs". | ||
| 185 | |||
| 186 | config USB_FUNCTIONFS | ||
| 187 | tristate "Function Filesystem" | ||
| 188 | select USB_LIBCOMPOSITE | ||
| 189 | select USB_F_FS | ||
| 190 | select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS) | ||
| 191 | help | ||
| 192 | The Function Filesystem (FunctionFS) lets one create USB | ||
| 193 | composite functions in user space in the same way GadgetFS | ||
| 194 | lets one create USB gadgets in user space. This allows creation | ||
| 195 | of composite gadgets such that some of the functions are | ||
| 196 | implemented in kernel space (for instance Ethernet, serial or | ||
| 197 | mass storage) and other are implemented in user space. | ||
| 198 | |||
| 199 | If you say "y" or "m" here you will be able what kind of | ||
| 200 | configurations the gadget will provide. | ||
| 201 | |||
| 202 | Say "y" to link the driver statically, or "m" to build | ||
| 203 | a dynamically linked module called "g_ffs". | ||
| 204 | |||
| 205 | config USB_FUNCTIONFS_ETH | ||
| 206 | bool "Include configuration with CDC ECM (Ethernet)" | ||
| 207 | depends on USB_FUNCTIONFS && NET | ||
| 208 | select USB_U_ETHER | ||
| 209 | select USB_F_ECM | ||
| 210 | select USB_F_SUBSET | ||
| 211 | help | ||
| 212 | Include a configuration with CDC ECM function (Ethernet) and the | ||
| 213 | Function Filesystem. | ||
| 214 | |||
| 215 | config USB_FUNCTIONFS_RNDIS | ||
| 216 | bool "Include configuration with RNDIS (Ethernet)" | ||
| 217 | depends on USB_FUNCTIONFS && NET | ||
| 218 | select USB_U_ETHER | ||
| 219 | select USB_F_RNDIS | ||
| 220 | help | ||
| 221 | Include a configuration with RNDIS function (Ethernet) and the Filesystem. | ||
| 222 | |||
| 223 | config USB_FUNCTIONFS_GENERIC | ||
| 224 | bool "Include 'pure' configuration" | ||
| 225 | depends on USB_FUNCTIONFS | ||
| 226 | help | ||
| 227 | Include a configuration with the Function Filesystem alone with | ||
| 228 | no Ethernet interface. | ||
| 229 | |||
| 230 | config USB_MASS_STORAGE | ||
| 231 | tristate "Mass Storage Gadget" | ||
| 232 | depends on BLOCK | ||
| 233 | select USB_LIBCOMPOSITE | ||
| 234 | select USB_F_MASS_STORAGE | ||
| 235 | help | ||
| 236 | The Mass Storage Gadget acts as a USB Mass Storage disk drive. | ||
| 237 | As its storage repository it can use a regular file or a block | ||
| 238 | device (in much the same way as the "loop" device driver), | ||
| 239 | specified as a module parameter or sysfs option. | ||
| 240 | |||
| 241 | This driver is a replacement for now removed File-backed | ||
| 242 | Storage Gadget (g_file_storage). | ||
| 243 | |||
| 244 | Say "y" to link the driver statically, or "m" to build | ||
| 245 | a dynamically linked module called "g_mass_storage". | ||
| 246 | |||
| 247 | config USB_GADGET_TARGET | ||
| 248 | tristate "USB Gadget Target Fabric Module" | ||
| 249 | depends on TARGET_CORE | ||
| 250 | select USB_LIBCOMPOSITE | ||
| 251 | help | ||
| 252 | This fabric is an USB gadget. Two USB protocols are supported that is | ||
| 253 | BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is | ||
| 254 | advertised on alternative interface 0 (primary) and UAS is on | ||
| 255 | alternative interface 1. Both protocols can work on USB2.0 and USB3.0. | ||
| 256 | UAS utilizes the USB 3.0 feature called streams support. | ||
| 257 | |||
| 258 | config USB_G_SERIAL | ||
| 259 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" | ||
| 260 | depends on TTY | ||
| 261 | select USB_U_SERIAL | ||
| 262 | select USB_F_ACM | ||
| 263 | select USB_F_SERIAL | ||
| 264 | select USB_F_OBEX | ||
| 265 | select USB_LIBCOMPOSITE | ||
| 266 | help | ||
| 267 | The Serial Gadget talks to the Linux-USB generic serial driver. | ||
| 268 | This driver supports a CDC-ACM module option, which can be used | ||
| 269 | to interoperate with MS-Windows hosts or with the Linux-USB | ||
| 270 | "cdc-acm" driver. | ||
| 271 | |||
| 272 | This driver also supports a CDC-OBEX option. You will need a | ||
| 273 | user space OBEX server talking to /dev/ttyGS*, since the kernel | ||
| 274 | itself doesn't implement the OBEX protocol. | ||
| 275 | |||
| 276 | Say "y" to link the driver statically, or "m" to build a | ||
| 277 | dynamically linked module called "g_serial". | ||
| 278 | |||
| 279 | For more information, see Documentation/usb/gadget_serial.txt | ||
| 280 | which includes instructions and a "driver info file" needed to | ||
| 281 | make MS-Windows work with CDC ACM. | ||
| 282 | |||
| 283 | config USB_MIDI_GADGET | ||
| 284 | tristate "MIDI Gadget" | ||
| 285 | depends on SND | ||
| 286 | select USB_LIBCOMPOSITE | ||
| 287 | select SND_RAWMIDI | ||
| 288 | help | ||
| 289 | The MIDI Gadget acts as a USB Audio device, with one MIDI | ||
| 290 | input and one MIDI output. These MIDI jacks appear as | ||
| 291 | a sound "card" in the ALSA sound system. Other MIDI | ||
| 292 | connections can then be made on the gadget system, using | ||
| 293 | ALSA's aconnect utility etc. | ||
| 294 | |||
| 295 | Say "y" to link the driver statically, or "m" to build a | ||
| 296 | dynamically linked module called "g_midi". | ||
| 297 | |||
| 298 | config USB_G_PRINTER | ||
| 299 | tristate "Printer Gadget" | ||
| 300 | select USB_LIBCOMPOSITE | ||
| 301 | help | ||
| 302 | The Printer Gadget channels data between the USB host and a | ||
| 303 | userspace program driving the print engine. The user space | ||
| 304 | program reads and writes the device file /dev/g_printer to | ||
| 305 | receive or send printer data. It can use ioctl calls to | ||
| 306 | the device file to get or set printer status. | ||
| 307 | |||
| 308 | Say "y" to link the driver statically, or "m" to build a | ||
| 309 | dynamically linked module called "g_printer". | ||
| 310 | |||
| 311 | For more information, see Documentation/usb/gadget_printer.txt | ||
| 312 | which includes sample code for accessing the device file. | ||
| 313 | |||
| 314 | if TTY | ||
| 315 | |||
| 316 | config USB_CDC_COMPOSITE | ||
| 317 | tristate "CDC Composite Device (Ethernet and ACM)" | ||
| 318 | depends on NET | ||
| 319 | select USB_LIBCOMPOSITE | ||
| 320 | select USB_U_SERIAL | ||
| 321 | select USB_U_ETHER | ||
| 322 | select USB_F_ACM | ||
| 323 | select USB_F_ECM | ||
| 324 | help | ||
| 325 | This driver provides two functions in one configuration: | ||
| 326 | a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. | ||
| 327 | |||
| 328 | This driver requires four bulk and two interrupt endpoints, | ||
| 329 | plus the ability to handle altsettings. Not all peripheral | ||
| 330 | controllers are that capable. | ||
| 331 | |||
| 332 | Say "y" to link the driver statically, or "m" to build a | ||
| 333 | dynamically linked module. | ||
| 334 | |||
| 335 | config USB_G_NOKIA | ||
| 336 | tristate "Nokia composite gadget" | ||
| 337 | depends on PHONET | ||
| 338 | select USB_LIBCOMPOSITE | ||
| 339 | select USB_U_SERIAL | ||
| 340 | select USB_U_ETHER | ||
| 341 | select USB_F_ACM | ||
| 342 | select USB_F_OBEX | ||
| 343 | select USB_F_PHONET | ||
| 344 | select USB_F_ECM | ||
| 345 | help | ||
| 346 | The Nokia composite gadget provides support for acm, obex | ||
| 347 | and phonet in only one composite gadget driver. | ||
| 348 | |||
| 349 | It's only really useful for N900 hardware. If you're building | ||
| 350 | a kernel for N900, say Y or M here. If unsure, say N. | ||
| 351 | |||
| 352 | config USB_G_ACM_MS | ||
| 353 | tristate "CDC Composite Device (ACM and mass storage)" | ||
| 354 | depends on BLOCK | ||
| 355 | select USB_LIBCOMPOSITE | ||
| 356 | select USB_U_SERIAL | ||
| 357 | select USB_F_ACM | ||
| 358 | select USB_F_MASS_STORAGE | ||
| 359 | help | ||
| 360 | This driver provides two functions in one configuration: | ||
| 361 | a mass storage, and a CDC ACM (serial port) link. | ||
| 362 | |||
| 363 | Say "y" to link the driver statically, or "m" to build a | ||
| 364 | dynamically linked module called "g_acm_ms". | ||
| 365 | |||
| 366 | config USB_G_MULTI | ||
| 367 | tristate "Multifunction Composite Gadget" | ||
| 368 | depends on BLOCK && NET | ||
| 369 | select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS | ||
| 370 | select USB_LIBCOMPOSITE | ||
| 371 | select USB_U_SERIAL | ||
| 372 | select USB_U_ETHER | ||
| 373 | select USB_F_ACM | ||
| 374 | select USB_F_MASS_STORAGE | ||
| 375 | help | ||
| 376 | The Multifunction Composite Gadget provides Ethernet (RNDIS | ||
| 377 | and/or CDC Ethernet), mass storage and ACM serial link | ||
| 378 | interfaces. | ||
| 379 | |||
| 380 | You will be asked to choose which of the two configurations is | ||
| 381 | to be available in the gadget. At least one configuration must | ||
| 382 | be chosen to make the gadget usable. Selecting more than one | ||
| 383 | configuration will prevent Windows from automatically detecting | ||
| 384 | the gadget as a composite gadget, so an INF file will be needed to | ||
| 385 | use the gadget. | ||
| 386 | |||
| 387 | Say "y" to link the driver statically, or "m" to build a | ||
| 388 | dynamically linked module called "g_multi". | ||
| 389 | |||
| 390 | config USB_G_MULTI_RNDIS | ||
| 391 | bool "RNDIS + CDC Serial + Storage configuration" | ||
| 392 | depends on USB_G_MULTI | ||
| 393 | select USB_F_RNDIS | ||
| 394 | default y | ||
| 395 | help | ||
| 396 | This option enables a configuration with RNDIS, CDC Serial and | ||
| 397 | Mass Storage functions available in the Multifunction Composite | ||
| 398 | Gadget. This is the configuration dedicated for Windows since RNDIS | ||
| 399 | is Microsoft's protocol. | ||
| 400 | |||
| 401 | If unsure, say "y". | ||
| 402 | |||
| 403 | config USB_G_MULTI_CDC | ||
| 404 | bool "CDC Ethernet + CDC Serial + Storage configuration" | ||
| 405 | depends on USB_G_MULTI | ||
| 406 | default n | ||
| 407 | select USB_F_ECM | ||
| 408 | help | ||
| 409 | This option enables a configuration with CDC Ethernet (ECM), CDC | ||
| 410 | Serial and Mass Storage functions available in the Multifunction | ||
| 411 | Composite Gadget. | ||
| 412 | |||
| 413 | If unsure, say "y". | ||
| 414 | |||
| 415 | endif # TTY | ||
| 416 | |||
| 417 | config USB_G_HID | ||
| 418 | tristate "HID Gadget" | ||
| 419 | select USB_LIBCOMPOSITE | ||
| 420 | help | ||
| 421 | The HID gadget driver provides generic emulation of USB | ||
| 422 | Human Interface Devices (HID). | ||
| 423 | |||
| 424 | For more information, see Documentation/usb/gadget_hid.txt which | ||
| 425 | includes sample code for accessing the device files. | ||
| 426 | |||
| 427 | Say "y" to link the driver statically, or "m" to build a | ||
| 428 | dynamically linked module called "g_hid". | ||
| 429 | |||
| 430 | # Standalone / single function gadgets | ||
| 431 | config USB_G_DBGP | ||
| 432 | tristate "EHCI Debug Device Gadget" | ||
| 433 | depends on TTY | ||
| 434 | select USB_LIBCOMPOSITE | ||
| 435 | help | ||
| 436 | This gadget emulates an EHCI Debug device. This is useful when you want | ||
| 437 | to interact with an EHCI Debug Port. | ||
| 438 | |||
| 439 | Say "y" to link the driver statically, or "m" to build a | ||
| 440 | dynamically linked module called "g_dbgp". | ||
| 441 | |||
| 442 | if USB_G_DBGP | ||
| 443 | choice | ||
| 444 | prompt "EHCI Debug Device mode" | ||
| 445 | default USB_G_DBGP_SERIAL | ||
| 446 | |||
| 447 | config USB_G_DBGP_PRINTK | ||
| 448 | depends on USB_G_DBGP | ||
| 449 | bool "printk" | ||
| 450 | help | ||
| 451 | Directly printk() received data. No interaction. | ||
| 452 | |||
| 453 | config USB_G_DBGP_SERIAL | ||
| 454 | depends on USB_G_DBGP | ||
| 455 | select USB_U_SERIAL | ||
| 456 | bool "serial" | ||
| 457 | help | ||
| 458 | Userland can interact using /dev/ttyGSxxx. | ||
| 459 | endchoice | ||
| 460 | endif | ||
| 461 | |||
| 462 | # put drivers that need isochronous transfer support (for audio | ||
| 463 | # or video class gadget drivers), or specific hardware, here. | ||
| 464 | config USB_G_WEBCAM | ||
| 465 | tristate "USB Webcam Gadget" | ||
| 466 | depends on VIDEO_DEV | ||
| 467 | select USB_LIBCOMPOSITE | ||
| 468 | select VIDEOBUF2_VMALLOC | ||
| 469 | help | ||
| 470 | The Webcam Gadget acts as a composite USB Audio and Video Class | ||
| 471 | device. It provides a userspace API to process UVC control requests | ||
| 472 | and stream video data to the host. | ||
| 473 | |||
| 474 | Say "y" to link the driver statically, or "m" to build a | ||
| 475 | dynamically linked module called "g_webcam". | ||
diff --git a/drivers/usb/gadget/legacy/Makefile b/drivers/usb/gadget/legacy/Makefile new file mode 100644 index 000000000000..edba2d1ee0f3 --- /dev/null +++ b/drivers/usb/gadget/legacy/Makefile | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | # | ||
| 2 | # USB gadget drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | ccflags-y := -Idrivers/usb/gadget/ | ||
| 6 | ccflags-y += -Idrivers/usb/gadget/udc/ | ||
| 7 | ccflags-y += -Idrivers/usb/gadget/function/ | ||
| 8 | |||
| 9 | g_zero-y := zero.o | ||
| 10 | g_audio-y := audio.o | ||
| 11 | g_ether-y := ether.o | ||
| 12 | g_serial-y := serial.o | ||
| 13 | g_midi-y := gmidi.o | ||
| 14 | gadgetfs-y := inode.o | ||
| 15 | g_mass_storage-y := mass_storage.o | ||
| 16 | g_printer-y := printer.o | ||
| 17 | g_cdc-y := cdc2.o | ||
| 18 | g_multi-y := multi.o | ||
| 19 | g_hid-y := hid.o | ||
| 20 | g_dbgp-y := dbgp.o | ||
| 21 | g_nokia-y := nokia.o | ||
| 22 | g_webcam-y := webcam.o | ||
| 23 | g_ncm-y := ncm.o | ||
| 24 | g_acm_ms-y := acm_ms.o | ||
| 25 | g_tcm_usb_gadget-y := tcm_usb_gadget.o | ||
| 26 | |||
| 27 | obj-$(CONFIG_USB_ZERO) += g_zero.o | ||
| 28 | obj-$(CONFIG_USB_AUDIO) += g_audio.o | ||
| 29 | obj-$(CONFIG_USB_ETH) += g_ether.o | ||
| 30 | obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o | ||
| 31 | obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o | ||
| 32 | obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o | ||
| 33 | obj-$(CONFIG_USB_G_SERIAL) += g_serial.o | ||
| 34 | obj-$(CONFIG_USB_G_PRINTER) += g_printer.o | ||
| 35 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o | ||
| 36 | obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o | ||
| 37 | obj-$(CONFIG_USB_G_HID) += g_hid.o | ||
| 38 | obj-$(CONFIG_USB_G_DBGP) += g_dbgp.o | ||
| 39 | obj-$(CONFIG_USB_G_MULTI) += g_multi.o | ||
| 40 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o | ||
| 41 | obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o | ||
| 42 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o | ||
| 43 | obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o | ||
| 44 | obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o | ||
diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c index a252444cc0a7..c30b7b572465 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/legacy/acm_ms.c | |||
| @@ -267,18 +267,8 @@ static __refdata struct usb_composite_driver acm_ms_driver = { | |||
| 267 | .unbind = __exit_p(acm_ms_unbind), | 267 | .unbind = __exit_p(acm_ms_unbind), |
| 268 | }; | 268 | }; |
| 269 | 269 | ||
| 270 | module_usb_composite_driver(acm_ms_driver); | ||
| 271 | |||
| 270 | MODULE_DESCRIPTION(DRIVER_DESC); | 272 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 271 | MODULE_AUTHOR("Klaus Schwarzkopf <schwarzkopf@sensortherm.de>"); | 273 | MODULE_AUTHOR("Klaus Schwarzkopf <schwarzkopf@sensortherm.de>"); |
| 272 | MODULE_LICENSE("GPL v2"); | 274 | MODULE_LICENSE("GPL v2"); |
| 273 | |||
| 274 | static int __init init(void) | ||
| 275 | { | ||
| 276 | return usb_composite_probe(&acm_ms_driver); | ||
| 277 | } | ||
| 278 | module_init(init); | ||
| 279 | |||
| 280 | static void __exit cleanup(void) | ||
| 281 | { | ||
| 282 | usb_composite_unregister(&acm_ms_driver); | ||
| 283 | } | ||
| 284 | module_exit(cleanup); | ||
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/legacy/audio.c index 231b0efe8fdc..6eb695e5e43a 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/legacy/audio.c | |||
| @@ -172,17 +172,7 @@ static __refdata struct usb_composite_driver audio_driver = { | |||
| 172 | .unbind = __exit_p(audio_unbind), | 172 | .unbind = __exit_p(audio_unbind), |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | static int __init init(void) | 175 | module_usb_composite_driver(audio_driver); |
| 176 | { | ||
| 177 | return usb_composite_probe(&audio_driver); | ||
| 178 | } | ||
| 179 | module_init(init); | ||
| 180 | |||
| 181 | static void __exit cleanup(void) | ||
| 182 | { | ||
| 183 | usb_composite_unregister(&audio_driver); | ||
| 184 | } | ||
| 185 | module_exit(cleanup); | ||
| 186 | 176 | ||
| 187 | MODULE_DESCRIPTION(DRIVER_DESC); | 177 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 188 | MODULE_AUTHOR("Bryan Wu <cooloney@kernel.org>"); | 178 | MODULE_AUTHOR("Bryan Wu <cooloney@kernel.org>"); |
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c index e126b6b248e6..2e85d9473478 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/legacy/cdc2.c | |||
| @@ -231,18 +231,8 @@ static __refdata struct usb_composite_driver cdc_driver = { | |||
| 231 | .unbind = __exit_p(cdc_unbind), | 231 | .unbind = __exit_p(cdc_unbind), |
| 232 | }; | 232 | }; |
| 233 | 233 | ||
| 234 | module_usb_composite_driver(cdc_driver); | ||
| 235 | |||
| 234 | MODULE_DESCRIPTION(DRIVER_DESC); | 236 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 235 | MODULE_AUTHOR("David Brownell"); | 237 | MODULE_AUTHOR("David Brownell"); |
| 236 | MODULE_LICENSE("GPL"); | 238 | MODULE_LICENSE("GPL"); |
| 237 | |||
| 238 | static int __init init(void) | ||
| 239 | { | ||
| 240 | return usb_composite_probe(&cdc_driver); | ||
| 241 | } | ||
| 242 | module_init(init); | ||
| 243 | |||
| 244 | static void __exit cleanup(void) | ||
| 245 | { | ||
| 246 | usb_composite_unregister(&cdc_driver); | ||
| 247 | } | ||
| 248 | module_exit(cleanup); | ||
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 986fc511a2ed..225e385a6160 100644 --- a/drivers/usb/gadget/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/ether.c b/drivers/usb/gadget/legacy/ether.c index c1c113ef950c..c5fdc61cdc4a 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/legacy/ether.c | |||
| @@ -475,18 +475,8 @@ static __refdata struct usb_composite_driver eth_driver = { | |||
| 475 | .unbind = __exit_p(eth_unbind), | 475 | .unbind = __exit_p(eth_unbind), |
| 476 | }; | 476 | }; |
| 477 | 477 | ||
| 478 | module_usb_composite_driver(eth_driver); | ||
| 479 | |||
| 478 | MODULE_DESCRIPTION(PREFIX DRIVER_DESC); | 480 | MODULE_DESCRIPTION(PREFIX DRIVER_DESC); |
| 479 | MODULE_AUTHOR("David Brownell, Benedikt Spanger"); | 481 | MODULE_AUTHOR("David Brownell, Benedikt Spanger"); |
| 480 | MODULE_LICENSE("GPL"); | 482 | MODULE_LICENSE("GPL"); |
| 481 | |||
| 482 | static int __init init(void) | ||
| 483 | { | ||
| 484 | return usb_composite_probe(ð_driver); | ||
| 485 | } | ||
| 486 | module_init(init); | ||
| 487 | |||
| 488 | static void __exit cleanup(void) | ||
| 489 | { | ||
| 490 | usb_composite_unregister(ð_driver); | ||
| 491 | } | ||
| 492 | module_exit(cleanup); | ||
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c index fe12e6a27448..06acfa55864a 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/legacy/g_ffs.c | |||
| @@ -276,7 +276,7 @@ module_exit(gfs_exit); | |||
| 276 | static void *functionfs_acquire_dev(struct ffs_dev *dev) | 276 | static void *functionfs_acquire_dev(struct ffs_dev *dev) |
| 277 | { | 277 | { |
| 278 | if (!try_module_get(THIS_MODULE)) | 278 | if (!try_module_get(THIS_MODULE)) |
| 279 | return ERR_PTR(-ENODEV); | 279 | return ERR_PTR(-ENOENT); |
| 280 | 280 | ||
| 281 | return 0; | 281 | return 0; |
| 282 | } | 282 | } |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index e879e2c9f461..3d696b86ff76 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c | |||
| @@ -163,15 +163,4 @@ static __refdata struct usb_composite_driver midi_driver = { | |||
| 163 | .unbind = __exit_p(midi_unbind), | 163 | .unbind = __exit_p(midi_unbind), |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | static int __init midi_init(void) | 166 | module_usb_composite_driver(midi_driver); |
| 167 | { | ||
| 168 | return usb_composite_probe(&midi_driver); | ||
| 169 | } | ||
| 170 | module_init(midi_init); | ||
| 171 | |||
| 172 | static void __exit midi_cleanup(void) | ||
| 173 | { | ||
| 174 | usb_composite_unregister(&midi_driver); | ||
| 175 | } | ||
| 176 | module_exit(midi_cleanup); | ||
| 177 | |||
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/legacy/hid.c index 778613eb37af..778613eb37af 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/legacy/hid.c | |||
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/legacy/inode.c index 2e4ce7704908..e96077b8bf79 100644 --- a/drivers/usb/gadget/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/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c index 8e27a8c96444..8e27a8c96444 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/legacy/mass_storage.c | |||
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/legacy/multi.c index 940f6cde8e89..39d27bb343b4 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/legacy/multi.c | |||
| @@ -507,15 +507,4 @@ static __refdata struct usb_composite_driver multi_driver = { | |||
| 507 | .needs_serial = 1, | 507 | .needs_serial = 1, |
| 508 | }; | 508 | }; |
| 509 | 509 | ||
| 510 | 510 | module_usb_composite_driver(multi_driver); | |
| 511 | static int __init multi_init(void) | ||
| 512 | { | ||
| 513 | return usb_composite_probe(&multi_driver); | ||
| 514 | } | ||
| 515 | module_init(multi_init); | ||
| 516 | |||
| 517 | static void __exit multi_exit(void) | ||
| 518 | { | ||
| 519 | usb_composite_unregister(&multi_driver); | ||
| 520 | } | ||
| 521 | module_exit(multi_exit); | ||
diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/legacy/ncm.c index 81956feca1bd..e90e23db2acb 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/legacy/ncm.c | |||
| @@ -204,18 +204,8 @@ static __refdata struct usb_composite_driver ncm_driver = { | |||
| 204 | .unbind = __exit_p(gncm_unbind), | 204 | .unbind = __exit_p(gncm_unbind), |
| 205 | }; | 205 | }; |
| 206 | 206 | ||
| 207 | module_usb_composite_driver(ncm_driver); | ||
| 208 | |||
| 207 | MODULE_DESCRIPTION(DRIVER_DESC); | 209 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 208 | MODULE_AUTHOR("Yauheni Kaliuta"); | 210 | MODULE_AUTHOR("Yauheni Kaliuta"); |
| 209 | MODULE_LICENSE("GPL"); | 211 | MODULE_LICENSE("GPL"); |
| 210 | |||
| 211 | static int __init init(void) | ||
| 212 | { | ||
| 213 | return usb_composite_probe(&ncm_driver); | ||
| 214 | } | ||
| 215 | module_init(init); | ||
| 216 | |||
| 217 | static void __exit cleanup(void) | ||
| 218 | { | ||
| 219 | usb_composite_unregister(&ncm_driver); | ||
| 220 | } | ||
| 221 | module_exit(cleanup); | ||
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/legacy/nokia.c index 3ab386167519..9b8fd701648c 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/legacy/nokia.c | |||
| @@ -347,14 +347,4 @@ static __refdata struct usb_composite_driver nokia_driver = { | |||
| 347 | .unbind = __exit_p(nokia_unbind), | 347 | .unbind = __exit_p(nokia_unbind), |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | static int __init nokia_init(void) | 350 | module_usb_composite_driver(nokia_driver); |
| 351 | { | ||
| 352 | return usb_composite_probe(&nokia_driver); | ||
| 353 | } | ||
| 354 | module_init(nokia_init); | ||
| 355 | |||
| 356 | static void __exit nokia_cleanup(void) | ||
| 357 | { | ||
| 358 | usb_composite_unregister(&nokia_driver); | ||
| 359 | } | ||
| 360 | module_exit(nokia_cleanup); | ||
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/legacy/printer.c index 6474081dcbaf..6474081dcbaf 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/legacy/printer.c | |||
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/legacy/serial.c index 1f5f978d35d5..1f5f978d35d5 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/legacy/serial.c | |||
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 6cdb7a534f23..6cdb7a534f23 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c | |||
diff --git a/drivers/usb/gadget/tcm_usb_gadget.h b/drivers/usb/gadget/legacy/tcm_usb_gadget.h index 8289219925b8..8289219925b8 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.h +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.h | |||
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/legacy/webcam.c index 8cef1e658c29..a11d8e420bfe 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c | |||
| @@ -390,20 +390,7 @@ static __refdata struct usb_composite_driver webcam_driver = { | |||
| 390 | .unbind = webcam_unbind, | 390 | .unbind = webcam_unbind, |
| 391 | }; | 391 | }; |
| 392 | 392 | ||
| 393 | static int __init | 393 | module_usb_composite_driver(webcam_driver); |
| 394 | webcam_init(void) | ||
| 395 | { | ||
| 396 | return usb_composite_probe(&webcam_driver); | ||
| 397 | } | ||
| 398 | |||
| 399 | static void __exit | ||
| 400 | webcam_cleanup(void) | ||
| 401 | { | ||
| 402 | usb_composite_unregister(&webcam_driver); | ||
| 403 | } | ||
| 404 | |||
| 405 | module_init(webcam_init); | ||
| 406 | module_exit(webcam_cleanup); | ||
| 407 | 394 | ||
| 408 | MODULE_AUTHOR("Laurent Pinchart"); | 395 | MODULE_AUTHOR("Laurent Pinchart"); |
| 409 | MODULE_DESCRIPTION("Webcam Video Gadget"); | 396 | MODULE_DESCRIPTION("Webcam Video Gadget"); |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/legacy/zero.c index 134f354ede62..c3d496828b74 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/legacy/zero.c | |||
| @@ -411,17 +411,7 @@ static __refdata struct usb_composite_driver zero_driver = { | |||
| 411 | .resume = zero_resume, | 411 | .resume = zero_resume, |
| 412 | }; | 412 | }; |
| 413 | 413 | ||
| 414 | module_usb_composite_driver(zero_driver); | ||
| 415 | |||
| 414 | MODULE_AUTHOR("David Brownell"); | 416 | MODULE_AUTHOR("David Brownell"); |
| 415 | MODULE_LICENSE("GPL"); | 417 | MODULE_LICENSE("GPL"); |
| 416 | |||
| 417 | static int __init init(void) | ||
| 418 | { | ||
| 419 | return usb_composite_probe(&zero_driver); | ||
| 420 | } | ||
| 421 | module_init(init); | ||
| 422 | |||
| 423 | static void __exit cleanup(void) | ||
| 424 | { | ||
| 425 | usb_composite_unregister(&zero_driver); | ||
| 426 | } | ||
| 427 | module_exit(cleanup); | ||
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c deleted file mode 100644 index 300b3a71383b..000000000000 --- a/drivers/usb/gadget/net2280.c +++ /dev/null | |||
| @@ -1,2905 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the PLX NET2280 USB device controller. | ||
| 3 | * Specs and errata are available from <http://www.plxtech.com>. | ||
| 4 | * | ||
| 5 | * PLX Technology Inc. (formerly NetChip Technology) supported the | ||
| 6 | * development of this driver. | ||
| 7 | * | ||
| 8 | * | ||
| 9 | * CODE STATUS HIGHLIGHTS | ||
| 10 | * | ||
| 11 | * This driver should work well with most "gadget" drivers, including | ||
| 12 | * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers | ||
| 13 | * as well as Gadget Zero and Gadgetfs. | ||
| 14 | * | ||
| 15 | * DMA is enabled by default. Drivers using transfer queues might use | ||
| 16 | * DMA chaining to remove IRQ latencies between transfers. (Except when | ||
| 17 | * short OUT transfers happen.) Drivers can use the req->no_interrupt | ||
| 18 | * hint to completely eliminate some IRQs, if a later IRQ is guaranteed | ||
| 19 | * and DMA chaining is enabled. | ||
| 20 | * | ||
| 21 | * Note that almost all the errata workarounds here are only needed for | ||
| 22 | * rev1 chips. Rev1a silicon (0110) fixes almost all of them. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Copyright (C) 2003 David Brownell | ||
| 27 | * Copyright (C) 2003-2005 PLX Technology, Inc. | ||
| 28 | * | ||
| 29 | * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility | ||
| 30 | * with 2282 chip | ||
| 31 | * | ||
| 32 | * This program is free software; you can redistribute it and/or modify | ||
| 33 | * it under the terms of the GNU General Public License as published by | ||
| 34 | * the Free Software Foundation; either version 2 of the License, or | ||
| 35 | * (at your option) any later version. | ||
| 36 | */ | ||
| 37 | |||
| 38 | #undef DEBUG /* messages on error and most fault paths */ | ||
| 39 | #undef VERBOSE /* extra debug messages (success too) */ | ||
| 40 | |||
| 41 | #include <linux/module.h> | ||
| 42 | #include <linux/pci.h> | ||
| 43 | #include <linux/dma-mapping.h> | ||
| 44 | #include <linux/kernel.h> | ||
| 45 | #include <linux/delay.h> | ||
| 46 | #include <linux/ioport.h> | ||
| 47 | #include <linux/slab.h> | ||
| 48 | #include <linux/errno.h> | ||
| 49 | #include <linux/init.h> | ||
| 50 | #include <linux/timer.h> | ||
| 51 | #include <linux/list.h> | ||
| 52 | #include <linux/interrupt.h> | ||
| 53 | #include <linux/moduleparam.h> | ||
| 54 | #include <linux/device.h> | ||
| 55 | #include <linux/usb/ch9.h> | ||
| 56 | #include <linux/usb/gadget.h> | ||
| 57 | #include <linux/prefetch.h> | ||
| 58 | |||
| 59 | #include <asm/byteorder.h> | ||
| 60 | #include <asm/io.h> | ||
| 61 | #include <asm/irq.h> | ||
| 62 | #include <asm/unaligned.h> | ||
| 63 | |||
| 64 | |||
| 65 | #define DRIVER_DESC "PLX NET228x USB Peripheral Controller" | ||
| 66 | #define DRIVER_VERSION "2005 Sept 27" | ||
| 67 | |||
| 68 | #define EP_DONTUSE 13 /* nonzero */ | ||
| 69 | |||
| 70 | #define USE_RDK_LEDS /* GPIO pins control three LEDs */ | ||
| 71 | |||
| 72 | |||
| 73 | static const char driver_name [] = "net2280"; | ||
| 74 | static const char driver_desc [] = DRIVER_DESC; | ||
| 75 | |||
| 76 | static const char ep0name [] = "ep0"; | ||
| 77 | static const char *const ep_name [] = { | ||
| 78 | ep0name, | ||
| 79 | "ep-a", "ep-b", "ep-c", "ep-d", | ||
| 80 | "ep-e", "ep-f", | ||
| 81 | }; | ||
| 82 | |||
| 83 | /* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO) | ||
| 84 | * use_dma_chaining -- dma descriptor queueing gives even more irq reduction | ||
| 85 | * | ||
| 86 | * The net2280 DMA engines are not tightly integrated with their FIFOs; | ||
| 87 | * not all cases are (yet) handled well in this driver or the silicon. | ||
| 88 | * Some gadget drivers work better with the dma support here than others. | ||
| 89 | * These two parameters let you use PIO or more aggressive DMA. | ||
| 90 | */ | ||
| 91 | static bool use_dma = 1; | ||
| 92 | static bool use_dma_chaining = 0; | ||
| 93 | |||
| 94 | /* "modprobe net2280 use_dma=n" etc */ | ||
| 95 | module_param (use_dma, bool, S_IRUGO); | ||
| 96 | module_param (use_dma_chaining, bool, S_IRUGO); | ||
| 97 | |||
| 98 | |||
| 99 | /* mode 0 == ep-{a,b,c,d} 1K fifo each | ||
| 100 | * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable | ||
| 101 | * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable | ||
| 102 | */ | ||
| 103 | static ushort fifo_mode = 0; | ||
| 104 | |||
| 105 | /* "modprobe net2280 fifo_mode=1" etc */ | ||
| 106 | module_param (fifo_mode, ushort, 0644); | ||
| 107 | |||
| 108 | /* enable_suspend -- When enabled, the driver will respond to | ||
| 109 | * USB suspend requests by powering down the NET2280. Otherwise, | ||
| 110 | * USB suspend requests will be ignored. This is acceptable for | ||
| 111 | * self-powered devices | ||
| 112 | */ | ||
| 113 | static bool enable_suspend = 0; | ||
| 114 | |||
| 115 | /* "modprobe net2280 enable_suspend=1" etc */ | ||
| 116 | module_param (enable_suspend, bool, S_IRUGO); | ||
| 117 | |||
| 118 | /* force full-speed operation */ | ||
| 119 | static bool full_speed; | ||
| 120 | module_param(full_speed, bool, 0444); | ||
| 121 | MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!"); | ||
| 122 | |||
| 123 | #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") | ||
| 124 | |||
| 125 | #if defined(CONFIG_USB_GADGET_DEBUG_FILES) || defined (DEBUG) | ||
| 126 | static char *type_string (u8 bmAttributes) | ||
| 127 | { | ||
| 128 | switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) { | ||
| 129 | case USB_ENDPOINT_XFER_BULK: return "bulk"; | ||
| 130 | case USB_ENDPOINT_XFER_ISOC: return "iso"; | ||
| 131 | case USB_ENDPOINT_XFER_INT: return "intr"; | ||
| 132 | } | ||
| 133 | return "control"; | ||
| 134 | } | ||
| 135 | #endif | ||
| 136 | |||
| 137 | #include "net2280.h" | ||
| 138 | |||
| 139 | #define valid_bit cpu_to_le32 (1 << VALID_BIT) | ||
| 140 | #define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) | ||
| 141 | |||
| 142 | /*-------------------------------------------------------------------------*/ | ||
| 143 | |||
| 144 | static int | ||
| 145 | net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | ||
| 146 | { | ||
| 147 | struct net2280 *dev; | ||
| 148 | struct net2280_ep *ep; | ||
| 149 | u32 max, tmp; | ||
| 150 | unsigned long flags; | ||
| 151 | |||
| 152 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 153 | if (!_ep || !desc || ep->desc || _ep->name == ep0name | ||
| 154 | || desc->bDescriptorType != USB_DT_ENDPOINT) | ||
| 155 | return -EINVAL; | ||
| 156 | dev = ep->dev; | ||
| 157 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 158 | return -ESHUTDOWN; | ||
| 159 | |||
| 160 | /* erratum 0119 workaround ties up an endpoint number */ | ||
| 161 | if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) | ||
| 162 | return -EDOM; | ||
| 163 | |||
| 164 | /* sanity check ep-e/ep-f since their fifos are small */ | ||
| 165 | max = usb_endpoint_maxp (desc) & 0x1fff; | ||
| 166 | if (ep->num > 4 && max > 64) | ||
| 167 | return -ERANGE; | ||
| 168 | |||
| 169 | spin_lock_irqsave (&dev->lock, flags); | ||
| 170 | _ep->maxpacket = max & 0x7ff; | ||
| 171 | ep->desc = desc; | ||
| 172 | |||
| 173 | /* ep_reset() has already been called */ | ||
| 174 | ep->stopped = 0; | ||
| 175 | ep->wedged = 0; | ||
| 176 | ep->out_overflow = 0; | ||
| 177 | |||
| 178 | /* set speed-dependent max packet; may kick in high bandwidth */ | ||
| 179 | set_idx_reg (dev->regs, REG_EP_MAXPKT (dev, ep->num), max); | ||
| 180 | |||
| 181 | /* FIFO lines can't go to different packets. PIO is ok, so | ||
| 182 | * use it instead of troublesome (non-bulk) multi-packet DMA. | ||
| 183 | */ | ||
| 184 | if (ep->dma && (max % 4) != 0 && use_dma_chaining) { | ||
| 185 | DEBUG (ep->dev, "%s, no dma for maxpacket %d\n", | ||
| 186 | ep->ep.name, ep->ep.maxpacket); | ||
| 187 | ep->dma = NULL; | ||
| 188 | } | ||
| 189 | |||
| 190 | /* set type, direction, address; reset fifo counters */ | ||
| 191 | writel ((1 << FIFO_FLUSH), &ep->regs->ep_stat); | ||
| 192 | tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
| 193 | if (tmp == USB_ENDPOINT_XFER_INT) { | ||
| 194 | /* erratum 0105 workaround prevents hs NYET */ | ||
| 195 | if (dev->chiprev == 0100 | ||
| 196 | && dev->gadget.speed == USB_SPEED_HIGH | ||
| 197 | && !(desc->bEndpointAddress & USB_DIR_IN)) | ||
| 198 | writel ((1 << CLEAR_NAK_OUT_PACKETS_MODE), | ||
| 199 | &ep->regs->ep_rsp); | ||
| 200 | } else if (tmp == USB_ENDPOINT_XFER_BULK) { | ||
| 201 | /* catch some particularly blatant driver bugs */ | ||
| 202 | if ((dev->gadget.speed == USB_SPEED_HIGH | ||
| 203 | && max != 512) | ||
| 204 | || (dev->gadget.speed == USB_SPEED_FULL | ||
| 205 | && max > 64)) { | ||
| 206 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 207 | return -ERANGE; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0; | ||
| 211 | tmp <<= ENDPOINT_TYPE; | ||
| 212 | tmp |= desc->bEndpointAddress; | ||
| 213 | tmp |= (4 << ENDPOINT_BYTE_COUNT); /* default full fifo lines */ | ||
| 214 | tmp |= 1 << ENDPOINT_ENABLE; | ||
| 215 | wmb (); | ||
| 216 | |||
| 217 | /* for OUT transfers, block the rx fifo until a read is posted */ | ||
| 218 | ep->is_in = (tmp & USB_DIR_IN) != 0; | ||
| 219 | if (!ep->is_in) | ||
| 220 | writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 221 | else if (dev->pdev->device != 0x2280) { | ||
| 222 | /* Added for 2282, Don't use nak packets on an in endpoint, | ||
| 223 | * this was ignored on 2280 | ||
| 224 | */ | ||
| 225 | writel ((1 << CLEAR_NAK_OUT_PACKETS) | ||
| 226 | | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); | ||
| 227 | } | ||
| 228 | |||
| 229 | writel (tmp, &ep->regs->ep_cfg); | ||
| 230 | |||
| 231 | /* enable irqs */ | ||
| 232 | if (!ep->dma) { /* pio, per-packet */ | ||
| 233 | tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0); | ||
| 234 | writel (tmp, &dev->regs->pciirqenb0); | ||
| 235 | |||
| 236 | tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) | ||
| 237 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); | ||
| 238 | if (dev->pdev->device == 0x2280) | ||
| 239 | tmp |= readl (&ep->regs->ep_irqenb); | ||
| 240 | writel (tmp, &ep->regs->ep_irqenb); | ||
| 241 | } else { /* dma, per-request */ | ||
| 242 | tmp = (1 << (8 + ep->num)); /* completion */ | ||
| 243 | tmp |= readl (&dev->regs->pciirqenb1); | ||
| 244 | writel (tmp, &dev->regs->pciirqenb1); | ||
| 245 | |||
| 246 | /* for short OUT transfers, dma completions can't | ||
| 247 | * advance the queue; do it pio-style, by hand. | ||
| 248 | * NOTE erratum 0112 workaround #2 | ||
| 249 | */ | ||
| 250 | if ((desc->bEndpointAddress & USB_DIR_IN) == 0) { | ||
| 251 | tmp = (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE); | ||
| 252 | writel (tmp, &ep->regs->ep_irqenb); | ||
| 253 | |||
| 254 | tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0); | ||
| 255 | writel (tmp, &dev->regs->pciirqenb0); | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | tmp = desc->bEndpointAddress; | ||
| 260 | DEBUG (dev, "enabled %s (ep%d%s-%s) %s max %04x\n", | ||
| 261 | _ep->name, tmp & 0x0f, DIR_STRING (tmp), | ||
| 262 | type_string (desc->bmAttributes), | ||
| 263 | ep->dma ? "dma" : "pio", max); | ||
| 264 | |||
| 265 | /* pci writes may still be posted */ | ||
| 266 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 267 | return 0; | ||
| 268 | } | ||
| 269 | |||
| 270 | static int handshake (u32 __iomem *ptr, u32 mask, u32 done, int usec) | ||
| 271 | { | ||
| 272 | u32 result; | ||
| 273 | |||
| 274 | do { | ||
| 275 | result = readl (ptr); | ||
| 276 | if (result == ~(u32)0) /* "device unplugged" */ | ||
| 277 | return -ENODEV; | ||
| 278 | result &= mask; | ||
| 279 | if (result == done) | ||
| 280 | return 0; | ||
| 281 | udelay (1); | ||
| 282 | usec--; | ||
| 283 | } while (usec > 0); | ||
| 284 | return -ETIMEDOUT; | ||
| 285 | } | ||
| 286 | |||
| 287 | static const struct usb_ep_ops net2280_ep_ops; | ||
| 288 | |||
| 289 | static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) | ||
| 290 | { | ||
| 291 | u32 tmp; | ||
| 292 | |||
| 293 | ep->desc = NULL; | ||
| 294 | INIT_LIST_HEAD (&ep->queue); | ||
| 295 | |||
| 296 | usb_ep_set_maxpacket_limit(&ep->ep, ~0); | ||
| 297 | ep->ep.ops = &net2280_ep_ops; | ||
| 298 | |||
| 299 | /* disable the dma, irqs, endpoint... */ | ||
| 300 | if (ep->dma) { | ||
| 301 | writel (0, &ep->dma->dmactl); | ||
| 302 | writel ( (1 << DMA_SCATTER_GATHER_DONE_INTERRUPT) | ||
| 303 | | (1 << DMA_TRANSACTION_DONE_INTERRUPT) | ||
| 304 | | (1 << DMA_ABORT) | ||
| 305 | , &ep->dma->dmastat); | ||
| 306 | |||
| 307 | tmp = readl (®s->pciirqenb0); | ||
| 308 | tmp &= ~(1 << ep->num); | ||
| 309 | writel (tmp, ®s->pciirqenb0); | ||
| 310 | } else { | ||
| 311 | tmp = readl (®s->pciirqenb1); | ||
| 312 | tmp &= ~(1 << (8 + ep->num)); /* completion */ | ||
| 313 | writel (tmp, ®s->pciirqenb1); | ||
| 314 | } | ||
| 315 | writel (0, &ep->regs->ep_irqenb); | ||
| 316 | |||
| 317 | /* init to our chosen defaults, notably so that we NAK OUT | ||
| 318 | * packets until the driver queues a read (+note erratum 0112) | ||
| 319 | */ | ||
| 320 | if (!ep->is_in || ep->dev->pdev->device == 0x2280) { | ||
| 321 | tmp = (1 << SET_NAK_OUT_PACKETS_MODE) | ||
| 322 | | (1 << SET_NAK_OUT_PACKETS) | ||
| 323 | | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | ||
| 324 | | (1 << CLEAR_INTERRUPT_MODE); | ||
| 325 | } else { | ||
| 326 | /* added for 2282 */ | ||
| 327 | tmp = (1 << CLEAR_NAK_OUT_PACKETS_MODE) | ||
| 328 | | (1 << CLEAR_NAK_OUT_PACKETS) | ||
| 329 | | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | ||
| 330 | | (1 << CLEAR_INTERRUPT_MODE); | ||
| 331 | } | ||
| 332 | |||
| 333 | if (ep->num != 0) { | ||
| 334 | tmp |= (1 << CLEAR_ENDPOINT_TOGGLE) | ||
| 335 | | (1 << CLEAR_ENDPOINT_HALT); | ||
| 336 | } | ||
| 337 | writel (tmp, &ep->regs->ep_rsp); | ||
| 338 | |||
| 339 | /* scrub most status bits, and flush any fifo state */ | ||
| 340 | if (ep->dev->pdev->device == 0x2280) | ||
| 341 | tmp = (1 << FIFO_OVERFLOW) | ||
| 342 | | (1 << FIFO_UNDERFLOW); | ||
| 343 | else | ||
| 344 | tmp = 0; | ||
| 345 | |||
| 346 | writel (tmp | (1 << TIMEOUT) | ||
| 347 | | (1 << USB_STALL_SENT) | ||
| 348 | | (1 << USB_IN_NAK_SENT) | ||
| 349 | | (1 << USB_IN_ACK_RCVD) | ||
| 350 | | (1 << USB_OUT_PING_NAK_SENT) | ||
| 351 | | (1 << USB_OUT_ACK_SENT) | ||
| 352 | | (1 << FIFO_FLUSH) | ||
| 353 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | ||
| 354 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | ||
| 355 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | ||
| 356 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | ||
| 357 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 358 | | (1 << DATA_IN_TOKEN_INTERRUPT) | ||
| 359 | , &ep->regs->ep_stat); | ||
| 360 | |||
| 361 | /* fifo size is handled separately */ | ||
| 362 | } | ||
| 363 | |||
| 364 | static void nuke (struct net2280_ep *); | ||
| 365 | |||
| 366 | static int net2280_disable (struct usb_ep *_ep) | ||
| 367 | { | ||
| 368 | struct net2280_ep *ep; | ||
| 369 | unsigned long flags; | ||
| 370 | |||
| 371 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 372 | if (!_ep || !ep->desc || _ep->name == ep0name) | ||
| 373 | return -EINVAL; | ||
| 374 | |||
| 375 | spin_lock_irqsave (&ep->dev->lock, flags); | ||
| 376 | nuke (ep); | ||
| 377 | ep_reset (ep->dev->regs, ep); | ||
| 378 | |||
| 379 | VDEBUG (ep->dev, "disabled %s %s\n", | ||
| 380 | ep->dma ? "dma" : "pio", _ep->name); | ||
| 381 | |||
| 382 | /* synch memory views with the device */ | ||
| 383 | (void) readl (&ep->regs->ep_cfg); | ||
| 384 | |||
| 385 | if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4) | ||
| 386 | ep->dma = &ep->dev->dma [ep->num - 1]; | ||
| 387 | |||
| 388 | spin_unlock_irqrestore (&ep->dev->lock, flags); | ||
| 389 | return 0; | ||
| 390 | } | ||
| 391 | |||
| 392 | /*-------------------------------------------------------------------------*/ | ||
| 393 | |||
| 394 | static struct usb_request * | ||
| 395 | net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) | ||
| 396 | { | ||
| 397 | struct net2280_ep *ep; | ||
| 398 | struct net2280_request *req; | ||
| 399 | |||
| 400 | if (!_ep) | ||
| 401 | return NULL; | ||
| 402 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 403 | |||
| 404 | req = kzalloc(sizeof(*req), gfp_flags); | ||
| 405 | if (!req) | ||
| 406 | return NULL; | ||
| 407 | |||
| 408 | INIT_LIST_HEAD (&req->queue); | ||
| 409 | |||
| 410 | /* this dma descriptor may be swapped with the previous dummy */ | ||
| 411 | if (ep->dma) { | ||
| 412 | struct net2280_dma *td; | ||
| 413 | |||
| 414 | td = pci_pool_alloc (ep->dev->requests, gfp_flags, | ||
| 415 | &req->td_dma); | ||
| 416 | if (!td) { | ||
| 417 | kfree (req); | ||
| 418 | return NULL; | ||
| 419 | } | ||
| 420 | td->dmacount = 0; /* not VALID */ | ||
| 421 | td->dmadesc = td->dmaaddr; | ||
| 422 | req->td = td; | ||
| 423 | } | ||
| 424 | return &req->req; | ||
| 425 | } | ||
| 426 | |||
| 427 | static void | ||
| 428 | net2280_free_request (struct usb_ep *_ep, struct usb_request *_req) | ||
| 429 | { | ||
| 430 | struct net2280_ep *ep; | ||
| 431 | struct net2280_request *req; | ||
| 432 | |||
| 433 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 434 | if (!_ep || !_req) | ||
| 435 | return; | ||
| 436 | |||
| 437 | req = container_of (_req, struct net2280_request, req); | ||
| 438 | WARN_ON (!list_empty (&req->queue)); | ||
| 439 | if (req->td) | ||
| 440 | pci_pool_free (ep->dev->requests, req->td, req->td_dma); | ||
| 441 | kfree (req); | ||
| 442 | } | ||
| 443 | |||
| 444 | /*-------------------------------------------------------------------------*/ | ||
| 445 | |||
| 446 | /* load a packet into the fifo we use for usb IN transfers. | ||
| 447 | * works for all endpoints. | ||
| 448 | * | ||
| 449 | * NOTE: pio with ep-a..ep-d could stuff multiple packets into the fifo | ||
| 450 | * at a time, but this code is simpler because it knows it only writes | ||
| 451 | * one packet. ep-a..ep-d should use dma instead. | ||
| 452 | */ | ||
| 453 | static void | ||
| 454 | write_fifo (struct net2280_ep *ep, struct usb_request *req) | ||
| 455 | { | ||
| 456 | struct net2280_ep_regs __iomem *regs = ep->regs; | ||
| 457 | u8 *buf; | ||
| 458 | u32 tmp; | ||
| 459 | unsigned count, total; | ||
| 460 | |||
| 461 | /* INVARIANT: fifo is currently empty. (testable) */ | ||
| 462 | |||
| 463 | if (req) { | ||
| 464 | buf = req->buf + req->actual; | ||
| 465 | prefetch (buf); | ||
| 466 | total = req->length - req->actual; | ||
| 467 | } else { | ||
| 468 | total = 0; | ||
| 469 | buf = NULL; | ||
| 470 | } | ||
| 471 | |||
| 472 | /* write just one packet at a time */ | ||
| 473 | count = ep->ep.maxpacket; | ||
| 474 | if (count > total) /* min() cannot be used on a bitfield */ | ||
| 475 | count = total; | ||
| 476 | |||
| 477 | VDEBUG (ep->dev, "write %s fifo (IN) %d bytes%s req %p\n", | ||
| 478 | ep->ep.name, count, | ||
| 479 | (count != ep->ep.maxpacket) ? " (short)" : "", | ||
| 480 | req); | ||
| 481 | while (count >= 4) { | ||
| 482 | /* NOTE be careful if you try to align these. fifo lines | ||
| 483 | * should normally be full (4 bytes) and successive partial | ||
| 484 | * lines are ok only in certain cases. | ||
| 485 | */ | ||
| 486 | tmp = get_unaligned ((u32 *)buf); | ||
| 487 | cpu_to_le32s (&tmp); | ||
| 488 | writel (tmp, ®s->ep_data); | ||
| 489 | buf += 4; | ||
| 490 | count -= 4; | ||
| 491 | } | ||
| 492 | |||
| 493 | /* last fifo entry is "short" unless we wrote a full packet. | ||
| 494 | * also explicitly validate last word in (periodic) transfers | ||
| 495 | * when maxpacket is not a multiple of 4 bytes. | ||
| 496 | */ | ||
| 497 | if (count || total < ep->ep.maxpacket) { | ||
| 498 | tmp = count ? get_unaligned ((u32 *)buf) : count; | ||
| 499 | cpu_to_le32s (&tmp); | ||
| 500 | set_fifo_bytecount (ep, count & 0x03); | ||
| 501 | writel (tmp, ®s->ep_data); | ||
| 502 | } | ||
| 503 | |||
| 504 | /* pci writes may still be posted */ | ||
| 505 | } | ||
| 506 | |||
| 507 | /* work around erratum 0106: PCI and USB race over the OUT fifo. | ||
| 508 | * caller guarantees chiprev 0100, out endpoint is NAKing, and | ||
| 509 | * there's no real data in the fifo. | ||
| 510 | * | ||
| 511 | * NOTE: also used in cases where that erratum doesn't apply: | ||
| 512 | * where the host wrote "too much" data to us. | ||
| 513 | */ | ||
| 514 | static void out_flush (struct net2280_ep *ep) | ||
| 515 | { | ||
| 516 | u32 __iomem *statp; | ||
| 517 | u32 tmp; | ||
| 518 | |||
| 519 | ASSERT_OUT_NAKING (ep); | ||
| 520 | |||
| 521 | statp = &ep->regs->ep_stat; | ||
| 522 | writel ( (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 523 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | ||
| 524 | , statp); | ||
| 525 | writel ((1 << FIFO_FLUSH), statp); | ||
| 526 | mb (); | ||
| 527 | tmp = readl (statp); | ||
| 528 | if (tmp & (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 529 | /* high speed did bulk NYET; fifo isn't filling */ | ||
| 530 | && ep->dev->gadget.speed == USB_SPEED_FULL) { | ||
| 531 | unsigned usec; | ||
| 532 | |||
| 533 | usec = 50; /* 64 byte bulk/interrupt */ | ||
| 534 | handshake (statp, (1 << USB_OUT_PING_NAK_SENT), | ||
| 535 | (1 << USB_OUT_PING_NAK_SENT), usec); | ||
| 536 | /* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */ | ||
| 537 | } | ||
| 538 | } | ||
| 539 | |||
| 540 | /* unload packet(s) from the fifo we use for usb OUT transfers. | ||
| 541 | * returns true iff the request completed, because of short packet | ||
| 542 | * or the request buffer having filled with full packets. | ||
| 543 | * | ||
| 544 | * for ep-a..ep-d this will read multiple packets out when they | ||
| 545 | * have been accepted. | ||
| 546 | */ | ||
| 547 | static int | ||
| 548 | read_fifo (struct net2280_ep *ep, struct net2280_request *req) | ||
| 549 | { | ||
| 550 | struct net2280_ep_regs __iomem *regs = ep->regs; | ||
| 551 | u8 *buf = req->req.buf + req->req.actual; | ||
| 552 | unsigned count, tmp, is_short; | ||
| 553 | unsigned cleanup = 0, prevent = 0; | ||
| 554 | |||
| 555 | /* erratum 0106 ... packets coming in during fifo reads might | ||
| 556 | * be incompletely rejected. not all cases have workarounds. | ||
| 557 | */ | ||
| 558 | if (ep->dev->chiprev == 0x0100 | ||
| 559 | && ep->dev->gadget.speed == USB_SPEED_FULL) { | ||
| 560 | udelay (1); | ||
| 561 | tmp = readl (&ep->regs->ep_stat); | ||
| 562 | if ((tmp & (1 << NAK_OUT_PACKETS))) | ||
| 563 | cleanup = 1; | ||
| 564 | else if ((tmp & (1 << FIFO_FULL))) { | ||
| 565 | start_out_naking (ep); | ||
| 566 | prevent = 1; | ||
| 567 | } | ||
| 568 | /* else: hope we don't see the problem */ | ||
| 569 | } | ||
| 570 | |||
| 571 | /* never overflow the rx buffer. the fifo reads packets until | ||
| 572 | * it sees a short one; we might not be ready for them all. | ||
| 573 | */ | ||
| 574 | prefetchw (buf); | ||
| 575 | count = readl (®s->ep_avail); | ||
| 576 | if (unlikely (count == 0)) { | ||
| 577 | udelay (1); | ||
| 578 | tmp = readl (&ep->regs->ep_stat); | ||
| 579 | count = readl (®s->ep_avail); | ||
| 580 | /* handled that data already? */ | ||
| 581 | if (count == 0 && (tmp & (1 << NAK_OUT_PACKETS)) == 0) | ||
| 582 | return 0; | ||
| 583 | } | ||
| 584 | |||
| 585 | tmp = req->req.length - req->req.actual; | ||
| 586 | if (count > tmp) { | ||
| 587 | /* as with DMA, data overflow gets flushed */ | ||
| 588 | if ((tmp % ep->ep.maxpacket) != 0) { | ||
| 589 | ERROR (ep->dev, | ||
| 590 | "%s out fifo %d bytes, expected %d\n", | ||
| 591 | ep->ep.name, count, tmp); | ||
| 592 | req->req.status = -EOVERFLOW; | ||
| 593 | cleanup = 1; | ||
| 594 | /* NAK_OUT_PACKETS will be set, so flushing is safe; | ||
| 595 | * the next read will start with the next packet | ||
| 596 | */ | ||
| 597 | } /* else it's a ZLP, no worries */ | ||
| 598 | count = tmp; | ||
| 599 | } | ||
| 600 | req->req.actual += count; | ||
| 601 | |||
| 602 | is_short = (count == 0) || ((count % ep->ep.maxpacket) != 0); | ||
| 603 | |||
| 604 | VDEBUG (ep->dev, "read %s fifo (OUT) %d bytes%s%s%s req %p %d/%d\n", | ||
| 605 | ep->ep.name, count, is_short ? " (short)" : "", | ||
| 606 | cleanup ? " flush" : "", prevent ? " nak" : "", | ||
| 607 | req, req->req.actual, req->req.length); | ||
| 608 | |||
| 609 | while (count >= 4) { | ||
| 610 | tmp = readl (®s->ep_data); | ||
| 611 | cpu_to_le32s (&tmp); | ||
| 612 | put_unaligned (tmp, (u32 *)buf); | ||
| 613 | buf += 4; | ||
| 614 | count -= 4; | ||
| 615 | } | ||
| 616 | if (count) { | ||
| 617 | tmp = readl (®s->ep_data); | ||
| 618 | /* LE conversion is implicit here: */ | ||
| 619 | do { | ||
| 620 | *buf++ = (u8) tmp; | ||
| 621 | tmp >>= 8; | ||
| 622 | } while (--count); | ||
| 623 | } | ||
| 624 | if (cleanup) | ||
| 625 | out_flush (ep); | ||
| 626 | if (prevent) { | ||
| 627 | writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 628 | (void) readl (&ep->regs->ep_rsp); | ||
| 629 | } | ||
| 630 | |||
| 631 | return is_short || ((req->req.actual == req->req.length) | ||
| 632 | && !req->req.zero); | ||
| 633 | } | ||
| 634 | |||
| 635 | /* fill out dma descriptor to match a given request */ | ||
| 636 | static void | ||
| 637 | fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid) | ||
| 638 | { | ||
| 639 | struct net2280_dma *td = req->td; | ||
| 640 | u32 dmacount = req->req.length; | ||
| 641 | |||
| 642 | /* don't let DMA continue after a short OUT packet, | ||
| 643 | * so overruns can't affect the next transfer. | ||
| 644 | * in case of overruns on max-size packets, we can't | ||
| 645 | * stop the fifo from filling but we can flush it. | ||
| 646 | */ | ||
| 647 | if (ep->is_in) | ||
| 648 | dmacount |= (1 << DMA_DIRECTION); | ||
| 649 | if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) | ||
| 650 | || ep->dev->pdev->device != 0x2280) | ||
| 651 | dmacount |= (1 << END_OF_CHAIN); | ||
| 652 | |||
| 653 | req->valid = valid; | ||
| 654 | if (valid) | ||
| 655 | dmacount |= (1 << VALID_BIT); | ||
| 656 | if (likely(!req->req.no_interrupt || !use_dma_chaining)) | ||
| 657 | dmacount |= (1 << DMA_DONE_INTERRUPT_ENABLE); | ||
| 658 | |||
| 659 | /* td->dmadesc = previously set by caller */ | ||
| 660 | td->dmaaddr = cpu_to_le32 (req->req.dma); | ||
| 661 | |||
| 662 | /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */ | ||
| 663 | wmb (); | ||
| 664 | td->dmacount = cpu_to_le32(dmacount); | ||
| 665 | } | ||
| 666 | |||
| 667 | static const u32 dmactl_default = | ||
| 668 | (1 << DMA_SCATTER_GATHER_DONE_INTERRUPT) | ||
| 669 | | (1 << DMA_CLEAR_COUNT_ENABLE) | ||
| 670 | /* erratum 0116 workaround part 1 (use POLLING) */ | ||
| 671 | | (POLL_100_USEC << DESCRIPTOR_POLLING_RATE) | ||
| 672 | | (1 << DMA_VALID_BIT_POLLING_ENABLE) | ||
| 673 | | (1 << DMA_VALID_BIT_ENABLE) | ||
| 674 | | (1 << DMA_SCATTER_GATHER_ENABLE) | ||
| 675 | /* erratum 0116 workaround part 2 (no AUTOSTART) */ | ||
| 676 | | (1 << DMA_ENABLE); | ||
| 677 | |||
| 678 | static inline void spin_stop_dma (struct net2280_dma_regs __iomem *dma) | ||
| 679 | { | ||
| 680 | handshake (&dma->dmactl, (1 << DMA_ENABLE), 0, 50); | ||
| 681 | } | ||
| 682 | |||
| 683 | static inline void stop_dma (struct net2280_dma_regs __iomem *dma) | ||
| 684 | { | ||
| 685 | writel (readl (&dma->dmactl) & ~(1 << DMA_ENABLE), &dma->dmactl); | ||
| 686 | spin_stop_dma (dma); | ||
| 687 | } | ||
| 688 | |||
| 689 | static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) | ||
| 690 | { | ||
| 691 | struct net2280_dma_regs __iomem *dma = ep->dma; | ||
| 692 | unsigned int tmp = (1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION); | ||
| 693 | |||
| 694 | if (ep->dev->pdev->device != 0x2280) | ||
| 695 | tmp |= (1 << END_OF_CHAIN); | ||
| 696 | |||
| 697 | writel (tmp, &dma->dmacount); | ||
| 698 | writel (readl (&dma->dmastat), &dma->dmastat); | ||
| 699 | |||
| 700 | writel (td_dma, &dma->dmadesc); | ||
| 701 | writel (dmactl, &dma->dmactl); | ||
| 702 | |||
| 703 | /* erratum 0116 workaround part 3: pci arbiter away from net2280 */ | ||
| 704 | (void) readl (&ep->dev->pci->pcimstctl); | ||
| 705 | |||
| 706 | writel ((1 << DMA_START), &dma->dmastat); | ||
| 707 | |||
| 708 | if (!ep->is_in) | ||
| 709 | stop_out_naking (ep); | ||
| 710 | } | ||
| 711 | |||
| 712 | static void start_dma (struct net2280_ep *ep, struct net2280_request *req) | ||
| 713 | { | ||
| 714 | u32 tmp; | ||
| 715 | struct net2280_dma_regs __iomem *dma = ep->dma; | ||
| 716 | |||
| 717 | /* FIXME can't use DMA for ZLPs */ | ||
| 718 | |||
| 719 | /* on this path we "know" there's no dma active (yet) */ | ||
| 720 | WARN_ON (readl (&dma->dmactl) & (1 << DMA_ENABLE)); | ||
| 721 | writel (0, &ep->dma->dmactl); | ||
| 722 | |||
| 723 | /* previous OUT packet might have been short */ | ||
| 724 | if (!ep->is_in && ((tmp = readl (&ep->regs->ep_stat)) | ||
| 725 | & (1 << NAK_OUT_PACKETS)) != 0) { | ||
| 726 | writel ((1 << SHORT_PACKET_TRANSFERRED_INTERRUPT), | ||
| 727 | &ep->regs->ep_stat); | ||
| 728 | |||
| 729 | tmp = readl (&ep->regs->ep_avail); | ||
| 730 | if (tmp) { | ||
| 731 | writel (readl (&dma->dmastat), &dma->dmastat); | ||
| 732 | |||
| 733 | /* transfer all/some fifo data */ | ||
| 734 | writel (req->req.dma, &dma->dmaaddr); | ||
| 735 | tmp = min (tmp, req->req.length); | ||
| 736 | |||
| 737 | /* dma irq, faking scatterlist status */ | ||
| 738 | req->td->dmacount = cpu_to_le32 (req->req.length - tmp); | ||
| 739 | writel ((1 << DMA_DONE_INTERRUPT_ENABLE) | ||
| 740 | | tmp, &dma->dmacount); | ||
| 741 | req->td->dmadesc = 0; | ||
| 742 | req->valid = 1; | ||
| 743 | |||
| 744 | writel ((1 << DMA_ENABLE), &dma->dmactl); | ||
| 745 | writel ((1 << DMA_START), &dma->dmastat); | ||
| 746 | return; | ||
| 747 | } | ||
| 748 | } | ||
| 749 | |||
| 750 | tmp = dmactl_default; | ||
| 751 | |||
| 752 | /* force packet boundaries between dma requests, but prevent the | ||
| 753 | * controller from automagically writing a last "short" packet | ||
| 754 | * (zero length) unless the driver explicitly said to do that. | ||
| 755 | */ | ||
| 756 | if (ep->is_in) { | ||
| 757 | if (likely ((req->req.length % ep->ep.maxpacket) != 0 | ||
| 758 | || req->req.zero)) { | ||
| 759 | tmp |= (1 << DMA_FIFO_VALIDATE); | ||
| 760 | ep->in_fifo_validate = 1; | ||
| 761 | } else | ||
| 762 | ep->in_fifo_validate = 0; | ||
| 763 | } | ||
| 764 | |||
| 765 | /* init req->td, pointing to the current dummy */ | ||
| 766 | req->td->dmadesc = cpu_to_le32 (ep->td_dma); | ||
| 767 | fill_dma_desc (ep, req, 1); | ||
| 768 | |||
| 769 | if (!use_dma_chaining) | ||
| 770 | req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN); | ||
| 771 | |||
| 772 | start_queue (ep, tmp, req->td_dma); | ||
| 773 | } | ||
| 774 | |||
| 775 | static inline void | ||
| 776 | queue_dma (struct net2280_ep *ep, struct net2280_request *req, int valid) | ||
| 777 | { | ||
| 778 | struct net2280_dma *end; | ||
| 779 | dma_addr_t tmp; | ||
| 780 | |||
| 781 | /* swap new dummy for old, link; fill and maybe activate */ | ||
| 782 | end = ep->dummy; | ||
| 783 | ep->dummy = req->td; | ||
| 784 | req->td = end; | ||
| 785 | |||
| 786 | tmp = ep->td_dma; | ||
| 787 | ep->td_dma = req->td_dma; | ||
| 788 | req->td_dma = tmp; | ||
| 789 | |||
| 790 | end->dmadesc = cpu_to_le32 (ep->td_dma); | ||
| 791 | |||
| 792 | fill_dma_desc (ep, req, valid); | ||
| 793 | } | ||
| 794 | |||
| 795 | static void | ||
| 796 | done (struct net2280_ep *ep, struct net2280_request *req, int status) | ||
| 797 | { | ||
| 798 | struct net2280 *dev; | ||
| 799 | unsigned stopped = ep->stopped; | ||
| 800 | |||
| 801 | list_del_init (&req->queue); | ||
| 802 | |||
| 803 | if (req->req.status == -EINPROGRESS) | ||
| 804 | req->req.status = status; | ||
| 805 | else | ||
| 806 | status = req->req.status; | ||
| 807 | |||
| 808 | dev = ep->dev; | ||
| 809 | if (ep->dma) | ||
| 810 | usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in); | ||
| 811 | |||
| 812 | if (status && status != -ESHUTDOWN) | ||
| 813 | VDEBUG (dev, "complete %s req %p stat %d len %u/%u\n", | ||
| 814 | ep->ep.name, &req->req, status, | ||
| 815 | req->req.actual, req->req.length); | ||
| 816 | |||
| 817 | /* don't modify queue heads during completion callback */ | ||
| 818 | ep->stopped = 1; | ||
| 819 | spin_unlock (&dev->lock); | ||
| 820 | req->req.complete (&ep->ep, &req->req); | ||
| 821 | spin_lock (&dev->lock); | ||
| 822 | ep->stopped = stopped; | ||
| 823 | } | ||
| 824 | |||
| 825 | /*-------------------------------------------------------------------------*/ | ||
| 826 | |||
| 827 | static int | ||
| 828 | net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | ||
| 829 | { | ||
| 830 | struct net2280_request *req; | ||
| 831 | struct net2280_ep *ep; | ||
| 832 | struct net2280 *dev; | ||
| 833 | unsigned long flags; | ||
| 834 | |||
| 835 | /* we always require a cpu-view buffer, so that we can | ||
| 836 | * always use pio (as fallback or whatever). | ||
| 837 | */ | ||
| 838 | req = container_of (_req, struct net2280_request, req); | ||
| 839 | if (!_req || !_req->complete || !_req->buf | ||
| 840 | || !list_empty (&req->queue)) | ||
| 841 | return -EINVAL; | ||
| 842 | if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) | ||
| 843 | return -EDOM; | ||
| 844 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 845 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 846 | return -EINVAL; | ||
| 847 | dev = ep->dev; | ||
| 848 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 849 | return -ESHUTDOWN; | ||
| 850 | |||
| 851 | /* FIXME implement PIO fallback for ZLPs with DMA */ | ||
| 852 | if (ep->dma && _req->length == 0) | ||
| 853 | return -EOPNOTSUPP; | ||
| 854 | |||
| 855 | /* set up dma mapping in case the caller didn't */ | ||
| 856 | if (ep->dma) { | ||
| 857 | int ret; | ||
| 858 | |||
| 859 | ret = usb_gadget_map_request(&dev->gadget, _req, | ||
| 860 | ep->is_in); | ||
| 861 | if (ret) | ||
| 862 | return ret; | ||
| 863 | } | ||
| 864 | |||
| 865 | #if 0 | ||
| 866 | VDEBUG (dev, "%s queue req %p, len %d buf %p\n", | ||
| 867 | _ep->name, _req, _req->length, _req->buf); | ||
| 868 | #endif | ||
| 869 | |||
| 870 | spin_lock_irqsave (&dev->lock, flags); | ||
| 871 | |||
| 872 | _req->status = -EINPROGRESS; | ||
| 873 | _req->actual = 0; | ||
| 874 | |||
| 875 | /* kickstart this i/o queue? */ | ||
| 876 | if (list_empty (&ep->queue) && !ep->stopped) { | ||
| 877 | /* use DMA if the endpoint supports it, else pio */ | ||
| 878 | if (ep->dma) | ||
| 879 | start_dma (ep, req); | ||
| 880 | else { | ||
| 881 | /* maybe there's no control data, just status ack */ | ||
| 882 | if (ep->num == 0 && _req->length == 0) { | ||
| 883 | allow_status (ep); | ||
| 884 | done (ep, req, 0); | ||
| 885 | VDEBUG (dev, "%s status ack\n", ep->ep.name); | ||
| 886 | goto done; | ||
| 887 | } | ||
| 888 | |||
| 889 | /* PIO ... stuff the fifo, or unblock it. */ | ||
| 890 | if (ep->is_in) | ||
| 891 | write_fifo (ep, _req); | ||
| 892 | else if (list_empty (&ep->queue)) { | ||
| 893 | u32 s; | ||
| 894 | |||
| 895 | /* OUT FIFO might have packet(s) buffered */ | ||
| 896 | s = readl (&ep->regs->ep_stat); | ||
| 897 | if ((s & (1 << FIFO_EMPTY)) == 0) { | ||
| 898 | /* note: _req->short_not_ok is | ||
| 899 | * ignored here since PIO _always_ | ||
| 900 | * stops queue advance here, and | ||
| 901 | * _req->status doesn't change for | ||
| 902 | * short reads (only _req->actual) | ||
| 903 | */ | ||
| 904 | if (read_fifo (ep, req)) { | ||
| 905 | done (ep, req, 0); | ||
| 906 | if (ep->num == 0) | ||
| 907 | allow_status (ep); | ||
| 908 | /* don't queue it */ | ||
| 909 | req = NULL; | ||
| 910 | } else | ||
| 911 | s = readl (&ep->regs->ep_stat); | ||
| 912 | } | ||
| 913 | |||
| 914 | /* don't NAK, let the fifo fill */ | ||
| 915 | if (req && (s & (1 << NAK_OUT_PACKETS))) | ||
| 916 | writel ((1 << CLEAR_NAK_OUT_PACKETS), | ||
| 917 | &ep->regs->ep_rsp); | ||
| 918 | } | ||
| 919 | } | ||
| 920 | |||
| 921 | } else if (ep->dma) { | ||
| 922 | int valid = 1; | ||
| 923 | |||
| 924 | if (ep->is_in) { | ||
| 925 | int expect; | ||
| 926 | |||
| 927 | /* preventing magic zlps is per-engine state, not | ||
| 928 | * per-transfer; irq logic must recover hiccups. | ||
| 929 | */ | ||
| 930 | expect = likely (req->req.zero | ||
| 931 | || (req->req.length % ep->ep.maxpacket) != 0); | ||
| 932 | if (expect != ep->in_fifo_validate) | ||
| 933 | valid = 0; | ||
| 934 | } | ||
| 935 | queue_dma (ep, req, valid); | ||
| 936 | |||
| 937 | } /* else the irq handler advances the queue. */ | ||
| 938 | |||
| 939 | ep->responded = 1; | ||
| 940 | if (req) | ||
| 941 | list_add_tail (&req->queue, &ep->queue); | ||
| 942 | done: | ||
| 943 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 944 | |||
| 945 | /* pci writes may still be posted */ | ||
| 946 | return 0; | ||
| 947 | } | ||
| 948 | |||
| 949 | static inline void | ||
| 950 | dma_done ( | ||
| 951 | struct net2280_ep *ep, | ||
| 952 | struct net2280_request *req, | ||
| 953 | u32 dmacount, | ||
| 954 | int status | ||
| 955 | ) | ||
| 956 | { | ||
| 957 | req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount); | ||
| 958 | done (ep, req, status); | ||
| 959 | } | ||
| 960 | |||
| 961 | static void restart_dma (struct net2280_ep *ep); | ||
| 962 | |||
| 963 | static void scan_dma_completions (struct net2280_ep *ep) | ||
| 964 | { | ||
| 965 | /* only look at descriptors that were "naturally" retired, | ||
| 966 | * so fifo and list head state won't matter | ||
| 967 | */ | ||
| 968 | while (!list_empty (&ep->queue)) { | ||
| 969 | struct net2280_request *req; | ||
| 970 | u32 tmp; | ||
| 971 | |||
| 972 | req = list_entry (ep->queue.next, | ||
| 973 | struct net2280_request, queue); | ||
| 974 | if (!req->valid) | ||
| 975 | break; | ||
| 976 | rmb (); | ||
| 977 | tmp = le32_to_cpup (&req->td->dmacount); | ||
| 978 | if ((tmp & (1 << VALID_BIT)) != 0) | ||
| 979 | break; | ||
| 980 | |||
| 981 | /* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short" | ||
| 982 | * cases where DMA must be aborted; this code handles | ||
| 983 | * all non-abort DMA completions. | ||
| 984 | */ | ||
| 985 | if (unlikely (req->td->dmadesc == 0)) { | ||
| 986 | /* paranoia */ | ||
| 987 | tmp = readl (&ep->dma->dmacount); | ||
| 988 | if (tmp & DMA_BYTE_COUNT_MASK) | ||
| 989 | break; | ||
| 990 | /* single transfer mode */ | ||
| 991 | dma_done (ep, req, tmp, 0); | ||
| 992 | break; | ||
| 993 | } else if (!ep->is_in | ||
| 994 | && (req->req.length % ep->ep.maxpacket) != 0) { | ||
| 995 | tmp = readl (&ep->regs->ep_stat); | ||
| 996 | |||
| 997 | /* AVOID TROUBLE HERE by not issuing short reads from | ||
| 998 | * your gadget driver. That helps avoids errata 0121, | ||
| 999 | * 0122, and 0124; not all cases trigger the warning. | ||
| 1000 | */ | ||
| 1001 | if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) { | ||
| 1002 | WARNING (ep->dev, "%s lost packet sync!\n", | ||
| 1003 | ep->ep.name); | ||
| 1004 | req->req.status = -EOVERFLOW; | ||
| 1005 | } else if ((tmp = readl (&ep->regs->ep_avail)) != 0) { | ||
| 1006 | /* fifo gets flushed later */ | ||
| 1007 | ep->out_overflow = 1; | ||
| 1008 | DEBUG (ep->dev, "%s dma, discard %d len %d\n", | ||
| 1009 | ep->ep.name, tmp, | ||
| 1010 | req->req.length); | ||
| 1011 | req->req.status = -EOVERFLOW; | ||
| 1012 | } | ||
| 1013 | } | ||
| 1014 | dma_done (ep, req, tmp, 0); | ||
| 1015 | } | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | static void restart_dma (struct net2280_ep *ep) | ||
| 1019 | { | ||
| 1020 | struct net2280_request *req; | ||
| 1021 | u32 dmactl = dmactl_default; | ||
| 1022 | |||
| 1023 | if (ep->stopped) | ||
| 1024 | return; | ||
| 1025 | req = list_entry (ep->queue.next, struct net2280_request, queue); | ||
| 1026 | |||
| 1027 | if (!use_dma_chaining) { | ||
| 1028 | start_dma (ep, req); | ||
| 1029 | return; | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | /* the 2280 will be processing the queue unless queue hiccups after | ||
| 1033 | * the previous transfer: | ||
| 1034 | * IN: wanted automagic zlp, head doesn't (or vice versa) | ||
| 1035 | * DMA_FIFO_VALIDATE doesn't init from dma descriptors. | ||
| 1036 | * OUT: was "usb-short", we must restart. | ||
| 1037 | */ | ||
| 1038 | if (ep->is_in && !req->valid) { | ||
| 1039 | struct net2280_request *entry, *prev = NULL; | ||
| 1040 | int reqmode, done = 0; | ||
| 1041 | |||
| 1042 | DEBUG (ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td); | ||
| 1043 | ep->in_fifo_validate = likely (req->req.zero | ||
| 1044 | || (req->req.length % ep->ep.maxpacket) != 0); | ||
| 1045 | if (ep->in_fifo_validate) | ||
| 1046 | dmactl |= (1 << DMA_FIFO_VALIDATE); | ||
| 1047 | list_for_each_entry (entry, &ep->queue, queue) { | ||
| 1048 | __le32 dmacount; | ||
| 1049 | |||
| 1050 | if (entry == req) | ||
| 1051 | continue; | ||
| 1052 | dmacount = entry->td->dmacount; | ||
| 1053 | if (!done) { | ||
| 1054 | reqmode = likely (entry->req.zero | ||
| 1055 | || (entry->req.length | ||
| 1056 | % ep->ep.maxpacket) != 0); | ||
| 1057 | if (reqmode == ep->in_fifo_validate) { | ||
| 1058 | entry->valid = 1; | ||
| 1059 | dmacount |= valid_bit; | ||
| 1060 | entry->td->dmacount = dmacount; | ||
| 1061 | prev = entry; | ||
| 1062 | continue; | ||
| 1063 | } else { | ||
| 1064 | /* force a hiccup */ | ||
| 1065 | prev->td->dmacount |= dma_done_ie; | ||
| 1066 | done = 1; | ||
| 1067 | } | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | /* walk the rest of the queue so unlinks behave */ | ||
| 1071 | entry->valid = 0; | ||
| 1072 | dmacount &= ~valid_bit; | ||
| 1073 | entry->td->dmacount = dmacount; | ||
| 1074 | prev = entry; | ||
| 1075 | } | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | writel (0, &ep->dma->dmactl); | ||
| 1079 | start_queue (ep, dmactl, req->td_dma); | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | static void abort_dma (struct net2280_ep *ep) | ||
| 1083 | { | ||
| 1084 | /* abort the current transfer */ | ||
| 1085 | if (likely (!list_empty (&ep->queue))) { | ||
| 1086 | /* FIXME work around errata 0121, 0122, 0124 */ | ||
| 1087 | writel ((1 << DMA_ABORT), &ep->dma->dmastat); | ||
| 1088 | spin_stop_dma (ep->dma); | ||
| 1089 | } else | ||
| 1090 | stop_dma (ep->dma); | ||
| 1091 | scan_dma_completions (ep); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | /* dequeue ALL requests */ | ||
| 1095 | static void nuke (struct net2280_ep *ep) | ||
| 1096 | { | ||
| 1097 | struct net2280_request *req; | ||
| 1098 | |||
| 1099 | /* called with spinlock held */ | ||
| 1100 | ep->stopped = 1; | ||
| 1101 | if (ep->dma) | ||
| 1102 | abort_dma (ep); | ||
| 1103 | while (!list_empty (&ep->queue)) { | ||
| 1104 | req = list_entry (ep->queue.next, | ||
| 1105 | struct net2280_request, | ||
| 1106 | queue); | ||
| 1107 | done (ep, req, -ESHUTDOWN); | ||
| 1108 | } | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | /* dequeue JUST ONE request */ | ||
| 1112 | static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req) | ||
| 1113 | { | ||
| 1114 | struct net2280_ep *ep; | ||
| 1115 | struct net2280_request *req; | ||
| 1116 | unsigned long flags; | ||
| 1117 | u32 dmactl; | ||
| 1118 | int stopped; | ||
| 1119 | |||
| 1120 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 1121 | if (!_ep || (!ep->desc && ep->num != 0) || !_req) | ||
| 1122 | return -EINVAL; | ||
| 1123 | |||
| 1124 | spin_lock_irqsave (&ep->dev->lock, flags); | ||
| 1125 | stopped = ep->stopped; | ||
| 1126 | |||
| 1127 | /* quiesce dma while we patch the queue */ | ||
| 1128 | dmactl = 0; | ||
| 1129 | ep->stopped = 1; | ||
| 1130 | if (ep->dma) { | ||
| 1131 | dmactl = readl (&ep->dma->dmactl); | ||
| 1132 | /* WARNING erratum 0127 may kick in ... */ | ||
| 1133 | stop_dma (ep->dma); | ||
| 1134 | scan_dma_completions (ep); | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | /* make sure it's still queued on this endpoint */ | ||
| 1138 | list_for_each_entry (req, &ep->queue, queue) { | ||
| 1139 | if (&req->req == _req) | ||
| 1140 | break; | ||
| 1141 | } | ||
| 1142 | if (&req->req != _req) { | ||
| 1143 | spin_unlock_irqrestore (&ep->dev->lock, flags); | ||
| 1144 | return -EINVAL; | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | /* queue head may be partially complete. */ | ||
| 1148 | if (ep->queue.next == &req->queue) { | ||
| 1149 | if (ep->dma) { | ||
| 1150 | DEBUG (ep->dev, "unlink (%s) dma\n", _ep->name); | ||
| 1151 | _req->status = -ECONNRESET; | ||
| 1152 | abort_dma (ep); | ||
| 1153 | if (likely (ep->queue.next == &req->queue)) { | ||
| 1154 | // NOTE: misreports single-transfer mode | ||
| 1155 | req->td->dmacount = 0; /* invalidate */ | ||
| 1156 | dma_done (ep, req, | ||
| 1157 | readl (&ep->dma->dmacount), | ||
| 1158 | -ECONNRESET); | ||
| 1159 | } | ||
| 1160 | } else { | ||
| 1161 | DEBUG (ep->dev, "unlink (%s) pio\n", _ep->name); | ||
| 1162 | done (ep, req, -ECONNRESET); | ||
| 1163 | } | ||
| 1164 | req = NULL; | ||
| 1165 | |||
| 1166 | /* patch up hardware chaining data */ | ||
| 1167 | } else if (ep->dma && use_dma_chaining) { | ||
| 1168 | if (req->queue.prev == ep->queue.next) { | ||
| 1169 | writel (le32_to_cpu (req->td->dmadesc), | ||
| 1170 | &ep->dma->dmadesc); | ||
| 1171 | if (req->td->dmacount & dma_done_ie) | ||
| 1172 | writel (readl (&ep->dma->dmacount) | ||
| 1173 | | le32_to_cpu(dma_done_ie), | ||
| 1174 | &ep->dma->dmacount); | ||
| 1175 | } else { | ||
| 1176 | struct net2280_request *prev; | ||
| 1177 | |||
| 1178 | prev = list_entry (req->queue.prev, | ||
| 1179 | struct net2280_request, queue); | ||
| 1180 | prev->td->dmadesc = req->td->dmadesc; | ||
| 1181 | if (req->td->dmacount & dma_done_ie) | ||
| 1182 | prev->td->dmacount |= dma_done_ie; | ||
| 1183 | } | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | if (req) | ||
| 1187 | done (ep, req, -ECONNRESET); | ||
| 1188 | ep->stopped = stopped; | ||
| 1189 | |||
| 1190 | if (ep->dma) { | ||
| 1191 | /* turn off dma on inactive queues */ | ||
| 1192 | if (list_empty (&ep->queue)) | ||
| 1193 | stop_dma (ep->dma); | ||
| 1194 | else if (!ep->stopped) { | ||
| 1195 | /* resume current request, or start new one */ | ||
| 1196 | if (req) | ||
| 1197 | writel (dmactl, &ep->dma->dmactl); | ||
| 1198 | else | ||
| 1199 | start_dma (ep, list_entry (ep->queue.next, | ||
| 1200 | struct net2280_request, queue)); | ||
| 1201 | } | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | spin_unlock_irqrestore (&ep->dev->lock, flags); | ||
| 1205 | return 0; | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | /*-------------------------------------------------------------------------*/ | ||
| 1209 | |||
| 1210 | static int net2280_fifo_status (struct usb_ep *_ep); | ||
| 1211 | |||
| 1212 | static int | ||
| 1213 | net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) | ||
| 1214 | { | ||
| 1215 | struct net2280_ep *ep; | ||
| 1216 | unsigned long flags; | ||
| 1217 | int retval = 0; | ||
| 1218 | |||
| 1219 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 1220 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1221 | return -EINVAL; | ||
| 1222 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1223 | return -ESHUTDOWN; | ||
| 1224 | if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03) | ||
| 1225 | == USB_ENDPOINT_XFER_ISOC) | ||
| 1226 | return -EINVAL; | ||
| 1227 | |||
| 1228 | spin_lock_irqsave (&ep->dev->lock, flags); | ||
| 1229 | if (!list_empty (&ep->queue)) | ||
| 1230 | retval = -EAGAIN; | ||
| 1231 | else if (ep->is_in && value && net2280_fifo_status (_ep) != 0) | ||
| 1232 | retval = -EAGAIN; | ||
| 1233 | else { | ||
| 1234 | VDEBUG (ep->dev, "%s %s %s\n", _ep->name, | ||
| 1235 | value ? "set" : "clear", | ||
| 1236 | wedged ? "wedge" : "halt"); | ||
| 1237 | /* set/clear, then synch memory views with the device */ | ||
| 1238 | if (value) { | ||
| 1239 | if (ep->num == 0) | ||
| 1240 | ep->dev->protocol_stall = 1; | ||
| 1241 | else | ||
| 1242 | set_halt (ep); | ||
| 1243 | if (wedged) | ||
| 1244 | ep->wedged = 1; | ||
| 1245 | } else { | ||
| 1246 | clear_halt (ep); | ||
| 1247 | ep->wedged = 0; | ||
| 1248 | } | ||
| 1249 | (void) readl (&ep->regs->ep_rsp); | ||
| 1250 | } | ||
| 1251 | spin_unlock_irqrestore (&ep->dev->lock, flags); | ||
| 1252 | |||
| 1253 | return retval; | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | static int | ||
| 1257 | net2280_set_halt(struct usb_ep *_ep, int value) | ||
| 1258 | { | ||
| 1259 | return net2280_set_halt_and_wedge(_ep, value, 0); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | static int | ||
| 1263 | net2280_set_wedge(struct usb_ep *_ep) | ||
| 1264 | { | ||
| 1265 | if (!_ep || _ep->name == ep0name) | ||
| 1266 | return -EINVAL; | ||
| 1267 | return net2280_set_halt_and_wedge(_ep, 1, 1); | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | static int | ||
| 1271 | net2280_fifo_status (struct usb_ep *_ep) | ||
| 1272 | { | ||
| 1273 | struct net2280_ep *ep; | ||
| 1274 | u32 avail; | ||
| 1275 | |||
| 1276 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 1277 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1278 | return -ENODEV; | ||
| 1279 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1280 | return -ESHUTDOWN; | ||
| 1281 | |||
| 1282 | avail = readl (&ep->regs->ep_avail) & ((1 << 12) - 1); | ||
| 1283 | if (avail > ep->fifo_size) | ||
| 1284 | return -EOVERFLOW; | ||
| 1285 | if (ep->is_in) | ||
| 1286 | avail = ep->fifo_size - avail; | ||
| 1287 | return avail; | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | static void | ||
| 1291 | net2280_fifo_flush (struct usb_ep *_ep) | ||
| 1292 | { | ||
| 1293 | struct net2280_ep *ep; | ||
| 1294 | |||
| 1295 | ep = container_of (_ep, struct net2280_ep, ep); | ||
| 1296 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1297 | return; | ||
| 1298 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1299 | return; | ||
| 1300 | |||
| 1301 | writel ((1 << FIFO_FLUSH), &ep->regs->ep_stat); | ||
| 1302 | (void) readl (&ep->regs->ep_rsp); | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | static const struct usb_ep_ops net2280_ep_ops = { | ||
| 1306 | .enable = net2280_enable, | ||
| 1307 | .disable = net2280_disable, | ||
| 1308 | |||
| 1309 | .alloc_request = net2280_alloc_request, | ||
| 1310 | .free_request = net2280_free_request, | ||
| 1311 | |||
| 1312 | .queue = net2280_queue, | ||
| 1313 | .dequeue = net2280_dequeue, | ||
| 1314 | |||
| 1315 | .set_halt = net2280_set_halt, | ||
| 1316 | .set_wedge = net2280_set_wedge, | ||
| 1317 | .fifo_status = net2280_fifo_status, | ||
| 1318 | .fifo_flush = net2280_fifo_flush, | ||
| 1319 | }; | ||
| 1320 | |||
| 1321 | /*-------------------------------------------------------------------------*/ | ||
| 1322 | |||
| 1323 | static int net2280_get_frame (struct usb_gadget *_gadget) | ||
| 1324 | { | ||
| 1325 | struct net2280 *dev; | ||
| 1326 | unsigned long flags; | ||
| 1327 | u16 retval; | ||
| 1328 | |||
| 1329 | if (!_gadget) | ||
| 1330 | return -ENODEV; | ||
| 1331 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1332 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1333 | retval = get_idx_reg (dev->regs, REG_FRAME) & 0x03ff; | ||
| 1334 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1335 | return retval; | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | static int net2280_wakeup (struct usb_gadget *_gadget) | ||
| 1339 | { | ||
| 1340 | struct net2280 *dev; | ||
| 1341 | u32 tmp; | ||
| 1342 | unsigned long flags; | ||
| 1343 | |||
| 1344 | if (!_gadget) | ||
| 1345 | return 0; | ||
| 1346 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1347 | |||
| 1348 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1349 | tmp = readl (&dev->usb->usbctl); | ||
| 1350 | if (tmp & (1 << DEVICE_REMOTE_WAKEUP_ENABLE)) | ||
| 1351 | writel (1 << GENERATE_RESUME, &dev->usb->usbstat); | ||
| 1352 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1353 | |||
| 1354 | /* pci writes may still be posted */ | ||
| 1355 | return 0; | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | static int net2280_set_selfpowered (struct usb_gadget *_gadget, int value) | ||
| 1359 | { | ||
| 1360 | struct net2280 *dev; | ||
| 1361 | u32 tmp; | ||
| 1362 | unsigned long flags; | ||
| 1363 | |||
| 1364 | if (!_gadget) | ||
| 1365 | return 0; | ||
| 1366 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1367 | |||
| 1368 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1369 | tmp = readl (&dev->usb->usbctl); | ||
| 1370 | if (value) | ||
| 1371 | tmp |= (1 << SELF_POWERED_STATUS); | ||
| 1372 | else | ||
| 1373 | tmp &= ~(1 << SELF_POWERED_STATUS); | ||
| 1374 | writel (tmp, &dev->usb->usbctl); | ||
| 1375 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1376 | |||
| 1377 | return 0; | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | static int net2280_pullup(struct usb_gadget *_gadget, int is_on) | ||
| 1381 | { | ||
| 1382 | struct net2280 *dev; | ||
| 1383 | u32 tmp; | ||
| 1384 | unsigned long flags; | ||
| 1385 | |||
| 1386 | if (!_gadget) | ||
| 1387 | return -ENODEV; | ||
| 1388 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1389 | |||
| 1390 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1391 | tmp = readl (&dev->usb->usbctl); | ||
| 1392 | dev->softconnect = (is_on != 0); | ||
| 1393 | if (is_on) | ||
| 1394 | tmp |= (1 << USB_DETECT_ENABLE); | ||
| 1395 | else | ||
| 1396 | tmp &= ~(1 << USB_DETECT_ENABLE); | ||
| 1397 | writel (tmp, &dev->usb->usbctl); | ||
| 1398 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1399 | |||
| 1400 | return 0; | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | static int net2280_start(struct usb_gadget *_gadget, | ||
| 1404 | struct usb_gadget_driver *driver); | ||
| 1405 | static int net2280_stop(struct usb_gadget *_gadget, | ||
| 1406 | struct usb_gadget_driver *driver); | ||
| 1407 | |||
| 1408 | static const struct usb_gadget_ops net2280_ops = { | ||
| 1409 | .get_frame = net2280_get_frame, | ||
| 1410 | .wakeup = net2280_wakeup, | ||
| 1411 | .set_selfpowered = net2280_set_selfpowered, | ||
| 1412 | .pullup = net2280_pullup, | ||
| 1413 | .udc_start = net2280_start, | ||
| 1414 | .udc_stop = net2280_stop, | ||
| 1415 | }; | ||
| 1416 | |||
| 1417 | /*-------------------------------------------------------------------------*/ | ||
| 1418 | |||
| 1419 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
| 1420 | |||
| 1421 | /* FIXME move these into procfs, and use seq_file. | ||
| 1422 | * Sysfs _still_ doesn't behave for arbitrarily sized files, | ||
| 1423 | * and also doesn't help products using this with 2.4 kernels. | ||
| 1424 | */ | ||
| 1425 | |||
| 1426 | /* "function" sysfs attribute */ | ||
| 1427 | static ssize_t function_show(struct device *_dev, struct device_attribute *attr, | ||
| 1428 | char *buf) | ||
| 1429 | { | ||
| 1430 | struct net2280 *dev = dev_get_drvdata (_dev); | ||
| 1431 | |||
| 1432 | if (!dev->driver | ||
| 1433 | || !dev->driver->function | ||
| 1434 | || strlen (dev->driver->function) > PAGE_SIZE) | ||
| 1435 | return 0; | ||
| 1436 | return scnprintf (buf, PAGE_SIZE, "%s\n", dev->driver->function); | ||
| 1437 | } | ||
| 1438 | static DEVICE_ATTR_RO(function); | ||
| 1439 | |||
| 1440 | static ssize_t registers_show(struct device *_dev, | ||
| 1441 | struct device_attribute *attr, char *buf) | ||
| 1442 | { | ||
| 1443 | struct net2280 *dev; | ||
| 1444 | char *next; | ||
| 1445 | unsigned size, t; | ||
| 1446 | unsigned long flags; | ||
| 1447 | int i; | ||
| 1448 | u32 t1, t2; | ||
| 1449 | const char *s; | ||
| 1450 | |||
| 1451 | dev = dev_get_drvdata (_dev); | ||
| 1452 | next = buf; | ||
| 1453 | size = PAGE_SIZE; | ||
| 1454 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1455 | |||
| 1456 | if (dev->driver) | ||
| 1457 | s = dev->driver->driver.name; | ||
| 1458 | else | ||
| 1459 | s = "(none)"; | ||
| 1460 | |||
| 1461 | /* Main Control Registers */ | ||
| 1462 | t = scnprintf (next, size, "%s version " DRIVER_VERSION | ||
| 1463 | ", chiprev %04x, dma %s\n\n" | ||
| 1464 | "devinit %03x fifoctl %08x gadget '%s'\n" | ||
| 1465 | "pci irqenb0 %02x irqenb1 %08x " | ||
| 1466 | "irqstat0 %04x irqstat1 %08x\n", | ||
| 1467 | driver_name, dev->chiprev, | ||
| 1468 | use_dma | ||
| 1469 | ? (use_dma_chaining ? "chaining" : "enabled") | ||
| 1470 | : "disabled", | ||
| 1471 | readl (&dev->regs->devinit), | ||
| 1472 | readl (&dev->regs->fifoctl), | ||
| 1473 | s, | ||
| 1474 | readl (&dev->regs->pciirqenb0), | ||
| 1475 | readl (&dev->regs->pciirqenb1), | ||
| 1476 | readl (&dev->regs->irqstat0), | ||
| 1477 | readl (&dev->regs->irqstat1)); | ||
| 1478 | size -= t; | ||
| 1479 | next += t; | ||
| 1480 | |||
| 1481 | /* USB Control Registers */ | ||
| 1482 | t1 = readl (&dev->usb->usbctl); | ||
| 1483 | t2 = readl (&dev->usb->usbstat); | ||
| 1484 | if (t1 & (1 << VBUS_PIN)) { | ||
| 1485 | if (t2 & (1 << HIGH_SPEED)) | ||
| 1486 | s = "high speed"; | ||
| 1487 | else if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1488 | s = "powered"; | ||
| 1489 | else | ||
| 1490 | s = "full speed"; | ||
| 1491 | /* full speed bit (6) not working?? */ | ||
| 1492 | } else | ||
| 1493 | s = "not attached"; | ||
| 1494 | t = scnprintf (next, size, | ||
| 1495 | "stdrsp %08x usbctl %08x usbstat %08x " | ||
| 1496 | "addr 0x%02x (%s)\n", | ||
| 1497 | readl (&dev->usb->stdrsp), t1, t2, | ||
| 1498 | readl (&dev->usb->ouraddr), s); | ||
| 1499 | size -= t; | ||
| 1500 | next += t; | ||
| 1501 | |||
| 1502 | /* PCI Master Control Registers */ | ||
| 1503 | |||
| 1504 | /* DMA Control Registers */ | ||
| 1505 | |||
| 1506 | /* Configurable EP Control Registers */ | ||
| 1507 | for (i = 0; i < 7; i++) { | ||
| 1508 | struct net2280_ep *ep; | ||
| 1509 | |||
| 1510 | ep = &dev->ep [i]; | ||
| 1511 | if (i && !ep->desc) | ||
| 1512 | continue; | ||
| 1513 | |||
| 1514 | t1 = readl (&ep->regs->ep_cfg); | ||
| 1515 | t2 = readl (&ep->regs->ep_rsp) & 0xff; | ||
| 1516 | t = scnprintf (next, size, | ||
| 1517 | "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" | ||
| 1518 | "irqenb %02x\n", | ||
| 1519 | ep->ep.name, t1, t2, | ||
| 1520 | (t2 & (1 << CLEAR_NAK_OUT_PACKETS)) | ||
| 1521 | ? "NAK " : "", | ||
| 1522 | (t2 & (1 << CLEAR_EP_HIDE_STATUS_PHASE)) | ||
| 1523 | ? "hide " : "", | ||
| 1524 | (t2 & (1 << CLEAR_EP_FORCE_CRC_ERROR)) | ||
| 1525 | ? "CRC " : "", | ||
| 1526 | (t2 & (1 << CLEAR_INTERRUPT_MODE)) | ||
| 1527 | ? "interrupt " : "", | ||
| 1528 | (t2 & (1<<CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)) | ||
| 1529 | ? "status " : "", | ||
| 1530 | (t2 & (1 << CLEAR_NAK_OUT_PACKETS_MODE)) | ||
| 1531 | ? "NAKmode " : "", | ||
| 1532 | (t2 & (1 << CLEAR_ENDPOINT_TOGGLE)) | ||
| 1533 | ? "DATA1 " : "DATA0 ", | ||
| 1534 | (t2 & (1 << CLEAR_ENDPOINT_HALT)) | ||
| 1535 | ? "HALT " : "", | ||
| 1536 | readl (&ep->regs->ep_irqenb)); | ||
| 1537 | size -= t; | ||
| 1538 | next += t; | ||
| 1539 | |||
| 1540 | t = scnprintf (next, size, | ||
| 1541 | "\tstat %08x avail %04x " | ||
| 1542 | "(ep%d%s-%s)%s\n", | ||
| 1543 | readl (&ep->regs->ep_stat), | ||
| 1544 | readl (&ep->regs->ep_avail), | ||
| 1545 | t1 & 0x0f, DIR_STRING (t1), | ||
| 1546 | type_string (t1 >> 8), | ||
| 1547 | ep->stopped ? "*" : ""); | ||
| 1548 | size -= t; | ||
| 1549 | next += t; | ||
| 1550 | |||
| 1551 | if (!ep->dma) | ||
| 1552 | continue; | ||
| 1553 | |||
| 1554 | t = scnprintf (next, size, | ||
| 1555 | " dma\tctl %08x stat %08x count %08x\n" | ||
| 1556 | "\taddr %08x desc %08x\n", | ||
| 1557 | readl (&ep->dma->dmactl), | ||
| 1558 | readl (&ep->dma->dmastat), | ||
| 1559 | readl (&ep->dma->dmacount), | ||
| 1560 | readl (&ep->dma->dmaaddr), | ||
| 1561 | readl (&ep->dma->dmadesc)); | ||
| 1562 | size -= t; | ||
| 1563 | next += t; | ||
| 1564 | |||
| 1565 | } | ||
| 1566 | |||
| 1567 | /* Indexed Registers */ | ||
| 1568 | // none yet | ||
| 1569 | |||
| 1570 | /* Statistics */ | ||
| 1571 | t = scnprintf (next, size, "\nirqs: "); | ||
| 1572 | size -= t; | ||
| 1573 | next += t; | ||
| 1574 | for (i = 0; i < 7; i++) { | ||
| 1575 | struct net2280_ep *ep; | ||
| 1576 | |||
| 1577 | ep = &dev->ep [i]; | ||
| 1578 | if (i && !ep->irqs) | ||
| 1579 | continue; | ||
| 1580 | t = scnprintf (next, size, " %s/%lu", ep->ep.name, ep->irqs); | ||
| 1581 | size -= t; | ||
| 1582 | next += t; | ||
| 1583 | |||
| 1584 | } | ||
| 1585 | t = scnprintf (next, size, "\n"); | ||
| 1586 | size -= t; | ||
| 1587 | next += t; | ||
| 1588 | |||
| 1589 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1590 | |||
| 1591 | return PAGE_SIZE - size; | ||
| 1592 | } | ||
| 1593 | static DEVICE_ATTR_RO(registers); | ||
| 1594 | |||
| 1595 | static ssize_t queues_show(struct device *_dev, struct device_attribute *attr, | ||
| 1596 | char *buf) | ||
| 1597 | { | ||
| 1598 | struct net2280 *dev; | ||
| 1599 | char *next; | ||
| 1600 | unsigned size; | ||
| 1601 | unsigned long flags; | ||
| 1602 | int i; | ||
| 1603 | |||
| 1604 | dev = dev_get_drvdata (_dev); | ||
| 1605 | next = buf; | ||
| 1606 | size = PAGE_SIZE; | ||
| 1607 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1608 | |||
| 1609 | for (i = 0; i < 7; i++) { | ||
| 1610 | struct net2280_ep *ep = &dev->ep [i]; | ||
| 1611 | struct net2280_request *req; | ||
| 1612 | int t; | ||
| 1613 | |||
| 1614 | if (i != 0) { | ||
| 1615 | const struct usb_endpoint_descriptor *d; | ||
| 1616 | |||
| 1617 | d = ep->desc; | ||
| 1618 | if (!d) | ||
| 1619 | continue; | ||
| 1620 | t = d->bEndpointAddress; | ||
| 1621 | t = scnprintf (next, size, | ||
| 1622 | "\n%s (ep%d%s-%s) max %04x %s fifo %d\n", | ||
| 1623 | ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK, | ||
| 1624 | (t & USB_DIR_IN) ? "in" : "out", | ||
| 1625 | ({ char *val; | ||
| 1626 | switch (d->bmAttributes & 0x03) { | ||
| 1627 | case USB_ENDPOINT_XFER_BULK: | ||
| 1628 | val = "bulk"; break; | ||
| 1629 | case USB_ENDPOINT_XFER_INT: | ||
| 1630 | val = "intr"; break; | ||
| 1631 | default: | ||
| 1632 | val = "iso"; break; | ||
| 1633 | } val; }), | ||
| 1634 | usb_endpoint_maxp (d) & 0x1fff, | ||
| 1635 | ep->dma ? "dma" : "pio", ep->fifo_size | ||
| 1636 | ); | ||
| 1637 | } else /* ep0 should only have one transfer queued */ | ||
| 1638 | t = scnprintf (next, size, "ep0 max 64 pio %s\n", | ||
| 1639 | ep->is_in ? "in" : "out"); | ||
| 1640 | if (t <= 0 || t > size) | ||
| 1641 | goto done; | ||
| 1642 | size -= t; | ||
| 1643 | next += t; | ||
| 1644 | |||
| 1645 | if (list_empty (&ep->queue)) { | ||
| 1646 | t = scnprintf (next, size, "\t(nothing queued)\n"); | ||
| 1647 | if (t <= 0 || t > size) | ||
| 1648 | goto done; | ||
| 1649 | size -= t; | ||
| 1650 | next += t; | ||
| 1651 | continue; | ||
| 1652 | } | ||
| 1653 | list_for_each_entry (req, &ep->queue, queue) { | ||
| 1654 | if (ep->dma && req->td_dma == readl (&ep->dma->dmadesc)) | ||
| 1655 | t = scnprintf (next, size, | ||
| 1656 | "\treq %p len %d/%d " | ||
| 1657 | "buf %p (dmacount %08x)\n", | ||
| 1658 | &req->req, req->req.actual, | ||
| 1659 | req->req.length, req->req.buf, | ||
| 1660 | readl (&ep->dma->dmacount)); | ||
| 1661 | else | ||
| 1662 | t = scnprintf (next, size, | ||
| 1663 | "\treq %p len %d/%d buf %p\n", | ||
| 1664 | &req->req, req->req.actual, | ||
| 1665 | req->req.length, req->req.buf); | ||
| 1666 | if (t <= 0 || t > size) | ||
| 1667 | goto done; | ||
| 1668 | size -= t; | ||
| 1669 | next += t; | ||
| 1670 | |||
| 1671 | if (ep->dma) { | ||
| 1672 | struct net2280_dma *td; | ||
| 1673 | |||
| 1674 | td = req->td; | ||
| 1675 | t = scnprintf (next, size, "\t td %08x " | ||
| 1676 | " count %08x buf %08x desc %08x\n", | ||
| 1677 | (u32) req->td_dma, | ||
| 1678 | le32_to_cpu (td->dmacount), | ||
| 1679 | le32_to_cpu (td->dmaaddr), | ||
| 1680 | le32_to_cpu (td->dmadesc)); | ||
| 1681 | if (t <= 0 || t > size) | ||
| 1682 | goto done; | ||
| 1683 | size -= t; | ||
| 1684 | next += t; | ||
| 1685 | } | ||
| 1686 | } | ||
| 1687 | } | ||
| 1688 | |||
| 1689 | done: | ||
| 1690 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1691 | return PAGE_SIZE - size; | ||
| 1692 | } | ||
| 1693 | static DEVICE_ATTR_RO(queues); | ||
| 1694 | |||
| 1695 | |||
| 1696 | #else | ||
| 1697 | |||
| 1698 | #define device_create_file(a,b) (0) | ||
| 1699 | #define device_remove_file(a,b) do { } while (0) | ||
| 1700 | |||
| 1701 | #endif | ||
| 1702 | |||
| 1703 | /*-------------------------------------------------------------------------*/ | ||
| 1704 | |||
| 1705 | /* another driver-specific mode might be a request type doing dma | ||
| 1706 | * to/from another device fifo instead of to/from memory. | ||
| 1707 | */ | ||
| 1708 | |||
| 1709 | static void set_fifo_mode (struct net2280 *dev, int mode) | ||
| 1710 | { | ||
| 1711 | /* keeping high bits preserves BAR2 */ | ||
| 1712 | writel ((0xffff << PCI_BASE2_RANGE) | mode, &dev->regs->fifoctl); | ||
| 1713 | |||
| 1714 | /* always ep-{a,b,e,f} ... maybe not ep-c or ep-d */ | ||
| 1715 | INIT_LIST_HEAD (&dev->gadget.ep_list); | ||
| 1716 | list_add_tail (&dev->ep [1].ep.ep_list, &dev->gadget.ep_list); | ||
| 1717 | list_add_tail (&dev->ep [2].ep.ep_list, &dev->gadget.ep_list); | ||
| 1718 | switch (mode) { | ||
| 1719 | case 0: | ||
| 1720 | list_add_tail (&dev->ep [3].ep.ep_list, &dev->gadget.ep_list); | ||
| 1721 | list_add_tail (&dev->ep [4].ep.ep_list, &dev->gadget.ep_list); | ||
| 1722 | dev->ep [1].fifo_size = dev->ep [2].fifo_size = 1024; | ||
| 1723 | break; | ||
| 1724 | case 1: | ||
| 1725 | dev->ep [1].fifo_size = dev->ep [2].fifo_size = 2048; | ||
| 1726 | break; | ||
| 1727 | case 2: | ||
| 1728 | list_add_tail (&dev->ep [3].ep.ep_list, &dev->gadget.ep_list); | ||
| 1729 | dev->ep [1].fifo_size = 2048; | ||
| 1730 | dev->ep [2].fifo_size = 1024; | ||
| 1731 | break; | ||
| 1732 | } | ||
| 1733 | /* fifo sizes for ep0, ep-c, ep-d, ep-e, and ep-f never change */ | ||
| 1734 | list_add_tail (&dev->ep [5].ep.ep_list, &dev->gadget.ep_list); | ||
| 1735 | list_add_tail (&dev->ep [6].ep.ep_list, &dev->gadget.ep_list); | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | /* keeping it simple: | ||
| 1739 | * - one bus driver, initted first; | ||
| 1740 | * - one function driver, initted second | ||
| 1741 | * | ||
| 1742 | * most of the work to support multiple net2280 controllers would | ||
| 1743 | * be to associate this gadget driver (yes?) with all of them, or | ||
| 1744 | * perhaps to bind specific drivers to specific devices. | ||
| 1745 | */ | ||
| 1746 | |||
| 1747 | static void usb_reset (struct net2280 *dev) | ||
| 1748 | { | ||
| 1749 | u32 tmp; | ||
| 1750 | |||
| 1751 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1752 | (void) readl (&dev->usb->usbctl); | ||
| 1753 | |||
| 1754 | net2280_led_init (dev); | ||
| 1755 | |||
| 1756 | /* disable automatic responses, and irqs */ | ||
| 1757 | writel (0, &dev->usb->stdrsp); | ||
| 1758 | writel (0, &dev->regs->pciirqenb0); | ||
| 1759 | writel (0, &dev->regs->pciirqenb1); | ||
| 1760 | |||
| 1761 | /* clear old dma and irq state */ | ||
| 1762 | for (tmp = 0; tmp < 4; tmp++) { | ||
| 1763 | struct net2280_ep *ep = &dev->ep [tmp + 1]; | ||
| 1764 | |||
| 1765 | if (ep->dma) | ||
| 1766 | abort_dma (ep); | ||
| 1767 | } | ||
| 1768 | writel (~0, &dev->regs->irqstat0), | ||
| 1769 | writel (~(1 << SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1), | ||
| 1770 | |||
| 1771 | /* reset, and enable pci */ | ||
| 1772 | tmp = readl (&dev->regs->devinit) | ||
| 1773 | | (1 << PCI_ENABLE) | ||
| 1774 | | (1 << FIFO_SOFT_RESET) | ||
| 1775 | | (1 << USB_SOFT_RESET) | ||
| 1776 | | (1 << M8051_RESET); | ||
| 1777 | writel (tmp, &dev->regs->devinit); | ||
| 1778 | |||
| 1779 | /* standard fifo and endpoint allocations */ | ||
| 1780 | set_fifo_mode (dev, (fifo_mode <= 2) ? fifo_mode : 0); | ||
| 1781 | } | ||
| 1782 | |||
| 1783 | static void usb_reinit (struct net2280 *dev) | ||
| 1784 | { | ||
| 1785 | u32 tmp; | ||
| 1786 | int init_dma; | ||
| 1787 | |||
| 1788 | /* use_dma changes are ignored till next device re-init */ | ||
| 1789 | init_dma = use_dma; | ||
| 1790 | |||
| 1791 | /* basic endpoint init */ | ||
| 1792 | for (tmp = 0; tmp < 7; tmp++) { | ||
| 1793 | struct net2280_ep *ep = &dev->ep [tmp]; | ||
| 1794 | |||
| 1795 | ep->ep.name = ep_name [tmp]; | ||
| 1796 | ep->dev = dev; | ||
| 1797 | ep->num = tmp; | ||
| 1798 | |||
| 1799 | if (tmp > 0 && tmp <= 4) { | ||
| 1800 | ep->fifo_size = 1024; | ||
| 1801 | if (init_dma) | ||
| 1802 | ep->dma = &dev->dma [tmp - 1]; | ||
| 1803 | } else | ||
| 1804 | ep->fifo_size = 64; | ||
| 1805 | ep->regs = &dev->epregs [tmp]; | ||
| 1806 | ep_reset (dev->regs, ep); | ||
| 1807 | } | ||
| 1808 | usb_ep_set_maxpacket_limit(&dev->ep [0].ep, 64); | ||
| 1809 | usb_ep_set_maxpacket_limit(&dev->ep [5].ep, 64); | ||
| 1810 | usb_ep_set_maxpacket_limit(&dev->ep [6].ep, 64); | ||
| 1811 | |||
| 1812 | dev->gadget.ep0 = &dev->ep [0].ep; | ||
| 1813 | dev->ep [0].stopped = 0; | ||
| 1814 | INIT_LIST_HEAD (&dev->gadget.ep0->ep_list); | ||
| 1815 | |||
| 1816 | /* we want to prevent lowlevel/insecure access from the USB host, | ||
| 1817 | * but erratum 0119 means this enable bit is ignored | ||
| 1818 | */ | ||
| 1819 | for (tmp = 0; tmp < 5; tmp++) | ||
| 1820 | writel (EP_DONTUSE, &dev->dep [tmp].dep_cfg); | ||
| 1821 | } | ||
| 1822 | |||
| 1823 | static void ep0_start (struct net2280 *dev) | ||
| 1824 | { | ||
| 1825 | writel ( (1 << CLEAR_EP_HIDE_STATUS_PHASE) | ||
| 1826 | | (1 << CLEAR_NAK_OUT_PACKETS) | ||
| 1827 | | (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | ||
| 1828 | , &dev->epregs [0].ep_rsp); | ||
| 1829 | |||
| 1830 | /* | ||
| 1831 | * hardware optionally handles a bunch of standard requests | ||
| 1832 | * that the API hides from drivers anyway. have it do so. | ||
| 1833 | * endpoint status/features are handled in software, to | ||
| 1834 | * help pass tests for some dubious behavior. | ||
| 1835 | */ | ||
| 1836 | writel ( (1 << SET_TEST_MODE) | ||
| 1837 | | (1 << SET_ADDRESS) | ||
| 1838 | | (1 << DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP) | ||
| 1839 | | (1 << GET_DEVICE_STATUS) | ||
| 1840 | | (1 << GET_INTERFACE_STATUS) | ||
| 1841 | , &dev->usb->stdrsp); | ||
| 1842 | writel ( (1 << USB_ROOT_PORT_WAKEUP_ENABLE) | ||
| 1843 | | (1 << SELF_POWERED_USB_DEVICE) | ||
| 1844 | | (1 << REMOTE_WAKEUP_SUPPORT) | ||
| 1845 | | (dev->softconnect << USB_DETECT_ENABLE) | ||
| 1846 | | (1 << SELF_POWERED_STATUS) | ||
| 1847 | , &dev->usb->usbctl); | ||
| 1848 | |||
| 1849 | /* enable irqs so we can see ep0 and general operation */ | ||
| 1850 | writel ( (1 << SETUP_PACKET_INTERRUPT_ENABLE) | ||
| 1851 | | (1 << ENDPOINT_0_INTERRUPT_ENABLE) | ||
| 1852 | , &dev->regs->pciirqenb0); | ||
| 1853 | writel ( (1 << PCI_INTERRUPT_ENABLE) | ||
| 1854 | | (1 << PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE) | ||
| 1855 | | (1 << PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE) | ||
| 1856 | | (1 << PCI_RETRY_ABORT_INTERRUPT_ENABLE) | ||
| 1857 | | (1 << VBUS_INTERRUPT_ENABLE) | ||
| 1858 | | (1 << ROOT_PORT_RESET_INTERRUPT_ENABLE) | ||
| 1859 | | (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) | ||
| 1860 | , &dev->regs->pciirqenb1); | ||
| 1861 | |||
| 1862 | /* don't leave any writes posted */ | ||
| 1863 | (void) readl (&dev->usb->usbctl); | ||
| 1864 | } | ||
| 1865 | |||
| 1866 | /* when a driver is successfully registered, it will receive | ||
| 1867 | * control requests including set_configuration(), which enables | ||
| 1868 | * non-control requests. then usb traffic follows until a | ||
| 1869 | * disconnect is reported. then a host may connect again, or | ||
| 1870 | * the driver might get unbound. | ||
| 1871 | */ | ||
| 1872 | static int net2280_start(struct usb_gadget *_gadget, | ||
| 1873 | struct usb_gadget_driver *driver) | ||
| 1874 | { | ||
| 1875 | struct net2280 *dev; | ||
| 1876 | int retval; | ||
| 1877 | unsigned i; | ||
| 1878 | |||
| 1879 | /* insist on high speed support from the driver, since | ||
| 1880 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) | ||
| 1881 | * "must not be used in normal operation" | ||
| 1882 | */ | ||
| 1883 | if (!driver || driver->max_speed < USB_SPEED_HIGH | ||
| 1884 | || !driver->setup) | ||
| 1885 | return -EINVAL; | ||
| 1886 | |||
| 1887 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1888 | |||
| 1889 | for (i = 0; i < 7; i++) | ||
| 1890 | dev->ep [i].irqs = 0; | ||
| 1891 | |||
| 1892 | /* hook up the driver ... */ | ||
| 1893 | dev->softconnect = 1; | ||
| 1894 | driver->driver.bus = NULL; | ||
| 1895 | dev->driver = driver; | ||
| 1896 | |||
| 1897 | retval = device_create_file (&dev->pdev->dev, &dev_attr_function); | ||
| 1898 | if (retval) goto err_unbind; | ||
| 1899 | retval = device_create_file (&dev->pdev->dev, &dev_attr_queues); | ||
| 1900 | if (retval) goto err_func; | ||
| 1901 | |||
| 1902 | /* Enable force-full-speed testing mode, if desired */ | ||
| 1903 | if (full_speed) | ||
| 1904 | writel(1 << FORCE_FULL_SPEED_MODE, &dev->usb->xcvrdiag); | ||
| 1905 | |||
| 1906 | /* ... then enable host detection and ep0; and we're ready | ||
| 1907 | * for set_configuration as well as eventual disconnect. | ||
| 1908 | */ | ||
| 1909 | net2280_led_active (dev, 1); | ||
| 1910 | ep0_start (dev); | ||
| 1911 | |||
| 1912 | DEBUG (dev, "%s ready, usbctl %08x stdrsp %08x\n", | ||
| 1913 | driver->driver.name, | ||
| 1914 | readl (&dev->usb->usbctl), | ||
| 1915 | readl (&dev->usb->stdrsp)); | ||
| 1916 | |||
| 1917 | /* pci writes may still be posted */ | ||
| 1918 | return 0; | ||
| 1919 | |||
| 1920 | err_func: | ||
| 1921 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | ||
| 1922 | err_unbind: | ||
| 1923 | dev->driver = NULL; | ||
| 1924 | return retval; | ||
| 1925 | } | ||
| 1926 | |||
| 1927 | static void | ||
| 1928 | stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver) | ||
| 1929 | { | ||
| 1930 | int i; | ||
| 1931 | |||
| 1932 | /* don't disconnect if it's not connected */ | ||
| 1933 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1934 | driver = NULL; | ||
| 1935 | |||
| 1936 | /* stop hardware; prevent new request submissions; | ||
| 1937 | * and kill any outstanding requests. | ||
| 1938 | */ | ||
| 1939 | usb_reset (dev); | ||
| 1940 | for (i = 0; i < 7; i++) | ||
| 1941 | nuke (&dev->ep [i]); | ||
| 1942 | |||
| 1943 | /* report disconnect; the driver is already quiesced */ | ||
| 1944 | if (driver) { | ||
| 1945 | spin_unlock(&dev->lock); | ||
| 1946 | driver->disconnect(&dev->gadget); | ||
| 1947 | spin_lock(&dev->lock); | ||
| 1948 | } | ||
| 1949 | |||
| 1950 | usb_reinit (dev); | ||
| 1951 | } | ||
| 1952 | |||
| 1953 | static int net2280_stop(struct usb_gadget *_gadget, | ||
| 1954 | struct usb_gadget_driver *driver) | ||
| 1955 | { | ||
| 1956 | struct net2280 *dev; | ||
| 1957 | unsigned long flags; | ||
| 1958 | |||
| 1959 | dev = container_of (_gadget, struct net2280, gadget); | ||
| 1960 | |||
| 1961 | spin_lock_irqsave (&dev->lock, flags); | ||
| 1962 | stop_activity (dev, driver); | ||
| 1963 | spin_unlock_irqrestore (&dev->lock, flags); | ||
| 1964 | |||
| 1965 | dev->driver = NULL; | ||
| 1966 | |||
| 1967 | net2280_led_active (dev, 0); | ||
| 1968 | |||
| 1969 | /* Disable full-speed test mode */ | ||
| 1970 | writel(0, &dev->usb->xcvrdiag); | ||
| 1971 | |||
| 1972 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | ||
| 1973 | device_remove_file (&dev->pdev->dev, &dev_attr_queues); | ||
| 1974 | |||
| 1975 | DEBUG(dev, "unregistered driver '%s'\n", | ||
| 1976 | driver ? driver->driver.name : ""); | ||
| 1977 | |||
| 1978 | return 0; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | /*-------------------------------------------------------------------------*/ | ||
| 1982 | |||
| 1983 | /* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq. | ||
| 1984 | * also works for dma-capable endpoints, in pio mode or just | ||
| 1985 | * to manually advance the queue after short OUT transfers. | ||
| 1986 | */ | ||
| 1987 | static void handle_ep_small (struct net2280_ep *ep) | ||
| 1988 | { | ||
| 1989 | struct net2280_request *req; | ||
| 1990 | u32 t; | ||
| 1991 | /* 0 error, 1 mid-data, 2 done */ | ||
| 1992 | int mode = 1; | ||
| 1993 | |||
| 1994 | if (!list_empty (&ep->queue)) | ||
| 1995 | req = list_entry (ep->queue.next, | ||
| 1996 | struct net2280_request, queue); | ||
| 1997 | else | ||
| 1998 | req = NULL; | ||
| 1999 | |||
| 2000 | /* ack all, and handle what we care about */ | ||
| 2001 | t = readl (&ep->regs->ep_stat); | ||
| 2002 | ep->irqs++; | ||
| 2003 | #if 0 | ||
| 2004 | VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n", | ||
| 2005 | ep->ep.name, t, req ? &req->req : 0); | ||
| 2006 | #endif | ||
| 2007 | if (!ep->is_in || ep->dev->pdev->device == 0x2280) | ||
| 2008 | writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); | ||
| 2009 | else | ||
| 2010 | /* Added for 2282 */ | ||
| 2011 | writel (t, &ep->regs->ep_stat); | ||
| 2012 | |||
| 2013 | /* for ep0, monitor token irqs to catch data stage length errors | ||
| 2014 | * and to synchronize on status. | ||
| 2015 | * | ||
| 2016 | * also, to defer reporting of protocol stalls ... here's where | ||
| 2017 | * data or status first appears, handling stalls here should never | ||
| 2018 | * cause trouble on the host side.. | ||
| 2019 | * | ||
| 2020 | * control requests could be slightly faster without token synch for | ||
| 2021 | * status, but status can jam up that way. | ||
| 2022 | */ | ||
| 2023 | if (unlikely (ep->num == 0)) { | ||
| 2024 | if (ep->is_in) { | ||
| 2025 | /* status; stop NAKing */ | ||
| 2026 | if (t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) { | ||
| 2027 | if (ep->dev->protocol_stall) { | ||
| 2028 | ep->stopped = 1; | ||
| 2029 | set_halt (ep); | ||
| 2030 | } | ||
| 2031 | if (!req) | ||
| 2032 | allow_status (ep); | ||
| 2033 | mode = 2; | ||
| 2034 | /* reply to extra IN data tokens with a zlp */ | ||
| 2035 | } else if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) { | ||
| 2036 | if (ep->dev->protocol_stall) { | ||
| 2037 | ep->stopped = 1; | ||
| 2038 | set_halt (ep); | ||
| 2039 | mode = 2; | ||
| 2040 | } else if (ep->responded && | ||
| 2041 | !req && !ep->stopped) | ||
| 2042 | write_fifo (ep, NULL); | ||
| 2043 | } | ||
| 2044 | } else { | ||
| 2045 | /* status; stop NAKing */ | ||
| 2046 | if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) { | ||
| 2047 | if (ep->dev->protocol_stall) { | ||
| 2048 | ep->stopped = 1; | ||
| 2049 | set_halt (ep); | ||
| 2050 | } | ||
| 2051 | mode = 2; | ||
| 2052 | /* an extra OUT token is an error */ | ||
| 2053 | } else if (((t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) | ||
| 2054 | && req | ||
| 2055 | && req->req.actual == req->req.length) | ||
| 2056 | || (ep->responded && !req)) { | ||
| 2057 | ep->dev->protocol_stall = 1; | ||
| 2058 | set_halt (ep); | ||
| 2059 | ep->stopped = 1; | ||
| 2060 | if (req) | ||
| 2061 | done (ep, req, -EOVERFLOW); | ||
| 2062 | req = NULL; | ||
| 2063 | } | ||
| 2064 | } | ||
| 2065 | } | ||
| 2066 | |||
| 2067 | if (unlikely (!req)) | ||
| 2068 | return; | ||
| 2069 | |||
| 2070 | /* manual DMA queue advance after short OUT */ | ||
| 2071 | if (likely (ep->dma)) { | ||
| 2072 | if (t & (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)) { | ||
| 2073 | u32 count; | ||
| 2074 | int stopped = ep->stopped; | ||
| 2075 | |||
| 2076 | /* TRANSFERRED works around OUT_DONE erratum 0112. | ||
| 2077 | * we expect (N <= maxpacket) bytes; host wrote M. | ||
| 2078 | * iff (M < N) we won't ever see a DMA interrupt. | ||
| 2079 | */ | ||
| 2080 | ep->stopped = 1; | ||
| 2081 | for (count = 0; ; t = readl (&ep->regs->ep_stat)) { | ||
| 2082 | |||
| 2083 | /* any preceding dma transfers must finish. | ||
| 2084 | * dma handles (M >= N), may empty the queue | ||
| 2085 | */ | ||
| 2086 | scan_dma_completions (ep); | ||
| 2087 | if (unlikely (list_empty (&ep->queue) | ||
| 2088 | || ep->out_overflow)) { | ||
| 2089 | req = NULL; | ||
| 2090 | break; | ||
| 2091 | } | ||
| 2092 | req = list_entry (ep->queue.next, | ||
| 2093 | struct net2280_request, queue); | ||
| 2094 | |||
| 2095 | /* here either (M < N), a "real" short rx; | ||
| 2096 | * or (M == N) and the queue didn't empty | ||
| 2097 | */ | ||
| 2098 | if (likely (t & (1 << FIFO_EMPTY))) { | ||
| 2099 | count = readl (&ep->dma->dmacount); | ||
| 2100 | count &= DMA_BYTE_COUNT_MASK; | ||
| 2101 | if (readl (&ep->dma->dmadesc) | ||
| 2102 | != req->td_dma) | ||
| 2103 | req = NULL; | ||
| 2104 | break; | ||
| 2105 | } | ||
| 2106 | udelay(1); | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | /* stop DMA, leave ep NAKing */ | ||
| 2110 | writel ((1 << DMA_ABORT), &ep->dma->dmastat); | ||
| 2111 | spin_stop_dma (ep->dma); | ||
| 2112 | |||
| 2113 | if (likely (req)) { | ||
| 2114 | req->td->dmacount = 0; | ||
| 2115 | t = readl (&ep->regs->ep_avail); | ||
| 2116 | dma_done (ep, req, count, | ||
| 2117 | (ep->out_overflow || t) | ||
| 2118 | ? -EOVERFLOW : 0); | ||
| 2119 | } | ||
| 2120 | |||
| 2121 | /* also flush to prevent erratum 0106 trouble */ | ||
| 2122 | if (unlikely (ep->out_overflow | ||
| 2123 | || (ep->dev->chiprev == 0x0100 | ||
| 2124 | && ep->dev->gadget.speed | ||
| 2125 | == USB_SPEED_FULL))) { | ||
| 2126 | out_flush (ep); | ||
| 2127 | ep->out_overflow = 0; | ||
| 2128 | } | ||
| 2129 | |||
| 2130 | /* (re)start dma if needed, stop NAKing */ | ||
| 2131 | ep->stopped = stopped; | ||
| 2132 | if (!list_empty (&ep->queue)) | ||
| 2133 | restart_dma (ep); | ||
| 2134 | } else | ||
| 2135 | DEBUG (ep->dev, "%s dma ep_stat %08x ??\n", | ||
| 2136 | ep->ep.name, t); | ||
| 2137 | return; | ||
| 2138 | |||
| 2139 | /* data packet(s) received (in the fifo, OUT) */ | ||
| 2140 | } else if (t & (1 << DATA_PACKET_RECEIVED_INTERRUPT)) { | ||
| 2141 | if (read_fifo (ep, req) && ep->num != 0) | ||
| 2142 | mode = 2; | ||
| 2143 | |||
| 2144 | /* data packet(s) transmitted (IN) */ | ||
| 2145 | } else if (t & (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)) { | ||
| 2146 | unsigned len; | ||
| 2147 | |||
| 2148 | len = req->req.length - req->req.actual; | ||
| 2149 | if (len > ep->ep.maxpacket) | ||
| 2150 | len = ep->ep.maxpacket; | ||
| 2151 | req->req.actual += len; | ||
| 2152 | |||
| 2153 | /* if we wrote it all, we're usually done */ | ||
| 2154 | if (req->req.actual == req->req.length) { | ||
| 2155 | if (ep->num == 0) { | ||
| 2156 | /* send zlps until the status stage */ | ||
| 2157 | } else if (!req->req.zero || len != ep->ep.maxpacket) | ||
| 2158 | mode = 2; | ||
| 2159 | } | ||
| 2160 | |||
| 2161 | /* there was nothing to do ... */ | ||
| 2162 | } else if (mode == 1) | ||
| 2163 | return; | ||
| 2164 | |||
| 2165 | /* done */ | ||
| 2166 | if (mode == 2) { | ||
| 2167 | /* stream endpoints often resubmit/unlink in completion */ | ||
| 2168 | done (ep, req, 0); | ||
| 2169 | |||
| 2170 | /* maybe advance queue to next request */ | ||
| 2171 | if (ep->num == 0) { | ||
| 2172 | /* NOTE: net2280 could let gadget driver start the | ||
| 2173 | * status stage later. since not all controllers let | ||
| 2174 | * them control that, the api doesn't (yet) allow it. | ||
| 2175 | */ | ||
| 2176 | if (!ep->stopped) | ||
| 2177 | allow_status (ep); | ||
| 2178 | req = NULL; | ||
| 2179 | } else { | ||
| 2180 | if (!list_empty (&ep->queue) && !ep->stopped) | ||
| 2181 | req = list_entry (ep->queue.next, | ||
| 2182 | struct net2280_request, queue); | ||
| 2183 | else | ||
| 2184 | req = NULL; | ||
| 2185 | if (req && !ep->is_in) | ||
| 2186 | stop_out_naking (ep); | ||
| 2187 | } | ||
| 2188 | } | ||
| 2189 | |||
| 2190 | /* is there a buffer for the next packet? | ||
| 2191 | * for best streaming performance, make sure there is one. | ||
| 2192 | */ | ||
| 2193 | if (req && !ep->stopped) { | ||
| 2194 | |||
| 2195 | /* load IN fifo with next packet (may be zlp) */ | ||
| 2196 | if (t & (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)) | ||
| 2197 | write_fifo (ep, &req->req); | ||
| 2198 | } | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | static struct net2280_ep * | ||
| 2202 | get_ep_by_addr (struct net2280 *dev, u16 wIndex) | ||
| 2203 | { | ||
| 2204 | struct net2280_ep *ep; | ||
| 2205 | |||
| 2206 | if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) | ||
| 2207 | return &dev->ep [0]; | ||
| 2208 | list_for_each_entry (ep, &dev->gadget.ep_list, ep.ep_list) { | ||
| 2209 | u8 bEndpointAddress; | ||
| 2210 | |||
| 2211 | if (!ep->desc) | ||
| 2212 | continue; | ||
| 2213 | bEndpointAddress = ep->desc->bEndpointAddress; | ||
| 2214 | if ((wIndex ^ bEndpointAddress) & USB_DIR_IN) | ||
| 2215 | continue; | ||
| 2216 | if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f)) | ||
| 2217 | return ep; | ||
| 2218 | } | ||
| 2219 | return NULL; | ||
| 2220 | } | ||
| 2221 | |||
| 2222 | static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | ||
| 2223 | { | ||
| 2224 | struct net2280_ep *ep; | ||
| 2225 | u32 num, scratch; | ||
| 2226 | |||
| 2227 | /* most of these don't need individual acks */ | ||
| 2228 | stat &= ~(1 << INTA_ASSERTED); | ||
| 2229 | if (!stat) | ||
| 2230 | return; | ||
| 2231 | // DEBUG (dev, "irqstat0 %04x\n", stat); | ||
| 2232 | |||
| 2233 | /* starting a control request? */ | ||
| 2234 | if (unlikely (stat & (1 << SETUP_PACKET_INTERRUPT))) { | ||
| 2235 | union { | ||
| 2236 | u32 raw [2]; | ||
| 2237 | struct usb_ctrlrequest r; | ||
| 2238 | } u; | ||
| 2239 | int tmp; | ||
| 2240 | struct net2280_request *req; | ||
| 2241 | |||
| 2242 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) { | ||
| 2243 | if (readl (&dev->usb->usbstat) & (1 << HIGH_SPEED)) | ||
| 2244 | dev->gadget.speed = USB_SPEED_HIGH; | ||
| 2245 | else | ||
| 2246 | dev->gadget.speed = USB_SPEED_FULL; | ||
| 2247 | net2280_led_speed (dev, dev->gadget.speed); | ||
| 2248 | DEBUG(dev, "%s\n", usb_speed_string(dev->gadget.speed)); | ||
| 2249 | } | ||
| 2250 | |||
| 2251 | ep = &dev->ep [0]; | ||
| 2252 | ep->irqs++; | ||
| 2253 | |||
| 2254 | /* make sure any leftover request state is cleared */ | ||
| 2255 | stat &= ~(1 << ENDPOINT_0_INTERRUPT); | ||
| 2256 | while (!list_empty (&ep->queue)) { | ||
| 2257 | req = list_entry (ep->queue.next, | ||
| 2258 | struct net2280_request, queue); | ||
| 2259 | done (ep, req, (req->req.actual == req->req.length) | ||
| 2260 | ? 0 : -EPROTO); | ||
| 2261 | } | ||
| 2262 | ep->stopped = 0; | ||
| 2263 | dev->protocol_stall = 0; | ||
| 2264 | |||
| 2265 | if (ep->dev->pdev->device == 0x2280) | ||
| 2266 | tmp = (1 << FIFO_OVERFLOW) | ||
| 2267 | | (1 << FIFO_UNDERFLOW); | ||
| 2268 | else | ||
| 2269 | tmp = 0; | ||
| 2270 | |||
| 2271 | writel (tmp | (1 << TIMEOUT) | ||
| 2272 | | (1 << USB_STALL_SENT) | ||
| 2273 | | (1 << USB_IN_NAK_SENT) | ||
| 2274 | | (1 << USB_IN_ACK_RCVD) | ||
| 2275 | | (1 << USB_OUT_PING_NAK_SENT) | ||
| 2276 | | (1 << USB_OUT_ACK_SENT) | ||
| 2277 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | ||
| 2278 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | ||
| 2279 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | ||
| 2280 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | ||
| 2281 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 2282 | | (1 << DATA_IN_TOKEN_INTERRUPT) | ||
| 2283 | , &ep->regs->ep_stat); | ||
| 2284 | u.raw [0] = readl (&dev->usb->setup0123); | ||
| 2285 | u.raw [1] = readl (&dev->usb->setup4567); | ||
| 2286 | |||
| 2287 | cpu_to_le32s (&u.raw [0]); | ||
| 2288 | cpu_to_le32s (&u.raw [1]); | ||
| 2289 | |||
| 2290 | tmp = 0; | ||
| 2291 | |||
| 2292 | #define w_value le16_to_cpu(u.r.wValue) | ||
| 2293 | #define w_index le16_to_cpu(u.r.wIndex) | ||
| 2294 | #define w_length le16_to_cpu(u.r.wLength) | ||
| 2295 | |||
| 2296 | /* ack the irq */ | ||
| 2297 | writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0); | ||
| 2298 | stat ^= (1 << SETUP_PACKET_INTERRUPT); | ||
| 2299 | |||
| 2300 | /* watch control traffic at the token level, and force | ||
| 2301 | * synchronization before letting the status stage happen. | ||
| 2302 | * FIXME ignore tokens we'll NAK, until driver responds. | ||
| 2303 | * that'll mean a lot less irqs for some drivers. | ||
| 2304 | */ | ||
| 2305 | ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0; | ||
| 2306 | if (ep->is_in) { | ||
| 2307 | scratch = (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | ||
| 2308 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 2309 | | (1 << DATA_IN_TOKEN_INTERRUPT); | ||
| 2310 | stop_out_naking (ep); | ||
| 2311 | } else | ||
| 2312 | scratch = (1 << DATA_PACKET_RECEIVED_INTERRUPT) | ||
| 2313 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | ||
| 2314 | | (1 << DATA_IN_TOKEN_INTERRUPT); | ||
| 2315 | writel (scratch, &dev->epregs [0].ep_irqenb); | ||
| 2316 | |||
| 2317 | /* we made the hardware handle most lowlevel requests; | ||
| 2318 | * everything else goes uplevel to the gadget code. | ||
| 2319 | */ | ||
| 2320 | ep->responded = 1; | ||
| 2321 | switch (u.r.bRequest) { | ||
| 2322 | case USB_REQ_GET_STATUS: { | ||
| 2323 | struct net2280_ep *e; | ||
| 2324 | __le32 status; | ||
| 2325 | |||
| 2326 | /* hw handles device and interface status */ | ||
| 2327 | if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT)) | ||
| 2328 | goto delegate; | ||
| 2329 | if ((e = get_ep_by_addr (dev, w_index)) == NULL | ||
| 2330 | || w_length > 2) | ||
| 2331 | goto do_stall; | ||
| 2332 | |||
| 2333 | if (readl (&e->regs->ep_rsp) | ||
| 2334 | & (1 << SET_ENDPOINT_HALT)) | ||
| 2335 | status = cpu_to_le32 (1); | ||
| 2336 | else | ||
| 2337 | status = cpu_to_le32 (0); | ||
| 2338 | |||
| 2339 | /* don't bother with a request object! */ | ||
| 2340 | writel (0, &dev->epregs [0].ep_irqenb); | ||
| 2341 | set_fifo_bytecount (ep, w_length); | ||
| 2342 | writel ((__force u32)status, &dev->epregs [0].ep_data); | ||
| 2343 | allow_status (ep); | ||
| 2344 | VDEBUG (dev, "%s stat %02x\n", ep->ep.name, status); | ||
| 2345 | goto next_endpoints; | ||
| 2346 | } | ||
| 2347 | break; | ||
| 2348 | case USB_REQ_CLEAR_FEATURE: { | ||
| 2349 | struct net2280_ep *e; | ||
| 2350 | |||
| 2351 | /* hw handles device features */ | ||
| 2352 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | ||
| 2353 | goto delegate; | ||
| 2354 | if (w_value != USB_ENDPOINT_HALT | ||
| 2355 | || w_length != 0) | ||
| 2356 | goto do_stall; | ||
| 2357 | if ((e = get_ep_by_addr (dev, w_index)) == NULL) | ||
| 2358 | goto do_stall; | ||
| 2359 | if (e->wedged) { | ||
| 2360 | VDEBUG(dev, "%s wedged, halt not cleared\n", | ||
| 2361 | ep->ep.name); | ||
| 2362 | } else { | ||
| 2363 | VDEBUG(dev, "%s clear halt\n", ep->ep.name); | ||
| 2364 | clear_halt(e); | ||
| 2365 | } | ||
| 2366 | allow_status (ep); | ||
| 2367 | goto next_endpoints; | ||
| 2368 | } | ||
| 2369 | break; | ||
| 2370 | case USB_REQ_SET_FEATURE: { | ||
| 2371 | struct net2280_ep *e; | ||
| 2372 | |||
| 2373 | /* hw handles device features */ | ||
| 2374 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | ||
| 2375 | goto delegate; | ||
| 2376 | if (w_value != USB_ENDPOINT_HALT | ||
| 2377 | || w_length != 0) | ||
| 2378 | goto do_stall; | ||
| 2379 | if ((e = get_ep_by_addr (dev, w_index)) == NULL) | ||
| 2380 | goto do_stall; | ||
| 2381 | if (e->ep.name == ep0name) | ||
| 2382 | goto do_stall; | ||
| 2383 | set_halt (e); | ||
| 2384 | allow_status (ep); | ||
| 2385 | VDEBUG (dev, "%s set halt\n", ep->ep.name); | ||
| 2386 | goto next_endpoints; | ||
| 2387 | } | ||
| 2388 | break; | ||
| 2389 | default: | ||
| 2390 | delegate: | ||
| 2391 | VDEBUG (dev, "setup %02x.%02x v%04x i%04x l%04x " | ||
| 2392 | "ep_cfg %08x\n", | ||
| 2393 | u.r.bRequestType, u.r.bRequest, | ||
| 2394 | w_value, w_index, w_length, | ||
| 2395 | readl (&ep->regs->ep_cfg)); | ||
| 2396 | ep->responded = 0; | ||
| 2397 | spin_unlock (&dev->lock); | ||
| 2398 | tmp = dev->driver->setup (&dev->gadget, &u.r); | ||
| 2399 | spin_lock (&dev->lock); | ||
| 2400 | } | ||
| 2401 | |||
| 2402 | /* stall ep0 on error */ | ||
| 2403 | if (tmp < 0) { | ||
| 2404 | do_stall: | ||
| 2405 | VDEBUG (dev, "req %02x.%02x protocol STALL; stat %d\n", | ||
| 2406 | u.r.bRequestType, u.r.bRequest, tmp); | ||
| 2407 | dev->protocol_stall = 1; | ||
| 2408 | } | ||
| 2409 | |||
| 2410 | /* some in/out token irq should follow; maybe stall then. | ||
| 2411 | * driver must queue a request (even zlp) or halt ep0 | ||
| 2412 | * before the host times out. | ||
| 2413 | */ | ||
| 2414 | } | ||
| 2415 | |||
| 2416 | #undef w_value | ||
| 2417 | #undef w_index | ||
| 2418 | #undef w_length | ||
| 2419 | |||
| 2420 | next_endpoints: | ||
| 2421 | /* endpoint data irq ? */ | ||
| 2422 | scratch = stat & 0x7f; | ||
| 2423 | stat &= ~0x7f; | ||
| 2424 | for (num = 0; scratch; num++) { | ||
| 2425 | u32 t; | ||
| 2426 | |||
| 2427 | /* do this endpoint's FIFO and queue need tending? */ | ||
| 2428 | t = 1 << num; | ||
| 2429 | if ((scratch & t) == 0) | ||
| 2430 | continue; | ||
| 2431 | scratch ^= t; | ||
| 2432 | |||
| 2433 | ep = &dev->ep [num]; | ||
| 2434 | handle_ep_small (ep); | ||
| 2435 | } | ||
| 2436 | |||
| 2437 | if (stat) | ||
| 2438 | DEBUG (dev, "unhandled irqstat0 %08x\n", stat); | ||
| 2439 | } | ||
| 2440 | |||
| 2441 | #define DMA_INTERRUPTS ( \ | ||
| 2442 | (1 << DMA_D_INTERRUPT) \ | ||
| 2443 | | (1 << DMA_C_INTERRUPT) \ | ||
| 2444 | | (1 << DMA_B_INTERRUPT) \ | ||
| 2445 | | (1 << DMA_A_INTERRUPT)) | ||
| 2446 | #define PCI_ERROR_INTERRUPTS ( \ | ||
| 2447 | (1 << PCI_MASTER_ABORT_RECEIVED_INTERRUPT) \ | ||
| 2448 | | (1 << PCI_TARGET_ABORT_RECEIVED_INTERRUPT) \ | ||
| 2449 | | (1 << PCI_RETRY_ABORT_INTERRUPT)) | ||
| 2450 | |||
| 2451 | static void handle_stat1_irqs (struct net2280 *dev, u32 stat) | ||
| 2452 | { | ||
| 2453 | struct net2280_ep *ep; | ||
| 2454 | u32 tmp, num, mask, scratch; | ||
| 2455 | |||
| 2456 | /* after disconnect there's nothing else to do! */ | ||
| 2457 | tmp = (1 << VBUS_INTERRUPT) | (1 << ROOT_PORT_RESET_INTERRUPT); | ||
| 2458 | mask = (1 << HIGH_SPEED) | (1 << FULL_SPEED); | ||
| 2459 | |||
| 2460 | /* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set. | ||
| 2461 | * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and | ||
| 2462 | * both HIGH_SPEED and FULL_SPEED clear (as ROOT_PORT_RESET_INTERRUPT | ||
| 2463 | * only indicates a change in the reset state). | ||
| 2464 | */ | ||
| 2465 | if (stat & tmp) { | ||
| 2466 | writel (tmp, &dev->regs->irqstat1); | ||
| 2467 | if ((((stat & (1 << ROOT_PORT_RESET_INTERRUPT)) | ||
| 2468 | && ((readl (&dev->usb->usbstat) & mask) | ||
| 2469 | == 0)) | ||
| 2470 | || ((readl (&dev->usb->usbctl) | ||
| 2471 | & (1 << VBUS_PIN)) == 0) | ||
| 2472 | ) && ( dev->gadget.speed != USB_SPEED_UNKNOWN)) { | ||
| 2473 | DEBUG (dev, "disconnect %s\n", | ||
| 2474 | dev->driver->driver.name); | ||
| 2475 | stop_activity (dev, dev->driver); | ||
| 2476 | ep0_start (dev); | ||
| 2477 | return; | ||
| 2478 | } | ||
| 2479 | stat &= ~tmp; | ||
| 2480 | |||
| 2481 | /* vBUS can bounce ... one of many reasons to ignore the | ||
| 2482 | * notion of hotplug events on bus connect/disconnect! | ||
| 2483 | */ | ||
| 2484 | if (!stat) | ||
| 2485 | return; | ||
| 2486 | } | ||
| 2487 | |||
| 2488 | /* NOTE: chip stays in PCI D0 state for now, but it could | ||
| 2489 | * enter D1 to save more power | ||
| 2490 | */ | ||
| 2491 | tmp = (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT); | ||
| 2492 | if (stat & tmp) { | ||
| 2493 | writel (tmp, &dev->regs->irqstat1); | ||
| 2494 | if (stat & (1 << SUSPEND_REQUEST_INTERRUPT)) { | ||
| 2495 | if (dev->driver->suspend) | ||
| 2496 | dev->driver->suspend (&dev->gadget); | ||
| 2497 | if (!enable_suspend) | ||
| 2498 | stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT); | ||
| 2499 | } else { | ||
| 2500 | if (dev->driver->resume) | ||
| 2501 | dev->driver->resume (&dev->gadget); | ||
| 2502 | /* at high speed, note erratum 0133 */ | ||
| 2503 | } | ||
| 2504 | stat &= ~tmp; | ||
| 2505 | } | ||
| 2506 | |||
| 2507 | /* clear any other status/irqs */ | ||
| 2508 | if (stat) | ||
| 2509 | writel (stat, &dev->regs->irqstat1); | ||
| 2510 | |||
| 2511 | /* some status we can just ignore */ | ||
| 2512 | if (dev->pdev->device == 0x2280) | ||
| 2513 | stat &= ~((1 << CONTROL_STATUS_INTERRUPT) | ||
| 2514 | | (1 << SUSPEND_REQUEST_INTERRUPT) | ||
| 2515 | | (1 << RESUME_INTERRUPT) | ||
| 2516 | | (1 << SOF_INTERRUPT)); | ||
| 2517 | else | ||
| 2518 | stat &= ~((1 << CONTROL_STATUS_INTERRUPT) | ||
| 2519 | | (1 << RESUME_INTERRUPT) | ||
| 2520 | | (1 << SOF_DOWN_INTERRUPT) | ||
| 2521 | | (1 << SOF_INTERRUPT)); | ||
| 2522 | |||
| 2523 | if (!stat) | ||
| 2524 | return; | ||
| 2525 | // DEBUG (dev, "irqstat1 %08x\n", stat); | ||
| 2526 | |||
| 2527 | /* DMA status, for ep-{a,b,c,d} */ | ||
| 2528 | scratch = stat & DMA_INTERRUPTS; | ||
| 2529 | stat &= ~DMA_INTERRUPTS; | ||
| 2530 | scratch >>= 9; | ||
| 2531 | for (num = 0; scratch; num++) { | ||
| 2532 | struct net2280_dma_regs __iomem *dma; | ||
| 2533 | |||
| 2534 | tmp = 1 << num; | ||
| 2535 | if ((tmp & scratch) == 0) | ||
| 2536 | continue; | ||
| 2537 | scratch ^= tmp; | ||
| 2538 | |||
| 2539 | ep = &dev->ep [num + 1]; | ||
| 2540 | dma = ep->dma; | ||
| 2541 | |||
| 2542 | if (!dma) | ||
| 2543 | continue; | ||
| 2544 | |||
| 2545 | /* clear ep's dma status */ | ||
| 2546 | tmp = readl (&dma->dmastat); | ||
| 2547 | writel (tmp, &dma->dmastat); | ||
| 2548 | |||
| 2549 | /* chaining should stop on abort, short OUT from fifo, | ||
| 2550 | * or (stat0 codepath) short OUT transfer. | ||
| 2551 | */ | ||
| 2552 | if (!use_dma_chaining) { | ||
| 2553 | if ((tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT)) | ||
| 2554 | == 0) { | ||
| 2555 | DEBUG (ep->dev, "%s no xact done? %08x\n", | ||
| 2556 | ep->ep.name, tmp); | ||
| 2557 | continue; | ||
| 2558 | } | ||
| 2559 | stop_dma (ep->dma); | ||
| 2560 | } | ||
| 2561 | |||
| 2562 | /* OUT transfers terminate when the data from the | ||
| 2563 | * host is in our memory. Process whatever's done. | ||
| 2564 | * On this path, we know transfer's last packet wasn't | ||
| 2565 | * less than req->length. NAK_OUT_PACKETS may be set, | ||
| 2566 | * or the FIFO may already be holding new packets. | ||
| 2567 | * | ||
| 2568 | * IN transfers can linger in the FIFO for a very | ||
| 2569 | * long time ... we ignore that for now, accounting | ||
| 2570 | * precisely (like PIO does) needs per-packet irqs | ||
| 2571 | */ | ||
| 2572 | scan_dma_completions (ep); | ||
| 2573 | |||
| 2574 | /* disable dma on inactive queues; else maybe restart */ | ||
| 2575 | if (list_empty (&ep->queue)) { | ||
| 2576 | if (use_dma_chaining) | ||
| 2577 | stop_dma (ep->dma); | ||
| 2578 | } else { | ||
| 2579 | tmp = readl (&dma->dmactl); | ||
| 2580 | if (!use_dma_chaining | ||
| 2581 | || (tmp & (1 << DMA_ENABLE)) == 0) | ||
| 2582 | restart_dma (ep); | ||
| 2583 | else if (ep->is_in && use_dma_chaining) { | ||
| 2584 | struct net2280_request *req; | ||
| 2585 | __le32 dmacount; | ||
| 2586 | |||
| 2587 | /* the descriptor at the head of the chain | ||
| 2588 | * may still have VALID_BIT clear; that's | ||
| 2589 | * used to trigger changing DMA_FIFO_VALIDATE | ||
| 2590 | * (affects automagic zlp writes). | ||
| 2591 | */ | ||
| 2592 | req = list_entry (ep->queue.next, | ||
| 2593 | struct net2280_request, queue); | ||
| 2594 | dmacount = req->td->dmacount; | ||
| 2595 | dmacount &= cpu_to_le32 ( | ||
| 2596 | (1 << VALID_BIT) | ||
| 2597 | | DMA_BYTE_COUNT_MASK); | ||
| 2598 | if (dmacount && (dmacount & valid_bit) == 0) | ||
| 2599 | restart_dma (ep); | ||
| 2600 | } | ||
| 2601 | } | ||
| 2602 | ep->irqs++; | ||
| 2603 | } | ||
| 2604 | |||
| 2605 | /* NOTE: there are other PCI errors we might usefully notice. | ||
| 2606 | * if they appear very often, here's where to try recovering. | ||
| 2607 | */ | ||
| 2608 | if (stat & PCI_ERROR_INTERRUPTS) { | ||
| 2609 | ERROR (dev, "pci dma error; stat %08x\n", stat); | ||
| 2610 | stat &= ~PCI_ERROR_INTERRUPTS; | ||
| 2611 | /* these are fatal errors, but "maybe" they won't | ||
| 2612 | * happen again ... | ||
| 2613 | */ | ||
| 2614 | stop_activity (dev, dev->driver); | ||
| 2615 | ep0_start (dev); | ||
| 2616 | stat = 0; | ||
| 2617 | } | ||
| 2618 | |||
| 2619 | if (stat) | ||
| 2620 | DEBUG (dev, "unhandled irqstat1 %08x\n", stat); | ||
| 2621 | } | ||
| 2622 | |||
| 2623 | static irqreturn_t net2280_irq (int irq, void *_dev) | ||
| 2624 | { | ||
| 2625 | struct net2280 *dev = _dev; | ||
| 2626 | |||
| 2627 | /* shared interrupt, not ours */ | ||
| 2628 | if (!(readl(&dev->regs->irqstat0) & (1 << INTA_ASSERTED))) | ||
| 2629 | return IRQ_NONE; | ||
| 2630 | |||
| 2631 | spin_lock (&dev->lock); | ||
| 2632 | |||
| 2633 | /* handle disconnect, dma, and more */ | ||
| 2634 | handle_stat1_irqs (dev, readl (&dev->regs->irqstat1)); | ||
| 2635 | |||
| 2636 | /* control requests and PIO */ | ||
| 2637 | handle_stat0_irqs (dev, readl (&dev->regs->irqstat0)); | ||
| 2638 | |||
| 2639 | spin_unlock (&dev->lock); | ||
| 2640 | |||
| 2641 | return IRQ_HANDLED; | ||
| 2642 | } | ||
| 2643 | |||
| 2644 | /*-------------------------------------------------------------------------*/ | ||
| 2645 | |||
| 2646 | static void gadget_release (struct device *_dev) | ||
| 2647 | { | ||
| 2648 | struct net2280 *dev = dev_get_drvdata (_dev); | ||
| 2649 | |||
| 2650 | kfree (dev); | ||
| 2651 | } | ||
| 2652 | |||
| 2653 | /* tear down the binding between this driver and the pci device */ | ||
| 2654 | |||
| 2655 | static void net2280_remove (struct pci_dev *pdev) | ||
| 2656 | { | ||
| 2657 | struct net2280 *dev = pci_get_drvdata (pdev); | ||
| 2658 | |||
| 2659 | usb_del_gadget_udc(&dev->gadget); | ||
| 2660 | |||
| 2661 | BUG_ON(dev->driver); | ||
| 2662 | |||
| 2663 | /* then clean up the resources we allocated during probe() */ | ||
| 2664 | net2280_led_shutdown (dev); | ||
| 2665 | if (dev->requests) { | ||
| 2666 | int i; | ||
| 2667 | for (i = 1; i < 5; i++) { | ||
| 2668 | if (!dev->ep [i].dummy) | ||
| 2669 | continue; | ||
| 2670 | pci_pool_free (dev->requests, dev->ep [i].dummy, | ||
| 2671 | dev->ep [i].td_dma); | ||
| 2672 | } | ||
| 2673 | pci_pool_destroy (dev->requests); | ||
| 2674 | } | ||
| 2675 | if (dev->got_irq) | ||
| 2676 | free_irq (pdev->irq, dev); | ||
| 2677 | if (dev->regs) | ||
| 2678 | iounmap (dev->regs); | ||
| 2679 | if (dev->region) | ||
| 2680 | release_mem_region (pci_resource_start (pdev, 0), | ||
| 2681 | pci_resource_len (pdev, 0)); | ||
| 2682 | if (dev->enabled) | ||
| 2683 | pci_disable_device (pdev); | ||
| 2684 | device_remove_file (&pdev->dev, &dev_attr_registers); | ||
| 2685 | |||
| 2686 | INFO (dev, "unbind\n"); | ||
| 2687 | } | ||
| 2688 | |||
| 2689 | /* wrap this driver around the specified device, but | ||
| 2690 | * don't respond over USB until a gadget driver binds to us. | ||
| 2691 | */ | ||
| 2692 | |||
| 2693 | static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | ||
| 2694 | { | ||
| 2695 | struct net2280 *dev; | ||
| 2696 | unsigned long resource, len; | ||
| 2697 | void __iomem *base = NULL; | ||
| 2698 | int retval, i; | ||
| 2699 | |||
| 2700 | /* alloc, and start init */ | ||
| 2701 | dev = kzalloc (sizeof *dev, GFP_KERNEL); | ||
| 2702 | if (dev == NULL){ | ||
| 2703 | retval = -ENOMEM; | ||
| 2704 | goto done; | ||
| 2705 | } | ||
| 2706 | |||
| 2707 | pci_set_drvdata (pdev, dev); | ||
| 2708 | spin_lock_init (&dev->lock); | ||
| 2709 | dev->pdev = pdev; | ||
| 2710 | dev->gadget.ops = &net2280_ops; | ||
| 2711 | dev->gadget.max_speed = USB_SPEED_HIGH; | ||
| 2712 | |||
| 2713 | /* the "gadget" abstracts/virtualizes the controller */ | ||
| 2714 | dev->gadget.name = driver_name; | ||
| 2715 | |||
| 2716 | /* now all the pci goodies ... */ | ||
| 2717 | if (pci_enable_device (pdev) < 0) { | ||
| 2718 | retval = -ENODEV; | ||
| 2719 | goto done; | ||
| 2720 | } | ||
| 2721 | dev->enabled = 1; | ||
| 2722 | |||
| 2723 | /* BAR 0 holds all the registers | ||
| 2724 | * BAR 1 is 8051 memory; unused here (note erratum 0103) | ||
| 2725 | * BAR 2 is fifo memory; unused here | ||
| 2726 | */ | ||
| 2727 | resource = pci_resource_start (pdev, 0); | ||
| 2728 | len = pci_resource_len (pdev, 0); | ||
| 2729 | if (!request_mem_region (resource, len, driver_name)) { | ||
| 2730 | DEBUG (dev, "controller already in use\n"); | ||
| 2731 | retval = -EBUSY; | ||
| 2732 | goto done; | ||
| 2733 | } | ||
| 2734 | dev->region = 1; | ||
| 2735 | |||
| 2736 | /* FIXME provide firmware download interface to put | ||
| 2737 | * 8051 code into the chip, e.g. to turn on PCI PM. | ||
| 2738 | */ | ||
| 2739 | |||
| 2740 | base = ioremap_nocache (resource, len); | ||
| 2741 | if (base == NULL) { | ||
| 2742 | DEBUG (dev, "can't map memory\n"); | ||
| 2743 | retval = -EFAULT; | ||
| 2744 | goto done; | ||
| 2745 | } | ||
| 2746 | dev->regs = (struct net2280_regs __iomem *) base; | ||
| 2747 | dev->usb = (struct net2280_usb_regs __iomem *) (base + 0x0080); | ||
| 2748 | dev->pci = (struct net2280_pci_regs __iomem *) (base + 0x0100); | ||
| 2749 | dev->dma = (struct net2280_dma_regs __iomem *) (base + 0x0180); | ||
| 2750 | dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200); | ||
| 2751 | dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300); | ||
| 2752 | |||
| 2753 | /* put into initial config, link up all endpoints */ | ||
| 2754 | writel (0, &dev->usb->usbctl); | ||
| 2755 | usb_reset (dev); | ||
| 2756 | usb_reinit (dev); | ||
| 2757 | |||
| 2758 | /* irq setup after old hardware is cleaned up */ | ||
| 2759 | if (!pdev->irq) { | ||
| 2760 | ERROR (dev, "No IRQ. Check PCI setup!\n"); | ||
| 2761 | retval = -ENODEV; | ||
| 2762 | goto done; | ||
| 2763 | } | ||
| 2764 | |||
| 2765 | if (request_irq (pdev->irq, net2280_irq, IRQF_SHARED, driver_name, dev) | ||
| 2766 | != 0) { | ||
| 2767 | ERROR (dev, "request interrupt %d failed\n", pdev->irq); | ||
| 2768 | retval = -EBUSY; | ||
| 2769 | goto done; | ||
| 2770 | } | ||
| 2771 | dev->got_irq = 1; | ||
| 2772 | |||
| 2773 | /* DMA setup */ | ||
| 2774 | /* NOTE: we know only the 32 LSBs of dma addresses may be nonzero */ | ||
| 2775 | dev->requests = pci_pool_create ("requests", pdev, | ||
| 2776 | sizeof (struct net2280_dma), | ||
| 2777 | 0 /* no alignment requirements */, | ||
| 2778 | 0 /* or page-crossing issues */); | ||
| 2779 | if (!dev->requests) { | ||
| 2780 | DEBUG (dev, "can't get request pool\n"); | ||
| 2781 | retval = -ENOMEM; | ||
| 2782 | goto done; | ||
| 2783 | } | ||
| 2784 | for (i = 1; i < 5; i++) { | ||
| 2785 | struct net2280_dma *td; | ||
| 2786 | |||
| 2787 | td = pci_pool_alloc (dev->requests, GFP_KERNEL, | ||
| 2788 | &dev->ep [i].td_dma); | ||
| 2789 | if (!td) { | ||
| 2790 | DEBUG (dev, "can't get dummy %d\n", i); | ||
| 2791 | retval = -ENOMEM; | ||
| 2792 | goto done; | ||
| 2793 | } | ||
| 2794 | td->dmacount = 0; /* not VALID */ | ||
| 2795 | td->dmadesc = td->dmaaddr; | ||
| 2796 | dev->ep [i].dummy = td; | ||
| 2797 | } | ||
| 2798 | |||
| 2799 | /* enable lower-overhead pci memory bursts during DMA */ | ||
| 2800 | writel ( (1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) | ||
| 2801 | // 256 write retries may not be enough... | ||
| 2802 | // | (1 << PCI_RETRY_ABORT_ENABLE) | ||
| 2803 | | (1 << DMA_READ_MULTIPLE_ENABLE) | ||
| 2804 | | (1 << DMA_READ_LINE_ENABLE) | ||
| 2805 | , &dev->pci->pcimstctl); | ||
| 2806 | /* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */ | ||
| 2807 | pci_set_master (pdev); | ||
| 2808 | pci_try_set_mwi (pdev); | ||
| 2809 | |||
| 2810 | /* ... also flushes any posted pci writes */ | ||
| 2811 | dev->chiprev = get_idx_reg (dev->regs, REG_CHIPREV) & 0xffff; | ||
| 2812 | |||
| 2813 | /* done */ | ||
| 2814 | INFO (dev, "%s\n", driver_desc); | ||
| 2815 | INFO (dev, "irq %d, pci mem %p, chip rev %04x\n", | ||
| 2816 | pdev->irq, base, dev->chiprev); | ||
| 2817 | INFO (dev, "version: " DRIVER_VERSION "; dma %s\n", | ||
| 2818 | use_dma | ||
| 2819 | ? (use_dma_chaining ? "chaining" : "enabled") | ||
| 2820 | : "disabled"); | ||
| 2821 | retval = device_create_file (&pdev->dev, &dev_attr_registers); | ||
| 2822 | if (retval) goto done; | ||
| 2823 | |||
| 2824 | retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget, | ||
| 2825 | gadget_release); | ||
| 2826 | if (retval) | ||
| 2827 | goto done; | ||
| 2828 | return 0; | ||
| 2829 | |||
| 2830 | done: | ||
| 2831 | if (dev) | ||
| 2832 | net2280_remove (pdev); | ||
| 2833 | return retval; | ||
| 2834 | } | ||
| 2835 | |||
| 2836 | /* make sure the board is quiescent; otherwise it will continue | ||
| 2837 | * generating IRQs across the upcoming reboot. | ||
| 2838 | */ | ||
| 2839 | |||
| 2840 | static void net2280_shutdown (struct pci_dev *pdev) | ||
| 2841 | { | ||
| 2842 | struct net2280 *dev = pci_get_drvdata (pdev); | ||
| 2843 | |||
| 2844 | /* disable IRQs */ | ||
| 2845 | writel (0, &dev->regs->pciirqenb0); | ||
| 2846 | writel (0, &dev->regs->pciirqenb1); | ||
| 2847 | |||
| 2848 | /* disable the pullup so the host will think we're gone */ | ||
| 2849 | writel (0, &dev->usb->usbctl); | ||
| 2850 | |||
| 2851 | /* Disable full-speed test mode */ | ||
| 2852 | writel(0, &dev->usb->xcvrdiag); | ||
| 2853 | } | ||
| 2854 | |||
| 2855 | |||
| 2856 | /*-------------------------------------------------------------------------*/ | ||
| 2857 | |||
| 2858 | static const struct pci_device_id pci_ids [] = { { | ||
| 2859 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 2860 | .class_mask = ~0, | ||
| 2861 | .vendor = 0x17cc, | ||
| 2862 | .device = 0x2280, | ||
| 2863 | .subvendor = PCI_ANY_ID, | ||
| 2864 | .subdevice = PCI_ANY_ID, | ||
| 2865 | }, { | ||
| 2866 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 2867 | .class_mask = ~0, | ||
| 2868 | .vendor = 0x17cc, | ||
| 2869 | .device = 0x2282, | ||
| 2870 | .subvendor = PCI_ANY_ID, | ||
| 2871 | .subdevice = PCI_ANY_ID, | ||
| 2872 | |||
| 2873 | }, { /* end: all zeroes */ } | ||
| 2874 | }; | ||
| 2875 | MODULE_DEVICE_TABLE (pci, pci_ids); | ||
| 2876 | |||
| 2877 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
| 2878 | static struct pci_driver net2280_pci_driver = { | ||
| 2879 | .name = (char *) driver_name, | ||
| 2880 | .id_table = pci_ids, | ||
| 2881 | |||
| 2882 | .probe = net2280_probe, | ||
| 2883 | .remove = net2280_remove, | ||
| 2884 | .shutdown = net2280_shutdown, | ||
| 2885 | |||
| 2886 | /* FIXME add power management support */ | ||
| 2887 | }; | ||
| 2888 | |||
| 2889 | MODULE_DESCRIPTION (DRIVER_DESC); | ||
| 2890 | MODULE_AUTHOR ("David Brownell"); | ||
| 2891 | MODULE_LICENSE ("GPL"); | ||
| 2892 | |||
| 2893 | static int __init init (void) | ||
| 2894 | { | ||
| 2895 | if (!use_dma) | ||
| 2896 | use_dma_chaining = 0; | ||
| 2897 | return pci_register_driver (&net2280_pci_driver); | ||
| 2898 | } | ||
| 2899 | module_init (init); | ||
| 2900 | |||
| 2901 | static void __exit cleanup (void) | ||
| 2902 | { | ||
| 2903 | pci_unregister_driver (&net2280_pci_driver); | ||
| 2904 | } | ||
| 2905 | module_exit (cleanup); | ||
diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h deleted file mode 100644 index a844be0d683a..000000000000 --- a/drivers/usb/gadget/net2280.h +++ /dev/null | |||
| @@ -1,308 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * NetChip 2280 high/full speed USB device controller. | ||
| 3 | * Unlike many such controllers, this one talks PCI. | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* | ||
| 7 | * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) | ||
| 8 | * Copyright (C) 2003 David Brownell | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/usb/net2280.h> | ||
| 17 | |||
| 18 | /*-------------------------------------------------------------------------*/ | ||
| 19 | |||
| 20 | #ifdef __KERNEL__ | ||
| 21 | |||
| 22 | /* indexed registers [11.10] are accessed indirectly | ||
| 23 | * caller must own the device lock. | ||
| 24 | */ | ||
| 25 | |||
| 26 | static inline u32 | ||
| 27 | get_idx_reg (struct net2280_regs __iomem *regs, u32 index) | ||
| 28 | { | ||
| 29 | writel (index, ®s->idxaddr); | ||
| 30 | /* NOTE: synchs device/cpu memory views */ | ||
| 31 | return readl (®s->idxdata); | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline void | ||
| 35 | set_idx_reg (struct net2280_regs __iomem *regs, u32 index, u32 value) | ||
| 36 | { | ||
| 37 | writel (index, ®s->idxaddr); | ||
| 38 | writel (value, ®s->idxdata); | ||
| 39 | /* posted, may not be visible yet */ | ||
| 40 | } | ||
| 41 | |||
| 42 | #endif /* __KERNEL__ */ | ||
| 43 | |||
| 44 | |||
| 45 | #define REG_DIAG 0x0 | ||
| 46 | #define RETRY_COUNTER 16 | ||
| 47 | #define FORCE_PCI_SERR 11 | ||
| 48 | #define FORCE_PCI_INTERRUPT 10 | ||
| 49 | #define FORCE_USB_INTERRUPT 9 | ||
| 50 | #define FORCE_CPU_INTERRUPT 8 | ||
| 51 | #define ILLEGAL_BYTE_ENABLES 5 | ||
| 52 | #define FAST_TIMES 4 | ||
| 53 | #define FORCE_RECEIVE_ERROR 2 | ||
| 54 | #define FORCE_TRANSMIT_CRC_ERROR 0 | ||
| 55 | #define REG_FRAME 0x02 /* from last sof */ | ||
| 56 | #define REG_CHIPREV 0x03 /* in bcd */ | ||
| 57 | #define REG_HS_NAK_RATE 0x0a /* NAK per N uframes */ | ||
| 58 | |||
| 59 | #define CHIPREV_1 0x0100 | ||
| 60 | #define CHIPREV_1A 0x0110 | ||
| 61 | |||
| 62 | #ifdef __KERNEL__ | ||
| 63 | |||
| 64 | /* ep a-f highspeed and fullspeed maxpacket, addresses | ||
| 65 | * computed from ep->num | ||
| 66 | */ | ||
| 67 | #define REG_EP_MAXPKT(dev,num) (((num) + 1) * 0x10 + \ | ||
| 68 | (((dev)->gadget.speed == USB_SPEED_HIGH) ? 0 : 1)) | ||
| 69 | |||
| 70 | /*-------------------------------------------------------------------------*/ | ||
| 71 | |||
| 72 | /* [8.3] for scatter/gather i/o | ||
| 73 | * use struct net2280_dma_regs bitfields | ||
| 74 | */ | ||
| 75 | struct net2280_dma { | ||
| 76 | __le32 dmacount; | ||
| 77 | __le32 dmaaddr; /* the buffer */ | ||
| 78 | __le32 dmadesc; /* next dma descriptor */ | ||
| 79 | __le32 _reserved; | ||
| 80 | } __attribute__ ((aligned (16))); | ||
| 81 | |||
| 82 | /*-------------------------------------------------------------------------*/ | ||
| 83 | |||
| 84 | /* DRIVER DATA STRUCTURES and UTILITIES */ | ||
| 85 | |||
| 86 | struct net2280_ep { | ||
| 87 | struct usb_ep ep; | ||
| 88 | struct net2280_ep_regs __iomem *regs; | ||
| 89 | struct net2280_dma_regs __iomem *dma; | ||
| 90 | struct net2280_dma *dummy; | ||
| 91 | dma_addr_t td_dma; /* of dummy */ | ||
| 92 | struct net2280 *dev; | ||
| 93 | unsigned long irqs; | ||
| 94 | |||
| 95 | /* analogous to a host-side qh */ | ||
| 96 | struct list_head queue; | ||
| 97 | const struct usb_endpoint_descriptor *desc; | ||
| 98 | unsigned num : 8, | ||
| 99 | fifo_size : 12, | ||
| 100 | in_fifo_validate : 1, | ||
| 101 | out_overflow : 1, | ||
| 102 | stopped : 1, | ||
| 103 | wedged : 1, | ||
| 104 | is_in : 1, | ||
| 105 | is_iso : 1, | ||
| 106 | responded : 1; | ||
| 107 | }; | ||
| 108 | |||
| 109 | static inline void allow_status (struct net2280_ep *ep) | ||
| 110 | { | ||
| 111 | /* ep0 only */ | ||
| 112 | writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | ||
| 113 | | (1 << CLEAR_NAK_OUT_PACKETS) | ||
| 114 | | (1 << CLEAR_NAK_OUT_PACKETS_MODE) | ||
| 115 | , &ep->regs->ep_rsp); | ||
| 116 | ep->stopped = 1; | ||
| 117 | } | ||
| 118 | |||
| 119 | /* count (<= 4) bytes in the next fifo write will be valid */ | ||
| 120 | static inline void set_fifo_bytecount (struct net2280_ep *ep, unsigned count) | ||
| 121 | { | ||
| 122 | writeb (count, 2 + (u8 __iomem *) &ep->regs->ep_cfg); | ||
| 123 | } | ||
| 124 | |||
| 125 | struct net2280_request { | ||
| 126 | struct usb_request req; | ||
| 127 | struct net2280_dma *td; | ||
| 128 | dma_addr_t td_dma; | ||
| 129 | struct list_head queue; | ||
| 130 | unsigned mapped : 1, | ||
| 131 | valid : 1; | ||
| 132 | }; | ||
| 133 | |||
| 134 | struct net2280 { | ||
| 135 | /* each pci device provides one gadget, several endpoints */ | ||
| 136 | struct usb_gadget gadget; | ||
| 137 | spinlock_t lock; | ||
| 138 | struct net2280_ep ep [7]; | ||
| 139 | struct usb_gadget_driver *driver; | ||
| 140 | unsigned enabled : 1, | ||
| 141 | protocol_stall : 1, | ||
| 142 | softconnect : 1, | ||
| 143 | got_irq : 1, | ||
| 144 | region : 1; | ||
| 145 | u16 chiprev; | ||
| 146 | |||
| 147 | /* pci state used to access those endpoints */ | ||
| 148 | struct pci_dev *pdev; | ||
| 149 | struct net2280_regs __iomem *regs; | ||
| 150 | struct net2280_usb_regs __iomem *usb; | ||
| 151 | struct net2280_pci_regs __iomem *pci; | ||
| 152 | struct net2280_dma_regs __iomem *dma; | ||
| 153 | struct net2280_dep_regs __iomem *dep; | ||
| 154 | struct net2280_ep_regs __iomem *epregs; | ||
| 155 | |||
| 156 | struct pci_pool *requests; | ||
| 157 | // statistics... | ||
| 158 | }; | ||
| 159 | |||
| 160 | static inline void set_halt (struct net2280_ep *ep) | ||
| 161 | { | ||
| 162 | /* ep0 and bulk/intr endpoints */ | ||
| 163 | writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | ||
| 164 | /* set NAK_OUT for erratum 0114 */ | ||
| 165 | | ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS) | ||
| 166 | | (1 << SET_ENDPOINT_HALT) | ||
| 167 | , &ep->regs->ep_rsp); | ||
| 168 | } | ||
| 169 | |||
| 170 | static inline void clear_halt (struct net2280_ep *ep) | ||
| 171 | { | ||
| 172 | /* ep0 and bulk/intr endpoints */ | ||
| 173 | writel ( (1 << CLEAR_ENDPOINT_HALT) | ||
| 174 | | (1 << CLEAR_ENDPOINT_TOGGLE) | ||
| 175 | /* unless the gadget driver left a short packet in the | ||
| 176 | * fifo, this reverses the erratum 0114 workaround. | ||
| 177 | */ | ||
| 178 | | ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS) | ||
| 179 | , &ep->regs->ep_rsp); | ||
| 180 | } | ||
| 181 | |||
| 182 | #ifdef USE_RDK_LEDS | ||
| 183 | |||
| 184 | static inline void net2280_led_init (struct net2280 *dev) | ||
| 185 | { | ||
| 186 | /* LED3 (green) is on during USB activity. note erratum 0113. */ | ||
| 187 | writel ((1 << GPIO3_LED_SELECT) | ||
| 188 | | (1 << GPIO3_OUTPUT_ENABLE) | ||
| 189 | | (1 << GPIO2_OUTPUT_ENABLE) | ||
| 190 | | (1 << GPIO1_OUTPUT_ENABLE) | ||
| 191 | | (1 << GPIO0_OUTPUT_ENABLE) | ||
| 192 | , &dev->regs->gpioctl); | ||
| 193 | } | ||
| 194 | |||
| 195 | /* indicate speed with bi-color LED 0/1 */ | ||
| 196 | static inline | ||
| 197 | void net2280_led_speed (struct net2280 *dev, enum usb_device_speed speed) | ||
| 198 | { | ||
| 199 | u32 val = readl (&dev->regs->gpioctl); | ||
| 200 | switch (speed) { | ||
| 201 | case USB_SPEED_HIGH: /* green */ | ||
| 202 | val &= ~(1 << GPIO0_DATA); | ||
| 203 | val |= (1 << GPIO1_DATA); | ||
| 204 | break; | ||
| 205 | case USB_SPEED_FULL: /* red */ | ||
| 206 | val &= ~(1 << GPIO1_DATA); | ||
| 207 | val |= (1 << GPIO0_DATA); | ||
| 208 | break; | ||
| 209 | default: /* (off/black) */ | ||
| 210 | val &= ~((1 << GPIO1_DATA) | (1 << GPIO0_DATA)); | ||
| 211 | break; | ||
| 212 | } | ||
| 213 | writel (val, &dev->regs->gpioctl); | ||
| 214 | } | ||
| 215 | |||
| 216 | /* indicate power with LED 2 */ | ||
| 217 | static inline void net2280_led_active (struct net2280 *dev, int is_active) | ||
| 218 | { | ||
| 219 | u32 val = readl (&dev->regs->gpioctl); | ||
| 220 | |||
| 221 | // FIXME this LED never seems to turn on. | ||
| 222 | if (is_active) | ||
| 223 | val |= GPIO2_DATA; | ||
| 224 | else | ||
| 225 | val &= ~GPIO2_DATA; | ||
| 226 | writel (val, &dev->regs->gpioctl); | ||
| 227 | } | ||
| 228 | static inline void net2280_led_shutdown (struct net2280 *dev) | ||
| 229 | { | ||
| 230 | /* turn off all four GPIO*_DATA bits */ | ||
| 231 | writel (readl (&dev->regs->gpioctl) & ~0x0f, | ||
| 232 | &dev->regs->gpioctl); | ||
| 233 | } | ||
| 234 | |||
| 235 | #else | ||
| 236 | |||
| 237 | #define net2280_led_init(dev) do { } while (0) | ||
| 238 | #define net2280_led_speed(dev, speed) do { } while (0) | ||
| 239 | #define net2280_led_shutdown(dev) do { } while (0) | ||
| 240 | |||
| 241 | #endif | ||
| 242 | |||
| 243 | /*-------------------------------------------------------------------------*/ | ||
| 244 | |||
| 245 | #define xprintk(dev,level,fmt,args...) \ | ||
| 246 | printk(level "%s %s: " fmt , driver_name , \ | ||
| 247 | pci_name(dev->pdev) , ## args) | ||
| 248 | |||
| 249 | #ifdef DEBUG | ||
| 250 | #undef DEBUG | ||
| 251 | #define DEBUG(dev,fmt,args...) \ | ||
| 252 | xprintk(dev , KERN_DEBUG , fmt , ## args) | ||
| 253 | #else | ||
| 254 | #define DEBUG(dev,fmt,args...) \ | ||
| 255 | do { } while (0) | ||
| 256 | #endif /* DEBUG */ | ||
| 257 | |||
| 258 | #ifdef VERBOSE | ||
| 259 | #define VDEBUG DEBUG | ||
| 260 | #else | ||
| 261 | #define VDEBUG(dev,fmt,args...) \ | ||
| 262 | do { } while (0) | ||
| 263 | #endif /* VERBOSE */ | ||
| 264 | |||
| 265 | #define ERROR(dev,fmt,args...) \ | ||
| 266 | xprintk(dev , KERN_ERR , fmt , ## args) | ||
| 267 | #define WARNING(dev,fmt,args...) \ | ||
| 268 | xprintk(dev , KERN_WARNING , fmt , ## args) | ||
| 269 | #define INFO(dev,fmt,args...) \ | ||
| 270 | xprintk(dev , KERN_INFO , fmt , ## args) | ||
| 271 | |||
| 272 | /*-------------------------------------------------------------------------*/ | ||
| 273 | |||
| 274 | static inline void start_out_naking (struct net2280_ep *ep) | ||
| 275 | { | ||
| 276 | /* NOTE: hardware races lurk here, and PING protocol issues */ | ||
| 277 | writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 278 | /* synch with device */ | ||
| 279 | readl (&ep->regs->ep_rsp); | ||
| 280 | } | ||
| 281 | |||
| 282 | #ifdef DEBUG | ||
| 283 | static inline void assert_out_naking (struct net2280_ep *ep, const char *where) | ||
| 284 | { | ||
| 285 | u32 tmp = readl (&ep->regs->ep_stat); | ||
| 286 | |||
| 287 | if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) { | ||
| 288 | DEBUG (ep->dev, "%s %s %08x !NAK\n", | ||
| 289 | ep->ep.name, where, tmp); | ||
| 290 | writel ((1 << SET_NAK_OUT_PACKETS), | ||
| 291 | &ep->regs->ep_rsp); | ||
| 292 | } | ||
| 293 | } | ||
| 294 | #define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__func__) | ||
| 295 | #else | ||
| 296 | #define ASSERT_OUT_NAKING(ep) do {} while (0) | ||
| 297 | #endif | ||
| 298 | |||
| 299 | static inline void stop_out_naking (struct net2280_ep *ep) | ||
| 300 | { | ||
| 301 | u32 tmp; | ||
| 302 | |||
| 303 | tmp = readl (&ep->regs->ep_stat); | ||
| 304 | if ((tmp & (1 << NAK_OUT_PACKETS)) != 0) | ||
| 305 | writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 306 | } | ||
| 307 | |||
| 308 | #endif /* __KERNEL__ */ | ||
diff --git a/drivers/usb/gadget/u_os_desc.h b/drivers/usb/gadget/u_os_desc.h index ea5cf8c2da28..947b7ddff691 100644 --- a/drivers/usb/gadget/u_os_desc.h +++ b/drivers/usb/gadget/u_os_desc.h | |||
| @@ -35,27 +35,63 @@ | |||
| 35 | #define USB_EXT_PROP_UNICODE_LINK 6 | 35 | #define USB_EXT_PROP_UNICODE_LINK 6 |
| 36 | #define USB_EXT_PROP_UNICODE_MULTI 7 | 36 | #define USB_EXT_PROP_UNICODE_MULTI 7 |
| 37 | 37 | ||
| 38 | static inline u8 *__usb_ext_prop_ptr(u8 *buf, size_t offset) | ||
| 39 | { | ||
| 40 | return buf + offset; | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline u8 *usb_ext_prop_size_ptr(u8 *buf) | ||
| 44 | { | ||
| 45 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_DW_SIZE); | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline u8 *usb_ext_prop_type_ptr(u8 *buf) | ||
| 49 | { | ||
| 50 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_DW_PROPERTY_DATA_TYPE); | ||
| 51 | } | ||
| 52 | |||
| 53 | static inline u8 *usb_ext_prop_name_len_ptr(u8 *buf) | ||
| 54 | { | ||
| 55 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_W_PROPERTY_NAME_LENGTH); | ||
| 56 | } | ||
| 57 | |||
| 58 | static inline u8 *usb_ext_prop_name_ptr(u8 *buf) | ||
| 59 | { | ||
| 60 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_B_PROPERTY_NAME); | ||
| 61 | } | ||
| 62 | |||
| 63 | static inline u8 *usb_ext_prop_data_len_ptr(u8 *buf, size_t off) | ||
| 64 | { | ||
| 65 | return __usb_ext_prop_ptr(buf, | ||
| 66 | USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + off); | ||
| 67 | } | ||
| 68 | |||
| 69 | static inline u8 *usb_ext_prop_data_ptr(u8 *buf, size_t off) | ||
| 70 | { | ||
| 71 | return __usb_ext_prop_ptr(buf, USB_EXT_PROP_B_PROPERTY_DATA + off); | ||
| 72 | } | ||
| 73 | |||
| 38 | static inline void usb_ext_prop_put_size(u8 *buf, int dw_size) | 74 | static inline void usb_ext_prop_put_size(u8 *buf, int dw_size) |
| 39 | { | 75 | { |
| 40 | put_unaligned_le32(dw_size, &buf[USB_EXT_PROP_DW_SIZE]); | 76 | put_unaligned_le32(dw_size, usb_ext_prop_size_ptr(buf)); |
| 41 | } | 77 | } |
| 42 | 78 | ||
| 43 | static inline void usb_ext_prop_put_type(u8 *buf, int type) | 79 | static inline void usb_ext_prop_put_type(u8 *buf, int type) |
| 44 | { | 80 | { |
| 45 | put_unaligned_le32(type, &buf[USB_EXT_PROP_DW_PROPERTY_DATA_TYPE]); | 81 | put_unaligned_le32(type, usb_ext_prop_type_ptr(buf)); |
| 46 | } | 82 | } |
| 47 | 83 | ||
| 48 | static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl) | 84 | static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl) |
| 49 | { | 85 | { |
| 50 | int result; | 86 | int result; |
| 51 | 87 | ||
| 52 | put_unaligned_le16(pnl, &buf[USB_EXT_PROP_W_PROPERTY_NAME_LENGTH]); | 88 | put_unaligned_le16(pnl, usb_ext_prop_name_len_ptr(buf)); |
| 53 | result = utf8s_to_utf16s(name, strlen(name), UTF16_LITTLE_ENDIAN, | 89 | result = utf8s_to_utf16s(name, strlen(name), UTF16_LITTLE_ENDIAN, |
| 54 | (wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_NAME], pnl - 2); | 90 | (wchar_t *) usb_ext_prop_name_ptr(buf), pnl - 2); |
| 55 | if (result < 0) | 91 | if (result < 0) |
| 56 | return result; | 92 | return result; |
| 57 | 93 | ||
| 58 | put_unaligned_le16(0, &buf[USB_EXT_PROP_B_PROPERTY_NAME + pnl]); | 94 | put_unaligned_le16(0, &buf[USB_EXT_PROP_B_PROPERTY_NAME + pnl - 2]); |
| 59 | 95 | ||
| 60 | return pnl; | 96 | return pnl; |
| 61 | } | 97 | } |
| @@ -63,26 +99,23 @@ static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl) | |||
| 63 | static inline void usb_ext_prop_put_binary(u8 *buf, int pnl, const u8 *data, | 99 | static inline void usb_ext_prop_put_binary(u8 *buf, int pnl, const u8 *data, |
| 64 | int data_len) | 100 | int data_len) |
| 65 | { | 101 | { |
| 66 | put_unaligned_le32(data_len, | 102 | put_unaligned_le32(data_len, usb_ext_prop_data_len_ptr(buf, pnl)); |
| 67 | &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]); | 103 | memcpy(usb_ext_prop_data_ptr(buf, pnl), data, data_len); |
| 68 | memcpy(&buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], data, data_len); | ||
| 69 | } | 104 | } |
| 70 | 105 | ||
| 71 | static inline int usb_ext_prop_put_unicode(u8 *buf, int pnl, const char *string, | 106 | static inline int usb_ext_prop_put_unicode(u8 *buf, int pnl, const char *string, |
| 72 | int data_len) | 107 | int data_len) |
| 73 | { | 108 | { |
| 74 | int result; | 109 | int result; |
| 75 | put_unaligned_le32(data_len, | 110 | put_unaligned_le32(data_len, usb_ext_prop_data_len_ptr(buf, pnl)); |
| 76 | &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]); | ||
| 77 | |||
| 78 | result = utf8s_to_utf16s(string, data_len >> 1, UTF16_LITTLE_ENDIAN, | 111 | result = utf8s_to_utf16s(string, data_len >> 1, UTF16_LITTLE_ENDIAN, |
| 79 | (wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], | 112 | (wchar_t *) usb_ext_prop_data_ptr(buf, pnl), |
| 80 | data_len - 2); | 113 | data_len - 2); |
| 81 | if (result < 0) | 114 | if (result < 0) |
| 82 | return result; | 115 | return result; |
| 83 | 116 | ||
| 84 | put_unaligned_le16(0, | 117 | put_unaligned_le16(0, |
| 85 | &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl + data_len]); | 118 | &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl + data_len - 2]); |
| 86 | 119 | ||
| 87 | return data_len; | 120 | return data_len; |
| 88 | } | 121 | } |
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig new file mode 100644 index 000000000000..34ebaa68504c --- /dev/null +++ b/drivers/usb/gadget/udc/Kconfig | |||
| @@ -0,0 +1,386 @@ | |||
| 1 | # | ||
| 2 | # USB Gadget support on a system involves | ||
| 3 | # (a) a peripheral controller, and | ||
| 4 | # (b) the gadget driver using it. | ||
| 5 | # | ||
| 6 | # NOTE: Gadget support ** DOES NOT ** depend on host-side CONFIG_USB !! | ||
| 7 | # | ||
| 8 | # - Host systems (like PCs) need CONFIG_USB (with "A" jacks). | ||
| 9 | # - Peripherals (like PDAs) need CONFIG_USB_GADGET (with "B" jacks). | ||
| 10 | # - Some systems have both kinds of controllers. | ||
| 11 | # | ||
| 12 | # With help from a special transceiver and a "Mini-AB" jack, systems with | ||
| 13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). | ||
| 14 | # | ||
| 15 | |||
| 16 | # | ||
| 17 | # USB Peripheral Controller Support | ||
| 18 | # | ||
| 19 | # The order here is alphabetical, except that integrated controllers go | ||
| 20 | # before discrete ones so they will be the initial/default value: | ||
| 21 | # - integrated/SOC controllers first | ||
| 22 | # - licensed IP used in both SOC and discrete versions | ||
| 23 | # - discrete ones (including all PCI-only controllers) | ||
| 24 | # - debug/dummy gadget+hcd is last. | ||
| 25 | # | ||
| 26 | menu "USB Peripheral Controller" | ||
| 27 | |||
| 28 | # | ||
| 29 | # Integrated controllers | ||
| 30 | # | ||
| 31 | |||
| 32 | config USB_AT91 | ||
| 33 | tristate "Atmel AT91 USB Device Port" | ||
| 34 | depends on ARCH_AT91 | ||
| 35 | help | ||
| 36 | Many Atmel AT91 processors (such as the AT91RM2000) have a | ||
| 37 | full speed USB Device Port with support for five configurable | ||
| 38 | endpoints (plus endpoint zero). | ||
| 39 | |||
| 40 | Say "y" to link the driver statically, or "m" to build a | ||
| 41 | dynamically linked module called "at91_udc" and force all | ||
| 42 | gadget drivers to also be dynamically linked. | ||
| 43 | |||
| 44 | config USB_LPC32XX | ||
| 45 | tristate "LPC32XX USB Peripheral Controller" | ||
| 46 | depends on ARCH_LPC32XX && I2C | ||
| 47 | select USB_ISP1301 | ||
| 48 | help | ||
| 49 | This option selects the USB device controller in the LPC32xx SoC. | ||
| 50 | |||
| 51 | Say "y" to link the driver statically, or "m" to build a | ||
| 52 | dynamically linked module called "lpc32xx_udc" and force all | ||
| 53 | gadget drivers to also be dynamically linked. | ||
| 54 | |||
| 55 | config USB_ATMEL_USBA | ||
| 56 | tristate "Atmel USBA" | ||
| 57 | depends on AVR32 || ARCH_AT91 | ||
| 58 | help | ||
| 59 | USBA is the integrated high-speed USB Device controller on | ||
| 60 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. | ||
| 61 | |||
| 62 | config USB_BCM63XX_UDC | ||
| 63 | tristate "Broadcom BCM63xx Peripheral Controller" | ||
| 64 | depends on BCM63XX | ||
| 65 | help | ||
| 66 | Many Broadcom BCM63xx chipsets (such as the BCM6328) have a | ||
| 67 | high speed USB Device Port with support for four fixed endpoints | ||
| 68 | (plus endpoint zero). | ||
| 69 | |||
| 70 | Say "y" to link the driver statically, or "m" to build a | ||
| 71 | dynamically linked module called "bcm63xx_udc". | ||
| 72 | |||
| 73 | config USB_FSL_USB2 | ||
| 74 | tristate "Freescale Highspeed USB DR Peripheral Controller" | ||
| 75 | depends on FSL_SOC || ARCH_MXC | ||
| 76 | select USB_FSL_MPH_DR_OF if OF | ||
| 77 | help | ||
| 78 | Some of Freescale PowerPC and i.MX processors have a High Speed | ||
| 79 | Dual-Role(DR) USB controller, which supports device mode. | ||
| 80 | |||
| 81 | The number of programmable endpoints is different through | ||
| 82 | SOC revisions. | ||
| 83 | |||
| 84 | Say "y" to link the driver statically, or "m" to build a | ||
| 85 | dynamically linked module called "fsl_usb2_udc" and force | ||
| 86 | all gadget drivers to also be dynamically linked. | ||
| 87 | |||
| 88 | config USB_FUSB300 | ||
| 89 | tristate "Faraday FUSB300 USB Peripheral Controller" | ||
| 90 | depends on !PHYS_ADDR_T_64BIT && HAS_DMA | ||
| 91 | help | ||
| 92 | Faraday usb device controller FUSB300 driver | ||
| 93 | |||
| 94 | config USB_FOTG210_UDC | ||
| 95 | depends on HAS_DMA | ||
| 96 | tristate "Faraday FOTG210 USB Peripheral Controller" | ||
| 97 | help | ||
| 98 | Faraday USB2.0 OTG controller which can be configured as | ||
| 99 | high speed or full speed USB device. This driver supppors | ||
| 100 | Bulk Transfer so far. | ||
| 101 | |||
| 102 | Say "y" to link the driver statically, or "m" to build a | ||
| 103 | dynamically linked module called "fotg210_udc". | ||
| 104 | |||
| 105 | config USB_GR_UDC | ||
| 106 | tristate "Aeroflex Gaisler GRUSBDC USB Peripheral Controller Driver" | ||
| 107 | depends on HAS_DMA | ||
| 108 | help | ||
| 109 | Select this to support Aeroflex Gaisler GRUSBDC cores from the GRLIB | ||
| 110 | VHDL IP core library. | ||
| 111 | |||
| 112 | config USB_OMAP | ||
| 113 | tristate "OMAP USB Device Controller" | ||
| 114 | depends on ARCH_OMAP1 | ||
| 115 | depends on ISP1301_OMAP || !(MACH_OMAP_H2 || MACH_OMAP_H3) | ||
| 116 | help | ||
| 117 | Many Texas Instruments OMAP processors have flexible full | ||
| 118 | speed USB device controllers, with support for up to 30 | ||
| 119 | endpoints (plus endpoint zero). This driver supports the | ||
| 120 | controller in the OMAP 1611, and should work with controllers | ||
| 121 | in other OMAP processors too, given minor tweaks. | ||
| 122 | |||
| 123 | Say "y" to link the driver statically, or "m" to build a | ||
| 124 | dynamically linked module called "omap_udc" and force all | ||
| 125 | gadget drivers to also be dynamically linked. | ||
| 126 | |||
| 127 | config USB_PXA25X | ||
| 128 | tristate "PXA 25x or IXP 4xx" | ||
| 129 | depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX | ||
| 130 | help | ||
| 131 | Intel's PXA 25x series XScale ARM-5TE processors include | ||
| 132 | an integrated full speed USB 1.1 device controller. The | ||
| 133 | controller in the IXP 4xx series is register-compatible. | ||
| 134 | |||
| 135 | It has fifteen fixed-function endpoints, as well as endpoint | ||
| 136 | zero (for control transfers). | ||
| 137 | |||
| 138 | Say "y" to link the driver statically, or "m" to build a | ||
| 139 | dynamically linked module called "pxa25x_udc" and force all | ||
| 140 | gadget drivers to also be dynamically linked. | ||
| 141 | |||
| 142 | # if there's only one gadget driver, using only two bulk endpoints, | ||
| 143 | # don't waste memory for the other endpoints | ||
| 144 | config USB_PXA25X_SMALL | ||
| 145 | depends on USB_PXA25X | ||
| 146 | bool | ||
| 147 | default n if USB_ETH_RNDIS | ||
| 148 | default y if USB_ZERO | ||
| 149 | default y if USB_ETH | ||
| 150 | default y if USB_G_SERIAL | ||
| 151 | |||
| 152 | config USB_R8A66597 | ||
| 153 | tristate "Renesas R8A66597 USB Peripheral Controller" | ||
| 154 | depends on HAS_DMA | ||
| 155 | help | ||
| 156 | R8A66597 is a discrete USB host and peripheral controller chip that | ||
| 157 | supports both full and high speed USB 2.0 data transfers. | ||
| 158 | It has nine configurable endpoints, and endpoint zero. | ||
| 159 | |||
| 160 | Say "y" to link the driver statically, or "m" to build a | ||
| 161 | dynamically linked module called "r8a66597_udc" and force all | ||
| 162 | gadget drivers to also be dynamically linked. | ||
| 163 | |||
| 164 | config USB_RENESAS_USBHS_UDC | ||
| 165 | tristate 'Renesas USBHS controller' | ||
| 166 | depends on USB_RENESAS_USBHS | ||
| 167 | help | ||
| 168 | Renesas USBHS is a discrete USB host and peripheral controller chip | ||
| 169 | that supports both full and high speed USB 2.0 data transfers. | ||
| 170 | It has nine or more configurable endpoints, and endpoint zero. | ||
| 171 | |||
| 172 | Say "y" to link the driver statically, or "m" to build a | ||
| 173 | dynamically linked module called "renesas_usbhs" and force all | ||
| 174 | gadget drivers to also be dynamically linked. | ||
| 175 | |||
| 176 | config USB_PXA27X | ||
| 177 | tristate "PXA 27x" | ||
| 178 | help | ||
| 179 | Intel's PXA 27x series XScale ARM v5TE processors include | ||
| 180 | an integrated full speed USB 1.1 device controller. | ||
| 181 | |||
| 182 | It has up to 23 endpoints, as well as endpoint zero (for | ||
| 183 | control transfers). | ||
| 184 | |||
| 185 | Say "y" to link the driver statically, or "m" to build a | ||
| 186 | dynamically linked module called "pxa27x_udc" and force all | ||
| 187 | gadget drivers to also be dynamically linked. | ||
| 188 | |||
| 189 | config USB_S3C2410 | ||
| 190 | tristate "S3C2410 USB Device Controller" | ||
| 191 | depends on ARCH_S3C24XX | ||
| 192 | help | ||
| 193 | Samsung's S3C2410 is an ARM-4 processor with an integrated | ||
| 194 | full speed USB 1.1 device controller. It has 4 configurable | ||
| 195 | endpoints, as well as endpoint zero (for control transfers). | ||
| 196 | |||
| 197 | This driver has been tested on the S3C2410, S3C2412, and | ||
| 198 | S3C2440 processors. | ||
| 199 | |||
| 200 | config USB_S3C2410_DEBUG | ||
| 201 | boolean "S3C2410 udc debug messages" | ||
| 202 | depends on USB_S3C2410 | ||
| 203 | |||
| 204 | config USB_S3C_HSUDC | ||
| 205 | tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" | ||
| 206 | depends on ARCH_S3C24XX | ||
| 207 | help | ||
| 208 | Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC | ||
| 209 | integrated with dual speed USB 2.0 device controller. It has | ||
| 210 | 8 endpoints, as well as endpoint zero. | ||
| 211 | |||
| 212 | This driver has been tested on S3C2416 and S3C2450 processors. | ||
| 213 | |||
| 214 | config USB_MV_UDC | ||
| 215 | tristate "Marvell USB2.0 Device Controller" | ||
| 216 | depends on HAS_DMA | ||
| 217 | help | ||
| 218 | Marvell Socs (including PXA and MMP series) include a high speed | ||
| 219 | USB2.0 OTG controller, which can be configured as high speed or | ||
| 220 | full speed USB peripheral. | ||
| 221 | |||
| 222 | config USB_MV_U3D | ||
| 223 | depends on HAS_DMA | ||
| 224 | tristate "MARVELL PXA2128 USB 3.0 controller" | ||
| 225 | help | ||
| 226 | MARVELL PXA2128 Processor series include a super speed USB3.0 device | ||
| 227 | controller, which support super speed USB peripheral. | ||
| 228 | |||
| 229 | # | ||
| 230 | # Controllers available in both integrated and discrete versions | ||
| 231 | # | ||
| 232 | |||
| 233 | config USB_M66592 | ||
| 234 | tristate "Renesas M66592 USB Peripheral Controller" | ||
| 235 | help | ||
| 236 | M66592 is a discrete USB peripheral controller chip that | ||
| 237 | supports both full and high speed USB 2.0 data transfers. | ||
| 238 | It has seven configurable endpoints, and endpoint zero. | ||
| 239 | |||
| 240 | Say "y" to link the driver statically, or "m" to build a | ||
| 241 | dynamically linked module called "m66592_udc" and force all | ||
| 242 | gadget drivers to also be dynamically linked. | ||
| 243 | |||
| 244 | # | ||
| 245 | # Controllers available only in discrete form (and all PCI controllers) | ||
| 246 | # | ||
| 247 | |||
| 248 | config USB_AMD5536UDC | ||
| 249 | tristate "AMD5536 UDC" | ||
| 250 | depends on PCI | ||
| 251 | help | ||
| 252 | The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. | ||
| 253 | It is a USB Highspeed DMA capable USB device controller. Beside ep0 | ||
| 254 | it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). | ||
| 255 | The UDC port supports OTG operation, and may be used as a host port | ||
| 256 | if it's not being used to implement peripheral or OTG roles. | ||
| 257 | |||
| 258 | Say "y" to link the driver statically, or "m" to build a | ||
| 259 | dynamically linked module called "amd5536udc" and force all | ||
| 260 | gadget drivers to also be dynamically linked. | ||
| 261 | |||
| 262 | config USB_FSL_QE | ||
| 263 | tristate "Freescale QE/CPM USB Device Controller" | ||
| 264 | depends on FSL_SOC && (QUICC_ENGINE || CPM) | ||
| 265 | help | ||
| 266 | Some of Freescale PowerPC processors have a Full Speed | ||
| 267 | QE/CPM2 USB controller, which support device mode with 4 | ||
| 268 | programmable endpoints. This driver supports the | ||
| 269 | controller in the MPC8360 and MPC8272, and should work with | ||
| 270 | controllers having QE or CPM2, given minor tweaks. | ||
| 271 | |||
| 272 | Set CONFIG_USB_GADGET to "m" to build this driver as a | ||
| 273 | dynamically linked module called "fsl_qe_udc". | ||
| 274 | |||
| 275 | config USB_NET2272 | ||
| 276 | tristate "PLX NET2272" | ||
| 277 | help | ||
| 278 | PLX NET2272 is a USB peripheral controller which supports | ||
| 279 | both full and high speed USB 2.0 data transfers. | ||
| 280 | |||
| 281 | It has three configurable endpoints, as well as endpoint zero | ||
| 282 | (for control transfer). | ||
| 283 | Say "y" to link the driver statically, or "m" to build a | ||
| 284 | dynamically linked module called "net2272" and force all | ||
| 285 | gadget drivers to also be dynamically linked. | ||
| 286 | |||
| 287 | config USB_NET2272_DMA | ||
| 288 | boolean "Support external DMA controller" | ||
| 289 | depends on USB_NET2272 && HAS_DMA | ||
| 290 | help | ||
| 291 | The NET2272 part can optionally support an external DMA | ||
| 292 | controller, but your board has to have support in the | ||
| 293 | driver itself. | ||
| 294 | |||
| 295 | If unsure, say "N" here. The driver works fine in PIO mode. | ||
| 296 | |||
| 297 | config USB_NET2280 | ||
| 298 | tristate "NetChip 228x / PLX USB338x" | ||
| 299 | depends on PCI | ||
| 300 | help | ||
| 301 | NetChip 2280 / 2282 is a PCI based USB peripheral controller which | ||
| 302 | supports both full and high speed USB 2.0 data transfers. | ||
| 303 | |||
| 304 | It has six configurable endpoints, as well as endpoint zero | ||
| 305 | (for control transfers) and several endpoints with dedicated | ||
| 306 | functions. | ||
| 307 | |||
| 308 | PLX 3380 / 3382 is a PCIe based USB peripheral controller which | ||
| 309 | supports full, high speed USB 2.0 and super speed USB 3.0 | ||
| 310 | data transfers. | ||
| 311 | |||
| 312 | It has eight configurable endpoints, as well as endpoint zero | ||
| 313 | (for control transfers) and several endpoints with dedicated | ||
| 314 | functions. | ||
| 315 | |||
| 316 | Say "y" to link the driver statically, or "m" to build a | ||
| 317 | dynamically linked module called "net2280" and force all | ||
| 318 | gadget drivers to also be dynamically linked. | ||
| 319 | |||
| 320 | config USB_GOKU | ||
| 321 | tristate "Toshiba TC86C001 'Goku-S'" | ||
| 322 | depends on PCI | ||
| 323 | help | ||
| 324 | The Toshiba TC86C001 is a PCI device which includes controllers | ||
| 325 | for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI). | ||
| 326 | |||
| 327 | The device controller has three configurable (bulk or interrupt) | ||
| 328 | endpoints, plus endpoint zero (for control transfers). | ||
| 329 | |||
| 330 | Say "y" to link the driver statically, or "m" to build a | ||
| 331 | dynamically linked module called "goku_udc" and to force all | ||
| 332 | gadget drivers to also be dynamically linked. | ||
| 333 | |||
| 334 | config USB_EG20T | ||
| 335 | tristate "Intel QUARK X1000/EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" | ||
| 336 | depends on PCI | ||
| 337 | help | ||
| 338 | This is a USB device driver for EG20T PCH. | ||
| 339 | EG20T PCH is the platform controller hub that is used in Intel's | ||
| 340 | general embedded platform. EG20T PCH has USB device interface. | ||
| 341 | Using this interface, it is able to access system devices connected | ||
| 342 | to USB device. | ||
| 343 | This driver enables USB device function. | ||
| 344 | USB device is a USB peripheral controller which | ||
| 345 | supports both full and high speed USB 2.0 data transfers. | ||
| 346 | This driver supports both control transfer and bulk transfer modes. | ||
| 347 | This driver dose not support interrupt transfer or isochronous | ||
| 348 | transfer modes. | ||
| 349 | |||
| 350 | This driver also can be used for LAPIS Semiconductor's ML7213 which is | ||
| 351 | for IVI(In-Vehicle Infotainment) use. | ||
| 352 | ML7831 is for general purpose use. | ||
| 353 | ML7213/ML7831 is companion chip for Intel Atom E6xx series. | ||
| 354 | ML7213/ML7831 is completely compatible for Intel EG20T PCH. | ||
| 355 | |||
| 356 | This driver can be used with Intel's Quark X1000 SOC platform | ||
| 357 | # | ||
| 358 | # LAST -- dummy/emulated controller | ||
| 359 | # | ||
| 360 | |||
| 361 | config USB_DUMMY_HCD | ||
| 362 | tristate "Dummy HCD (DEVELOPMENT)" | ||
| 363 | depends on USB=y || (USB=m && USB_GADGET=m) | ||
| 364 | help | ||
| 365 | This host controller driver emulates USB, looping all data transfer | ||
| 366 | requests back to a USB "gadget driver" in the same host. The host | ||
| 367 | side is the master; the gadget side is the slave. Gadget drivers | ||
| 368 | can be high, full, or low speed; and they have access to endpoints | ||
| 369 | like those from NET2280, PXA2xx, or SA1100 hardware. | ||
| 370 | |||
| 371 | This may help in some stages of creating a driver to embed in a | ||
| 372 | Linux device, since it lets you debug several parts of the gadget | ||
| 373 | driver without its hardware or drivers being involved. | ||
| 374 | |||
| 375 | Since such a gadget side driver needs to interoperate with a host | ||
| 376 | side Linux-USB device driver, this may help to debug both sides | ||
| 377 | of a USB protocol stack. | ||
| 378 | |||
| 379 | Say "y" to link the driver statically, or "m" to build a | ||
| 380 | dynamically linked module called "dummy_hcd" and force all | ||
| 381 | gadget drivers to also be dynamically linked. | ||
| 382 | |||
| 383 | # NOTE: Please keep dummy_hcd LAST so that "real hardware" appears | ||
| 384 | # first and will be selected by default. | ||
| 385 | |||
| 386 | endmenu | ||
diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile new file mode 100644 index 000000000000..4096122bb283 --- /dev/null +++ b/drivers/usb/gadget/udc/Makefile | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | # | ||
| 2 | # USB peripheral controller drivers | ||
| 3 | # | ||
| 4 | obj-$(CONFIG_USB_GADGET) += udc-core.o | ||
| 5 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | ||
| 6 | obj-$(CONFIG_USB_NET2272) += net2272.o | ||
| 7 | obj-$(CONFIG_USB_NET2280) += net2280.o | ||
| 8 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o | ||
| 9 | obj-$(CONFIG_USB_PXA25X) += pxa25x_udc.o | ||
| 10 | obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o | ||
| 11 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | ||
| 12 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | ||
| 13 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o | ||
| 14 | obj-$(CONFIG_USB_AT91) += at91_udc.o | ||
| 15 | obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o | ||
| 16 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o | ||
| 17 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | ||
| 18 | fsl_usb2_udc-y := fsl_udc_core.o | ||
| 19 | fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | ||
| 20 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | ||
| 21 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | ||
| 22 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | ||
| 23 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o | ||
| 24 | obj-$(CONFIG_USB_LPC32XX) += lpc32xx_udc.o | ||
| 25 | obj-$(CONFIG_USB_EG20T) += pch_udc.o | ||
| 26 | obj-$(CONFIG_USB_MV_UDC) += mv_udc.o | ||
| 27 | mv_udc-y := mv_udc_core.o | ||
| 28 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o | ||
| 29 | obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o | ||
| 30 | obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o | ||
| 31 | obj-$(CONFIG_USB_GR_UDC) += gr_udc.o | ||
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 41b062eb4de0..41b062eb4de0 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c | |||
diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/udc/amd5536udc.h index 6744d3b83109..6744d3b83109 100644 --- a/drivers/usb/gadget/amd5536udc.h +++ b/drivers/usb/gadget/udc/amd5536udc.h | |||
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index cfd18bcca723..cfd18bcca723 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c | |||
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h index 017524663381..017524663381 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/udc/at91_udc.h | |||
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 76023ce449a3..c9fe67e29d35 100644 --- a/drivers/usb/gadget/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 | } |
| @@ -1979,7 +1979,7 @@ static struct usba_ep * usba_udc_pdata(struct platform_device *pdev, | |||
| 1979 | return eps; | 1979 | return eps; |
| 1980 | } | 1980 | } |
| 1981 | 1981 | ||
| 1982 | static int __init usba_udc_probe(struct platform_device *pdev) | 1982 | static int usba_udc_probe(struct platform_device *pdev) |
| 1983 | { | 1983 | { |
| 1984 | struct resource *regs, *fifo; | 1984 | struct resource *regs, *fifo; |
| 1985 | struct clk *pclk, *hclk; | 1985 | struct clk *pclk, *hclk; |
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h index a70706e8cb02..a70706e8cb02 100644 --- a/drivers/usb/gadget/atmel_usba_udc.h +++ b/drivers/usb/gadget/udc/atmel_usba_udc.h | |||
diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index e969eb809a85..e969eb809a85 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c | |||
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 2b54955d3166..2b54955d3166 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c | |||
diff --git a/drivers/usb/gadget/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c index e143d69f6017..e143d69f6017 100644 --- a/drivers/usb/gadget/fotg210-udc.c +++ b/drivers/usb/gadget/udc/fotg210-udc.c | |||
diff --git a/drivers/usb/gadget/fotg210.h b/drivers/usb/gadget/udc/fotg210.h index bbf991bcbe7c..bbf991bcbe7c 100644 --- a/drivers/usb/gadget/fotg210.h +++ b/drivers/usb/gadget/udc/fotg210.h | |||
diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/udc/fsl_mxc_udc.c index 9b140fc4d3bc..f16e149c5b3e 100644 --- a/drivers/usb/gadget/fsl_mxc_udc.c +++ b/drivers/usb/gadget/udc/fsl_mxc_udc.c | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| 20 | 20 | ||
| 21 | #include "fsl_usb2_udc.h" | ||
| 22 | |||
| 21 | static struct clk *mxc_ahb_clk; | 23 | static struct clk *mxc_ahb_clk; |
| 22 | static struct clk *mxc_per_clk; | 24 | static struct clk *mxc_per_clk; |
| 23 | static struct clk *mxc_ipg_clk; | 25 | static struct clk *mxc_ipg_clk; |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index ad5483335167..732430804841 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c | |||
| @@ -2539,7 +2539,7 @@ static int qe_udc_probe(struct platform_device *ofdev) | |||
| 2539 | goto err2; | 2539 | goto err2; |
| 2540 | 2540 | ||
| 2541 | /* create a buf for ZLP send, need to remain zeroed */ | 2541 | /* create a buf for ZLP send, need to remain zeroed */ |
| 2542 | udc->nullbuf = kzalloc(256, GFP_KERNEL); | 2542 | udc->nullbuf = devm_kzalloc(&ofdev->dev, 256, GFP_KERNEL); |
| 2543 | if (udc->nullbuf == NULL) { | 2543 | if (udc->nullbuf == NULL) { |
| 2544 | dev_err(udc->dev, "cannot alloc nullbuf\n"); | 2544 | dev_err(udc->dev, "cannot alloc nullbuf\n"); |
| 2545 | ret = -ENOMEM; | 2545 | ret = -ENOMEM; |
| @@ -2547,10 +2547,10 @@ static int qe_udc_probe(struct platform_device *ofdev) | |||
| 2547 | } | 2547 | } |
| 2548 | 2548 | ||
| 2549 | /* buffer for data of get_status request */ | 2549 | /* buffer for data of get_status request */ |
| 2550 | udc->statusbuf = kzalloc(2, GFP_KERNEL); | 2550 | udc->statusbuf = devm_kzalloc(&ofdev->dev, 2, GFP_KERNEL); |
| 2551 | if (udc->statusbuf == NULL) { | 2551 | if (udc->statusbuf == NULL) { |
| 2552 | ret = -ENOMEM; | 2552 | ret = -ENOMEM; |
| 2553 | goto err4; | 2553 | goto err3; |
| 2554 | } | 2554 | } |
| 2555 | 2555 | ||
| 2556 | udc->nullp = virt_to_phys((void *)udc->nullbuf); | 2556 | udc->nullp = virt_to_phys((void *)udc->nullbuf); |
| @@ -2581,13 +2581,13 @@ static int qe_udc_probe(struct platform_device *ofdev) | |||
| 2581 | if (ret) { | 2581 | if (ret) { |
| 2582 | dev_err(udc->dev, "cannot request irq %d err %d\n", | 2582 | dev_err(udc->dev, "cannot request irq %d err %d\n", |
| 2583 | udc->usb_irq, ret); | 2583 | udc->usb_irq, ret); |
| 2584 | goto err5; | 2584 | goto err4; |
| 2585 | } | 2585 | } |
| 2586 | 2586 | ||
| 2587 | ret = usb_add_gadget_udc_release(&ofdev->dev, &udc->gadget, | 2587 | ret = usb_add_gadget_udc_release(&ofdev->dev, &udc->gadget, |
| 2588 | qe_udc_release); | 2588 | qe_udc_release); |
| 2589 | if (ret) | 2589 | if (ret) |
| 2590 | goto err6; | 2590 | goto err5; |
| 2591 | 2591 | ||
| 2592 | platform_set_drvdata(ofdev, udc); | 2592 | platform_set_drvdata(ofdev, udc); |
| 2593 | dev_info(udc->dev, | 2593 | dev_info(udc->dev, |
| @@ -2595,9 +2595,9 @@ static int qe_udc_probe(struct platform_device *ofdev) | |||
| 2595 | (udc->soc_type == PORT_QE) ? "QE" : "CPM"); | 2595 | (udc->soc_type == PORT_QE) ? "QE" : "CPM"); |
| 2596 | return 0; | 2596 | return 0; |
| 2597 | 2597 | ||
| 2598 | err6: | ||
| 2599 | free_irq(udc->usb_irq, udc); | ||
| 2600 | err5: | 2598 | err5: |
| 2599 | free_irq(udc->usb_irq, udc); | ||
| 2600 | err4: | ||
| 2601 | irq_dispose_mapping(udc->usb_irq); | 2601 | irq_dispose_mapping(udc->usb_irq); |
| 2602 | err_noirq: | 2602 | err_noirq: |
| 2603 | if (udc->nullmap) { | 2603 | if (udc->nullmap) { |
| @@ -2610,9 +2610,6 @@ err_noirq: | |||
| 2610 | udc->nullp, 256, | 2610 | udc->nullp, 256, |
| 2611 | DMA_TO_DEVICE); | 2611 | DMA_TO_DEVICE); |
| 2612 | } | 2612 | } |
| 2613 | kfree(udc->statusbuf); | ||
| 2614 | err4: | ||
| 2615 | kfree(udc->nullbuf); | ||
| 2616 | err3: | 2613 | err3: |
| 2617 | ep = &udc->eps[0]; | 2614 | ep = &udc->eps[0]; |
| 2618 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); | 2615 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); |
| @@ -2660,8 +2657,6 @@ static int qe_udc_remove(struct platform_device *ofdev) | |||
| 2660 | udc->nullp, 256, | 2657 | udc->nullp, 256, |
| 2661 | DMA_TO_DEVICE); | 2658 | DMA_TO_DEVICE); |
| 2662 | } | 2659 | } |
| 2663 | kfree(udc->statusbuf); | ||
| 2664 | kfree(udc->nullbuf); | ||
| 2665 | 2660 | ||
| 2666 | ep = &udc->eps[0]; | 2661 | ep = &udc->eps[0]; |
| 2667 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); | 2662 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); |
diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/udc/fsl_qe_udc.h index 7026919fc901..7026919fc901 100644 --- a/drivers/usb/gadget/fsl_qe_udc.h +++ b/drivers/usb/gadget/udc/fsl_qe_udc.h | |||
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 28e4fc957026..75b23ea077a7 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c | |||
| @@ -59,9 +59,9 @@ | |||
| 59 | static const char driver_name[] = "fsl-usb2-udc"; | 59 | static const char driver_name[] = "fsl-usb2-udc"; |
| 60 | static const char driver_desc[] = DRIVER_DESC; | 60 | static const char driver_desc[] = DRIVER_DESC; |
| 61 | 61 | ||
| 62 | static struct usb_dr_device *dr_regs; | 62 | static struct usb_dr_device __iomem *dr_regs; |
| 63 | 63 | ||
| 64 | static struct usb_sys_interface *usb_sys_regs; | 64 | static struct usb_sys_interface __iomem *usb_sys_regs; |
| 65 | 65 | ||
| 66 | /* it is initialized in probe() */ | 66 | /* it is initialized in probe() */ |
| 67 | static struct fsl_udc *udc_controller = NULL; | 67 | static struct fsl_udc *udc_controller = NULL; |
| @@ -159,6 +159,8 @@ static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) {} | |||
| 159 | * request is still in progress. | 159 | * request is still in progress. |
| 160 | *--------------------------------------------------------------*/ | 160 | *--------------------------------------------------------------*/ |
| 161 | static void done(struct fsl_ep *ep, struct fsl_req *req, int status) | 161 | static void done(struct fsl_ep *ep, struct fsl_req *req, int status) |
| 162 | __releases(ep->udc->lock) | ||
| 163 | __acquires(ep->udc->lock) | ||
| 162 | { | 164 | { |
| 163 | struct fsl_udc *udc = NULL; | 165 | struct fsl_udc *udc = NULL; |
| 164 | unsigned char stopped = ep->stopped; | 166 | unsigned char stopped = ep->stopped; |
| @@ -1392,6 +1394,8 @@ stall: | |||
| 1392 | 1394 | ||
| 1393 | static void setup_received_irq(struct fsl_udc *udc, | 1395 | static void setup_received_irq(struct fsl_udc *udc, |
| 1394 | struct usb_ctrlrequest *setup) | 1396 | struct usb_ctrlrequest *setup) |
| 1397 | __releases(udc->lock) | ||
| 1398 | __acquires(udc->lock) | ||
| 1395 | { | 1399 | { |
| 1396 | u16 wValue = le16_to_cpu(setup->wValue); | 1400 | u16 wValue = le16_to_cpu(setup->wValue); |
| 1397 | u16 wIndex = le16_to_cpu(setup->wIndex); | 1401 | u16 wIndex = le16_to_cpu(setup->wIndex); |
| @@ -1957,8 +1961,7 @@ static int fsl_udc_start(struct usb_gadget *g, | |||
| 1957 | &udc_controller->gadget); | 1961 | &udc_controller->gadget); |
| 1958 | if (retval < 0) { | 1962 | if (retval < 0) { |
| 1959 | ERR("can't bind to transceiver\n"); | 1963 | ERR("can't bind to transceiver\n"); |
| 1960 | driver->unbind(&udc_controller->gadget); | 1964 | udc_controller->driver = NULL; |
| 1961 | udc_controller->driver = 0; | ||
| 1962 | return retval; | 1965 | return retval; |
| 1963 | } | 1966 | } |
| 1964 | } | 1967 | } |
| @@ -2246,7 +2249,7 @@ static void fsl_udc_release(struct device *dev) | |||
| 2246 | * init resource for globle controller | 2249 | * init resource for globle controller |
| 2247 | * Return the udc handle on success or NULL on failure | 2250 | * Return the udc handle on success or NULL on failure |
| 2248 | ------------------------------------------------------------------*/ | 2251 | ------------------------------------------------------------------*/ |
| 2249 | static int __init struct_udc_setup(struct fsl_udc *udc, | 2252 | static int struct_udc_setup(struct fsl_udc *udc, |
| 2250 | struct platform_device *pdev) | 2253 | struct platform_device *pdev) |
| 2251 | { | 2254 | { |
| 2252 | struct fsl_usb2_platform_data *pdata; | 2255 | struct fsl_usb2_platform_data *pdata; |
| @@ -2298,7 +2301,7 @@ static int __init struct_udc_setup(struct fsl_udc *udc, | |||
| 2298 | * ep0out is not used so do nothing here | 2301 | * ep0out is not used so do nothing here |
| 2299 | * ep0in should be taken care | 2302 | * ep0in should be taken care |
| 2300 | *--------------------------------------------------------------*/ | 2303 | *--------------------------------------------------------------*/ |
| 2301 | static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, | 2304 | static int struct_ep_setup(struct fsl_udc *udc, unsigned char index, |
| 2302 | char *name, int link) | 2305 | char *name, int link) |
| 2303 | { | 2306 | { |
| 2304 | struct fsl_ep *ep = &udc->eps[index]; | 2307 | struct fsl_ep *ep = &udc->eps[index]; |
| @@ -2331,7 +2334,7 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, | |||
| 2331 | * all intialization operations implemented here except enabling usb_intr reg | 2334 | * all intialization operations implemented here except enabling usb_intr reg |
| 2332 | * board setup should have been done in the platform code | 2335 | * board setup should have been done in the platform code |
| 2333 | */ | 2336 | */ |
| 2334 | static int __init fsl_udc_probe(struct platform_device *pdev) | 2337 | static int fsl_udc_probe(struct platform_device *pdev) |
| 2335 | { | 2338 | { |
| 2336 | struct fsl_usb2_platform_data *pdata; | 2339 | struct fsl_usb2_platform_data *pdata; |
| 2337 | struct resource *res; | 2340 | struct resource *res; |
| @@ -2380,7 +2383,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
| 2380 | goto err_release_mem_region; | 2383 | goto err_release_mem_region; |
| 2381 | } | 2384 | } |
| 2382 | 2385 | ||
| 2383 | pdata->regs = (void *)dr_regs; | 2386 | pdata->regs = (void __iomem *)dr_regs; |
| 2384 | 2387 | ||
| 2385 | /* | 2388 | /* |
| 2386 | * do platform specific init: check the clock, grab/config pins, etc. | 2389 | * do platform specific init: check the clock, grab/config pins, etc. |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/udc/fsl_usb2_udc.h index c6703bb07b23..84715625b2b3 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/udc/fsl_usb2_udc.h | |||
| @@ -12,6 +12,9 @@ | |||
| 12 | #ifndef __FSL_USB2_UDC_H | 12 | #ifndef __FSL_USB2_UDC_H |
| 13 | #define __FSL_USB2_UDC_H | 13 | #define __FSL_USB2_UDC_H |
| 14 | 14 | ||
| 15 | #include <linux/usb/ch9.h> | ||
| 16 | #include <linux/usb/gadget.h> | ||
| 17 | |||
| 15 | /* ### define USB registers here | 18 | /* ### define USB registers here |
| 16 | */ | 19 | */ |
| 17 | #define USB_MAX_CTRL_PAYLOAD 64 | 20 | #define USB_MAX_CTRL_PAYLOAD 64 |
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index 3deb4e938071..5c5d1adda7eb 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c | |||
| @@ -1325,8 +1325,6 @@ static int fusb300_udc_stop(struct usb_gadget *g, | |||
| 1325 | { | 1325 | { |
| 1326 | struct fusb300 *fusb300 = to_fusb300(g); | 1326 | struct fusb300 *fusb300 = to_fusb300(g); |
| 1327 | 1327 | ||
| 1328 | driver->unbind(&fusb300->gadget); | ||
| 1329 | |||
| 1330 | init_controller(fusb300); | 1328 | init_controller(fusb300); |
| 1331 | fusb300->driver = NULL; | 1329 | fusb300->driver = NULL; |
| 1332 | 1330 | ||
| @@ -1359,7 +1357,7 @@ static int __exit fusb300_remove(struct platform_device *pdev) | |||
| 1359 | return 0; | 1357 | return 0; |
| 1360 | } | 1358 | } |
| 1361 | 1359 | ||
| 1362 | static int __init fusb300_probe(struct platform_device *pdev) | 1360 | static int fusb300_probe(struct platform_device *pdev) |
| 1363 | { | 1361 | { |
| 1364 | struct resource *res, *ires, *ires1; | 1362 | struct resource *res, *ires, *ires1; |
| 1365 | void __iomem *reg = NULL; | 1363 | void __iomem *reg = NULL; |
| @@ -1400,13 +1398,17 @@ static int __init fusb300_probe(struct platform_device *pdev) | |||
| 1400 | 1398 | ||
| 1401 | /* initialize udc */ | 1399 | /* initialize udc */ |
| 1402 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); | 1400 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); |
| 1403 | if (fusb300 == NULL) | 1401 | if (fusb300 == NULL) { |
| 1402 | ret = -ENOMEM; | ||
| 1404 | goto clean_up; | 1403 | goto clean_up; |
| 1404 | } | ||
| 1405 | 1405 | ||
| 1406 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { | 1406 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { |
| 1407 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); | 1407 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); |
| 1408 | if (_ep[i] == NULL) | 1408 | if (_ep[i] == NULL) { |
| 1409 | ret = -ENOMEM; | ||
| 1409 | goto clean_up; | 1410 | goto clean_up; |
| 1411 | } | ||
| 1410 | fusb300->ep[i] = _ep[i]; | 1412 | fusb300->ep[i] = _ep[i]; |
| 1411 | } | 1413 | } |
| 1412 | 1414 | ||
diff --git a/drivers/usb/gadget/fusb300_udc.h b/drivers/usb/gadget/udc/fusb300_udc.h index ae811d8d38b4..ae811d8d38b4 100644 --- a/drivers/usb/gadget/fusb300_udc.h +++ b/drivers/usb/gadget/udc/fusb300_udc.h | |||
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/udc/gadget_chips.h index bcd04bc66b98..bcd04bc66b98 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/udc/gadget_chips.h | |||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index 6c85839e15ad..6c85839e15ad 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c | |||
diff --git a/drivers/usb/gadget/goku_udc.h b/drivers/usb/gadget/udc/goku_udc.h index 86d2adafe149..86d2adafe149 100644 --- a/drivers/usb/gadget/goku_udc.h +++ b/drivers/usb/gadget/udc/goku_udc.h | |||
diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index c7004ee89c90..08df5c4f46ce 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c | |||
| @@ -2213,7 +2213,7 @@ out: | |||
| 2213 | return retval; | 2213 | return retval; |
| 2214 | } | 2214 | } |
| 2215 | 2215 | ||
| 2216 | static struct of_device_id gr_match[] = { | 2216 | static const struct of_device_id gr_match[] = { |
| 2217 | {.name = "GAISLER_USBDC"}, | 2217 | {.name = "GAISLER_USBDC"}, |
| 2218 | {.name = "01_021"}, | 2218 | {.name = "01_021"}, |
| 2219 | {}, | 2219 | {}, |
diff --git a/drivers/usb/gadget/gr_udc.h b/drivers/usb/gadget/udc/gr_udc.h index 8388897d9ec3..8388897d9ec3 100644 --- a/drivers/usb/gadget/gr_udc.h +++ b/drivers/usb/gadget/udc/gr_udc.h | |||
diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index e471580a2a3b..1629ad7dcb80 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c | |||
| @@ -3036,7 +3036,7 @@ struct lpc32xx_usbd_cfg lpc32xx_usbddata = { | |||
| 3036 | 3036 | ||
| 3037 | static u64 lpc32xx_usbd_dmamask = ~(u32) 0x7F; | 3037 | static u64 lpc32xx_usbd_dmamask = ~(u32) 0x7F; |
| 3038 | 3038 | ||
| 3039 | static int __init lpc32xx_udc_probe(struct platform_device *pdev) | 3039 | static int lpc32xx_udc_probe(struct platform_device *pdev) |
| 3040 | { | 3040 | { |
| 3041 | struct device *dev = &pdev->dev; | 3041 | struct device *dev = &pdev->dev; |
| 3042 | struct lpc32xx_udc *udc; | 3042 | struct lpc32xx_udc *udc; |
| @@ -3045,11 +3045,10 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) | |||
| 3045 | dma_addr_t dma_handle; | 3045 | dma_addr_t dma_handle; |
| 3046 | struct device_node *isp1301_node; | 3046 | struct device_node *isp1301_node; |
| 3047 | 3047 | ||
| 3048 | udc = kzalloc(sizeof(*udc), GFP_KERNEL); | 3048 | udc = kmemdup(&controller_template, sizeof(*udc), GFP_KERNEL); |
| 3049 | if (!udc) | 3049 | if (!udc) |
| 3050 | return -ENOMEM; | 3050 | return -ENOMEM; |
| 3051 | 3051 | ||
| 3052 | memcpy(udc, &controller_template, sizeof(*udc)); | ||
| 3053 | for (i = 0; i <= 15; i++) | 3052 | for (i = 0; i <= 15; i++) |
| 3054 | udc->ep[i].udc = udc; | 3053 | udc->ep[i].udc = udc; |
| 3055 | udc->gadget.ep0 = &udc->ep[0].ep; | 3054 | udc->gadget.ep0 = &udc->ep[0].ep; |
| @@ -3397,7 +3396,7 @@ static int lpc32xx_udc_resume(struct platform_device *pdev) | |||
| 3397 | #endif | 3396 | #endif |
| 3398 | 3397 | ||
| 3399 | #ifdef CONFIG_OF | 3398 | #ifdef CONFIG_OF |
| 3400 | static struct of_device_id lpc32xx_udc_of_match[] = { | 3399 | static const struct of_device_id lpc32xx_udc_of_match[] = { |
| 3401 | { .compatible = "nxp,lpc3220-udc", }, | 3400 | { .compatible = "nxp,lpc3220-udc", }, |
| 3402 | { }, | 3401 | { }, |
| 3403 | }; | 3402 | }; |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index 0d17174b86f8..de88d33b44b2 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c | |||
| @@ -1492,8 +1492,6 @@ static int m66592_udc_stop(struct usb_gadget *g, | |||
| 1492 | 1492 | ||
| 1493 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); | 1493 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); |
| 1494 | 1494 | ||
| 1495 | driver->unbind(&m66592->gadget); | ||
| 1496 | |||
| 1497 | init_controller(m66592); | 1495 | init_controller(m66592); |
| 1498 | disable_controller(m66592); | 1496 | disable_controller(m66592); |
| 1499 | 1497 | ||
| @@ -1553,7 +1551,7 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r) | |||
| 1553 | { | 1551 | { |
| 1554 | } | 1552 | } |
| 1555 | 1553 | ||
| 1556 | static int __init m66592_probe(struct platform_device *pdev) | 1554 | static int m66592_probe(struct platform_device *pdev) |
| 1557 | { | 1555 | { |
| 1558 | struct resource *res, *ires; | 1556 | struct resource *res, *ires; |
| 1559 | void __iomem *reg = NULL; | 1557 | void __iomem *reg = NULL; |
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/udc/m66592-udc.h index 96d49d7bfb6b..96d49d7bfb6b 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/udc/m66592-udc.h | |||
diff --git a/drivers/usb/gadget/mv_u3d.h b/drivers/usb/gadget/udc/mv_u3d.h index e32a787ac373..e32a787ac373 100644 --- a/drivers/usb/gadget/mv_u3d.h +++ b/drivers/usb/gadget/udc/mv_u3d.h | |||
diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index 16248711c152..16248711c152 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c | |||
diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/udc/mv_udc.h index be77f207dbaf..be77f207dbaf 100644 --- a/drivers/usb/gadget/mv_udc.h +++ b/drivers/usb/gadget/udc/mv_udc.h | |||
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index fcff3a571b45..040fb169b162 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c | |||
| @@ -332,7 +332,7 @@ static int queue_dtd(struct mv_ep *ep, struct mv_req *req) | |||
| 332 | /* clear active and halt bit, in case set from a previous error */ | 332 | /* clear active and halt bit, in case set from a previous error */ |
| 333 | dqh->size_ioc_int_sts &= ~(DTD_STATUS_ACTIVE | DTD_STATUS_HALTED); | 333 | dqh->size_ioc_int_sts &= ~(DTD_STATUS_ACTIVE | DTD_STATUS_HALTED); |
| 334 | 334 | ||
| 335 | /* Ensure that updates to the QH will occure before priming. */ | 335 | /* Ensure that updates to the QH will occur before priming. */ |
| 336 | wmb(); | 336 | wmb(); |
| 337 | 337 | ||
| 338 | /* Prime the Endpoint */ | 338 | /* Prime the Endpoint */ |
| @@ -1656,7 +1656,7 @@ static void handle_setup_packet(struct mv_udc *udc, u8 ep_num, | |||
| 1656 | dev_dbg(&udc->dev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", | 1656 | dev_dbg(&udc->dev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", |
| 1657 | setup->bRequestType, setup->bRequest, | 1657 | setup->bRequestType, setup->bRequest, |
| 1658 | setup->wValue, setup->wIndex, setup->wLength); | 1658 | setup->wValue, setup->wIndex, setup->wLength); |
| 1659 | /* We process some stardard setup requests here */ | 1659 | /* We process some standard setup requests here */ |
| 1660 | if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | 1660 | if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { |
| 1661 | switch (setup->bRequest) { | 1661 | switch (setup->bRequest) { |
| 1662 | case USB_REQ_GET_STATUS: | 1662 | case USB_REQ_GET_STATUS: |
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/udc/net2272.c index ca15405583e2..059cfe527982 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c | |||
| @@ -1453,7 +1453,7 @@ static int net2272_start(struct usb_gadget *_gadget, | |||
| 1453 | struct net2272 *dev; | 1453 | struct net2272 *dev; |
| 1454 | unsigned i; | 1454 | unsigned i; |
| 1455 | 1455 | ||
| 1456 | if (!driver || !driver->unbind || !driver->setup || | 1456 | if (!driver || !driver->setup || |
| 1457 | driver->max_speed != USB_SPEED_HIGH) | 1457 | driver->max_speed != USB_SPEED_HIGH) |
| 1458 | return -EINVAL; | 1458 | return -EINVAL; |
| 1459 | 1459 | ||
diff --git a/drivers/usb/gadget/net2272.h b/drivers/usb/gadget/udc/net2272.h index e59505789359..e59505789359 100644 --- a/drivers/usb/gadget/net2272.h +++ b/drivers/usb/gadget/udc/net2272.h | |||
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c new file mode 100644 index 000000000000..f4eac113690e --- /dev/null +++ b/drivers/usb/gadget/udc/net2280.c | |||
| @@ -0,0 +1,3827 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the PLX NET2280 USB device controller. | ||
| 3 | * Specs and errata are available from <http://www.plxtech.com>. | ||
| 4 | * | ||
| 5 | * PLX Technology Inc. (formerly NetChip Technology) supported the | ||
| 6 | * development of this driver. | ||
| 7 | * | ||
| 8 | * | ||
| 9 | * CODE STATUS HIGHLIGHTS | ||
| 10 | * | ||
| 11 | * This driver should work well with most "gadget" drivers, including | ||
| 12 | * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers | ||
| 13 | * as well as Gadget Zero and Gadgetfs. | ||
| 14 | * | ||
| 15 | * DMA is enabled by default. Drivers using transfer queues might use | ||
| 16 | * DMA chaining to remove IRQ latencies between transfers. (Except when | ||
| 17 | * short OUT transfers happen.) Drivers can use the req->no_interrupt | ||
| 18 | * hint to completely eliminate some IRQs, if a later IRQ is guaranteed | ||
| 19 | * and DMA chaining is enabled. | ||
| 20 | * | ||
| 21 | * MSI is enabled by default. The legacy IRQ is used if MSI couldn't | ||
| 22 | * be enabled. | ||
| 23 | * | ||
| 24 | * Note that almost all the errata workarounds here are only needed for | ||
| 25 | * rev1 chips. Rev1a silicon (0110) fixes almost all of them. | ||
| 26 | */ | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Copyright (C) 2003 David Brownell | ||
| 30 | * Copyright (C) 2003-2005 PLX Technology, Inc. | ||
| 31 | * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS | ||
| 32 | * | ||
| 33 | * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility | ||
| 34 | * with 2282 chip | ||
| 35 | * | ||
| 36 | * Modified Ricardo Ribalda Qtechnology AS to provide compatibility | ||
| 37 | * with usb 338x chip. Based on PLX driver | ||
| 38 | * | ||
| 39 | * This program is free software; you can redistribute it and/or modify | ||
| 40 | * it under the terms of the GNU General Public License as published by | ||
| 41 | * the Free Software Foundation; either version 2 of the License, or | ||
| 42 | * (at your option) any later version. | ||
| 43 | */ | ||
| 44 | |||
| 45 | #include <linux/module.h> | ||
| 46 | #include <linux/pci.h> | ||
| 47 | #include <linux/dma-mapping.h> | ||
| 48 | #include <linux/kernel.h> | ||
| 49 | #include <linux/delay.h> | ||
| 50 | #include <linux/ioport.h> | ||
| 51 | #include <linux/slab.h> | ||
| 52 | #include <linux/errno.h> | ||
| 53 | #include <linux/init.h> | ||
| 54 | #include <linux/timer.h> | ||
| 55 | #include <linux/list.h> | ||
| 56 | #include <linux/interrupt.h> | ||
| 57 | #include <linux/moduleparam.h> | ||
| 58 | #include <linux/device.h> | ||
| 59 | #include <linux/usb/ch9.h> | ||
| 60 | #include <linux/usb/gadget.h> | ||
| 61 | #include <linux/prefetch.h> | ||
| 62 | #include <linux/io.h> | ||
| 63 | |||
| 64 | #include <asm/byteorder.h> | ||
| 65 | #include <asm/irq.h> | ||
| 66 | #include <asm/unaligned.h> | ||
| 67 | |||
| 68 | #define DRIVER_DESC "PLX NET228x/USB338x USB Peripheral Controller" | ||
| 69 | #define DRIVER_VERSION "2005 Sept 27/v3.0" | ||
| 70 | |||
| 71 | #define EP_DONTUSE 13 /* nonzero */ | ||
| 72 | |||
| 73 | #define USE_RDK_LEDS /* GPIO pins control three LEDs */ | ||
| 74 | |||
| 75 | |||
| 76 | static const char driver_name[] = "net2280"; | ||
| 77 | static const char driver_desc[] = DRIVER_DESC; | ||
| 78 | |||
| 79 | static const u32 ep_bit[9] = { 0, 17, 2, 19, 4, 1, 18, 3, 20 }; | ||
| 80 | static const char ep0name[] = "ep0"; | ||
| 81 | static const char *const ep_name[] = { | ||
| 82 | ep0name, | ||
| 83 | "ep-a", "ep-b", "ep-c", "ep-d", | ||
| 84 | "ep-e", "ep-f", "ep-g", "ep-h", | ||
| 85 | }; | ||
| 86 | |||
| 87 | /* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO) | ||
| 88 | * use_dma_chaining -- dma descriptor queueing gives even more irq reduction | ||
| 89 | * | ||
| 90 | * The net2280 DMA engines are not tightly integrated with their FIFOs; | ||
| 91 | * not all cases are (yet) handled well in this driver or the silicon. | ||
| 92 | * Some gadget drivers work better with the dma support here than others. | ||
| 93 | * These two parameters let you use PIO or more aggressive DMA. | ||
| 94 | */ | ||
| 95 | static bool use_dma = true; | ||
| 96 | static bool use_dma_chaining; | ||
| 97 | static bool use_msi = true; | ||
| 98 | |||
| 99 | /* "modprobe net2280 use_dma=n" etc */ | ||
| 100 | module_param(use_dma, bool, 0444); | ||
| 101 | module_param(use_dma_chaining, bool, 0444); | ||
| 102 | module_param(use_msi, bool, 0444); | ||
| 103 | |||
| 104 | /* mode 0 == ep-{a,b,c,d} 1K fifo each | ||
| 105 | * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable | ||
| 106 | * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable | ||
| 107 | */ | ||
| 108 | static ushort fifo_mode; | ||
| 109 | |||
| 110 | /* "modprobe net2280 fifo_mode=1" etc */ | ||
| 111 | module_param(fifo_mode, ushort, 0644); | ||
| 112 | |||
| 113 | /* enable_suspend -- When enabled, the driver will respond to | ||
| 114 | * USB suspend requests by powering down the NET2280. Otherwise, | ||
| 115 | * USB suspend requests will be ignored. This is acceptable for | ||
| 116 | * self-powered devices | ||
| 117 | */ | ||
| 118 | static bool enable_suspend; | ||
| 119 | |||
| 120 | /* "modprobe net2280 enable_suspend=1" etc */ | ||
| 121 | module_param(enable_suspend, bool, 0444); | ||
| 122 | |||
| 123 | /* force full-speed operation */ | ||
| 124 | static bool full_speed; | ||
| 125 | module_param(full_speed, bool, 0444); | ||
| 126 | MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!"); | ||
| 127 | |||
| 128 | #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") | ||
| 129 | |||
| 130 | static char *type_string(u8 bmAttributes) | ||
| 131 | { | ||
| 132 | switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) { | ||
| 133 | case USB_ENDPOINT_XFER_BULK: return "bulk"; | ||
| 134 | case USB_ENDPOINT_XFER_ISOC: return "iso"; | ||
| 135 | case USB_ENDPOINT_XFER_INT: return "intr"; | ||
| 136 | } | ||
| 137 | return "control"; | ||
| 138 | } | ||
| 139 | |||
| 140 | #include "net2280.h" | ||
| 141 | |||
| 142 | #define valid_bit cpu_to_le32(BIT(VALID_BIT)) | ||
| 143 | #define dma_done_ie cpu_to_le32(BIT(DMA_DONE_INTERRUPT_ENABLE)) | ||
| 144 | |||
| 145 | /*-------------------------------------------------------------------------*/ | ||
| 146 | static inline void enable_pciirqenb(struct net2280_ep *ep) | ||
| 147 | { | ||
| 148 | u32 tmp = readl(&ep->dev->regs->pciirqenb0); | ||
| 149 | |||
| 150 | if (ep->dev->quirks & PLX_LEGACY) | ||
| 151 | tmp |= BIT(ep->num); | ||
| 152 | else | ||
| 153 | tmp |= BIT(ep_bit[ep->num]); | ||
| 154 | writel(tmp, &ep->dev->regs->pciirqenb0); | ||
| 155 | |||
| 156 | return; | ||
| 157 | } | ||
| 158 | |||
| 159 | static int | ||
| 160 | net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | ||
| 161 | { | ||
| 162 | struct net2280 *dev; | ||
| 163 | struct net2280_ep *ep; | ||
| 164 | u32 max, tmp; | ||
| 165 | unsigned long flags; | ||
| 166 | static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 }; | ||
| 167 | |||
| 168 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 169 | if (!_ep || !desc || ep->desc || _ep->name == ep0name || | ||
| 170 | desc->bDescriptorType != USB_DT_ENDPOINT) | ||
| 171 | return -EINVAL; | ||
| 172 | dev = ep->dev; | ||
| 173 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 174 | return -ESHUTDOWN; | ||
| 175 | |||
| 176 | /* erratum 0119 workaround ties up an endpoint number */ | ||
| 177 | if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) | ||
| 178 | return -EDOM; | ||
| 179 | |||
| 180 | if (dev->quirks & PLX_SUPERSPEED) { | ||
| 181 | if ((desc->bEndpointAddress & 0x0f) >= 0x0c) | ||
| 182 | return -EDOM; | ||
| 183 | ep->is_in = !!usb_endpoint_dir_in(desc); | ||
| 184 | if (dev->enhanced_mode && ep->is_in && ep_key[ep->num]) | ||
| 185 | return -EINVAL; | ||
| 186 | } | ||
| 187 | |||
| 188 | /* sanity check ep-e/ep-f since their fifos are small */ | ||
| 189 | max = usb_endpoint_maxp(desc) & 0x1fff; | ||
| 190 | if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY)) | ||
| 191 | return -ERANGE; | ||
| 192 | |||
| 193 | spin_lock_irqsave(&dev->lock, flags); | ||
| 194 | _ep->maxpacket = max & 0x7ff; | ||
| 195 | ep->desc = desc; | ||
| 196 | |||
| 197 | /* ep_reset() has already been called */ | ||
| 198 | ep->stopped = 0; | ||
| 199 | ep->wedged = 0; | ||
| 200 | ep->out_overflow = 0; | ||
| 201 | |||
| 202 | /* set speed-dependent max packet; may kick in high bandwidth */ | ||
| 203 | set_max_speed(ep, max); | ||
| 204 | |||
| 205 | /* FIFO lines can't go to different packets. PIO is ok, so | ||
| 206 | * use it instead of troublesome (non-bulk) multi-packet DMA. | ||
| 207 | */ | ||
| 208 | if (ep->dma && (max % 4) != 0 && use_dma_chaining) { | ||
| 209 | ep_dbg(ep->dev, "%s, no dma for maxpacket %d\n", | ||
| 210 | ep->ep.name, ep->ep.maxpacket); | ||
| 211 | ep->dma = NULL; | ||
| 212 | } | ||
| 213 | |||
| 214 | /* set type, direction, address; reset fifo counters */ | ||
| 215 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); | ||
| 216 | tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
| 217 | if (tmp == USB_ENDPOINT_XFER_INT) { | ||
| 218 | /* erratum 0105 workaround prevents hs NYET */ | ||
| 219 | if (dev->chiprev == 0100 && | ||
| 220 | dev->gadget.speed == USB_SPEED_HIGH && | ||
| 221 | !(desc->bEndpointAddress & USB_DIR_IN)) | ||
| 222 | writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE), | ||
| 223 | &ep->regs->ep_rsp); | ||
| 224 | } else if (tmp == USB_ENDPOINT_XFER_BULK) { | ||
| 225 | /* catch some particularly blatant driver bugs */ | ||
| 226 | if ((dev->gadget.speed == USB_SPEED_SUPER && max != 1024) || | ||
| 227 | (dev->gadget.speed == USB_SPEED_HIGH && max != 512) || | ||
| 228 | (dev->gadget.speed == USB_SPEED_FULL && max > 64)) { | ||
| 229 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 230 | return -ERANGE; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC); | ||
| 234 | /* Enable this endpoint */ | ||
| 235 | if (dev->quirks & PLX_LEGACY) { | ||
| 236 | tmp <<= ENDPOINT_TYPE; | ||
| 237 | tmp |= desc->bEndpointAddress; | ||
| 238 | /* default full fifo lines */ | ||
| 239 | tmp |= (4 << ENDPOINT_BYTE_COUNT); | ||
| 240 | tmp |= BIT(ENDPOINT_ENABLE); | ||
| 241 | ep->is_in = (tmp & USB_DIR_IN) != 0; | ||
| 242 | } else { | ||
| 243 | /* In Legacy mode, only OUT endpoints are used */ | ||
| 244 | if (dev->enhanced_mode && ep->is_in) { | ||
| 245 | tmp <<= IN_ENDPOINT_TYPE; | ||
| 246 | tmp |= BIT(IN_ENDPOINT_ENABLE); | ||
| 247 | /* Not applicable to Legacy */ | ||
| 248 | tmp |= BIT(ENDPOINT_DIRECTION); | ||
| 249 | } else { | ||
| 250 | tmp <<= OUT_ENDPOINT_TYPE; | ||
| 251 | tmp |= BIT(OUT_ENDPOINT_ENABLE); | ||
| 252 | tmp |= (ep->is_in << ENDPOINT_DIRECTION); | ||
| 253 | } | ||
| 254 | |||
| 255 | tmp |= usb_endpoint_num(desc); | ||
| 256 | tmp |= (ep->ep.maxburst << MAX_BURST_SIZE); | ||
| 257 | } | ||
| 258 | |||
| 259 | /* Make sure all the registers are written before ep_rsp*/ | ||
| 260 | wmb(); | ||
| 261 | |||
| 262 | /* for OUT transfers, block the rx fifo until a read is posted */ | ||
| 263 | if (!ep->is_in) | ||
| 264 | writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 265 | else if (!(dev->quirks & PLX_2280)) { | ||
| 266 | /* Added for 2282, Don't use nak packets on an in endpoint, | ||
| 267 | * this was ignored on 2280 | ||
| 268 | */ | ||
| 269 | writel(BIT(CLEAR_NAK_OUT_PACKETS) | | ||
| 270 | BIT(CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); | ||
| 271 | } | ||
| 272 | |||
| 273 | writel(tmp, &ep->cfg->ep_cfg); | ||
| 274 | |||
| 275 | /* enable irqs */ | ||
| 276 | if (!ep->dma) { /* pio, per-packet */ | ||
| 277 | enable_pciirqenb(ep); | ||
| 278 | |||
| 279 | tmp = BIT(DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) | | ||
| 280 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); | ||
| 281 | if (dev->quirks & PLX_2280) | ||
| 282 | tmp |= readl(&ep->regs->ep_irqenb); | ||
| 283 | writel(tmp, &ep->regs->ep_irqenb); | ||
| 284 | } else { /* dma, per-request */ | ||
| 285 | tmp = BIT((8 + ep->num)); /* completion */ | ||
| 286 | tmp |= readl(&dev->regs->pciirqenb1); | ||
| 287 | writel(tmp, &dev->regs->pciirqenb1); | ||
| 288 | |||
| 289 | /* for short OUT transfers, dma completions can't | ||
| 290 | * advance the queue; do it pio-style, by hand. | ||
| 291 | * NOTE erratum 0112 workaround #2 | ||
| 292 | */ | ||
| 293 | if ((desc->bEndpointAddress & USB_DIR_IN) == 0) { | ||
| 294 | tmp = BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE); | ||
| 295 | writel(tmp, &ep->regs->ep_irqenb); | ||
| 296 | |||
| 297 | enable_pciirqenb(ep); | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | tmp = desc->bEndpointAddress; | ||
| 302 | ep_dbg(dev, "enabled %s (ep%d%s-%s) %s max %04x\n", | ||
| 303 | _ep->name, tmp & 0x0f, DIR_STRING(tmp), | ||
| 304 | type_string(desc->bmAttributes), | ||
| 305 | ep->dma ? "dma" : "pio", max); | ||
| 306 | |||
| 307 | /* pci writes may still be posted */ | ||
| 308 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 309 | return 0; | ||
| 310 | } | ||
| 311 | |||
| 312 | static int handshake(u32 __iomem *ptr, u32 mask, u32 done, int usec) | ||
| 313 | { | ||
| 314 | u32 result; | ||
| 315 | |||
| 316 | do { | ||
| 317 | result = readl(ptr); | ||
| 318 | if (result == ~(u32)0) /* "device unplugged" */ | ||
| 319 | return -ENODEV; | ||
| 320 | result &= mask; | ||
| 321 | if (result == done) | ||
| 322 | return 0; | ||
| 323 | udelay(1); | ||
| 324 | usec--; | ||
| 325 | } while (usec > 0); | ||
| 326 | return -ETIMEDOUT; | ||
| 327 | } | ||
| 328 | |||
| 329 | static const struct usb_ep_ops net2280_ep_ops; | ||
| 330 | |||
| 331 | static void ep_reset_228x(struct net2280_regs __iomem *regs, | ||
| 332 | struct net2280_ep *ep) | ||
| 333 | { | ||
| 334 | u32 tmp; | ||
| 335 | |||
| 336 | ep->desc = NULL; | ||
| 337 | INIT_LIST_HEAD(&ep->queue); | ||
| 338 | |||
| 339 | usb_ep_set_maxpacket_limit(&ep->ep, ~0); | ||
| 340 | ep->ep.ops = &net2280_ep_ops; | ||
| 341 | |||
| 342 | /* disable the dma, irqs, endpoint... */ | ||
| 343 | if (ep->dma) { | ||
| 344 | writel(0, &ep->dma->dmactl); | ||
| 345 | writel(BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) | | ||
| 346 | BIT(DMA_TRANSACTION_DONE_INTERRUPT) | | ||
| 347 | BIT(DMA_ABORT), | ||
| 348 | &ep->dma->dmastat); | ||
| 349 | |||
| 350 | tmp = readl(®s->pciirqenb0); | ||
| 351 | tmp &= ~BIT(ep->num); | ||
| 352 | writel(tmp, ®s->pciirqenb0); | ||
| 353 | } else { | ||
| 354 | tmp = readl(®s->pciirqenb1); | ||
| 355 | tmp &= ~BIT((8 + ep->num)); /* completion */ | ||
| 356 | writel(tmp, ®s->pciirqenb1); | ||
| 357 | } | ||
| 358 | writel(0, &ep->regs->ep_irqenb); | ||
| 359 | |||
| 360 | /* init to our chosen defaults, notably so that we NAK OUT | ||
| 361 | * packets until the driver queues a read (+note erratum 0112) | ||
| 362 | */ | ||
| 363 | if (!ep->is_in || (ep->dev->quirks & PLX_2280)) { | ||
| 364 | tmp = BIT(SET_NAK_OUT_PACKETS_MODE) | | ||
| 365 | BIT(SET_NAK_OUT_PACKETS) | | ||
| 366 | BIT(CLEAR_EP_HIDE_STATUS_PHASE) | | ||
| 367 | BIT(CLEAR_INTERRUPT_MODE); | ||
| 368 | } else { | ||
| 369 | /* added for 2282 */ | ||
| 370 | tmp = BIT(CLEAR_NAK_OUT_PACKETS_MODE) | | ||
| 371 | BIT(CLEAR_NAK_OUT_PACKETS) | | ||
| 372 | BIT(CLEAR_EP_HIDE_STATUS_PHASE) | | ||
| 373 | BIT(CLEAR_INTERRUPT_MODE); | ||
| 374 | } | ||
| 375 | |||
| 376 | if (ep->num != 0) { | ||
| 377 | tmp |= BIT(CLEAR_ENDPOINT_TOGGLE) | | ||
| 378 | BIT(CLEAR_ENDPOINT_HALT); | ||
| 379 | } | ||
| 380 | writel(tmp, &ep->regs->ep_rsp); | ||
| 381 | |||
| 382 | /* scrub most status bits, and flush any fifo state */ | ||
| 383 | if (ep->dev->quirks & PLX_2280) | ||
| 384 | tmp = BIT(FIFO_OVERFLOW) | | ||
| 385 | BIT(FIFO_UNDERFLOW); | ||
| 386 | else | ||
| 387 | tmp = 0; | ||
| 388 | |||
| 389 | writel(tmp | BIT(TIMEOUT) | | ||
| 390 | BIT(USB_STALL_SENT) | | ||
| 391 | BIT(USB_IN_NAK_SENT) | | ||
| 392 | BIT(USB_IN_ACK_RCVD) | | ||
| 393 | BIT(USB_OUT_PING_NAK_SENT) | | ||
| 394 | BIT(USB_OUT_ACK_SENT) | | ||
| 395 | BIT(FIFO_FLUSH) | | ||
| 396 | BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) | | ||
| 397 | BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) | | ||
| 398 | BIT(DATA_PACKET_RECEIVED_INTERRUPT) | | ||
| 399 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
| 400 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 401 | BIT(DATA_IN_TOKEN_INTERRUPT), | ||
| 402 | &ep->regs->ep_stat); | ||
| 403 | |||
| 404 | /* fifo size is handled separately */ | ||
| 405 | } | ||
| 406 | |||
| 407 | static void ep_reset_338x(struct net2280_regs __iomem *regs, | ||
| 408 | struct net2280_ep *ep) | ||
| 409 | { | ||
| 410 | u32 tmp, dmastat; | ||
| 411 | |||
| 412 | ep->desc = NULL; | ||
| 413 | INIT_LIST_HEAD(&ep->queue); | ||
| 414 | |||
| 415 | usb_ep_set_maxpacket_limit(&ep->ep, ~0); | ||
| 416 | ep->ep.ops = &net2280_ep_ops; | ||
| 417 | |||
| 418 | /* disable the dma, irqs, endpoint... */ | ||
| 419 | if (ep->dma) { | ||
| 420 | writel(0, &ep->dma->dmactl); | ||
| 421 | writel(BIT(DMA_ABORT_DONE_INTERRUPT) | | ||
| 422 | BIT(DMA_PAUSE_DONE_INTERRUPT) | | ||
| 423 | BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) | | ||
| 424 | BIT(DMA_TRANSACTION_DONE_INTERRUPT), | ||
| 425 | /* | BIT(DMA_ABORT), */ | ||
| 426 | &ep->dma->dmastat); | ||
| 427 | |||
| 428 | dmastat = readl(&ep->dma->dmastat); | ||
| 429 | if (dmastat == 0x5002) { | ||
| 430 | ep_warn(ep->dev, "The dmastat return = %x!!\n", | ||
| 431 | dmastat); | ||
| 432 | writel(0x5a, &ep->dma->dmastat); | ||
| 433 | } | ||
| 434 | |||
| 435 | tmp = readl(®s->pciirqenb0); | ||
| 436 | tmp &= ~BIT(ep_bit[ep->num]); | ||
| 437 | writel(tmp, ®s->pciirqenb0); | ||
| 438 | } else { | ||
| 439 | if (ep->num < 5) { | ||
| 440 | tmp = readl(®s->pciirqenb1); | ||
| 441 | tmp &= ~BIT((8 + ep->num)); /* completion */ | ||
| 442 | writel(tmp, ®s->pciirqenb1); | ||
| 443 | } | ||
| 444 | } | ||
| 445 | writel(0, &ep->regs->ep_irqenb); | ||
| 446 | |||
| 447 | writel(BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) | | ||
| 448 | BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) | | ||
| 449 | BIT(FIFO_OVERFLOW) | | ||
| 450 | BIT(DATA_PACKET_RECEIVED_INTERRUPT) | | ||
| 451 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
| 452 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 453 | BIT(DATA_IN_TOKEN_INTERRUPT), &ep->regs->ep_stat); | ||
| 454 | } | ||
| 455 | |||
| 456 | static void nuke(struct net2280_ep *); | ||
| 457 | |||
| 458 | static int net2280_disable(struct usb_ep *_ep) | ||
| 459 | { | ||
| 460 | struct net2280_ep *ep; | ||
| 461 | unsigned long flags; | ||
| 462 | |||
| 463 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 464 | if (!_ep || !ep->desc || _ep->name == ep0name) | ||
| 465 | return -EINVAL; | ||
| 466 | |||
| 467 | spin_lock_irqsave(&ep->dev->lock, flags); | ||
| 468 | nuke(ep); | ||
| 469 | |||
| 470 | if (ep->dev->quirks & PLX_SUPERSPEED) | ||
| 471 | ep_reset_338x(ep->dev->regs, ep); | ||
| 472 | else | ||
| 473 | ep_reset_228x(ep->dev->regs, ep); | ||
| 474 | |||
| 475 | ep_vdbg(ep->dev, "disabled %s %s\n", | ||
| 476 | ep->dma ? "dma" : "pio", _ep->name); | ||
| 477 | |||
| 478 | /* synch memory views with the device */ | ||
| 479 | (void)readl(&ep->cfg->ep_cfg); | ||
| 480 | |||
| 481 | if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4) | ||
| 482 | ep->dma = &ep->dev->dma[ep->num - 1]; | ||
| 483 | |||
| 484 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | /*-------------------------------------------------------------------------*/ | ||
| 489 | |||
| 490 | static struct usb_request | ||
| 491 | *net2280_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) | ||
| 492 | { | ||
| 493 | struct net2280_ep *ep; | ||
| 494 | struct net2280_request *req; | ||
| 495 | |||
| 496 | if (!_ep) | ||
| 497 | return NULL; | ||
| 498 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 499 | |||
| 500 | req = kzalloc(sizeof(*req), gfp_flags); | ||
| 501 | if (!req) | ||
| 502 | return NULL; | ||
| 503 | |||
| 504 | INIT_LIST_HEAD(&req->queue); | ||
| 505 | |||
| 506 | /* this dma descriptor may be swapped with the previous dummy */ | ||
| 507 | if (ep->dma) { | ||
| 508 | struct net2280_dma *td; | ||
| 509 | |||
| 510 | td = pci_pool_alloc(ep->dev->requests, gfp_flags, | ||
| 511 | &req->td_dma); | ||
| 512 | if (!td) { | ||
| 513 | kfree(req); | ||
| 514 | return NULL; | ||
| 515 | } | ||
| 516 | td->dmacount = 0; /* not VALID */ | ||
| 517 | td->dmadesc = td->dmaaddr; | ||
| 518 | req->td = td; | ||
| 519 | } | ||
| 520 | return &req->req; | ||
| 521 | } | ||
| 522 | |||
| 523 | static void net2280_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
| 524 | { | ||
| 525 | struct net2280_ep *ep; | ||
| 526 | struct net2280_request *req; | ||
| 527 | |||
| 528 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 529 | if (!_ep || !_req) | ||
| 530 | return; | ||
| 531 | |||
| 532 | req = container_of(_req, struct net2280_request, req); | ||
| 533 | WARN_ON(!list_empty(&req->queue)); | ||
| 534 | if (req->td) | ||
| 535 | pci_pool_free(ep->dev->requests, req->td, req->td_dma); | ||
| 536 | kfree(req); | ||
| 537 | } | ||
| 538 | |||
| 539 | /*-------------------------------------------------------------------------*/ | ||
| 540 | |||
| 541 | /* load a packet into the fifo we use for usb IN transfers. | ||
| 542 | * works for all endpoints. | ||
| 543 | * | ||
| 544 | * NOTE: pio with ep-a..ep-d could stuff multiple packets into the fifo | ||
| 545 | * at a time, but this code is simpler because it knows it only writes | ||
| 546 | * one packet. ep-a..ep-d should use dma instead. | ||
| 547 | */ | ||
| 548 | static void write_fifo(struct net2280_ep *ep, struct usb_request *req) | ||
| 549 | { | ||
| 550 | struct net2280_ep_regs __iomem *regs = ep->regs; | ||
| 551 | u8 *buf; | ||
| 552 | u32 tmp; | ||
| 553 | unsigned count, total; | ||
| 554 | |||
| 555 | /* INVARIANT: fifo is currently empty. (testable) */ | ||
| 556 | |||
| 557 | if (req) { | ||
| 558 | buf = req->buf + req->actual; | ||
| 559 | prefetch(buf); | ||
| 560 | total = req->length - req->actual; | ||
| 561 | } else { | ||
| 562 | total = 0; | ||
| 563 | buf = NULL; | ||
| 564 | } | ||
| 565 | |||
| 566 | /* write just one packet at a time */ | ||
| 567 | count = ep->ep.maxpacket; | ||
| 568 | if (count > total) /* min() cannot be used on a bitfield */ | ||
| 569 | count = total; | ||
| 570 | |||
| 571 | ep_vdbg(ep->dev, "write %s fifo (IN) %d bytes%s req %p\n", | ||
| 572 | ep->ep.name, count, | ||
| 573 | (count != ep->ep.maxpacket) ? " (short)" : "", | ||
| 574 | req); | ||
| 575 | while (count >= 4) { | ||
| 576 | /* NOTE be careful if you try to align these. fifo lines | ||
| 577 | * should normally be full (4 bytes) and successive partial | ||
| 578 | * lines are ok only in certain cases. | ||
| 579 | */ | ||
| 580 | tmp = get_unaligned((u32 *)buf); | ||
| 581 | cpu_to_le32s(&tmp); | ||
| 582 | writel(tmp, ®s->ep_data); | ||
| 583 | buf += 4; | ||
| 584 | count -= 4; | ||
| 585 | } | ||
| 586 | |||
| 587 | /* last fifo entry is "short" unless we wrote a full packet. | ||
| 588 | * also explicitly validate last word in (periodic) transfers | ||
| 589 | * when maxpacket is not a multiple of 4 bytes. | ||
| 590 | */ | ||
| 591 | if (count || total < ep->ep.maxpacket) { | ||
| 592 | tmp = count ? get_unaligned((u32 *)buf) : count; | ||
| 593 | cpu_to_le32s(&tmp); | ||
| 594 | set_fifo_bytecount(ep, count & 0x03); | ||
| 595 | writel(tmp, ®s->ep_data); | ||
| 596 | } | ||
| 597 | |||
| 598 | /* pci writes may still be posted */ | ||
| 599 | } | ||
| 600 | |||
| 601 | /* work around erratum 0106: PCI and USB race over the OUT fifo. | ||
| 602 | * caller guarantees chiprev 0100, out endpoint is NAKing, and | ||
| 603 | * there's no real data in the fifo. | ||
| 604 | * | ||
| 605 | * NOTE: also used in cases where that erratum doesn't apply: | ||
| 606 | * where the host wrote "too much" data to us. | ||
| 607 | */ | ||
| 608 | static void out_flush(struct net2280_ep *ep) | ||
| 609 | { | ||
| 610 | u32 __iomem *statp; | ||
| 611 | u32 tmp; | ||
| 612 | |||
| 613 | ASSERT_OUT_NAKING(ep); | ||
| 614 | |||
| 615 | statp = &ep->regs->ep_stat; | ||
| 616 | writel(BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 617 | BIT(DATA_PACKET_RECEIVED_INTERRUPT), | ||
| 618 | statp); | ||
| 619 | writel(BIT(FIFO_FLUSH), statp); | ||
| 620 | /* Make sure that stap is written */ | ||
| 621 | mb(); | ||
| 622 | tmp = readl(statp); | ||
| 623 | if (tmp & BIT(DATA_OUT_PING_TOKEN_INTERRUPT) && | ||
| 624 | /* high speed did bulk NYET; fifo isn't filling */ | ||
| 625 | ep->dev->gadget.speed == USB_SPEED_FULL) { | ||
| 626 | unsigned usec; | ||
| 627 | |||
| 628 | usec = 50; /* 64 byte bulk/interrupt */ | ||
| 629 | handshake(statp, BIT(USB_OUT_PING_NAK_SENT), | ||
| 630 | BIT(USB_OUT_PING_NAK_SENT), usec); | ||
| 631 | /* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */ | ||
| 632 | } | ||
| 633 | } | ||
| 634 | |||
| 635 | /* unload packet(s) from the fifo we use for usb OUT transfers. | ||
| 636 | * returns true iff the request completed, because of short packet | ||
| 637 | * or the request buffer having filled with full packets. | ||
| 638 | * | ||
| 639 | * for ep-a..ep-d this will read multiple packets out when they | ||
| 640 | * have been accepted. | ||
| 641 | */ | ||
| 642 | static int read_fifo(struct net2280_ep *ep, struct net2280_request *req) | ||
| 643 | { | ||
| 644 | struct net2280_ep_regs __iomem *regs = ep->regs; | ||
| 645 | u8 *buf = req->req.buf + req->req.actual; | ||
| 646 | unsigned count, tmp, is_short; | ||
| 647 | unsigned cleanup = 0, prevent = 0; | ||
| 648 | |||
| 649 | /* erratum 0106 ... packets coming in during fifo reads might | ||
| 650 | * be incompletely rejected. not all cases have workarounds. | ||
| 651 | */ | ||
| 652 | if (ep->dev->chiprev == 0x0100 && | ||
| 653 | ep->dev->gadget.speed == USB_SPEED_FULL) { | ||
| 654 | udelay(1); | ||
| 655 | tmp = readl(&ep->regs->ep_stat); | ||
| 656 | if ((tmp & BIT(NAK_OUT_PACKETS))) | ||
| 657 | cleanup = 1; | ||
| 658 | else if ((tmp & BIT(FIFO_FULL))) { | ||
| 659 | start_out_naking(ep); | ||
| 660 | prevent = 1; | ||
| 661 | } | ||
| 662 | /* else: hope we don't see the problem */ | ||
| 663 | } | ||
| 664 | |||
| 665 | /* never overflow the rx buffer. the fifo reads packets until | ||
| 666 | * it sees a short one; we might not be ready for them all. | ||
| 667 | */ | ||
| 668 | prefetchw(buf); | ||
| 669 | count = readl(®s->ep_avail); | ||
| 670 | if (unlikely(count == 0)) { | ||
| 671 | udelay(1); | ||
| 672 | tmp = readl(&ep->regs->ep_stat); | ||
| 673 | count = readl(®s->ep_avail); | ||
| 674 | /* handled that data already? */ | ||
| 675 | if (count == 0 && (tmp & BIT(NAK_OUT_PACKETS)) == 0) | ||
| 676 | return 0; | ||
| 677 | } | ||
| 678 | |||
| 679 | tmp = req->req.length - req->req.actual; | ||
| 680 | if (count > tmp) { | ||
| 681 | /* as with DMA, data overflow gets flushed */ | ||
| 682 | if ((tmp % ep->ep.maxpacket) != 0) { | ||
| 683 | ep_err(ep->dev, | ||
| 684 | "%s out fifo %d bytes, expected %d\n", | ||
| 685 | ep->ep.name, count, tmp); | ||
| 686 | req->req.status = -EOVERFLOW; | ||
| 687 | cleanup = 1; | ||
| 688 | /* NAK_OUT_PACKETS will be set, so flushing is safe; | ||
| 689 | * the next read will start with the next packet | ||
| 690 | */ | ||
| 691 | } /* else it's a ZLP, no worries */ | ||
| 692 | count = tmp; | ||
| 693 | } | ||
| 694 | req->req.actual += count; | ||
| 695 | |||
| 696 | is_short = (count == 0) || ((count % ep->ep.maxpacket) != 0); | ||
| 697 | |||
| 698 | ep_vdbg(ep->dev, "read %s fifo (OUT) %d bytes%s%s%s req %p %d/%d\n", | ||
| 699 | ep->ep.name, count, is_short ? " (short)" : "", | ||
| 700 | cleanup ? " flush" : "", prevent ? " nak" : "", | ||
| 701 | req, req->req.actual, req->req.length); | ||
| 702 | |||
| 703 | while (count >= 4) { | ||
| 704 | tmp = readl(®s->ep_data); | ||
| 705 | cpu_to_le32s(&tmp); | ||
| 706 | put_unaligned(tmp, (u32 *)buf); | ||
| 707 | buf += 4; | ||
| 708 | count -= 4; | ||
| 709 | } | ||
| 710 | if (count) { | ||
| 711 | tmp = readl(®s->ep_data); | ||
| 712 | /* LE conversion is implicit here: */ | ||
| 713 | do { | ||
| 714 | *buf++ = (u8) tmp; | ||
| 715 | tmp >>= 8; | ||
| 716 | } while (--count); | ||
| 717 | } | ||
| 718 | if (cleanup) | ||
| 719 | out_flush(ep); | ||
| 720 | if (prevent) { | ||
| 721 | writel(BIT(CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 722 | (void) readl(&ep->regs->ep_rsp); | ||
| 723 | } | ||
| 724 | |||
| 725 | return is_short || ((req->req.actual == req->req.length) && | ||
| 726 | !req->req.zero); | ||
| 727 | } | ||
| 728 | |||
| 729 | /* fill out dma descriptor to match a given request */ | ||
| 730 | static void fill_dma_desc(struct net2280_ep *ep, | ||
| 731 | struct net2280_request *req, int valid) | ||
| 732 | { | ||
| 733 | struct net2280_dma *td = req->td; | ||
| 734 | u32 dmacount = req->req.length; | ||
| 735 | |||
| 736 | /* don't let DMA continue after a short OUT packet, | ||
| 737 | * so overruns can't affect the next transfer. | ||
| 738 | * in case of overruns on max-size packets, we can't | ||
| 739 | * stop the fifo from filling but we can flush it. | ||
| 740 | */ | ||
| 741 | if (ep->is_in) | ||
| 742 | dmacount |= BIT(DMA_DIRECTION); | ||
| 743 | if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) || | ||
| 744 | !(ep->dev->quirks & PLX_2280)) | ||
| 745 | dmacount |= BIT(END_OF_CHAIN); | ||
| 746 | |||
| 747 | req->valid = valid; | ||
| 748 | if (valid) | ||
| 749 | dmacount |= BIT(VALID_BIT); | ||
| 750 | if (likely(!req->req.no_interrupt || !use_dma_chaining)) | ||
| 751 | dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE); | ||
| 752 | |||
| 753 | /* td->dmadesc = previously set by caller */ | ||
| 754 | td->dmaaddr = cpu_to_le32 (req->req.dma); | ||
| 755 | |||
| 756 | /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */ | ||
| 757 | wmb(); | ||
| 758 | td->dmacount = cpu_to_le32(dmacount); | ||
| 759 | } | ||
| 760 | |||
| 761 | static const u32 dmactl_default = | ||
| 762 | BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) | | ||
| 763 | BIT(DMA_CLEAR_COUNT_ENABLE) | | ||
| 764 | /* erratum 0116 workaround part 1 (use POLLING) */ | ||
| 765 | (POLL_100_USEC << DESCRIPTOR_POLLING_RATE) | | ||
| 766 | BIT(DMA_VALID_BIT_POLLING_ENABLE) | | ||
| 767 | BIT(DMA_VALID_BIT_ENABLE) | | ||
| 768 | BIT(DMA_SCATTER_GATHER_ENABLE) | | ||
| 769 | /* erratum 0116 workaround part 2 (no AUTOSTART) */ | ||
| 770 | BIT(DMA_ENABLE); | ||
| 771 | |||
| 772 | static inline void spin_stop_dma(struct net2280_dma_regs __iomem *dma) | ||
| 773 | { | ||
| 774 | handshake(&dma->dmactl, BIT(DMA_ENABLE), 0, 50); | ||
| 775 | } | ||
| 776 | |||
| 777 | static inline void stop_dma(struct net2280_dma_regs __iomem *dma) | ||
| 778 | { | ||
| 779 | writel(readl(&dma->dmactl) & ~BIT(DMA_ENABLE), &dma->dmactl); | ||
| 780 | spin_stop_dma(dma); | ||
| 781 | } | ||
| 782 | |||
| 783 | static void start_queue(struct net2280_ep *ep, u32 dmactl, u32 td_dma) | ||
| 784 | { | ||
| 785 | struct net2280_dma_regs __iomem *dma = ep->dma; | ||
| 786 | unsigned int tmp = BIT(VALID_BIT) | (ep->is_in << DMA_DIRECTION); | ||
| 787 | |||
| 788 | if (!(ep->dev->quirks & PLX_2280)) | ||
| 789 | tmp |= BIT(END_OF_CHAIN); | ||
| 790 | |||
| 791 | writel(tmp, &dma->dmacount); | ||
| 792 | writel(readl(&dma->dmastat), &dma->dmastat); | ||
| 793 | |||
| 794 | writel(td_dma, &dma->dmadesc); | ||
| 795 | if (ep->dev->quirks & PLX_SUPERSPEED) | ||
| 796 | dmactl |= BIT(DMA_REQUEST_OUTSTANDING); | ||
| 797 | writel(dmactl, &dma->dmactl); | ||
| 798 | |||
| 799 | /* erratum 0116 workaround part 3: pci arbiter away from net2280 */ | ||
| 800 | (void) readl(&ep->dev->pci->pcimstctl); | ||
| 801 | |||
| 802 | writel(BIT(DMA_START), &dma->dmastat); | ||
| 803 | |||
| 804 | if (!ep->is_in) | ||
| 805 | stop_out_naking(ep); | ||
| 806 | } | ||
| 807 | |||
| 808 | static void start_dma(struct net2280_ep *ep, struct net2280_request *req) | ||
| 809 | { | ||
| 810 | u32 tmp; | ||
| 811 | struct net2280_dma_regs __iomem *dma = ep->dma; | ||
| 812 | |||
| 813 | /* FIXME can't use DMA for ZLPs */ | ||
| 814 | |||
| 815 | /* on this path we "know" there's no dma active (yet) */ | ||
| 816 | WARN_ON(readl(&dma->dmactl) & BIT(DMA_ENABLE)); | ||
| 817 | writel(0, &ep->dma->dmactl); | ||
| 818 | |||
| 819 | /* previous OUT packet might have been short */ | ||
| 820 | if (!ep->is_in && (readl(&ep->regs->ep_stat) & | ||
| 821 | BIT(NAK_OUT_PACKETS))) { | ||
| 822 | writel(BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT), | ||
| 823 | &ep->regs->ep_stat); | ||
| 824 | |||
| 825 | tmp = readl(&ep->regs->ep_avail); | ||
| 826 | if (tmp) { | ||
| 827 | writel(readl(&dma->dmastat), &dma->dmastat); | ||
| 828 | |||
| 829 | /* transfer all/some fifo data */ | ||
| 830 | writel(req->req.dma, &dma->dmaaddr); | ||
| 831 | tmp = min(tmp, req->req.length); | ||
| 832 | |||
| 833 | /* dma irq, faking scatterlist status */ | ||
| 834 | req->td->dmacount = cpu_to_le32(req->req.length - tmp); | ||
| 835 | writel(BIT(DMA_DONE_INTERRUPT_ENABLE) | tmp, | ||
| 836 | &dma->dmacount); | ||
| 837 | req->td->dmadesc = 0; | ||
| 838 | req->valid = 1; | ||
| 839 | |||
| 840 | writel(BIT(DMA_ENABLE), &dma->dmactl); | ||
| 841 | writel(BIT(DMA_START), &dma->dmastat); | ||
| 842 | return; | ||
| 843 | } | ||
| 844 | } | ||
| 845 | |||
| 846 | tmp = dmactl_default; | ||
| 847 | |||
| 848 | /* force packet boundaries between dma requests, but prevent the | ||
| 849 | * controller from automagically writing a last "short" packet | ||
| 850 | * (zero length) unless the driver explicitly said to do that. | ||
| 851 | */ | ||
| 852 | if (ep->is_in) { | ||
| 853 | if (likely((req->req.length % ep->ep.maxpacket) || | ||
| 854 | req->req.zero)){ | ||
| 855 | tmp |= BIT(DMA_FIFO_VALIDATE); | ||
| 856 | ep->in_fifo_validate = 1; | ||
| 857 | } else | ||
| 858 | ep->in_fifo_validate = 0; | ||
| 859 | } | ||
| 860 | |||
| 861 | /* init req->td, pointing to the current dummy */ | ||
| 862 | req->td->dmadesc = cpu_to_le32 (ep->td_dma); | ||
| 863 | fill_dma_desc(ep, req, 1); | ||
| 864 | |||
| 865 | if (!use_dma_chaining) | ||
| 866 | req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN)); | ||
| 867 | |||
| 868 | start_queue(ep, tmp, req->td_dma); | ||
| 869 | } | ||
| 870 | |||
| 871 | static inline void resume_dma(struct net2280_ep *ep) | ||
| 872 | { | ||
| 873 | writel(readl(&ep->dma->dmactl) | BIT(DMA_ENABLE), &ep->dma->dmactl); | ||
| 874 | |||
| 875 | ep->dma_started = true; | ||
| 876 | } | ||
| 877 | |||
| 878 | static inline void ep_stop_dma(struct net2280_ep *ep) | ||
| 879 | { | ||
| 880 | writel(readl(&ep->dma->dmactl) & ~BIT(DMA_ENABLE), &ep->dma->dmactl); | ||
| 881 | spin_stop_dma(ep->dma); | ||
| 882 | |||
| 883 | ep->dma_started = false; | ||
| 884 | } | ||
| 885 | |||
| 886 | static inline void | ||
| 887 | queue_dma(struct net2280_ep *ep, struct net2280_request *req, int valid) | ||
| 888 | { | ||
| 889 | struct net2280_dma *end; | ||
| 890 | dma_addr_t tmp; | ||
| 891 | |||
| 892 | /* swap new dummy for old, link; fill and maybe activate */ | ||
| 893 | end = ep->dummy; | ||
| 894 | ep->dummy = req->td; | ||
| 895 | req->td = end; | ||
| 896 | |||
| 897 | tmp = ep->td_dma; | ||
| 898 | ep->td_dma = req->td_dma; | ||
| 899 | req->td_dma = tmp; | ||
| 900 | |||
| 901 | end->dmadesc = cpu_to_le32 (ep->td_dma); | ||
| 902 | |||
| 903 | fill_dma_desc(ep, req, valid); | ||
| 904 | } | ||
| 905 | |||
| 906 | static void | ||
| 907 | done(struct net2280_ep *ep, struct net2280_request *req, int status) | ||
| 908 | { | ||
| 909 | struct net2280 *dev; | ||
| 910 | unsigned stopped = ep->stopped; | ||
| 911 | |||
| 912 | list_del_init(&req->queue); | ||
| 913 | |||
| 914 | if (req->req.status == -EINPROGRESS) | ||
| 915 | req->req.status = status; | ||
| 916 | else | ||
| 917 | status = req->req.status; | ||
| 918 | |||
| 919 | dev = ep->dev; | ||
| 920 | if (ep->dma) | ||
| 921 | usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in); | ||
| 922 | |||
| 923 | if (status && status != -ESHUTDOWN) | ||
| 924 | ep_vdbg(dev, "complete %s req %p stat %d len %u/%u\n", | ||
| 925 | ep->ep.name, &req->req, status, | ||
| 926 | req->req.actual, req->req.length); | ||
| 927 | |||
| 928 | /* don't modify queue heads during completion callback */ | ||
| 929 | ep->stopped = 1; | ||
| 930 | spin_unlock(&dev->lock); | ||
| 931 | req->req.complete(&ep->ep, &req->req); | ||
| 932 | spin_lock(&dev->lock); | ||
| 933 | ep->stopped = stopped; | ||
| 934 | } | ||
| 935 | |||
| 936 | /*-------------------------------------------------------------------------*/ | ||
| 937 | |||
| 938 | static int | ||
| 939 | net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | ||
| 940 | { | ||
| 941 | struct net2280_request *req; | ||
| 942 | struct net2280_ep *ep; | ||
| 943 | struct net2280 *dev; | ||
| 944 | unsigned long flags; | ||
| 945 | |||
| 946 | /* we always require a cpu-view buffer, so that we can | ||
| 947 | * always use pio (as fallback or whatever). | ||
| 948 | */ | ||
| 949 | req = container_of(_req, struct net2280_request, req); | ||
| 950 | if (!_req || !_req->complete || !_req->buf || | ||
| 951 | !list_empty(&req->queue)) | ||
| 952 | return -EINVAL; | ||
| 953 | if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) | ||
| 954 | return -EDOM; | ||
| 955 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 956 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 957 | return -EINVAL; | ||
| 958 | dev = ep->dev; | ||
| 959 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 960 | return -ESHUTDOWN; | ||
| 961 | |||
| 962 | /* FIXME implement PIO fallback for ZLPs with DMA */ | ||
| 963 | if (ep->dma && _req->length == 0) | ||
| 964 | return -EOPNOTSUPP; | ||
| 965 | |||
| 966 | /* set up dma mapping in case the caller didn't */ | ||
| 967 | if (ep->dma) { | ||
| 968 | int ret; | ||
| 969 | |||
| 970 | ret = usb_gadget_map_request(&dev->gadget, _req, | ||
| 971 | ep->is_in); | ||
| 972 | if (ret) | ||
| 973 | return ret; | ||
| 974 | } | ||
| 975 | |||
| 976 | #if 0 | ||
| 977 | ep_vdbg(dev, "%s queue req %p, len %d buf %p\n", | ||
| 978 | _ep->name, _req, _req->length, _req->buf); | ||
| 979 | #endif | ||
| 980 | |||
| 981 | spin_lock_irqsave(&dev->lock, flags); | ||
| 982 | |||
| 983 | _req->status = -EINPROGRESS; | ||
| 984 | _req->actual = 0; | ||
| 985 | |||
| 986 | /* kickstart this i/o queue? */ | ||
| 987 | if (list_empty(&ep->queue) && !ep->stopped) { | ||
| 988 | /* DMA request while EP halted */ | ||
| 989 | if (ep->dma && | ||
| 990 | (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)) && | ||
| 991 | (dev->quirks & PLX_SUPERSPEED)) { | ||
| 992 | int valid = 1; | ||
| 993 | if (ep->is_in) { | ||
| 994 | int expect; | ||
| 995 | expect = likely(req->req.zero || | ||
| 996 | ((req->req.length % | ||
| 997 | ep->ep.maxpacket) != 0)); | ||
| 998 | if (expect != ep->in_fifo_validate) | ||
| 999 | valid = 0; | ||
| 1000 | } | ||
| 1001 | queue_dma(ep, req, valid); | ||
| 1002 | } | ||
| 1003 | /* use DMA if the endpoint supports it, else pio */ | ||
| 1004 | else if (ep->dma) | ||
| 1005 | start_dma(ep, req); | ||
| 1006 | else { | ||
| 1007 | /* maybe there's no control data, just status ack */ | ||
| 1008 | if (ep->num == 0 && _req->length == 0) { | ||
| 1009 | allow_status(ep); | ||
| 1010 | done(ep, req, 0); | ||
| 1011 | ep_vdbg(dev, "%s status ack\n", ep->ep.name); | ||
| 1012 | goto done; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | /* PIO ... stuff the fifo, or unblock it. */ | ||
| 1016 | if (ep->is_in) | ||
| 1017 | write_fifo(ep, _req); | ||
| 1018 | else if (list_empty(&ep->queue)) { | ||
| 1019 | u32 s; | ||
| 1020 | |||
| 1021 | /* OUT FIFO might have packet(s) buffered */ | ||
| 1022 | s = readl(&ep->regs->ep_stat); | ||
| 1023 | if ((s & BIT(FIFO_EMPTY)) == 0) { | ||
| 1024 | /* note: _req->short_not_ok is | ||
| 1025 | * ignored here since PIO _always_ | ||
| 1026 | * stops queue advance here, and | ||
| 1027 | * _req->status doesn't change for | ||
| 1028 | * short reads (only _req->actual) | ||
| 1029 | */ | ||
| 1030 | if (read_fifo(ep, req) && | ||
| 1031 | ep->num == 0) { | ||
| 1032 | done(ep, req, 0); | ||
| 1033 | allow_status(ep); | ||
| 1034 | /* don't queue it */ | ||
| 1035 | req = NULL; | ||
| 1036 | } else if (read_fifo(ep, req) && | ||
| 1037 | ep->num != 0) { | ||
| 1038 | done(ep, req, 0); | ||
| 1039 | req = NULL; | ||
| 1040 | } else | ||
| 1041 | s = readl(&ep->regs->ep_stat); | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | /* don't NAK, let the fifo fill */ | ||
| 1045 | if (req && (s & BIT(NAK_OUT_PACKETS))) | ||
| 1046 | writel(BIT(CLEAR_NAK_OUT_PACKETS), | ||
| 1047 | &ep->regs->ep_rsp); | ||
| 1048 | } | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | } else if (ep->dma) { | ||
| 1052 | int valid = 1; | ||
| 1053 | |||
| 1054 | if (ep->is_in) { | ||
| 1055 | int expect; | ||
| 1056 | |||
| 1057 | /* preventing magic zlps is per-engine state, not | ||
| 1058 | * per-transfer; irq logic must recover hiccups. | ||
| 1059 | */ | ||
| 1060 | expect = likely(req->req.zero || | ||
| 1061 | (req->req.length % ep->ep.maxpacket)); | ||
| 1062 | if (expect != ep->in_fifo_validate) | ||
| 1063 | valid = 0; | ||
| 1064 | } | ||
| 1065 | queue_dma(ep, req, valid); | ||
| 1066 | |||
| 1067 | } /* else the irq handler advances the queue. */ | ||
| 1068 | |||
| 1069 | ep->responded = 1; | ||
| 1070 | if (req) | ||
| 1071 | list_add_tail(&req->queue, &ep->queue); | ||
| 1072 | done: | ||
| 1073 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1074 | |||
| 1075 | /* pci writes may still be posted */ | ||
| 1076 | return 0; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | static inline void | ||
| 1080 | dma_done(struct net2280_ep *ep, struct net2280_request *req, u32 dmacount, | ||
| 1081 | int status) | ||
| 1082 | { | ||
| 1083 | req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount); | ||
| 1084 | done(ep, req, status); | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | static void restart_dma(struct net2280_ep *ep); | ||
| 1088 | |||
| 1089 | static void scan_dma_completions(struct net2280_ep *ep) | ||
| 1090 | { | ||
| 1091 | /* only look at descriptors that were "naturally" retired, | ||
| 1092 | * so fifo and list head state won't matter | ||
| 1093 | */ | ||
| 1094 | while (!list_empty(&ep->queue)) { | ||
| 1095 | struct net2280_request *req; | ||
| 1096 | u32 tmp; | ||
| 1097 | |||
| 1098 | req = list_entry(ep->queue.next, | ||
| 1099 | struct net2280_request, queue); | ||
| 1100 | if (!req->valid) | ||
| 1101 | break; | ||
| 1102 | rmb(); | ||
| 1103 | tmp = le32_to_cpup(&req->td->dmacount); | ||
| 1104 | if ((tmp & BIT(VALID_BIT)) != 0) | ||
| 1105 | break; | ||
| 1106 | |||
| 1107 | /* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short" | ||
| 1108 | * cases where DMA must be aborted; this code handles | ||
| 1109 | * all non-abort DMA completions. | ||
| 1110 | */ | ||
| 1111 | if (unlikely(req->td->dmadesc == 0)) { | ||
| 1112 | /* paranoia */ | ||
| 1113 | tmp = readl(&ep->dma->dmacount); | ||
| 1114 | if (tmp & DMA_BYTE_COUNT_MASK) | ||
| 1115 | break; | ||
| 1116 | /* single transfer mode */ | ||
| 1117 | dma_done(ep, req, tmp, 0); | ||
| 1118 | break; | ||
| 1119 | } else if (!ep->is_in && | ||
| 1120 | (req->req.length % ep->ep.maxpacket) != 0) { | ||
| 1121 | tmp = readl(&ep->regs->ep_stat); | ||
| 1122 | if (ep->dev->quirks & PLX_SUPERSPEED) | ||
| 1123 | return dma_done(ep, req, tmp, 0); | ||
| 1124 | |||
| 1125 | /* AVOID TROUBLE HERE by not issuing short reads from | ||
| 1126 | * your gadget driver. That helps avoids errata 0121, | ||
| 1127 | * 0122, and 0124; not all cases trigger the warning. | ||
| 1128 | */ | ||
| 1129 | if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) { | ||
| 1130 | ep_warn(ep->dev, "%s lost packet sync!\n", | ||
| 1131 | ep->ep.name); | ||
| 1132 | req->req.status = -EOVERFLOW; | ||
| 1133 | } else { | ||
| 1134 | tmp = readl(&ep->regs->ep_avail); | ||
| 1135 | if (tmp) { | ||
| 1136 | /* fifo gets flushed later */ | ||
| 1137 | ep->out_overflow = 1; | ||
| 1138 | ep_dbg(ep->dev, | ||
| 1139 | "%s dma, discard %d len %d\n", | ||
| 1140 | ep->ep.name, tmp, | ||
| 1141 | req->req.length); | ||
| 1142 | req->req.status = -EOVERFLOW; | ||
| 1143 | } | ||
| 1144 | } | ||
| 1145 | } | ||
| 1146 | dma_done(ep, req, tmp, 0); | ||
| 1147 | } | ||
| 1148 | } | ||
| 1149 | |||
| 1150 | static void restart_dma(struct net2280_ep *ep) | ||
| 1151 | { | ||
| 1152 | struct net2280_request *req; | ||
| 1153 | u32 dmactl = dmactl_default; | ||
| 1154 | |||
| 1155 | if (ep->stopped) | ||
| 1156 | return; | ||
| 1157 | req = list_entry(ep->queue.next, struct net2280_request, queue); | ||
| 1158 | |||
| 1159 | if (!use_dma_chaining) { | ||
| 1160 | start_dma(ep, req); | ||
| 1161 | return; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | /* the 2280 will be processing the queue unless queue hiccups after | ||
| 1165 | * the previous transfer: | ||
| 1166 | * IN: wanted automagic zlp, head doesn't (or vice versa) | ||
| 1167 | * DMA_FIFO_VALIDATE doesn't init from dma descriptors. | ||
| 1168 | * OUT: was "usb-short", we must restart. | ||
| 1169 | */ | ||
| 1170 | if (ep->is_in && !req->valid) { | ||
| 1171 | struct net2280_request *entry, *prev = NULL; | ||
| 1172 | int reqmode, done = 0; | ||
| 1173 | |||
| 1174 | ep_dbg(ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td); | ||
| 1175 | ep->in_fifo_validate = likely(req->req.zero || | ||
| 1176 | (req->req.length % ep->ep.maxpacket) != 0); | ||
| 1177 | if (ep->in_fifo_validate) | ||
| 1178 | dmactl |= BIT(DMA_FIFO_VALIDATE); | ||
| 1179 | list_for_each_entry(entry, &ep->queue, queue) { | ||
| 1180 | __le32 dmacount; | ||
| 1181 | |||
| 1182 | if (entry == req) | ||
| 1183 | continue; | ||
| 1184 | dmacount = entry->td->dmacount; | ||
| 1185 | if (!done) { | ||
| 1186 | reqmode = likely(entry->req.zero || | ||
| 1187 | (entry->req.length % ep->ep.maxpacket)); | ||
| 1188 | if (reqmode == ep->in_fifo_validate) { | ||
| 1189 | entry->valid = 1; | ||
| 1190 | dmacount |= valid_bit; | ||
| 1191 | entry->td->dmacount = dmacount; | ||
| 1192 | prev = entry; | ||
| 1193 | continue; | ||
| 1194 | } else { | ||
| 1195 | /* force a hiccup */ | ||
| 1196 | prev->td->dmacount |= dma_done_ie; | ||
| 1197 | done = 1; | ||
| 1198 | } | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | /* walk the rest of the queue so unlinks behave */ | ||
| 1202 | entry->valid = 0; | ||
| 1203 | dmacount &= ~valid_bit; | ||
| 1204 | entry->td->dmacount = dmacount; | ||
| 1205 | prev = entry; | ||
| 1206 | } | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | writel(0, &ep->dma->dmactl); | ||
| 1210 | start_queue(ep, dmactl, req->td_dma); | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | static void abort_dma_228x(struct net2280_ep *ep) | ||
| 1214 | { | ||
| 1215 | /* abort the current transfer */ | ||
| 1216 | if (likely(!list_empty(&ep->queue))) { | ||
| 1217 | /* FIXME work around errata 0121, 0122, 0124 */ | ||
| 1218 | writel(BIT(DMA_ABORT), &ep->dma->dmastat); | ||
| 1219 | spin_stop_dma(ep->dma); | ||
| 1220 | } else | ||
| 1221 | stop_dma(ep->dma); | ||
| 1222 | scan_dma_completions(ep); | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | static void abort_dma_338x(struct net2280_ep *ep) | ||
| 1226 | { | ||
| 1227 | writel(BIT(DMA_ABORT), &ep->dma->dmastat); | ||
| 1228 | spin_stop_dma(ep->dma); | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | static void abort_dma(struct net2280_ep *ep) | ||
| 1232 | { | ||
| 1233 | if (ep->dev->quirks & PLX_LEGACY) | ||
| 1234 | return abort_dma_228x(ep); | ||
| 1235 | return abort_dma_338x(ep); | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | /* dequeue ALL requests */ | ||
| 1239 | static void nuke(struct net2280_ep *ep) | ||
| 1240 | { | ||
| 1241 | struct net2280_request *req; | ||
| 1242 | |||
| 1243 | /* called with spinlock held */ | ||
| 1244 | ep->stopped = 1; | ||
| 1245 | if (ep->dma) | ||
| 1246 | abort_dma(ep); | ||
| 1247 | while (!list_empty(&ep->queue)) { | ||
| 1248 | req = list_entry(ep->queue.next, | ||
| 1249 | struct net2280_request, | ||
| 1250 | queue); | ||
| 1251 | done(ep, req, -ESHUTDOWN); | ||
| 1252 | } | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | /* dequeue JUST ONE request */ | ||
| 1256 | static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
| 1257 | { | ||
| 1258 | struct net2280_ep *ep; | ||
| 1259 | struct net2280_request *req; | ||
| 1260 | unsigned long flags; | ||
| 1261 | u32 dmactl; | ||
| 1262 | int stopped; | ||
| 1263 | |||
| 1264 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 1265 | if (!_ep || (!ep->desc && ep->num != 0) || !_req) | ||
| 1266 | return -EINVAL; | ||
| 1267 | |||
| 1268 | spin_lock_irqsave(&ep->dev->lock, flags); | ||
| 1269 | stopped = ep->stopped; | ||
| 1270 | |||
| 1271 | /* quiesce dma while we patch the queue */ | ||
| 1272 | dmactl = 0; | ||
| 1273 | ep->stopped = 1; | ||
| 1274 | if (ep->dma) { | ||
| 1275 | dmactl = readl(&ep->dma->dmactl); | ||
| 1276 | /* WARNING erratum 0127 may kick in ... */ | ||
| 1277 | stop_dma(ep->dma); | ||
| 1278 | scan_dma_completions(ep); | ||
| 1279 | } | ||
| 1280 | |||
| 1281 | /* make sure it's still queued on this endpoint */ | ||
| 1282 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 1283 | if (&req->req == _req) | ||
| 1284 | break; | ||
| 1285 | } | ||
| 1286 | if (&req->req != _req) { | ||
| 1287 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 1288 | return -EINVAL; | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | /* queue head may be partially complete. */ | ||
| 1292 | if (ep->queue.next == &req->queue) { | ||
| 1293 | if (ep->dma) { | ||
| 1294 | ep_dbg(ep->dev, "unlink (%s) dma\n", _ep->name); | ||
| 1295 | _req->status = -ECONNRESET; | ||
| 1296 | abort_dma(ep); | ||
| 1297 | if (likely(ep->queue.next == &req->queue)) { | ||
| 1298 | /* NOTE: misreports single-transfer mode*/ | ||
| 1299 | req->td->dmacount = 0; /* invalidate */ | ||
| 1300 | dma_done(ep, req, | ||
| 1301 | readl(&ep->dma->dmacount), | ||
| 1302 | -ECONNRESET); | ||
| 1303 | } | ||
| 1304 | } else { | ||
| 1305 | ep_dbg(ep->dev, "unlink (%s) pio\n", _ep->name); | ||
| 1306 | done(ep, req, -ECONNRESET); | ||
| 1307 | } | ||
| 1308 | req = NULL; | ||
| 1309 | |||
| 1310 | /* patch up hardware chaining data */ | ||
| 1311 | } else if (ep->dma && use_dma_chaining) { | ||
| 1312 | if (req->queue.prev == ep->queue.next) { | ||
| 1313 | writel(le32_to_cpu(req->td->dmadesc), | ||
| 1314 | &ep->dma->dmadesc); | ||
| 1315 | if (req->td->dmacount & dma_done_ie) | ||
| 1316 | writel(readl(&ep->dma->dmacount) | | ||
| 1317 | le32_to_cpu(dma_done_ie), | ||
| 1318 | &ep->dma->dmacount); | ||
| 1319 | } else { | ||
| 1320 | struct net2280_request *prev; | ||
| 1321 | |||
| 1322 | prev = list_entry(req->queue.prev, | ||
| 1323 | struct net2280_request, queue); | ||
| 1324 | prev->td->dmadesc = req->td->dmadesc; | ||
| 1325 | if (req->td->dmacount & dma_done_ie) | ||
| 1326 | prev->td->dmacount |= dma_done_ie; | ||
| 1327 | } | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | if (req) | ||
| 1331 | done(ep, req, -ECONNRESET); | ||
| 1332 | ep->stopped = stopped; | ||
| 1333 | |||
| 1334 | if (ep->dma) { | ||
| 1335 | /* turn off dma on inactive queues */ | ||
| 1336 | if (list_empty(&ep->queue)) | ||
| 1337 | stop_dma(ep->dma); | ||
| 1338 | else if (!ep->stopped) { | ||
| 1339 | /* resume current request, or start new one */ | ||
| 1340 | if (req) | ||
| 1341 | writel(dmactl, &ep->dma->dmactl); | ||
| 1342 | else | ||
| 1343 | start_dma(ep, list_entry(ep->queue.next, | ||
| 1344 | struct net2280_request, queue)); | ||
| 1345 | } | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 1349 | return 0; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | /*-------------------------------------------------------------------------*/ | ||
| 1353 | |||
| 1354 | static int net2280_fifo_status(struct usb_ep *_ep); | ||
| 1355 | |||
| 1356 | static int | ||
| 1357 | net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) | ||
| 1358 | { | ||
| 1359 | struct net2280_ep *ep; | ||
| 1360 | unsigned long flags; | ||
| 1361 | int retval = 0; | ||
| 1362 | |||
| 1363 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 1364 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1365 | return -EINVAL; | ||
| 1366 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1367 | return -ESHUTDOWN; | ||
| 1368 | if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03) | ||
| 1369 | == USB_ENDPOINT_XFER_ISOC) | ||
| 1370 | return -EINVAL; | ||
| 1371 | |||
| 1372 | spin_lock_irqsave(&ep->dev->lock, flags); | ||
| 1373 | if (!list_empty(&ep->queue)) | ||
| 1374 | retval = -EAGAIN; | ||
| 1375 | else if (ep->is_in && value && net2280_fifo_status(_ep) != 0) | ||
| 1376 | retval = -EAGAIN; | ||
| 1377 | else { | ||
| 1378 | ep_vdbg(ep->dev, "%s %s %s\n", _ep->name, | ||
| 1379 | value ? "set" : "clear", | ||
| 1380 | wedged ? "wedge" : "halt"); | ||
| 1381 | /* set/clear, then synch memory views with the device */ | ||
| 1382 | if (value) { | ||
| 1383 | if (ep->num == 0) | ||
| 1384 | ep->dev->protocol_stall = 1; | ||
| 1385 | else | ||
| 1386 | set_halt(ep); | ||
| 1387 | if (wedged) | ||
| 1388 | ep->wedged = 1; | ||
| 1389 | } else { | ||
| 1390 | clear_halt(ep); | ||
| 1391 | if (ep->dev->quirks & PLX_SUPERSPEED && | ||
| 1392 | !list_empty(&ep->queue) && ep->td_dma) | ||
| 1393 | restart_dma(ep); | ||
| 1394 | ep->wedged = 0; | ||
| 1395 | } | ||
| 1396 | (void) readl(&ep->regs->ep_rsp); | ||
| 1397 | } | ||
| 1398 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 1399 | |||
| 1400 | return retval; | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | static int net2280_set_halt(struct usb_ep *_ep, int value) | ||
| 1404 | { | ||
| 1405 | return net2280_set_halt_and_wedge(_ep, value, 0); | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | static int net2280_set_wedge(struct usb_ep *_ep) | ||
| 1409 | { | ||
| 1410 | if (!_ep || _ep->name == ep0name) | ||
| 1411 | return -EINVAL; | ||
| 1412 | return net2280_set_halt_and_wedge(_ep, 1, 1); | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | static int net2280_fifo_status(struct usb_ep *_ep) | ||
| 1416 | { | ||
| 1417 | struct net2280_ep *ep; | ||
| 1418 | u32 avail; | ||
| 1419 | |||
| 1420 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 1421 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1422 | return -ENODEV; | ||
| 1423 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1424 | return -ESHUTDOWN; | ||
| 1425 | |||
| 1426 | avail = readl(&ep->regs->ep_avail) & (BIT(12) - 1); | ||
| 1427 | if (avail > ep->fifo_size) | ||
| 1428 | return -EOVERFLOW; | ||
| 1429 | if (ep->is_in) | ||
| 1430 | avail = ep->fifo_size - avail; | ||
| 1431 | return avail; | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | static void net2280_fifo_flush(struct usb_ep *_ep) | ||
| 1435 | { | ||
| 1436 | struct net2280_ep *ep; | ||
| 1437 | |||
| 1438 | ep = container_of(_ep, struct net2280_ep, ep); | ||
| 1439 | if (!_ep || (!ep->desc && ep->num != 0)) | ||
| 1440 | return; | ||
| 1441 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1442 | return; | ||
| 1443 | |||
| 1444 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); | ||
| 1445 | (void) readl(&ep->regs->ep_rsp); | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | static const struct usb_ep_ops net2280_ep_ops = { | ||
| 1449 | .enable = net2280_enable, | ||
| 1450 | .disable = net2280_disable, | ||
| 1451 | |||
| 1452 | .alloc_request = net2280_alloc_request, | ||
| 1453 | .free_request = net2280_free_request, | ||
| 1454 | |||
| 1455 | .queue = net2280_queue, | ||
| 1456 | .dequeue = net2280_dequeue, | ||
| 1457 | |||
| 1458 | .set_halt = net2280_set_halt, | ||
| 1459 | .set_wedge = net2280_set_wedge, | ||
| 1460 | .fifo_status = net2280_fifo_status, | ||
| 1461 | .fifo_flush = net2280_fifo_flush, | ||
| 1462 | }; | ||
| 1463 | |||
| 1464 | /*-------------------------------------------------------------------------*/ | ||
| 1465 | |||
| 1466 | static int net2280_get_frame(struct usb_gadget *_gadget) | ||
| 1467 | { | ||
| 1468 | struct net2280 *dev; | ||
| 1469 | unsigned long flags; | ||
| 1470 | u16 retval; | ||
| 1471 | |||
| 1472 | if (!_gadget) | ||
| 1473 | return -ENODEV; | ||
| 1474 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 1475 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1476 | retval = get_idx_reg(dev->regs, REG_FRAME) & 0x03ff; | ||
| 1477 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1478 | return retval; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | static int net2280_wakeup(struct usb_gadget *_gadget) | ||
| 1482 | { | ||
| 1483 | struct net2280 *dev; | ||
| 1484 | u32 tmp; | ||
| 1485 | unsigned long flags; | ||
| 1486 | |||
| 1487 | if (!_gadget) | ||
| 1488 | return 0; | ||
| 1489 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 1490 | |||
| 1491 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1492 | tmp = readl(&dev->usb->usbctl); | ||
| 1493 | if (tmp & BIT(DEVICE_REMOTE_WAKEUP_ENABLE)) | ||
| 1494 | writel(BIT(GENERATE_RESUME), &dev->usb->usbstat); | ||
| 1495 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1496 | |||
| 1497 | /* pci writes may still be posted */ | ||
| 1498 | return 0; | ||
| 1499 | } | ||
| 1500 | |||
| 1501 | static int net2280_set_selfpowered(struct usb_gadget *_gadget, int value) | ||
| 1502 | { | ||
| 1503 | struct net2280 *dev; | ||
| 1504 | u32 tmp; | ||
| 1505 | unsigned long flags; | ||
| 1506 | |||
| 1507 | if (!_gadget) | ||
| 1508 | return 0; | ||
| 1509 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 1510 | |||
| 1511 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1512 | tmp = readl(&dev->usb->usbctl); | ||
| 1513 | if (value) { | ||
| 1514 | tmp |= BIT(SELF_POWERED_STATUS); | ||
| 1515 | dev->selfpowered = 1; | ||
| 1516 | } else { | ||
| 1517 | tmp &= ~BIT(SELF_POWERED_STATUS); | ||
| 1518 | dev->selfpowered = 0; | ||
| 1519 | } | ||
| 1520 | writel(tmp, &dev->usb->usbctl); | ||
| 1521 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1522 | |||
| 1523 | return 0; | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | static int net2280_pullup(struct usb_gadget *_gadget, int is_on) | ||
| 1527 | { | ||
| 1528 | struct net2280 *dev; | ||
| 1529 | u32 tmp; | ||
| 1530 | unsigned long flags; | ||
| 1531 | |||
| 1532 | if (!_gadget) | ||
| 1533 | return -ENODEV; | ||
| 1534 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 1535 | |||
| 1536 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1537 | tmp = readl(&dev->usb->usbctl); | ||
| 1538 | dev->softconnect = (is_on != 0); | ||
| 1539 | if (is_on) | ||
| 1540 | tmp |= BIT(USB_DETECT_ENABLE); | ||
| 1541 | else | ||
| 1542 | tmp &= ~BIT(USB_DETECT_ENABLE); | ||
| 1543 | writel(tmp, &dev->usb->usbctl); | ||
| 1544 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1545 | |||
| 1546 | return 0; | ||
| 1547 | } | ||
| 1548 | |||
| 1549 | static int net2280_start(struct usb_gadget *_gadget, | ||
| 1550 | struct usb_gadget_driver *driver); | ||
| 1551 | static int net2280_stop(struct usb_gadget *_gadget, | ||
| 1552 | struct usb_gadget_driver *driver); | ||
| 1553 | |||
| 1554 | static const struct usb_gadget_ops net2280_ops = { | ||
| 1555 | .get_frame = net2280_get_frame, | ||
| 1556 | .wakeup = net2280_wakeup, | ||
| 1557 | .set_selfpowered = net2280_set_selfpowered, | ||
| 1558 | .pullup = net2280_pullup, | ||
| 1559 | .udc_start = net2280_start, | ||
| 1560 | .udc_stop = net2280_stop, | ||
| 1561 | }; | ||
| 1562 | |||
| 1563 | /*-------------------------------------------------------------------------*/ | ||
| 1564 | |||
| 1565 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
| 1566 | |||
| 1567 | /* FIXME move these into procfs, and use seq_file. | ||
| 1568 | * Sysfs _still_ doesn't behave for arbitrarily sized files, | ||
| 1569 | * and also doesn't help products using this with 2.4 kernels. | ||
| 1570 | */ | ||
| 1571 | |||
| 1572 | /* "function" sysfs attribute */ | ||
| 1573 | static ssize_t function_show(struct device *_dev, struct device_attribute *attr, | ||
| 1574 | char *buf) | ||
| 1575 | { | ||
| 1576 | struct net2280 *dev = dev_get_drvdata(_dev); | ||
| 1577 | |||
| 1578 | if (!dev->driver || !dev->driver->function || | ||
| 1579 | strlen(dev->driver->function) > PAGE_SIZE) | ||
| 1580 | return 0; | ||
| 1581 | return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function); | ||
| 1582 | } | ||
| 1583 | static DEVICE_ATTR_RO(function); | ||
| 1584 | |||
| 1585 | static ssize_t registers_show(struct device *_dev, | ||
| 1586 | struct device_attribute *attr, char *buf) | ||
| 1587 | { | ||
| 1588 | struct net2280 *dev; | ||
| 1589 | char *next; | ||
| 1590 | unsigned size, t; | ||
| 1591 | unsigned long flags; | ||
| 1592 | int i; | ||
| 1593 | u32 t1, t2; | ||
| 1594 | const char *s; | ||
| 1595 | |||
| 1596 | dev = dev_get_drvdata(_dev); | ||
| 1597 | next = buf; | ||
| 1598 | size = PAGE_SIZE; | ||
| 1599 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1600 | |||
| 1601 | if (dev->driver) | ||
| 1602 | s = dev->driver->driver.name; | ||
| 1603 | else | ||
| 1604 | s = "(none)"; | ||
| 1605 | |||
| 1606 | /* Main Control Registers */ | ||
| 1607 | t = scnprintf(next, size, "%s version " DRIVER_VERSION | ||
| 1608 | ", chiprev %04x, dma %s\n\n" | ||
| 1609 | "devinit %03x fifoctl %08x gadget '%s'\n" | ||
| 1610 | "pci irqenb0 %02x irqenb1 %08x " | ||
| 1611 | "irqstat0 %04x irqstat1 %08x\n", | ||
| 1612 | driver_name, dev->chiprev, | ||
| 1613 | use_dma | ||
| 1614 | ? (use_dma_chaining ? "chaining" : "enabled") | ||
| 1615 | : "disabled", | ||
| 1616 | readl(&dev->regs->devinit), | ||
| 1617 | readl(&dev->regs->fifoctl), | ||
| 1618 | s, | ||
| 1619 | readl(&dev->regs->pciirqenb0), | ||
| 1620 | readl(&dev->regs->pciirqenb1), | ||
| 1621 | readl(&dev->regs->irqstat0), | ||
| 1622 | readl(&dev->regs->irqstat1)); | ||
| 1623 | size -= t; | ||
| 1624 | next += t; | ||
| 1625 | |||
| 1626 | /* USB Control Registers */ | ||
| 1627 | t1 = readl(&dev->usb->usbctl); | ||
| 1628 | t2 = readl(&dev->usb->usbstat); | ||
| 1629 | if (t1 & BIT(VBUS_PIN)) { | ||
| 1630 | if (t2 & BIT(HIGH_SPEED)) | ||
| 1631 | s = "high speed"; | ||
| 1632 | else if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 1633 | s = "powered"; | ||
| 1634 | else | ||
| 1635 | s = "full speed"; | ||
| 1636 | /* full speed bit (6) not working?? */ | ||
| 1637 | } else | ||
| 1638 | s = "not attached"; | ||
| 1639 | t = scnprintf(next, size, | ||
| 1640 | "stdrsp %08x usbctl %08x usbstat %08x " | ||
| 1641 | "addr 0x%02x (%s)\n", | ||
| 1642 | readl(&dev->usb->stdrsp), t1, t2, | ||
| 1643 | readl(&dev->usb->ouraddr), s); | ||
| 1644 | size -= t; | ||
| 1645 | next += t; | ||
| 1646 | |||
| 1647 | /* PCI Master Control Registers */ | ||
| 1648 | |||
| 1649 | /* DMA Control Registers */ | ||
| 1650 | |||
| 1651 | /* Configurable EP Control Registers */ | ||
| 1652 | for (i = 0; i < dev->n_ep; i++) { | ||
| 1653 | struct net2280_ep *ep; | ||
| 1654 | |||
| 1655 | ep = &dev->ep[i]; | ||
| 1656 | if (i && !ep->desc) | ||
| 1657 | continue; | ||
| 1658 | |||
| 1659 | t1 = readl(&ep->cfg->ep_cfg); | ||
| 1660 | t2 = readl(&ep->regs->ep_rsp) & 0xff; | ||
| 1661 | t = scnprintf(next, size, | ||
| 1662 | "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" | ||
| 1663 | "irqenb %02x\n", | ||
| 1664 | ep->ep.name, t1, t2, | ||
| 1665 | (t2 & BIT(CLEAR_NAK_OUT_PACKETS)) | ||
| 1666 | ? "NAK " : "", | ||
| 1667 | (t2 & BIT(CLEAR_EP_HIDE_STATUS_PHASE)) | ||
| 1668 | ? "hide " : "", | ||
| 1669 | (t2 & BIT(CLEAR_EP_FORCE_CRC_ERROR)) | ||
| 1670 | ? "CRC " : "", | ||
| 1671 | (t2 & BIT(CLEAR_INTERRUPT_MODE)) | ||
| 1672 | ? "interrupt " : "", | ||
| 1673 | (t2 & BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)) | ||
| 1674 | ? "status " : "", | ||
| 1675 | (t2 & BIT(CLEAR_NAK_OUT_PACKETS_MODE)) | ||
| 1676 | ? "NAKmode " : "", | ||
| 1677 | (t2 & BIT(CLEAR_ENDPOINT_TOGGLE)) | ||
| 1678 | ? "DATA1 " : "DATA0 ", | ||
| 1679 | (t2 & BIT(CLEAR_ENDPOINT_HALT)) | ||
| 1680 | ? "HALT " : "", | ||
| 1681 | readl(&ep->regs->ep_irqenb)); | ||
| 1682 | size -= t; | ||
| 1683 | next += t; | ||
| 1684 | |||
| 1685 | t = scnprintf(next, size, | ||
| 1686 | "\tstat %08x avail %04x " | ||
| 1687 | "(ep%d%s-%s)%s\n", | ||
| 1688 | readl(&ep->regs->ep_stat), | ||
| 1689 | readl(&ep->regs->ep_avail), | ||
| 1690 | t1 & 0x0f, DIR_STRING(t1), | ||
| 1691 | type_string(t1 >> 8), | ||
| 1692 | ep->stopped ? "*" : ""); | ||
| 1693 | size -= t; | ||
| 1694 | next += t; | ||
| 1695 | |||
| 1696 | if (!ep->dma) | ||
| 1697 | continue; | ||
| 1698 | |||
| 1699 | t = scnprintf(next, size, | ||
| 1700 | " dma\tctl %08x stat %08x count %08x\n" | ||
| 1701 | "\taddr %08x desc %08x\n", | ||
| 1702 | readl(&ep->dma->dmactl), | ||
| 1703 | readl(&ep->dma->dmastat), | ||
| 1704 | readl(&ep->dma->dmacount), | ||
| 1705 | readl(&ep->dma->dmaaddr), | ||
| 1706 | readl(&ep->dma->dmadesc)); | ||
| 1707 | size -= t; | ||
| 1708 | next += t; | ||
| 1709 | |||
| 1710 | } | ||
| 1711 | |||
| 1712 | /* Indexed Registers (none yet) */ | ||
| 1713 | |||
| 1714 | /* Statistics */ | ||
| 1715 | t = scnprintf(next, size, "\nirqs: "); | ||
| 1716 | size -= t; | ||
| 1717 | next += t; | ||
| 1718 | for (i = 0; i < dev->n_ep; i++) { | ||
| 1719 | struct net2280_ep *ep; | ||
| 1720 | |||
| 1721 | ep = &dev->ep[i]; | ||
| 1722 | if (i && !ep->irqs) | ||
| 1723 | continue; | ||
| 1724 | t = scnprintf(next, size, " %s/%lu", ep->ep.name, ep->irqs); | ||
| 1725 | size -= t; | ||
| 1726 | next += t; | ||
| 1727 | |||
| 1728 | } | ||
| 1729 | t = scnprintf(next, size, "\n"); | ||
| 1730 | size -= t; | ||
| 1731 | next += t; | ||
| 1732 | |||
| 1733 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1734 | |||
| 1735 | return PAGE_SIZE - size; | ||
| 1736 | } | ||
| 1737 | static DEVICE_ATTR_RO(registers); | ||
| 1738 | |||
| 1739 | static ssize_t queues_show(struct device *_dev, struct device_attribute *attr, | ||
| 1740 | char *buf) | ||
| 1741 | { | ||
| 1742 | struct net2280 *dev; | ||
| 1743 | char *next; | ||
| 1744 | unsigned size; | ||
| 1745 | unsigned long flags; | ||
| 1746 | int i; | ||
| 1747 | |||
| 1748 | dev = dev_get_drvdata(_dev); | ||
| 1749 | next = buf; | ||
| 1750 | size = PAGE_SIZE; | ||
| 1751 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1752 | |||
| 1753 | for (i = 0; i < dev->n_ep; i++) { | ||
| 1754 | struct net2280_ep *ep = &dev->ep[i]; | ||
| 1755 | struct net2280_request *req; | ||
| 1756 | int t; | ||
| 1757 | |||
| 1758 | if (i != 0) { | ||
| 1759 | const struct usb_endpoint_descriptor *d; | ||
| 1760 | |||
| 1761 | d = ep->desc; | ||
| 1762 | if (!d) | ||
| 1763 | continue; | ||
| 1764 | t = d->bEndpointAddress; | ||
| 1765 | t = scnprintf(next, size, | ||
| 1766 | "\n%s (ep%d%s-%s) max %04x %s fifo %d\n", | ||
| 1767 | ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK, | ||
| 1768 | (t & USB_DIR_IN) ? "in" : "out", | ||
| 1769 | type_string(d->bmAttributes), | ||
| 1770 | usb_endpoint_maxp(d) & 0x1fff, | ||
| 1771 | ep->dma ? "dma" : "pio", ep->fifo_size | ||
| 1772 | ); | ||
| 1773 | } else /* ep0 should only have one transfer queued */ | ||
| 1774 | t = scnprintf(next, size, "ep0 max 64 pio %s\n", | ||
| 1775 | ep->is_in ? "in" : "out"); | ||
| 1776 | if (t <= 0 || t > size) | ||
| 1777 | goto done; | ||
| 1778 | size -= t; | ||
| 1779 | next += t; | ||
| 1780 | |||
| 1781 | if (list_empty(&ep->queue)) { | ||
| 1782 | t = scnprintf(next, size, "\t(nothing queued)\n"); | ||
| 1783 | if (t <= 0 || t > size) | ||
| 1784 | goto done; | ||
| 1785 | size -= t; | ||
| 1786 | next += t; | ||
| 1787 | continue; | ||
| 1788 | } | ||
| 1789 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 1790 | if (ep->dma && req->td_dma == readl(&ep->dma->dmadesc)) | ||
| 1791 | t = scnprintf(next, size, | ||
| 1792 | "\treq %p len %d/%d " | ||
| 1793 | "buf %p (dmacount %08x)\n", | ||
| 1794 | &req->req, req->req.actual, | ||
| 1795 | req->req.length, req->req.buf, | ||
| 1796 | readl(&ep->dma->dmacount)); | ||
| 1797 | else | ||
| 1798 | t = scnprintf(next, size, | ||
| 1799 | "\treq %p len %d/%d buf %p\n", | ||
| 1800 | &req->req, req->req.actual, | ||
| 1801 | req->req.length, req->req.buf); | ||
| 1802 | if (t <= 0 || t > size) | ||
| 1803 | goto done; | ||
| 1804 | size -= t; | ||
| 1805 | next += t; | ||
| 1806 | |||
| 1807 | if (ep->dma) { | ||
| 1808 | struct net2280_dma *td; | ||
| 1809 | |||
| 1810 | td = req->td; | ||
| 1811 | t = scnprintf(next, size, "\t td %08x " | ||
| 1812 | " count %08x buf %08x desc %08x\n", | ||
| 1813 | (u32) req->td_dma, | ||
| 1814 | le32_to_cpu(td->dmacount), | ||
| 1815 | le32_to_cpu(td->dmaaddr), | ||
| 1816 | le32_to_cpu(td->dmadesc)); | ||
| 1817 | if (t <= 0 || t > size) | ||
| 1818 | goto done; | ||
| 1819 | size -= t; | ||
| 1820 | next += t; | ||
| 1821 | } | ||
| 1822 | } | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | done: | ||
| 1826 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1827 | return PAGE_SIZE - size; | ||
| 1828 | } | ||
| 1829 | static DEVICE_ATTR_RO(queues); | ||
| 1830 | |||
| 1831 | |||
| 1832 | #else | ||
| 1833 | |||
| 1834 | #define device_create_file(a, b) (0) | ||
| 1835 | #define device_remove_file(a, b) do { } while (0) | ||
| 1836 | |||
| 1837 | #endif | ||
| 1838 | |||
| 1839 | /*-------------------------------------------------------------------------*/ | ||
| 1840 | |||
| 1841 | /* another driver-specific mode might be a request type doing dma | ||
| 1842 | * to/from another device fifo instead of to/from memory. | ||
| 1843 | */ | ||
| 1844 | |||
| 1845 | static void set_fifo_mode(struct net2280 *dev, int mode) | ||
| 1846 | { | ||
| 1847 | /* keeping high bits preserves BAR2 */ | ||
| 1848 | writel((0xffff << PCI_BASE2_RANGE) | mode, &dev->regs->fifoctl); | ||
| 1849 | |||
| 1850 | /* always ep-{a,b,e,f} ... maybe not ep-c or ep-d */ | ||
| 1851 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
| 1852 | list_add_tail(&dev->ep[1].ep.ep_list, &dev->gadget.ep_list); | ||
| 1853 | list_add_tail(&dev->ep[2].ep.ep_list, &dev->gadget.ep_list); | ||
| 1854 | switch (mode) { | ||
| 1855 | case 0: | ||
| 1856 | list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list); | ||
| 1857 | list_add_tail(&dev->ep[4].ep.ep_list, &dev->gadget.ep_list); | ||
| 1858 | dev->ep[1].fifo_size = dev->ep[2].fifo_size = 1024; | ||
| 1859 | break; | ||
| 1860 | case 1: | ||
| 1861 | dev->ep[1].fifo_size = dev->ep[2].fifo_size = 2048; | ||
| 1862 | break; | ||
| 1863 | case 2: | ||
| 1864 | list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list); | ||
| 1865 | dev->ep[1].fifo_size = 2048; | ||
| 1866 | dev->ep[2].fifo_size = 1024; | ||
| 1867 | break; | ||
| 1868 | } | ||
| 1869 | /* fifo sizes for ep0, ep-c, ep-d, ep-e, and ep-f never change */ | ||
| 1870 | list_add_tail(&dev->ep[5].ep.ep_list, &dev->gadget.ep_list); | ||
| 1871 | list_add_tail(&dev->ep[6].ep.ep_list, &dev->gadget.ep_list); | ||
| 1872 | } | ||
| 1873 | |||
| 1874 | static void defect7374_disable_data_eps(struct net2280 *dev) | ||
| 1875 | { | ||
| 1876 | /* | ||
| 1877 | * For Defect 7374, disable data EPs (and more): | ||
| 1878 | * - This phase undoes the earlier phase of the Defect 7374 workaround, | ||
| 1879 | * returing ep regs back to normal. | ||
| 1880 | */ | ||
| 1881 | struct net2280_ep *ep; | ||
| 1882 | int i; | ||
| 1883 | unsigned char ep_sel; | ||
| 1884 | u32 tmp_reg; | ||
| 1885 | |||
| 1886 | for (i = 1; i < 5; i++) { | ||
| 1887 | ep = &dev->ep[i]; | ||
| 1888 | writel(0, &ep->cfg->ep_cfg); | ||
| 1889 | } | ||
| 1890 | |||
| 1891 | /* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */ | ||
| 1892 | for (i = 0; i < 6; i++) | ||
| 1893 | writel(0, &dev->dep[i].dep_cfg); | ||
| 1894 | |||
| 1895 | for (ep_sel = 0; ep_sel <= 21; ep_sel++) { | ||
| 1896 | /* Select an endpoint for subsequent operations: */ | ||
| 1897 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
| 1898 | writel(((tmp_reg & ~0x1f) | ep_sel), &dev->plregs->pl_ep_ctrl); | ||
| 1899 | |||
| 1900 | if (ep_sel < 2 || (ep_sel > 9 && ep_sel < 14) || | ||
| 1901 | ep_sel == 18 || ep_sel == 20) | ||
| 1902 | continue; | ||
| 1903 | |||
| 1904 | /* Change settings on some selected endpoints */ | ||
| 1905 | tmp_reg = readl(&dev->plregs->pl_ep_cfg_4); | ||
| 1906 | tmp_reg &= ~BIT(NON_CTRL_IN_TOLERATE_BAD_DIR); | ||
| 1907 | writel(tmp_reg, &dev->plregs->pl_ep_cfg_4); | ||
| 1908 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
| 1909 | tmp_reg |= BIT(EP_INITIALIZED); | ||
| 1910 | writel(tmp_reg, &dev->plregs->pl_ep_ctrl); | ||
| 1911 | } | ||
| 1912 | } | ||
| 1913 | |||
| 1914 | static void defect7374_enable_data_eps_zero(struct net2280 *dev) | ||
| 1915 | { | ||
| 1916 | u32 tmp = 0, tmp_reg; | ||
| 1917 | u32 fsmvalue, scratch; | ||
| 1918 | int i; | ||
| 1919 | unsigned char ep_sel; | ||
| 1920 | |||
| 1921 | scratch = get_idx_reg(dev->regs, SCRATCH); | ||
| 1922 | fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD); | ||
| 1923 | scratch &= ~(0xf << DEFECT7374_FSM_FIELD); | ||
| 1924 | |||
| 1925 | /*See if firmware needs to set up for workaround*/ | ||
| 1926 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) { | ||
| 1927 | ep_warn(dev, "Operate Defect 7374 workaround soft this time"); | ||
| 1928 | ep_warn(dev, "It will operate on cold-reboot and SS connect"); | ||
| 1929 | |||
| 1930 | /*GPEPs:*/ | ||
| 1931 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) | | ||
| 1932 | (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) | | ||
| 1933 | ((dev->enhanced_mode) ? | ||
| 1934 | BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) | | ||
| 1935 | BIT(IN_ENDPOINT_ENABLE)); | ||
| 1936 | |||
| 1937 | for (i = 1; i < 5; i++) | ||
| 1938 | writel(tmp, &dev->ep[i].cfg->ep_cfg); | ||
| 1939 | |||
| 1940 | /* CSRIN, PCIIN, STATIN, RCIN*/ | ||
| 1941 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE)); | ||
| 1942 | writel(tmp, &dev->dep[1].dep_cfg); | ||
| 1943 | writel(tmp, &dev->dep[3].dep_cfg); | ||
| 1944 | writel(tmp, &dev->dep[4].dep_cfg); | ||
| 1945 | writel(tmp, &dev->dep[5].dep_cfg); | ||
| 1946 | |||
| 1947 | /*Implemented for development and debug. | ||
| 1948 | * Can be refined/tuned later.*/ | ||
| 1949 | for (ep_sel = 0; ep_sel <= 21; ep_sel++) { | ||
| 1950 | /* Select an endpoint for subsequent operations: */ | ||
| 1951 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
| 1952 | writel(((tmp_reg & ~0x1f) | ep_sel), | ||
| 1953 | &dev->plregs->pl_ep_ctrl); | ||
| 1954 | |||
| 1955 | if (ep_sel == 1) { | ||
| 1956 | tmp = | ||
| 1957 | (readl(&dev->plregs->pl_ep_ctrl) | | ||
| 1958 | BIT(CLEAR_ACK_ERROR_CODE) | 0); | ||
| 1959 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
| 1960 | continue; | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) || | ||
| 1964 | ep_sel == 18 || ep_sel == 20) | ||
| 1965 | continue; | ||
| 1966 | |||
| 1967 | tmp = (readl(&dev->plregs->pl_ep_cfg_4) | | ||
| 1968 | BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0); | ||
| 1969 | writel(tmp, &dev->plregs->pl_ep_cfg_4); | ||
| 1970 | |||
| 1971 | tmp = readl(&dev->plregs->pl_ep_ctrl) & | ||
| 1972 | ~BIT(EP_INITIALIZED); | ||
| 1973 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
| 1974 | |||
| 1975 | } | ||
| 1976 | |||
| 1977 | /* Set FSM to focus on the first Control Read: | ||
| 1978 | * - Tip: Connection speed is known upon the first | ||
| 1979 | * setup request.*/ | ||
| 1980 | scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ; | ||
| 1981 | set_idx_reg(dev->regs, SCRATCH, scratch); | ||
| 1982 | |||
| 1983 | } else{ | ||
| 1984 | ep_warn(dev, "Defect 7374 workaround soft will NOT operate"); | ||
| 1985 | ep_warn(dev, "It will operate on cold-reboot and SS connect"); | ||
| 1986 | } | ||
| 1987 | } | ||
| 1988 | |||
| 1989 | /* keeping it simple: | ||
| 1990 | * - one bus driver, initted first; | ||
| 1991 | * - one function driver, initted second | ||
| 1992 | * | ||
| 1993 | * most of the work to support multiple net2280 controllers would | ||
| 1994 | * be to associate this gadget driver (yes?) with all of them, or | ||
| 1995 | * perhaps to bind specific drivers to specific devices. | ||
| 1996 | */ | ||
| 1997 | |||
| 1998 | static void usb_reset_228x(struct net2280 *dev) | ||
| 1999 | { | ||
| 2000 | u32 tmp; | ||
| 2001 | |||
| 2002 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 2003 | (void) readl(&dev->usb->usbctl); | ||
| 2004 | |||
| 2005 | net2280_led_init(dev); | ||
| 2006 | |||
| 2007 | /* disable automatic responses, and irqs */ | ||
| 2008 | writel(0, &dev->usb->stdrsp); | ||
| 2009 | writel(0, &dev->regs->pciirqenb0); | ||
| 2010 | writel(0, &dev->regs->pciirqenb1); | ||
| 2011 | |||
| 2012 | /* clear old dma and irq state */ | ||
| 2013 | for (tmp = 0; tmp < 4; tmp++) { | ||
| 2014 | struct net2280_ep *ep = &dev->ep[tmp + 1]; | ||
| 2015 | if (ep->dma) | ||
| 2016 | abort_dma(ep); | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | writel(~0, &dev->regs->irqstat0), | ||
| 2020 | writel(~(u32)BIT(SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1), | ||
| 2021 | |||
| 2022 | /* reset, and enable pci */ | ||
| 2023 | tmp = readl(&dev->regs->devinit) | | ||
| 2024 | BIT(PCI_ENABLE) | | ||
| 2025 | BIT(FIFO_SOFT_RESET) | | ||
| 2026 | BIT(USB_SOFT_RESET) | | ||
| 2027 | BIT(M8051_RESET); | ||
| 2028 | writel(tmp, &dev->regs->devinit); | ||
| 2029 | |||
| 2030 | /* standard fifo and endpoint allocations */ | ||
| 2031 | set_fifo_mode(dev, (fifo_mode <= 2) ? fifo_mode : 0); | ||
| 2032 | } | ||
| 2033 | |||
| 2034 | static void usb_reset_338x(struct net2280 *dev) | ||
| 2035 | { | ||
| 2036 | u32 tmp; | ||
| 2037 | u32 fsmvalue; | ||
| 2038 | |||
| 2039 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 2040 | (void)readl(&dev->usb->usbctl); | ||
| 2041 | |||
| 2042 | net2280_led_init(dev); | ||
| 2043 | |||
| 2044 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
| 2045 | (0xf << DEFECT7374_FSM_FIELD); | ||
| 2046 | |||
| 2047 | /* See if firmware needs to set up for workaround: */ | ||
| 2048 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) { | ||
| 2049 | ep_info(dev, "%s: Defect 7374 FsmValue 0x%08x\n", __func__, | ||
| 2050 | fsmvalue); | ||
| 2051 | } else { | ||
| 2052 | /* disable automatic responses, and irqs */ | ||
| 2053 | writel(0, &dev->usb->stdrsp); | ||
| 2054 | writel(0, &dev->regs->pciirqenb0); | ||
| 2055 | writel(0, &dev->regs->pciirqenb1); | ||
| 2056 | } | ||
| 2057 | |||
| 2058 | /* clear old dma and irq state */ | ||
| 2059 | for (tmp = 0; tmp < 4; tmp++) { | ||
| 2060 | struct net2280_ep *ep = &dev->ep[tmp + 1]; | ||
| 2061 | |||
| 2062 | if (ep->dma) | ||
| 2063 | abort_dma(ep); | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1); | ||
| 2067 | |||
| 2068 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) { | ||
| 2069 | /* reset, and enable pci */ | ||
| 2070 | tmp = readl(&dev->regs->devinit) | | ||
| 2071 | BIT(PCI_ENABLE) | | ||
| 2072 | BIT(FIFO_SOFT_RESET) | | ||
| 2073 | BIT(USB_SOFT_RESET) | | ||
| 2074 | BIT(M8051_RESET); | ||
| 2075 | |||
| 2076 | writel(tmp, &dev->regs->devinit); | ||
| 2077 | } | ||
| 2078 | |||
| 2079 | /* always ep-{1,2,3,4} ... maybe not ep-3 or ep-4 */ | ||
| 2080 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
| 2081 | |||
| 2082 | for (tmp = 1; tmp < dev->n_ep; tmp++) | ||
| 2083 | list_add_tail(&dev->ep[tmp].ep.ep_list, &dev->gadget.ep_list); | ||
| 2084 | |||
| 2085 | } | ||
| 2086 | |||
| 2087 | static void usb_reset(struct net2280 *dev) | ||
| 2088 | { | ||
| 2089 | if (dev->quirks & PLX_LEGACY) | ||
| 2090 | return usb_reset_228x(dev); | ||
| 2091 | return usb_reset_338x(dev); | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | static void usb_reinit_228x(struct net2280 *dev) | ||
| 2095 | { | ||
| 2096 | u32 tmp; | ||
| 2097 | int init_dma; | ||
| 2098 | |||
| 2099 | /* use_dma changes are ignored till next device re-init */ | ||
| 2100 | init_dma = use_dma; | ||
| 2101 | |||
| 2102 | /* basic endpoint init */ | ||
| 2103 | for (tmp = 0; tmp < 7; tmp++) { | ||
| 2104 | struct net2280_ep *ep = &dev->ep[tmp]; | ||
| 2105 | |||
| 2106 | ep->ep.name = ep_name[tmp]; | ||
| 2107 | ep->dev = dev; | ||
| 2108 | ep->num = tmp; | ||
| 2109 | |||
| 2110 | if (tmp > 0 && tmp <= 4) { | ||
| 2111 | ep->fifo_size = 1024; | ||
| 2112 | if (init_dma) | ||
| 2113 | ep->dma = &dev->dma[tmp - 1]; | ||
| 2114 | } else | ||
| 2115 | ep->fifo_size = 64; | ||
| 2116 | ep->regs = &dev->epregs[tmp]; | ||
| 2117 | ep->cfg = &dev->epregs[tmp]; | ||
| 2118 | ep_reset_228x(dev->regs, ep); | ||
| 2119 | } | ||
| 2120 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 64); | ||
| 2121 | usb_ep_set_maxpacket_limit(&dev->ep[5].ep, 64); | ||
| 2122 | usb_ep_set_maxpacket_limit(&dev->ep[6].ep, 64); | ||
| 2123 | |||
| 2124 | dev->gadget.ep0 = &dev->ep[0].ep; | ||
| 2125 | dev->ep[0].stopped = 0; | ||
| 2126 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
| 2127 | |||
| 2128 | /* we want to prevent lowlevel/insecure access from the USB host, | ||
| 2129 | * but erratum 0119 means this enable bit is ignored | ||
| 2130 | */ | ||
| 2131 | for (tmp = 0; tmp < 5; tmp++) | ||
| 2132 | writel(EP_DONTUSE, &dev->dep[tmp].dep_cfg); | ||
| 2133 | } | ||
| 2134 | |||
| 2135 | static void usb_reinit_338x(struct net2280 *dev) | ||
| 2136 | { | ||
| 2137 | int init_dma; | ||
| 2138 | int i; | ||
| 2139 | u32 tmp, val; | ||
| 2140 | u32 fsmvalue; | ||
| 2141 | static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 }; | ||
| 2142 | static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00, | ||
| 2143 | 0x00, 0xC0, 0x00, 0xC0 }; | ||
| 2144 | |||
| 2145 | /* use_dma changes are ignored till next device re-init */ | ||
| 2146 | init_dma = use_dma; | ||
| 2147 | |||
| 2148 | /* basic endpoint init */ | ||
| 2149 | for (i = 0; i < dev->n_ep; i++) { | ||
| 2150 | struct net2280_ep *ep = &dev->ep[i]; | ||
| 2151 | |||
| 2152 | ep->ep.name = ep_name[i]; | ||
| 2153 | ep->dev = dev; | ||
| 2154 | ep->num = i; | ||
| 2155 | |||
| 2156 | if (i > 0 && i <= 4 && init_dma) | ||
| 2157 | ep->dma = &dev->dma[i - 1]; | ||
| 2158 | |||
| 2159 | if (dev->enhanced_mode) { | ||
| 2160 | ep->cfg = &dev->epregs[ne[i]]; | ||
| 2161 | ep->regs = (struct net2280_ep_regs __iomem *) | ||
| 2162 | (((void __iomem *)&dev->epregs[ne[i]]) + | ||
| 2163 | ep_reg_addr[i]); | ||
| 2164 | ep->fiforegs = &dev->fiforegs[i]; | ||
| 2165 | } else { | ||
| 2166 | ep->cfg = &dev->epregs[i]; | ||
| 2167 | ep->regs = &dev->epregs[i]; | ||
| 2168 | ep->fiforegs = &dev->fiforegs[i]; | ||
| 2169 | } | ||
| 2170 | |||
| 2171 | ep->fifo_size = (i != 0) ? 2048 : 512; | ||
| 2172 | |||
| 2173 | ep_reset_338x(dev->regs, ep); | ||
| 2174 | } | ||
| 2175 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 512); | ||
| 2176 | |||
| 2177 | dev->gadget.ep0 = &dev->ep[0].ep; | ||
| 2178 | dev->ep[0].stopped = 0; | ||
| 2179 | |||
| 2180 | /* Link layer set up */ | ||
| 2181 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
| 2182 | (0xf << DEFECT7374_FSM_FIELD); | ||
| 2183 | |||
| 2184 | /* See if driver needs to set up for workaround: */ | ||
| 2185 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) | ||
| 2186 | ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", | ||
| 2187 | __func__, fsmvalue); | ||
| 2188 | else { | ||
| 2189 | tmp = readl(&dev->usb_ext->usbctl2) & | ||
| 2190 | ~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE)); | ||
| 2191 | writel(tmp, &dev->usb_ext->usbctl2); | ||
| 2192 | } | ||
| 2193 | |||
| 2194 | /* Hardware Defect and Workaround */ | ||
| 2195 | val = readl(&dev->ll_lfps_regs->ll_lfps_5); | ||
| 2196 | val &= ~(0xf << TIMER_LFPS_6US); | ||
| 2197 | val |= 0x5 << TIMER_LFPS_6US; | ||
| 2198 | writel(val, &dev->ll_lfps_regs->ll_lfps_5); | ||
| 2199 | |||
| 2200 | val = readl(&dev->ll_lfps_regs->ll_lfps_6); | ||
| 2201 | val &= ~(0xffff << TIMER_LFPS_80US); | ||
| 2202 | val |= 0x0100 << TIMER_LFPS_80US; | ||
| 2203 | writel(val, &dev->ll_lfps_regs->ll_lfps_6); | ||
| 2204 | |||
| 2205 | /* | ||
| 2206 | * AA_AB Errata. Issue 4. Workaround for SuperSpeed USB | ||
| 2207 | * Hot Reset Exit Handshake may Fail in Specific Case using | ||
| 2208 | * Default Register Settings. Workaround for Enumeration test. | ||
| 2209 | */ | ||
| 2210 | val = readl(&dev->ll_tsn_regs->ll_tsn_counters_2); | ||
| 2211 | val &= ~(0x1f << HOT_TX_NORESET_TS2); | ||
| 2212 | val |= 0x10 << HOT_TX_NORESET_TS2; | ||
| 2213 | writel(val, &dev->ll_tsn_regs->ll_tsn_counters_2); | ||
| 2214 | |||
| 2215 | val = readl(&dev->ll_tsn_regs->ll_tsn_counters_3); | ||
| 2216 | val &= ~(0x1f << HOT_RX_RESET_TS2); | ||
| 2217 | val |= 0x3 << HOT_RX_RESET_TS2; | ||
| 2218 | writel(val, &dev->ll_tsn_regs->ll_tsn_counters_3); | ||
| 2219 | |||
| 2220 | /* | ||
| 2221 | * Set Recovery Idle to Recover bit: | ||
| 2222 | * - On SS connections, setting Recovery Idle to Recover Fmw improves | ||
| 2223 | * link robustness with various hosts and hubs. | ||
| 2224 | * - It is safe to set for all connection speeds; all chip revisions. | ||
| 2225 | * - R-M-W to leave other bits undisturbed. | ||
| 2226 | * - Reference PLX TT-7372 | ||
| 2227 | */ | ||
| 2228 | val = readl(&dev->ll_chicken_reg->ll_tsn_chicken_bit); | ||
| 2229 | val |= BIT(RECOVERY_IDLE_TO_RECOVER_FMW); | ||
| 2230 | writel(val, &dev->ll_chicken_reg->ll_tsn_chicken_bit); | ||
| 2231 | |||
| 2232 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
| 2233 | |||
| 2234 | /* disable dedicated endpoints */ | ||
| 2235 | writel(0x0D, &dev->dep[0].dep_cfg); | ||
| 2236 | writel(0x0D, &dev->dep[1].dep_cfg); | ||
| 2237 | writel(0x0E, &dev->dep[2].dep_cfg); | ||
| 2238 | writel(0x0E, &dev->dep[3].dep_cfg); | ||
| 2239 | writel(0x0F, &dev->dep[4].dep_cfg); | ||
| 2240 | writel(0x0C, &dev->dep[5].dep_cfg); | ||
| 2241 | } | ||
| 2242 | |||
| 2243 | static void usb_reinit(struct net2280 *dev) | ||
| 2244 | { | ||
| 2245 | if (dev->quirks & PLX_LEGACY) | ||
| 2246 | return usb_reinit_228x(dev); | ||
| 2247 | return usb_reinit_338x(dev); | ||
| 2248 | } | ||
| 2249 | |||
| 2250 | static void ep0_start_228x(struct net2280 *dev) | ||
| 2251 | { | ||
| 2252 | writel(BIT(CLEAR_EP_HIDE_STATUS_PHASE) | | ||
| 2253 | BIT(CLEAR_NAK_OUT_PACKETS) | | ||
| 2254 | BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE), | ||
| 2255 | &dev->epregs[0].ep_rsp); | ||
| 2256 | |||
| 2257 | /* | ||
| 2258 | * hardware optionally handles a bunch of standard requests | ||
| 2259 | * that the API hides from drivers anyway. have it do so. | ||
| 2260 | * endpoint status/features are handled in software, to | ||
| 2261 | * help pass tests for some dubious behavior. | ||
| 2262 | */ | ||
| 2263 | writel(BIT(SET_TEST_MODE) | | ||
| 2264 | BIT(SET_ADDRESS) | | ||
| 2265 | BIT(DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP) | | ||
| 2266 | BIT(GET_DEVICE_STATUS) | | ||
| 2267 | BIT(GET_INTERFACE_STATUS), | ||
| 2268 | &dev->usb->stdrsp); | ||
| 2269 | writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) | | ||
| 2270 | BIT(SELF_POWERED_USB_DEVICE) | | ||
| 2271 | BIT(REMOTE_WAKEUP_SUPPORT) | | ||
| 2272 | (dev->softconnect << USB_DETECT_ENABLE) | | ||
| 2273 | BIT(SELF_POWERED_STATUS), | ||
| 2274 | &dev->usb->usbctl); | ||
| 2275 | |||
| 2276 | /* enable irqs so we can see ep0 and general operation */ | ||
| 2277 | writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) | | ||
| 2278 | BIT(ENDPOINT_0_INTERRUPT_ENABLE), | ||
| 2279 | &dev->regs->pciirqenb0); | ||
| 2280 | writel(BIT(PCI_INTERRUPT_ENABLE) | | ||
| 2281 | BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE) | | ||
| 2282 | BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE) | | ||
| 2283 | BIT(PCI_RETRY_ABORT_INTERRUPT_ENABLE) | | ||
| 2284 | BIT(VBUS_INTERRUPT_ENABLE) | | ||
| 2285 | BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) | | ||
| 2286 | BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE), | ||
| 2287 | &dev->regs->pciirqenb1); | ||
| 2288 | |||
| 2289 | /* don't leave any writes posted */ | ||
| 2290 | (void) readl(&dev->usb->usbctl); | ||
| 2291 | } | ||
| 2292 | |||
| 2293 | static void ep0_start_338x(struct net2280 *dev) | ||
| 2294 | { | ||
| 2295 | u32 fsmvalue; | ||
| 2296 | |||
| 2297 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
| 2298 | (0xf << DEFECT7374_FSM_FIELD); | ||
| 2299 | |||
| 2300 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) | ||
| 2301 | ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", __func__, | ||
| 2302 | fsmvalue); | ||
| 2303 | else | ||
| 2304 | writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) | | ||
| 2305 | BIT(SET_EP_HIDE_STATUS_PHASE), | ||
| 2306 | &dev->epregs[0].ep_rsp); | ||
| 2307 | |||
| 2308 | /* | ||
| 2309 | * hardware optionally handles a bunch of standard requests | ||
| 2310 | * that the API hides from drivers anyway. have it do so. | ||
| 2311 | * endpoint status/features are handled in software, to | ||
| 2312 | * help pass tests for some dubious behavior. | ||
| 2313 | */ | ||
| 2314 | writel(BIT(SET_ISOCHRONOUS_DELAY) | | ||
| 2315 | BIT(SET_SEL) | | ||
| 2316 | BIT(SET_TEST_MODE) | | ||
| 2317 | BIT(SET_ADDRESS) | | ||
| 2318 | BIT(GET_INTERFACE_STATUS) | | ||
| 2319 | BIT(GET_DEVICE_STATUS), | ||
| 2320 | &dev->usb->stdrsp); | ||
| 2321 | dev->wakeup_enable = 1; | ||
| 2322 | writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) | | ||
| 2323 | (dev->softconnect << USB_DETECT_ENABLE) | | ||
| 2324 | BIT(DEVICE_REMOTE_WAKEUP_ENABLE), | ||
| 2325 | &dev->usb->usbctl); | ||
| 2326 | |||
| 2327 | /* enable irqs so we can see ep0 and general operation */ | ||
| 2328 | writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) | | ||
| 2329 | BIT(ENDPOINT_0_INTERRUPT_ENABLE), | ||
| 2330 | &dev->regs->pciirqenb0); | ||
| 2331 | writel(BIT(PCI_INTERRUPT_ENABLE) | | ||
| 2332 | BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) | | ||
| 2333 | BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) | | ||
| 2334 | BIT(VBUS_INTERRUPT_ENABLE), | ||
| 2335 | &dev->regs->pciirqenb1); | ||
| 2336 | |||
| 2337 | /* don't leave any writes posted */ | ||
| 2338 | (void)readl(&dev->usb->usbctl); | ||
| 2339 | } | ||
| 2340 | |||
| 2341 | static void ep0_start(struct net2280 *dev) | ||
| 2342 | { | ||
| 2343 | if (dev->quirks & PLX_LEGACY) | ||
| 2344 | return ep0_start_228x(dev); | ||
| 2345 | return ep0_start_338x(dev); | ||
| 2346 | } | ||
| 2347 | |||
| 2348 | /* when a driver is successfully registered, it will receive | ||
| 2349 | * control requests including set_configuration(), which enables | ||
| 2350 | * non-control requests. then usb traffic follows until a | ||
| 2351 | * disconnect is reported. then a host may connect again, or | ||
| 2352 | * the driver might get unbound. | ||
| 2353 | */ | ||
| 2354 | static int net2280_start(struct usb_gadget *_gadget, | ||
| 2355 | struct usb_gadget_driver *driver) | ||
| 2356 | { | ||
| 2357 | struct net2280 *dev; | ||
| 2358 | int retval; | ||
| 2359 | unsigned i; | ||
| 2360 | |||
| 2361 | /* insist on high speed support from the driver, since | ||
| 2362 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) | ||
| 2363 | * "must not be used in normal operation" | ||
| 2364 | */ | ||
| 2365 | if (!driver || driver->max_speed < USB_SPEED_HIGH || | ||
| 2366 | !driver->setup) | ||
| 2367 | return -EINVAL; | ||
| 2368 | |||
| 2369 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 2370 | |||
| 2371 | for (i = 0; i < dev->n_ep; i++) | ||
| 2372 | dev->ep[i].irqs = 0; | ||
| 2373 | |||
| 2374 | /* hook up the driver ... */ | ||
| 2375 | dev->softconnect = 1; | ||
| 2376 | driver->driver.bus = NULL; | ||
| 2377 | dev->driver = driver; | ||
| 2378 | |||
| 2379 | retval = device_create_file(&dev->pdev->dev, &dev_attr_function); | ||
| 2380 | if (retval) | ||
| 2381 | goto err_unbind; | ||
| 2382 | retval = device_create_file(&dev->pdev->dev, &dev_attr_queues); | ||
| 2383 | if (retval) | ||
| 2384 | goto err_func; | ||
| 2385 | |||
| 2386 | /* Enable force-full-speed testing mode, if desired */ | ||
| 2387 | if (full_speed && (dev->quirks & PLX_LEGACY)) | ||
| 2388 | writel(BIT(FORCE_FULL_SPEED_MODE), &dev->usb->xcvrdiag); | ||
| 2389 | |||
| 2390 | /* ... then enable host detection and ep0; and we're ready | ||
| 2391 | * for set_configuration as well as eventual disconnect. | ||
| 2392 | */ | ||
| 2393 | net2280_led_active(dev, 1); | ||
| 2394 | |||
| 2395 | if (dev->quirks & PLX_SUPERSPEED) | ||
| 2396 | defect7374_enable_data_eps_zero(dev); | ||
| 2397 | |||
| 2398 | ep0_start(dev); | ||
| 2399 | |||
| 2400 | ep_dbg(dev, "%s ready, usbctl %08x stdrsp %08x\n", | ||
| 2401 | driver->driver.name, | ||
| 2402 | readl(&dev->usb->usbctl), | ||
| 2403 | readl(&dev->usb->stdrsp)); | ||
| 2404 | |||
| 2405 | /* pci writes may still be posted */ | ||
| 2406 | return 0; | ||
| 2407 | |||
| 2408 | err_func: | ||
| 2409 | device_remove_file(&dev->pdev->dev, &dev_attr_function); | ||
| 2410 | err_unbind: | ||
| 2411 | dev->driver = NULL; | ||
| 2412 | return retval; | ||
| 2413 | } | ||
| 2414 | |||
| 2415 | static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver) | ||
| 2416 | { | ||
| 2417 | int i; | ||
| 2418 | |||
| 2419 | /* don't disconnect if it's not connected */ | ||
| 2420 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 2421 | driver = NULL; | ||
| 2422 | |||
| 2423 | /* stop hardware; prevent new request submissions; | ||
| 2424 | * and kill any outstanding requests. | ||
| 2425 | */ | ||
| 2426 | usb_reset(dev); | ||
| 2427 | for (i = 0; i < dev->n_ep; i++) | ||
| 2428 | nuke(&dev->ep[i]); | ||
| 2429 | |||
| 2430 | /* report disconnect; the driver is already quiesced */ | ||
| 2431 | if (driver) { | ||
| 2432 | spin_unlock(&dev->lock); | ||
| 2433 | driver->disconnect(&dev->gadget); | ||
| 2434 | spin_lock(&dev->lock); | ||
| 2435 | } | ||
| 2436 | |||
| 2437 | usb_reinit(dev); | ||
| 2438 | } | ||
| 2439 | |||
| 2440 | static int net2280_stop(struct usb_gadget *_gadget, | ||
| 2441 | struct usb_gadget_driver *driver) | ||
| 2442 | { | ||
| 2443 | struct net2280 *dev; | ||
| 2444 | unsigned long flags; | ||
| 2445 | |||
| 2446 | dev = container_of(_gadget, struct net2280, gadget); | ||
| 2447 | |||
| 2448 | spin_lock_irqsave(&dev->lock, flags); | ||
| 2449 | stop_activity(dev, driver); | ||
| 2450 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 2451 | |||
| 2452 | dev->driver = NULL; | ||
| 2453 | |||
| 2454 | net2280_led_active(dev, 0); | ||
| 2455 | |||
| 2456 | /* Disable full-speed test mode */ | ||
| 2457 | if (dev->quirks & PLX_LEGACY) | ||
| 2458 | writel(0, &dev->usb->xcvrdiag); | ||
| 2459 | |||
| 2460 | device_remove_file(&dev->pdev->dev, &dev_attr_function); | ||
| 2461 | device_remove_file(&dev->pdev->dev, &dev_attr_queues); | ||
| 2462 | |||
| 2463 | ep_dbg(dev, "unregistered driver '%s'\n", | ||
| 2464 | driver ? driver->driver.name : ""); | ||
| 2465 | |||
| 2466 | return 0; | ||
| 2467 | } | ||
| 2468 | |||
| 2469 | /*-------------------------------------------------------------------------*/ | ||
| 2470 | |||
| 2471 | /* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq. | ||
| 2472 | * also works for dma-capable endpoints, in pio mode or just | ||
| 2473 | * to manually advance the queue after short OUT transfers. | ||
| 2474 | */ | ||
| 2475 | static void handle_ep_small(struct net2280_ep *ep) | ||
| 2476 | { | ||
| 2477 | struct net2280_request *req; | ||
| 2478 | u32 t; | ||
| 2479 | /* 0 error, 1 mid-data, 2 done */ | ||
| 2480 | int mode = 1; | ||
| 2481 | |||
| 2482 | if (!list_empty(&ep->queue)) | ||
| 2483 | req = list_entry(ep->queue.next, | ||
| 2484 | struct net2280_request, queue); | ||
| 2485 | else | ||
| 2486 | req = NULL; | ||
| 2487 | |||
| 2488 | /* ack all, and handle what we care about */ | ||
| 2489 | t = readl(&ep->regs->ep_stat); | ||
| 2490 | ep->irqs++; | ||
| 2491 | #if 0 | ||
| 2492 | ep_vdbg(ep->dev, "%s ack ep_stat %08x, req %p\n", | ||
| 2493 | ep->ep.name, t, req ? &req->req : 0); | ||
| 2494 | #endif | ||
| 2495 | if (!ep->is_in || (ep->dev->quirks & PLX_2280)) | ||
| 2496 | writel(t & ~BIT(NAK_OUT_PACKETS), &ep->regs->ep_stat); | ||
| 2497 | else | ||
| 2498 | /* Added for 2282 */ | ||
| 2499 | writel(t, &ep->regs->ep_stat); | ||
| 2500 | |||
| 2501 | /* for ep0, monitor token irqs to catch data stage length errors | ||
| 2502 | * and to synchronize on status. | ||
| 2503 | * | ||
| 2504 | * also, to defer reporting of protocol stalls ... here's where | ||
| 2505 | * data or status first appears, handling stalls here should never | ||
| 2506 | * cause trouble on the host side.. | ||
| 2507 | * | ||
| 2508 | * control requests could be slightly faster without token synch for | ||
| 2509 | * status, but status can jam up that way. | ||
| 2510 | */ | ||
| 2511 | if (unlikely(ep->num == 0)) { | ||
| 2512 | if (ep->is_in) { | ||
| 2513 | /* status; stop NAKing */ | ||
| 2514 | if (t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) { | ||
| 2515 | if (ep->dev->protocol_stall) { | ||
| 2516 | ep->stopped = 1; | ||
| 2517 | set_halt(ep); | ||
| 2518 | } | ||
| 2519 | if (!req) | ||
| 2520 | allow_status(ep); | ||
| 2521 | mode = 2; | ||
| 2522 | /* reply to extra IN data tokens with a zlp */ | ||
| 2523 | } else if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) { | ||
| 2524 | if (ep->dev->protocol_stall) { | ||
| 2525 | ep->stopped = 1; | ||
| 2526 | set_halt(ep); | ||
| 2527 | mode = 2; | ||
| 2528 | } else if (ep->responded && | ||
| 2529 | !req && !ep->stopped) | ||
| 2530 | write_fifo(ep, NULL); | ||
| 2531 | } | ||
| 2532 | } else { | ||
| 2533 | /* status; stop NAKing */ | ||
| 2534 | if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) { | ||
| 2535 | if (ep->dev->protocol_stall) { | ||
| 2536 | ep->stopped = 1; | ||
| 2537 | set_halt(ep); | ||
| 2538 | } | ||
| 2539 | mode = 2; | ||
| 2540 | /* an extra OUT token is an error */ | ||
| 2541 | } else if (((t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) && | ||
| 2542 | req && | ||
| 2543 | req->req.actual == req->req.length) || | ||
| 2544 | (ep->responded && !req)) { | ||
| 2545 | ep->dev->protocol_stall = 1; | ||
| 2546 | set_halt(ep); | ||
| 2547 | ep->stopped = 1; | ||
| 2548 | if (req) | ||
| 2549 | done(ep, req, -EOVERFLOW); | ||
| 2550 | req = NULL; | ||
| 2551 | } | ||
| 2552 | } | ||
| 2553 | } | ||
| 2554 | |||
| 2555 | if (unlikely(!req)) | ||
| 2556 | return; | ||
| 2557 | |||
| 2558 | /* manual DMA queue advance after short OUT */ | ||
| 2559 | if (likely(ep->dma)) { | ||
| 2560 | if (t & BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT)) { | ||
| 2561 | u32 count; | ||
| 2562 | int stopped = ep->stopped; | ||
| 2563 | |||
| 2564 | /* TRANSFERRED works around OUT_DONE erratum 0112. | ||
| 2565 | * we expect (N <= maxpacket) bytes; host wrote M. | ||
| 2566 | * iff (M < N) we won't ever see a DMA interrupt. | ||
| 2567 | */ | ||
| 2568 | ep->stopped = 1; | ||
| 2569 | for (count = 0; ; t = readl(&ep->regs->ep_stat)) { | ||
| 2570 | |||
| 2571 | /* any preceding dma transfers must finish. | ||
| 2572 | * dma handles (M >= N), may empty the queue | ||
| 2573 | */ | ||
| 2574 | scan_dma_completions(ep); | ||
| 2575 | if (unlikely(list_empty(&ep->queue) || | ||
| 2576 | ep->out_overflow)) { | ||
| 2577 | req = NULL; | ||
| 2578 | break; | ||
| 2579 | } | ||
| 2580 | req = list_entry(ep->queue.next, | ||
| 2581 | struct net2280_request, queue); | ||
| 2582 | |||
| 2583 | /* here either (M < N), a "real" short rx; | ||
| 2584 | * or (M == N) and the queue didn't empty | ||
| 2585 | */ | ||
| 2586 | if (likely(t & BIT(FIFO_EMPTY))) { | ||
| 2587 | count = readl(&ep->dma->dmacount); | ||
| 2588 | count &= DMA_BYTE_COUNT_MASK; | ||
| 2589 | if (readl(&ep->dma->dmadesc) | ||
| 2590 | != req->td_dma) | ||
| 2591 | req = NULL; | ||
| 2592 | break; | ||
| 2593 | } | ||
| 2594 | udelay(1); | ||
| 2595 | } | ||
| 2596 | |||
| 2597 | /* stop DMA, leave ep NAKing */ | ||
| 2598 | writel(BIT(DMA_ABORT), &ep->dma->dmastat); | ||
| 2599 | spin_stop_dma(ep->dma); | ||
| 2600 | |||
| 2601 | if (likely(req)) { | ||
| 2602 | req->td->dmacount = 0; | ||
| 2603 | t = readl(&ep->regs->ep_avail); | ||
| 2604 | dma_done(ep, req, count, | ||
| 2605 | (ep->out_overflow || t) | ||
| 2606 | ? -EOVERFLOW : 0); | ||
| 2607 | } | ||
| 2608 | |||
| 2609 | /* also flush to prevent erratum 0106 trouble */ | ||
| 2610 | if (unlikely(ep->out_overflow || | ||
| 2611 | (ep->dev->chiprev == 0x0100 && | ||
| 2612 | ep->dev->gadget.speed | ||
| 2613 | == USB_SPEED_FULL))) { | ||
| 2614 | out_flush(ep); | ||
| 2615 | ep->out_overflow = 0; | ||
| 2616 | } | ||
| 2617 | |||
| 2618 | /* (re)start dma if needed, stop NAKing */ | ||
| 2619 | ep->stopped = stopped; | ||
| 2620 | if (!list_empty(&ep->queue)) | ||
| 2621 | restart_dma(ep); | ||
| 2622 | } else | ||
| 2623 | ep_dbg(ep->dev, "%s dma ep_stat %08x ??\n", | ||
| 2624 | ep->ep.name, t); | ||
| 2625 | return; | ||
| 2626 | |||
| 2627 | /* data packet(s) received (in the fifo, OUT) */ | ||
| 2628 | } else if (t & BIT(DATA_PACKET_RECEIVED_INTERRUPT)) { | ||
| 2629 | if (read_fifo(ep, req) && ep->num != 0) | ||
| 2630 | mode = 2; | ||
| 2631 | |||
| 2632 | /* data packet(s) transmitted (IN) */ | ||
| 2633 | } else if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT)) { | ||
| 2634 | unsigned len; | ||
| 2635 | |||
| 2636 | len = req->req.length - req->req.actual; | ||
| 2637 | if (len > ep->ep.maxpacket) | ||
| 2638 | len = ep->ep.maxpacket; | ||
| 2639 | req->req.actual += len; | ||
| 2640 | |||
| 2641 | /* if we wrote it all, we're usually done */ | ||
| 2642 | /* send zlps until the status stage */ | ||
| 2643 | if ((req->req.actual == req->req.length) && | ||
| 2644 | (!req->req.zero || len != ep->ep.maxpacket) && ep->num) | ||
| 2645 | mode = 2; | ||
| 2646 | |||
| 2647 | /* there was nothing to do ... */ | ||
| 2648 | } else if (mode == 1) | ||
| 2649 | return; | ||
| 2650 | |||
| 2651 | /* done */ | ||
| 2652 | if (mode == 2) { | ||
| 2653 | /* stream endpoints often resubmit/unlink in completion */ | ||
| 2654 | done(ep, req, 0); | ||
| 2655 | |||
| 2656 | /* maybe advance queue to next request */ | ||
| 2657 | if (ep->num == 0) { | ||
| 2658 | /* NOTE: net2280 could let gadget driver start the | ||
| 2659 | * status stage later. since not all controllers let | ||
| 2660 | * them control that, the api doesn't (yet) allow it. | ||
| 2661 | */ | ||
| 2662 | if (!ep->stopped) | ||
| 2663 | allow_status(ep); | ||
| 2664 | req = NULL; | ||
| 2665 | } else { | ||
| 2666 | if (!list_empty(&ep->queue) && !ep->stopped) | ||
| 2667 | req = list_entry(ep->queue.next, | ||
| 2668 | struct net2280_request, queue); | ||
| 2669 | else | ||
| 2670 | req = NULL; | ||
| 2671 | if (req && !ep->is_in) | ||
| 2672 | stop_out_naking(ep); | ||
| 2673 | } | ||
| 2674 | } | ||
| 2675 | |||
| 2676 | /* is there a buffer for the next packet? | ||
| 2677 | * for best streaming performance, make sure there is one. | ||
| 2678 | */ | ||
| 2679 | if (req && !ep->stopped) { | ||
| 2680 | |||
| 2681 | /* load IN fifo with next packet (may be zlp) */ | ||
| 2682 | if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT)) | ||
| 2683 | write_fifo(ep, &req->req); | ||
| 2684 | } | ||
| 2685 | } | ||
| 2686 | |||
| 2687 | static struct net2280_ep *get_ep_by_addr(struct net2280 *dev, u16 wIndex) | ||
| 2688 | { | ||
| 2689 | struct net2280_ep *ep; | ||
| 2690 | |||
| 2691 | if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) | ||
| 2692 | return &dev->ep[0]; | ||
| 2693 | list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) { | ||
| 2694 | u8 bEndpointAddress; | ||
| 2695 | |||
| 2696 | if (!ep->desc) | ||
| 2697 | continue; | ||
| 2698 | bEndpointAddress = ep->desc->bEndpointAddress; | ||
| 2699 | if ((wIndex ^ bEndpointAddress) & USB_DIR_IN) | ||
| 2700 | continue; | ||
| 2701 | if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f)) | ||
| 2702 | return ep; | ||
| 2703 | } | ||
| 2704 | return NULL; | ||
| 2705 | } | ||
| 2706 | |||
| 2707 | static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r) | ||
| 2708 | { | ||
| 2709 | u32 scratch, fsmvalue; | ||
| 2710 | u32 ack_wait_timeout, state; | ||
| 2711 | |||
| 2712 | /* Workaround for Defect 7374 (U1/U2 erroneously rejected): */ | ||
| 2713 | scratch = get_idx_reg(dev->regs, SCRATCH); | ||
| 2714 | fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD); | ||
| 2715 | scratch &= ~(0xf << DEFECT7374_FSM_FIELD); | ||
| 2716 | |||
| 2717 | if (!((fsmvalue == DEFECT7374_FSM_WAITING_FOR_CONTROL_READ) && | ||
| 2718 | (r.bRequestType & USB_DIR_IN))) | ||
| 2719 | return; | ||
| 2720 | |||
| 2721 | /* This is the first Control Read for this connection: */ | ||
| 2722 | if (!(readl(&dev->usb->usbstat) & BIT(SUPER_SPEED_MODE))) { | ||
| 2723 | /* | ||
| 2724 | * Connection is NOT SS: | ||
| 2725 | * - Connection must be FS or HS. | ||
| 2726 | * - This FSM state should allow workaround software to | ||
| 2727 | * run after the next USB connection. | ||
| 2728 | */ | ||
| 2729 | scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ; | ||
| 2730 | goto restore_data_eps; | ||
| 2731 | } | ||
| 2732 | |||
| 2733 | /* Connection is SS: */ | ||
| 2734 | for (ack_wait_timeout = 0; | ||
| 2735 | ack_wait_timeout < DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS; | ||
| 2736 | ack_wait_timeout++) { | ||
| 2737 | |||
| 2738 | state = readl(&dev->plregs->pl_ep_status_1) | ||
| 2739 | & (0xff << STATE); | ||
| 2740 | if ((state >= (ACK_GOOD_NORMAL << STATE)) && | ||
| 2741 | (state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) { | ||
| 2742 | scratch |= DEFECT7374_FSM_SS_CONTROL_READ; | ||
| 2743 | break; | ||
| 2744 | } | ||
| 2745 | |||
| 2746 | /* | ||
| 2747 | * We have not yet received host's Data Phase ACK | ||
| 2748 | * - Wait and try again. | ||
| 2749 | */ | ||
| 2750 | udelay(DEFECT_7374_PROCESSOR_WAIT_TIME); | ||
| 2751 | |||
| 2752 | continue; | ||
| 2753 | } | ||
| 2754 | |||
| 2755 | |||
| 2756 | if (ack_wait_timeout >= DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS) { | ||
| 2757 | ep_err(dev, "FAIL: Defect 7374 workaround waited but failed " | ||
| 2758 | "to detect SS host's data phase ACK."); | ||
| 2759 | ep_err(dev, "PL_EP_STATUS_1(23:16):.Expected from 0x11 to 0x16" | ||
| 2760 | "got 0x%2.2x.\n", state >> STATE); | ||
| 2761 | } else { | ||
| 2762 | ep_warn(dev, "INFO: Defect 7374 workaround waited about\n" | ||
| 2763 | "%duSec for Control Read Data Phase ACK\n", | ||
| 2764 | DEFECT_7374_PROCESSOR_WAIT_TIME * ack_wait_timeout); | ||
| 2765 | } | ||
| 2766 | |||
| 2767 | restore_data_eps: | ||
| 2768 | /* | ||
| 2769 | * Restore data EPs to their pre-workaround settings (disabled, | ||
| 2770 | * initialized, and other details). | ||
| 2771 | */ | ||
| 2772 | defect7374_disable_data_eps(dev); | ||
| 2773 | |||
| 2774 | set_idx_reg(dev->regs, SCRATCH, scratch); | ||
| 2775 | |||
| 2776 | return; | ||
| 2777 | } | ||
| 2778 | |||
| 2779 | static void ep_stall(struct net2280_ep *ep, int stall) | ||
| 2780 | { | ||
| 2781 | struct net2280 *dev = ep->dev; | ||
| 2782 | u32 val; | ||
| 2783 | static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 }; | ||
| 2784 | |||
| 2785 | if (stall) { | ||
| 2786 | writel(BIT(SET_ENDPOINT_HALT) | | ||
| 2787 | /* BIT(SET_NAK_PACKETS) | */ | ||
| 2788 | BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE), | ||
| 2789 | &ep->regs->ep_rsp); | ||
| 2790 | ep->is_halt = 1; | ||
| 2791 | } else { | ||
| 2792 | if (dev->gadget.speed == USB_SPEED_SUPER) { | ||
| 2793 | /* | ||
| 2794 | * Workaround for SS SeqNum not cleared via | ||
| 2795 | * Endpoint Halt (Clear) bit. select endpoint | ||
| 2796 | */ | ||
| 2797 | val = readl(&dev->plregs->pl_ep_ctrl); | ||
| 2798 | val = (val & ~0x1f) | ep_pl[ep->num]; | ||
| 2799 | writel(val, &dev->plregs->pl_ep_ctrl); | ||
| 2800 | |||
| 2801 | val |= BIT(SEQUENCE_NUMBER_RESET); | ||
| 2802 | writel(val, &dev->plregs->pl_ep_ctrl); | ||
| 2803 | } | ||
| 2804 | val = readl(&ep->regs->ep_rsp); | ||
| 2805 | val |= BIT(CLEAR_ENDPOINT_HALT) | | ||
| 2806 | BIT(CLEAR_ENDPOINT_TOGGLE); | ||
| 2807 | writel(val, | ||
| 2808 | /* | BIT(CLEAR_NAK_PACKETS),*/ | ||
| 2809 | &ep->regs->ep_rsp); | ||
| 2810 | ep->is_halt = 0; | ||
| 2811 | val = readl(&ep->regs->ep_rsp); | ||
| 2812 | } | ||
| 2813 | } | ||
| 2814 | |||
| 2815 | static void ep_stdrsp(struct net2280_ep *ep, int value, int wedged) | ||
| 2816 | { | ||
| 2817 | /* set/clear, then synch memory views with the device */ | ||
| 2818 | if (value) { | ||
| 2819 | ep->stopped = 1; | ||
| 2820 | if (ep->num == 0) | ||
| 2821 | ep->dev->protocol_stall = 1; | ||
| 2822 | else { | ||
| 2823 | if (ep->dma) | ||
| 2824 | ep_stop_dma(ep); | ||
| 2825 | ep_stall(ep, true); | ||
| 2826 | } | ||
| 2827 | |||
| 2828 | if (wedged) | ||
| 2829 | ep->wedged = 1; | ||
| 2830 | } else { | ||
| 2831 | ep->stopped = 0; | ||
| 2832 | ep->wedged = 0; | ||
| 2833 | |||
| 2834 | ep_stall(ep, false); | ||
| 2835 | |||
| 2836 | /* Flush the queue */ | ||
| 2837 | if (!list_empty(&ep->queue)) { | ||
| 2838 | struct net2280_request *req = | ||
| 2839 | list_entry(ep->queue.next, struct net2280_request, | ||
| 2840 | queue); | ||
| 2841 | if (ep->dma) | ||
| 2842 | resume_dma(ep); | ||
| 2843 | else { | ||
| 2844 | if (ep->is_in) | ||
| 2845 | write_fifo(ep, &req->req); | ||
| 2846 | else { | ||
| 2847 | if (read_fifo(ep, req)) | ||
| 2848 | done(ep, req, 0); | ||
| 2849 | } | ||
| 2850 | } | ||
| 2851 | } | ||
| 2852 | } | ||
| 2853 | } | ||
| 2854 | |||
| 2855 | static void handle_stat0_irqs_superspeed(struct net2280 *dev, | ||
| 2856 | struct net2280_ep *ep, struct usb_ctrlrequest r) | ||
| 2857 | { | ||
| 2858 | int tmp = 0; | ||
| 2859 | |||
| 2860 | #define w_value le16_to_cpu(r.wValue) | ||
| 2861 | #define w_index le16_to_cpu(r.wIndex) | ||
| 2862 | #define w_length le16_to_cpu(r.wLength) | ||
| 2863 | |||
| 2864 | switch (r.bRequest) { | ||
| 2865 | struct net2280_ep *e; | ||
| 2866 | u16 status; | ||
| 2867 | |||
| 2868 | case USB_REQ_SET_CONFIGURATION: | ||
| 2869 | dev->addressed_state = !w_value; | ||
| 2870 | goto usb3_delegate; | ||
| 2871 | |||
| 2872 | case USB_REQ_GET_STATUS: | ||
| 2873 | switch (r.bRequestType) { | ||
| 2874 | case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
| 2875 | status = dev->wakeup_enable ? 0x02 : 0x00; | ||
| 2876 | if (dev->selfpowered) | ||
| 2877 | status |= BIT(0); | ||
| 2878 | status |= (dev->u1_enable << 2 | dev->u2_enable << 3 | | ||
| 2879 | dev->ltm_enable << 4); | ||
| 2880 | writel(0, &dev->epregs[0].ep_irqenb); | ||
| 2881 | set_fifo_bytecount(ep, sizeof(status)); | ||
| 2882 | writel((__force u32) status, &dev->epregs[0].ep_data); | ||
| 2883 | allow_status_338x(ep); | ||
| 2884 | break; | ||
| 2885 | |||
| 2886 | case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
| 2887 | e = get_ep_by_addr(dev, w_index); | ||
| 2888 | if (!e) | ||
| 2889 | goto do_stall3; | ||
| 2890 | status = readl(&e->regs->ep_rsp) & | ||
| 2891 | BIT(CLEAR_ENDPOINT_HALT); | ||
| 2892 | writel(0, &dev->epregs[0].ep_irqenb); | ||
| 2893 | set_fifo_bytecount(ep, sizeof(status)); | ||
| 2894 | writel((__force u32) status, &dev->epregs[0].ep_data); | ||
| 2895 | allow_status_338x(ep); | ||
| 2896 | break; | ||
| 2897 | |||
| 2898 | default: | ||
| 2899 | goto usb3_delegate; | ||
| 2900 | } | ||
| 2901 | break; | ||
| 2902 | |||
| 2903 | case USB_REQ_CLEAR_FEATURE: | ||
| 2904 | switch (r.bRequestType) { | ||
| 2905 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
| 2906 | if (!dev->addressed_state) { | ||
| 2907 | switch (w_value) { | ||
| 2908 | case USB_DEVICE_U1_ENABLE: | ||
| 2909 | dev->u1_enable = 0; | ||
| 2910 | writel(readl(&dev->usb_ext->usbctl2) & | ||
| 2911 | ~BIT(U1_ENABLE), | ||
| 2912 | &dev->usb_ext->usbctl2); | ||
| 2913 | allow_status_338x(ep); | ||
| 2914 | goto next_endpoints3; | ||
| 2915 | |||
| 2916 | case USB_DEVICE_U2_ENABLE: | ||
| 2917 | dev->u2_enable = 0; | ||
| 2918 | writel(readl(&dev->usb_ext->usbctl2) & | ||
| 2919 | ~BIT(U2_ENABLE), | ||
| 2920 | &dev->usb_ext->usbctl2); | ||
| 2921 | allow_status_338x(ep); | ||
| 2922 | goto next_endpoints3; | ||
| 2923 | |||
| 2924 | case USB_DEVICE_LTM_ENABLE: | ||
| 2925 | dev->ltm_enable = 0; | ||
| 2926 | writel(readl(&dev->usb_ext->usbctl2) & | ||
| 2927 | ~BIT(LTM_ENABLE), | ||
| 2928 | &dev->usb_ext->usbctl2); | ||
| 2929 | allow_status_338x(ep); | ||
| 2930 | goto next_endpoints3; | ||
| 2931 | |||
| 2932 | default: | ||
| 2933 | break; | ||
| 2934 | } | ||
| 2935 | } | ||
| 2936 | if (w_value == USB_DEVICE_REMOTE_WAKEUP) { | ||
| 2937 | dev->wakeup_enable = 0; | ||
| 2938 | writel(readl(&dev->usb->usbctl) & | ||
| 2939 | ~BIT(DEVICE_REMOTE_WAKEUP_ENABLE), | ||
| 2940 | &dev->usb->usbctl); | ||
| 2941 | allow_status_338x(ep); | ||
| 2942 | break; | ||
| 2943 | } | ||
| 2944 | goto usb3_delegate; | ||
| 2945 | |||
| 2946 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
| 2947 | e = get_ep_by_addr(dev, w_index); | ||
| 2948 | if (!e) | ||
| 2949 | goto do_stall3; | ||
| 2950 | if (w_value != USB_ENDPOINT_HALT) | ||
| 2951 | goto do_stall3; | ||
| 2952 | ep_vdbg(dev, "%s clear halt\n", e->ep.name); | ||
| 2953 | ep_stall(e, false); | ||
| 2954 | if (!list_empty(&e->queue) && e->td_dma) | ||
| 2955 | restart_dma(e); | ||
| 2956 | allow_status(ep); | ||
| 2957 | ep->stopped = 1; | ||
| 2958 | break; | ||
| 2959 | |||
| 2960 | default: | ||
| 2961 | goto usb3_delegate; | ||
| 2962 | } | ||
| 2963 | break; | ||
| 2964 | case USB_REQ_SET_FEATURE: | ||
| 2965 | switch (r.bRequestType) { | ||
| 2966 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
| 2967 | if (!dev->addressed_state) { | ||
| 2968 | switch (w_value) { | ||
| 2969 | case USB_DEVICE_U1_ENABLE: | ||
| 2970 | dev->u1_enable = 1; | ||
| 2971 | writel(readl(&dev->usb_ext->usbctl2) | | ||
| 2972 | BIT(U1_ENABLE), | ||
| 2973 | &dev->usb_ext->usbctl2); | ||
| 2974 | allow_status_338x(ep); | ||
| 2975 | goto next_endpoints3; | ||
| 2976 | |||
| 2977 | case USB_DEVICE_U2_ENABLE: | ||
| 2978 | dev->u2_enable = 1; | ||
| 2979 | writel(readl(&dev->usb_ext->usbctl2) | | ||
| 2980 | BIT(U2_ENABLE), | ||
| 2981 | &dev->usb_ext->usbctl2); | ||
| 2982 | allow_status_338x(ep); | ||
| 2983 | goto next_endpoints3; | ||
| 2984 | |||
| 2985 | case USB_DEVICE_LTM_ENABLE: | ||
| 2986 | dev->ltm_enable = 1; | ||
| 2987 | writel(readl(&dev->usb_ext->usbctl2) | | ||
| 2988 | BIT(LTM_ENABLE), | ||
| 2989 | &dev->usb_ext->usbctl2); | ||
| 2990 | allow_status_338x(ep); | ||
| 2991 | goto next_endpoints3; | ||
| 2992 | default: | ||
| 2993 | break; | ||
| 2994 | } | ||
| 2995 | } | ||
| 2996 | |||
| 2997 | if (w_value == USB_DEVICE_REMOTE_WAKEUP) { | ||
| 2998 | dev->wakeup_enable = 1; | ||
| 2999 | writel(readl(&dev->usb->usbctl) | | ||
| 3000 | BIT(DEVICE_REMOTE_WAKEUP_ENABLE), | ||
| 3001 | &dev->usb->usbctl); | ||
| 3002 | allow_status_338x(ep); | ||
| 3003 | break; | ||
| 3004 | } | ||
| 3005 | goto usb3_delegate; | ||
| 3006 | |||
| 3007 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
| 3008 | e = get_ep_by_addr(dev, w_index); | ||
| 3009 | if (!e || (w_value != USB_ENDPOINT_HALT)) | ||
| 3010 | goto do_stall3; | ||
| 3011 | ep_stdrsp(e, true, false); | ||
| 3012 | allow_status_338x(ep); | ||
| 3013 | break; | ||
| 3014 | |||
| 3015 | default: | ||
| 3016 | goto usb3_delegate; | ||
| 3017 | } | ||
| 3018 | |||
| 3019 | break; | ||
| 3020 | default: | ||
| 3021 | |||
| 3022 | usb3_delegate: | ||
| 3023 | ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x ep_cfg %08x\n", | ||
| 3024 | r.bRequestType, r.bRequest, | ||
| 3025 | w_value, w_index, w_length, | ||
| 3026 | readl(&ep->cfg->ep_cfg)); | ||
| 3027 | |||
| 3028 | ep->responded = 0; | ||
| 3029 | spin_unlock(&dev->lock); | ||
| 3030 | tmp = dev->driver->setup(&dev->gadget, &r); | ||
| 3031 | spin_lock(&dev->lock); | ||
| 3032 | } | ||
| 3033 | do_stall3: | ||
| 3034 | if (tmp < 0) { | ||
| 3035 | ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n", | ||
| 3036 | r.bRequestType, r.bRequest, tmp); | ||
| 3037 | dev->protocol_stall = 1; | ||
| 3038 | /* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */ | ||
| 3039 | ep_stall(ep, true); | ||
| 3040 | } | ||
| 3041 | |||
| 3042 | next_endpoints3: | ||
| 3043 | |||
| 3044 | #undef w_value | ||
| 3045 | #undef w_index | ||
| 3046 | #undef w_length | ||
| 3047 | |||
| 3048 | return; | ||
| 3049 | } | ||
| 3050 | |||
| 3051 | static void handle_stat0_irqs(struct net2280 *dev, u32 stat) | ||
| 3052 | { | ||
| 3053 | struct net2280_ep *ep; | ||
| 3054 | u32 num, scratch; | ||
| 3055 | |||
| 3056 | /* most of these don't need individual acks */ | ||
| 3057 | stat &= ~BIT(INTA_ASSERTED); | ||
| 3058 | if (!stat) | ||
| 3059 | return; | ||
| 3060 | /* ep_dbg(dev, "irqstat0 %04x\n", stat); */ | ||
| 3061 | |||
| 3062 | /* starting a control request? */ | ||
| 3063 | if (unlikely(stat & BIT(SETUP_PACKET_INTERRUPT))) { | ||
| 3064 | union { | ||
| 3065 | u32 raw[2]; | ||
| 3066 | struct usb_ctrlrequest r; | ||
| 3067 | } u; | ||
| 3068 | int tmp; | ||
| 3069 | struct net2280_request *req; | ||
| 3070 | |||
| 3071 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) { | ||
| 3072 | u32 val = readl(&dev->usb->usbstat); | ||
| 3073 | if (val & BIT(SUPER_SPEED)) { | ||
| 3074 | dev->gadget.speed = USB_SPEED_SUPER; | ||
| 3075 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, | ||
| 3076 | EP0_SS_MAX_PACKET_SIZE); | ||
| 3077 | } else if (val & BIT(HIGH_SPEED)) { | ||
| 3078 | dev->gadget.speed = USB_SPEED_HIGH; | ||
| 3079 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, | ||
| 3080 | EP0_HS_MAX_PACKET_SIZE); | ||
| 3081 | } else { | ||
| 3082 | dev->gadget.speed = USB_SPEED_FULL; | ||
| 3083 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, | ||
| 3084 | EP0_HS_MAX_PACKET_SIZE); | ||
| 3085 | } | ||
| 3086 | net2280_led_speed(dev, dev->gadget.speed); | ||
| 3087 | ep_dbg(dev, "%s\n", | ||
| 3088 | usb_speed_string(dev->gadget.speed)); | ||
| 3089 | } | ||
| 3090 | |||
| 3091 | ep = &dev->ep[0]; | ||
| 3092 | ep->irqs++; | ||
| 3093 | |||
| 3094 | /* make sure any leftover request state is cleared */ | ||
| 3095 | stat &= ~BIT(ENDPOINT_0_INTERRUPT); | ||
| 3096 | while (!list_empty(&ep->queue)) { | ||
| 3097 | req = list_entry(ep->queue.next, | ||
| 3098 | struct net2280_request, queue); | ||
| 3099 | done(ep, req, (req->req.actual == req->req.length) | ||
| 3100 | ? 0 : -EPROTO); | ||
| 3101 | } | ||
| 3102 | ep->stopped = 0; | ||
| 3103 | dev->protocol_stall = 0; | ||
| 3104 | if (dev->quirks & PLX_SUPERSPEED) | ||
| 3105 | ep->is_halt = 0; | ||
| 3106 | else{ | ||
| 3107 | if (ep->dev->quirks & PLX_2280) | ||
| 3108 | tmp = BIT(FIFO_OVERFLOW) | | ||
| 3109 | BIT(FIFO_UNDERFLOW); | ||
| 3110 | else | ||
| 3111 | tmp = 0; | ||
| 3112 | |||
| 3113 | writel(tmp | BIT(TIMEOUT) | | ||
| 3114 | BIT(USB_STALL_SENT) | | ||
| 3115 | BIT(USB_IN_NAK_SENT) | | ||
| 3116 | BIT(USB_IN_ACK_RCVD) | | ||
| 3117 | BIT(USB_OUT_PING_NAK_SENT) | | ||
| 3118 | BIT(USB_OUT_ACK_SENT) | | ||
| 3119 | BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) | | ||
| 3120 | BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) | | ||
| 3121 | BIT(DATA_PACKET_RECEIVED_INTERRUPT) | | ||
| 3122 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
| 3123 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 3124 | BIT(DATA_IN_TOKEN_INTERRUPT), | ||
| 3125 | &ep->regs->ep_stat); | ||
| 3126 | } | ||
| 3127 | u.raw[0] = readl(&dev->usb->setup0123); | ||
| 3128 | u.raw[1] = readl(&dev->usb->setup4567); | ||
| 3129 | |||
| 3130 | cpu_to_le32s(&u.raw[0]); | ||
| 3131 | cpu_to_le32s(&u.raw[1]); | ||
| 3132 | |||
| 3133 | if (dev->quirks & PLX_SUPERSPEED) | ||
| 3134 | defect7374_workaround(dev, u.r); | ||
| 3135 | |||
| 3136 | tmp = 0; | ||
| 3137 | |||
| 3138 | #define w_value le16_to_cpu(u.r.wValue) | ||
| 3139 | #define w_index le16_to_cpu(u.r.wIndex) | ||
| 3140 | #define w_length le16_to_cpu(u.r.wLength) | ||
| 3141 | |||
| 3142 | /* ack the irq */ | ||
| 3143 | writel(BIT(SETUP_PACKET_INTERRUPT), &dev->regs->irqstat0); | ||
| 3144 | stat ^= BIT(SETUP_PACKET_INTERRUPT); | ||
| 3145 | |||
| 3146 | /* watch control traffic at the token level, and force | ||
| 3147 | * synchronization before letting the status stage happen. | ||
| 3148 | * FIXME ignore tokens we'll NAK, until driver responds. | ||
| 3149 | * that'll mean a lot less irqs for some drivers. | ||
| 3150 | */ | ||
| 3151 | ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0; | ||
| 3152 | if (ep->is_in) { | ||
| 3153 | scratch = BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
| 3154 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 3155 | BIT(DATA_IN_TOKEN_INTERRUPT); | ||
| 3156 | stop_out_naking(ep); | ||
| 3157 | } else | ||
| 3158 | scratch = BIT(DATA_PACKET_RECEIVED_INTERRUPT) | | ||
| 3159 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
| 3160 | BIT(DATA_IN_TOKEN_INTERRUPT); | ||
| 3161 | writel(scratch, &dev->epregs[0].ep_irqenb); | ||
| 3162 | |||
| 3163 | /* we made the hardware handle most lowlevel requests; | ||
| 3164 | * everything else goes uplevel to the gadget code. | ||
| 3165 | */ | ||
| 3166 | ep->responded = 1; | ||
| 3167 | |||
| 3168 | if (dev->gadget.speed == USB_SPEED_SUPER) { | ||
| 3169 | handle_stat0_irqs_superspeed(dev, ep, u.r); | ||
| 3170 | goto next_endpoints; | ||
| 3171 | } | ||
| 3172 | |||
| 3173 | switch (u.r.bRequest) { | ||
| 3174 | case USB_REQ_GET_STATUS: { | ||
| 3175 | struct net2280_ep *e; | ||
| 3176 | __le32 status; | ||
| 3177 | |||
| 3178 | /* hw handles device and interface status */ | ||
| 3179 | if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT)) | ||
| 3180 | goto delegate; | ||
| 3181 | e = get_ep_by_addr(dev, w_index); | ||
| 3182 | if (!e || w_length > 2) | ||
| 3183 | goto do_stall; | ||
| 3184 | |||
| 3185 | if (readl(&e->regs->ep_rsp) & BIT(SET_ENDPOINT_HALT)) | ||
| 3186 | status = cpu_to_le32(1); | ||
| 3187 | else | ||
| 3188 | status = cpu_to_le32(0); | ||
| 3189 | |||
| 3190 | /* don't bother with a request object! */ | ||
| 3191 | writel(0, &dev->epregs[0].ep_irqenb); | ||
| 3192 | set_fifo_bytecount(ep, w_length); | ||
| 3193 | writel((__force u32)status, &dev->epregs[0].ep_data); | ||
| 3194 | allow_status(ep); | ||
| 3195 | ep_vdbg(dev, "%s stat %02x\n", ep->ep.name, status); | ||
| 3196 | goto next_endpoints; | ||
| 3197 | } | ||
| 3198 | break; | ||
| 3199 | case USB_REQ_CLEAR_FEATURE: { | ||
| 3200 | struct net2280_ep *e; | ||
| 3201 | |||
| 3202 | /* hw handles device features */ | ||
| 3203 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | ||
| 3204 | goto delegate; | ||
| 3205 | if (w_value != USB_ENDPOINT_HALT || w_length != 0) | ||
| 3206 | goto do_stall; | ||
| 3207 | e = get_ep_by_addr(dev, w_index); | ||
| 3208 | if (!e) | ||
| 3209 | goto do_stall; | ||
| 3210 | if (e->wedged) { | ||
| 3211 | ep_vdbg(dev, "%s wedged, halt not cleared\n", | ||
| 3212 | ep->ep.name); | ||
| 3213 | } else { | ||
| 3214 | ep_vdbg(dev, "%s clear halt\n", e->ep.name); | ||
| 3215 | clear_halt(e); | ||
| 3216 | if ((ep->dev->quirks & PLX_SUPERSPEED) && | ||
| 3217 | !list_empty(&e->queue) && e->td_dma) | ||
| 3218 | restart_dma(e); | ||
| 3219 | } | ||
| 3220 | allow_status(ep); | ||
| 3221 | goto next_endpoints; | ||
| 3222 | } | ||
| 3223 | break; | ||
| 3224 | case USB_REQ_SET_FEATURE: { | ||
| 3225 | struct net2280_ep *e; | ||
| 3226 | |||
| 3227 | /* hw handles device features */ | ||
| 3228 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | ||
| 3229 | goto delegate; | ||
| 3230 | if (w_value != USB_ENDPOINT_HALT || w_length != 0) | ||
| 3231 | goto do_stall; | ||
| 3232 | e = get_ep_by_addr(dev, w_index); | ||
| 3233 | if (!e) | ||
| 3234 | goto do_stall; | ||
| 3235 | if (e->ep.name == ep0name) | ||
| 3236 | goto do_stall; | ||
| 3237 | set_halt(e); | ||
| 3238 | if ((dev->quirks & PLX_SUPERSPEED) && e->dma) | ||
| 3239 | abort_dma(e); | ||
| 3240 | allow_status(ep); | ||
| 3241 | ep_vdbg(dev, "%s set halt\n", ep->ep.name); | ||
| 3242 | goto next_endpoints; | ||
| 3243 | } | ||
| 3244 | break; | ||
| 3245 | default: | ||
| 3246 | delegate: | ||
| 3247 | ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x " | ||
| 3248 | "ep_cfg %08x\n", | ||
| 3249 | u.r.bRequestType, u.r.bRequest, | ||
| 3250 | w_value, w_index, w_length, | ||
| 3251 | readl(&ep->cfg->ep_cfg)); | ||
| 3252 | ep->responded = 0; | ||
| 3253 | spin_unlock(&dev->lock); | ||
| 3254 | tmp = dev->driver->setup(&dev->gadget, &u.r); | ||
| 3255 | spin_lock(&dev->lock); | ||
| 3256 | } | ||
| 3257 | |||
| 3258 | /* stall ep0 on error */ | ||
| 3259 | if (tmp < 0) { | ||
| 3260 | do_stall: | ||
| 3261 | ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n", | ||
| 3262 | u.r.bRequestType, u.r.bRequest, tmp); | ||
| 3263 | dev->protocol_stall = 1; | ||
| 3264 | } | ||
| 3265 | |||
| 3266 | /* some in/out token irq should follow; maybe stall then. | ||
| 3267 | * driver must queue a request (even zlp) or halt ep0 | ||
| 3268 | * before the host times out. | ||
| 3269 | */ | ||
| 3270 | } | ||
| 3271 | |||
| 3272 | #undef w_value | ||
| 3273 | #undef w_index | ||
| 3274 | #undef w_length | ||
| 3275 | |||
| 3276 | next_endpoints: | ||
| 3277 | /* endpoint data irq ? */ | ||
| 3278 | scratch = stat & 0x7f; | ||
| 3279 | stat &= ~0x7f; | ||
| 3280 | for (num = 0; scratch; num++) { | ||
| 3281 | u32 t; | ||
| 3282 | |||
| 3283 | /* do this endpoint's FIFO and queue need tending? */ | ||
| 3284 | t = BIT(num); | ||
| 3285 | if ((scratch & t) == 0) | ||
| 3286 | continue; | ||
| 3287 | scratch ^= t; | ||
| 3288 | |||
| 3289 | ep = &dev->ep[num]; | ||
| 3290 | handle_ep_small(ep); | ||
| 3291 | } | ||
| 3292 | |||
| 3293 | if (stat) | ||
| 3294 | ep_dbg(dev, "unhandled irqstat0 %08x\n", stat); | ||
| 3295 | } | ||
| 3296 | |||
| 3297 | #define DMA_INTERRUPTS (BIT(DMA_D_INTERRUPT) | \ | ||
| 3298 | BIT(DMA_C_INTERRUPT) | \ | ||
| 3299 | BIT(DMA_B_INTERRUPT) | \ | ||
| 3300 | BIT(DMA_A_INTERRUPT)) | ||
| 3301 | #define PCI_ERROR_INTERRUPTS ( \ | ||
| 3302 | BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT) | \ | ||
| 3303 | BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT) | \ | ||
| 3304 | BIT(PCI_RETRY_ABORT_INTERRUPT)) | ||
| 3305 | |||
| 3306 | static void handle_stat1_irqs(struct net2280 *dev, u32 stat) | ||
| 3307 | { | ||
| 3308 | struct net2280_ep *ep; | ||
| 3309 | u32 tmp, num, mask, scratch; | ||
| 3310 | |||
| 3311 | /* after disconnect there's nothing else to do! */ | ||
| 3312 | tmp = BIT(VBUS_INTERRUPT) | BIT(ROOT_PORT_RESET_INTERRUPT); | ||
| 3313 | mask = BIT(SUPER_SPEED) | BIT(HIGH_SPEED) | BIT(FULL_SPEED); | ||
| 3314 | |||
| 3315 | /* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set. | ||
| 3316 | * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and | ||
| 3317 | * both HIGH_SPEED and FULL_SPEED clear (as ROOT_PORT_RESET_INTERRUPT | ||
| 3318 | * only indicates a change in the reset state). | ||
| 3319 | */ | ||
| 3320 | if (stat & tmp) { | ||
| 3321 | writel(tmp, &dev->regs->irqstat1); | ||
| 3322 | if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) && | ||
| 3323 | (readl(&dev->usb->usbstat) & mask)) || | ||
| 3324 | ((readl(&dev->usb->usbctl) & | ||
| 3325 | BIT(VBUS_PIN)) == 0)) && | ||
| 3326 | (dev->gadget.speed != USB_SPEED_UNKNOWN)) { | ||
| 3327 | ep_dbg(dev, "disconnect %s\n", | ||
| 3328 | dev->driver->driver.name); | ||
| 3329 | stop_activity(dev, dev->driver); | ||
| 3330 | ep0_start(dev); | ||
| 3331 | return; | ||
| 3332 | } | ||
| 3333 | stat &= ~tmp; | ||
| 3334 | |||
| 3335 | /* vBUS can bounce ... one of many reasons to ignore the | ||
| 3336 | * notion of hotplug events on bus connect/disconnect! | ||
| 3337 | */ | ||
| 3338 | if (!stat) | ||
| 3339 | return; | ||
| 3340 | } | ||
| 3341 | |||
| 3342 | /* NOTE: chip stays in PCI D0 state for now, but it could | ||
| 3343 | * enter D1 to save more power | ||
| 3344 | */ | ||
| 3345 | tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT); | ||
| 3346 | if (stat & tmp) { | ||
| 3347 | writel(tmp, &dev->regs->irqstat1); | ||
| 3348 | if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) { | ||
| 3349 | if (dev->driver->suspend) | ||
| 3350 | dev->driver->suspend(&dev->gadget); | ||
| 3351 | if (!enable_suspend) | ||
| 3352 | stat &= ~BIT(SUSPEND_REQUEST_INTERRUPT); | ||
| 3353 | } else { | ||
| 3354 | if (dev->driver->resume) | ||
| 3355 | dev->driver->resume(&dev->gadget); | ||
| 3356 | /* at high speed, note erratum 0133 */ | ||
| 3357 | } | ||
| 3358 | stat &= ~tmp; | ||
| 3359 | } | ||
| 3360 | |||
| 3361 | /* clear any other status/irqs */ | ||
| 3362 | if (stat) | ||
| 3363 | writel(stat, &dev->regs->irqstat1); | ||
| 3364 | |||
| 3365 | /* some status we can just ignore */ | ||
| 3366 | if (dev->quirks & PLX_2280) | ||
| 3367 | stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) | | ||
| 3368 | BIT(SUSPEND_REQUEST_INTERRUPT) | | ||
| 3369 | BIT(RESUME_INTERRUPT) | | ||
| 3370 | BIT(SOF_INTERRUPT)); | ||
| 3371 | else | ||
| 3372 | stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) | | ||
| 3373 | BIT(RESUME_INTERRUPT) | | ||
| 3374 | BIT(SOF_DOWN_INTERRUPT) | | ||
| 3375 | BIT(SOF_INTERRUPT)); | ||
| 3376 | |||
| 3377 | if (!stat) | ||
| 3378 | return; | ||
| 3379 | /* ep_dbg(dev, "irqstat1 %08x\n", stat);*/ | ||
| 3380 | |||
| 3381 | /* DMA status, for ep-{a,b,c,d} */ | ||
| 3382 | scratch = stat & DMA_INTERRUPTS; | ||
| 3383 | stat &= ~DMA_INTERRUPTS; | ||
| 3384 | scratch >>= 9; | ||
| 3385 | for (num = 0; scratch; num++) { | ||
| 3386 | struct net2280_dma_regs __iomem *dma; | ||
| 3387 | |||
| 3388 | tmp = BIT(num); | ||
| 3389 | if ((tmp & scratch) == 0) | ||
| 3390 | continue; | ||
| 3391 | scratch ^= tmp; | ||
| 3392 | |||
| 3393 | ep = &dev->ep[num + 1]; | ||
| 3394 | dma = ep->dma; | ||
| 3395 | |||
| 3396 | if (!dma) | ||
| 3397 | continue; | ||
| 3398 | |||
| 3399 | /* clear ep's dma status */ | ||
| 3400 | tmp = readl(&dma->dmastat); | ||
| 3401 | writel(tmp, &dma->dmastat); | ||
| 3402 | |||
| 3403 | /* dma sync*/ | ||
| 3404 | if (dev->quirks & PLX_SUPERSPEED) { | ||
| 3405 | u32 r_dmacount = readl(&dma->dmacount); | ||
| 3406 | if (!ep->is_in && (r_dmacount & 0x00FFFFFF) && | ||
| 3407 | (tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) | ||
| 3408 | continue; | ||
| 3409 | } | ||
| 3410 | |||
| 3411 | /* chaining should stop on abort, short OUT from fifo, | ||
| 3412 | * or (stat0 codepath) short OUT transfer. | ||
| 3413 | */ | ||
| 3414 | if (!use_dma_chaining) { | ||
| 3415 | if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) { | ||
| 3416 | ep_dbg(ep->dev, "%s no xact done? %08x\n", | ||
| 3417 | ep->ep.name, tmp); | ||
| 3418 | continue; | ||
| 3419 | } | ||
| 3420 | stop_dma(ep->dma); | ||
| 3421 | } | ||
| 3422 | |||
| 3423 | /* OUT transfers terminate when the data from the | ||
| 3424 | * host is in our memory. Process whatever's done. | ||
| 3425 | * On this path, we know transfer's last packet wasn't | ||
| 3426 | * less than req->length. NAK_OUT_PACKETS may be set, | ||
| 3427 | * or the FIFO may already be holding new packets. | ||
| 3428 | * | ||
| 3429 | * IN transfers can linger in the FIFO for a very | ||
| 3430 | * long time ... we ignore that for now, accounting | ||
| 3431 | * precisely (like PIO does) needs per-packet irqs | ||
| 3432 | */ | ||
| 3433 | scan_dma_completions(ep); | ||
| 3434 | |||
| 3435 | /* disable dma on inactive queues; else maybe restart */ | ||
| 3436 | if (list_empty(&ep->queue)) { | ||
| 3437 | if (use_dma_chaining) | ||
| 3438 | stop_dma(ep->dma); | ||
| 3439 | } else { | ||
| 3440 | tmp = readl(&dma->dmactl); | ||
| 3441 | if (!use_dma_chaining || (tmp & BIT(DMA_ENABLE)) == 0) | ||
| 3442 | restart_dma(ep); | ||
| 3443 | else if (ep->is_in && use_dma_chaining) { | ||
| 3444 | struct net2280_request *req; | ||
| 3445 | __le32 dmacount; | ||
| 3446 | |||
| 3447 | /* the descriptor at the head of the chain | ||
| 3448 | * may still have VALID_BIT clear; that's | ||
| 3449 | * used to trigger changing DMA_FIFO_VALIDATE | ||
| 3450 | * (affects automagic zlp writes). | ||
| 3451 | */ | ||
| 3452 | req = list_entry(ep->queue.next, | ||
| 3453 | struct net2280_request, queue); | ||
| 3454 | dmacount = req->td->dmacount; | ||
| 3455 | dmacount &= cpu_to_le32(BIT(VALID_BIT) | | ||
| 3456 | DMA_BYTE_COUNT_MASK); | ||
| 3457 | if (dmacount && (dmacount & valid_bit) == 0) | ||
| 3458 | restart_dma(ep); | ||
| 3459 | } | ||
| 3460 | } | ||
| 3461 | ep->irqs++; | ||
| 3462 | } | ||
| 3463 | |||
| 3464 | /* NOTE: there are other PCI errors we might usefully notice. | ||
| 3465 | * if they appear very often, here's where to try recovering. | ||
| 3466 | */ | ||
| 3467 | if (stat & PCI_ERROR_INTERRUPTS) { | ||
| 3468 | ep_err(dev, "pci dma error; stat %08x\n", stat); | ||
| 3469 | stat &= ~PCI_ERROR_INTERRUPTS; | ||
| 3470 | /* these are fatal errors, but "maybe" they won't | ||
| 3471 | * happen again ... | ||
| 3472 | */ | ||
| 3473 | stop_activity(dev, dev->driver); | ||
| 3474 | ep0_start(dev); | ||
| 3475 | stat = 0; | ||
| 3476 | } | ||
| 3477 | |||
| 3478 | if (stat) | ||
| 3479 | ep_dbg(dev, "unhandled irqstat1 %08x\n", stat); | ||
| 3480 | } | ||
| 3481 | |||
| 3482 | static irqreturn_t net2280_irq(int irq, void *_dev) | ||
| 3483 | { | ||
| 3484 | struct net2280 *dev = _dev; | ||
| 3485 | |||
| 3486 | /* shared interrupt, not ours */ | ||
| 3487 | if ((dev->quirks & PLX_LEGACY) && | ||
| 3488 | (!(readl(&dev->regs->irqstat0) & BIT(INTA_ASSERTED)))) | ||
| 3489 | return IRQ_NONE; | ||
| 3490 | |||
| 3491 | spin_lock(&dev->lock); | ||
| 3492 | |||
| 3493 | /* handle disconnect, dma, and more */ | ||
| 3494 | handle_stat1_irqs(dev, readl(&dev->regs->irqstat1)); | ||
| 3495 | |||
| 3496 | /* control requests and PIO */ | ||
| 3497 | handle_stat0_irqs(dev, readl(&dev->regs->irqstat0)); | ||
| 3498 | |||
| 3499 | if (dev->quirks & PLX_SUPERSPEED) { | ||
| 3500 | /* re-enable interrupt to trigger any possible new interrupt */ | ||
| 3501 | u32 pciirqenb1 = readl(&dev->regs->pciirqenb1); | ||
| 3502 | writel(pciirqenb1 & 0x7FFFFFFF, &dev->regs->pciirqenb1); | ||
| 3503 | writel(pciirqenb1, &dev->regs->pciirqenb1); | ||
| 3504 | } | ||
| 3505 | |||
| 3506 | spin_unlock(&dev->lock); | ||
| 3507 | |||
| 3508 | return IRQ_HANDLED; | ||
| 3509 | } | ||
| 3510 | |||
| 3511 | /*-------------------------------------------------------------------------*/ | ||
| 3512 | |||
| 3513 | static void gadget_release(struct device *_dev) | ||
| 3514 | { | ||
| 3515 | struct net2280 *dev = dev_get_drvdata(_dev); | ||
| 3516 | |||
| 3517 | kfree(dev); | ||
| 3518 | } | ||
| 3519 | |||
| 3520 | /* tear down the binding between this driver and the pci device */ | ||
| 3521 | |||
| 3522 | static void net2280_remove(struct pci_dev *pdev) | ||
| 3523 | { | ||
| 3524 | struct net2280 *dev = pci_get_drvdata(pdev); | ||
| 3525 | |||
| 3526 | usb_del_gadget_udc(&dev->gadget); | ||
| 3527 | |||
| 3528 | BUG_ON(dev->driver); | ||
| 3529 | |||
| 3530 | /* then clean up the resources we allocated during probe() */ | ||
| 3531 | net2280_led_shutdown(dev); | ||
| 3532 | if (dev->requests) { | ||
| 3533 | int i; | ||
| 3534 | for (i = 1; i < 5; i++) { | ||
| 3535 | if (!dev->ep[i].dummy) | ||
| 3536 | continue; | ||
| 3537 | pci_pool_free(dev->requests, dev->ep[i].dummy, | ||
| 3538 | dev->ep[i].td_dma); | ||
| 3539 | } | ||
| 3540 | pci_pool_destroy(dev->requests); | ||
| 3541 | } | ||
| 3542 | if (dev->got_irq) | ||
| 3543 | free_irq(pdev->irq, dev); | ||
| 3544 | if (use_msi && dev->quirks & PLX_SUPERSPEED) | ||
| 3545 | pci_disable_msi(pdev); | ||
| 3546 | if (dev->regs) | ||
| 3547 | iounmap(dev->regs); | ||
| 3548 | if (dev->region) | ||
| 3549 | release_mem_region(pci_resource_start(pdev, 0), | ||
| 3550 | pci_resource_len(pdev, 0)); | ||
| 3551 | if (dev->enabled) | ||
| 3552 | pci_disable_device(pdev); | ||
| 3553 | device_remove_file(&pdev->dev, &dev_attr_registers); | ||
| 3554 | |||
| 3555 | ep_info(dev, "unbind\n"); | ||
| 3556 | } | ||
| 3557 | |||
| 3558 | /* wrap this driver around the specified device, but | ||
| 3559 | * don't respond over USB until a gadget driver binds to us. | ||
| 3560 | */ | ||
| 3561 | |||
| 3562 | static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
| 3563 | { | ||
| 3564 | struct net2280 *dev; | ||
| 3565 | unsigned long resource, len; | ||
| 3566 | void __iomem *base = NULL; | ||
| 3567 | int retval, i; | ||
| 3568 | |||
| 3569 | if (!use_dma) | ||
| 3570 | use_dma_chaining = 0; | ||
| 3571 | |||
| 3572 | /* alloc, and start init */ | ||
| 3573 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 3574 | if (dev == NULL) { | ||
| 3575 | retval = -ENOMEM; | ||
| 3576 | goto done; | ||
| 3577 | } | ||
| 3578 | |||
| 3579 | pci_set_drvdata(pdev, dev); | ||
| 3580 | spin_lock_init(&dev->lock); | ||
| 3581 | dev->quirks = id->driver_data; | ||
| 3582 | dev->pdev = pdev; | ||
| 3583 | dev->gadget.ops = &net2280_ops; | ||
| 3584 | dev->gadget.max_speed = (dev->quirks & PLX_SUPERSPEED) ? | ||
| 3585 | USB_SPEED_SUPER : USB_SPEED_HIGH; | ||
| 3586 | |||
| 3587 | /* the "gadget" abstracts/virtualizes the controller */ | ||
| 3588 | dev->gadget.name = driver_name; | ||
| 3589 | |||
| 3590 | /* now all the pci goodies ... */ | ||
| 3591 | if (pci_enable_device(pdev) < 0) { | ||
| 3592 | retval = -ENODEV; | ||
| 3593 | goto done; | ||
| 3594 | } | ||
| 3595 | dev->enabled = 1; | ||
| 3596 | |||
| 3597 | /* BAR 0 holds all the registers | ||
| 3598 | * BAR 1 is 8051 memory; unused here (note erratum 0103) | ||
| 3599 | * BAR 2 is fifo memory; unused here | ||
| 3600 | */ | ||
| 3601 | resource = pci_resource_start(pdev, 0); | ||
| 3602 | len = pci_resource_len(pdev, 0); | ||
| 3603 | if (!request_mem_region(resource, len, driver_name)) { | ||
| 3604 | ep_dbg(dev, "controller already in use\n"); | ||
| 3605 | retval = -EBUSY; | ||
| 3606 | goto done; | ||
| 3607 | } | ||
| 3608 | dev->region = 1; | ||
| 3609 | |||
| 3610 | /* FIXME provide firmware download interface to put | ||
| 3611 | * 8051 code into the chip, e.g. to turn on PCI PM. | ||
| 3612 | */ | ||
| 3613 | |||
| 3614 | base = ioremap_nocache(resource, len); | ||
| 3615 | if (base == NULL) { | ||
| 3616 | ep_dbg(dev, "can't map memory\n"); | ||
| 3617 | retval = -EFAULT; | ||
| 3618 | goto done; | ||
| 3619 | } | ||
| 3620 | dev->regs = (struct net2280_regs __iomem *) base; | ||
| 3621 | dev->usb = (struct net2280_usb_regs __iomem *) (base + 0x0080); | ||
| 3622 | dev->pci = (struct net2280_pci_regs __iomem *) (base + 0x0100); | ||
| 3623 | dev->dma = (struct net2280_dma_regs __iomem *) (base + 0x0180); | ||
| 3624 | dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200); | ||
| 3625 | dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300); | ||
| 3626 | |||
| 3627 | if (dev->quirks & PLX_SUPERSPEED) { | ||
| 3628 | u32 fsmvalue; | ||
| 3629 | u32 usbstat; | ||
| 3630 | dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *) | ||
| 3631 | (base + 0x00b4); | ||
| 3632 | dev->fiforegs = (struct usb338x_fifo_regs __iomem *) | ||
| 3633 | (base + 0x0500); | ||
| 3634 | dev->llregs = (struct usb338x_ll_regs __iomem *) | ||
| 3635 | (base + 0x0700); | ||
| 3636 | dev->ll_lfps_regs = (struct usb338x_ll_lfps_regs __iomem *) | ||
| 3637 | (base + 0x0748); | ||
| 3638 | dev->ll_tsn_regs = (struct usb338x_ll_tsn_regs __iomem *) | ||
| 3639 | (base + 0x077c); | ||
| 3640 | dev->ll_chicken_reg = (struct usb338x_ll_chi_regs __iomem *) | ||
| 3641 | (base + 0x079c); | ||
| 3642 | dev->plregs = (struct usb338x_pl_regs __iomem *) | ||
| 3643 | (base + 0x0800); | ||
| 3644 | usbstat = readl(&dev->usb->usbstat); | ||
| 3645 | dev->enhanced_mode = !!(usbstat & BIT(11)); | ||
| 3646 | dev->n_ep = (dev->enhanced_mode) ? 9 : 5; | ||
| 3647 | /* put into initial config, link up all endpoints */ | ||
| 3648 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
| 3649 | (0xf << DEFECT7374_FSM_FIELD); | ||
| 3650 | /* See if firmware needs to set up for workaround: */ | ||
| 3651 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) | ||
| 3652 | writel(0, &dev->usb->usbctl); | ||
| 3653 | } else{ | ||
| 3654 | dev->enhanced_mode = 0; | ||
| 3655 | dev->n_ep = 7; | ||
| 3656 | /* put into initial config, link up all endpoints */ | ||
| 3657 | writel(0, &dev->usb->usbctl); | ||
| 3658 | } | ||
| 3659 | |||
| 3660 | usb_reset(dev); | ||
| 3661 | usb_reinit(dev); | ||
| 3662 | |||
| 3663 | /* irq setup after old hardware is cleaned up */ | ||
| 3664 | if (!pdev->irq) { | ||
| 3665 | ep_err(dev, "No IRQ. Check PCI setup!\n"); | ||
| 3666 | retval = -ENODEV; | ||
| 3667 | goto done; | ||
| 3668 | } | ||
| 3669 | |||
| 3670 | if (use_msi && (dev->quirks & PLX_SUPERSPEED)) | ||
| 3671 | if (pci_enable_msi(pdev)) | ||
| 3672 | ep_err(dev, "Failed to enable MSI mode\n"); | ||
| 3673 | |||
| 3674 | if (request_irq(pdev->irq, net2280_irq, IRQF_SHARED, | ||
| 3675 | driver_name, dev)) { | ||
| 3676 | ep_err(dev, "request interrupt %d failed\n", pdev->irq); | ||
| 3677 | retval = -EBUSY; | ||
| 3678 | goto done; | ||
| 3679 | } | ||
| 3680 | dev->got_irq = 1; | ||
| 3681 | |||
| 3682 | /* DMA setup */ | ||
| 3683 | /* NOTE: we know only the 32 LSBs of dma addresses may be nonzero */ | ||
| 3684 | dev->requests = pci_pool_create("requests", pdev, | ||
| 3685 | sizeof(struct net2280_dma), | ||
| 3686 | 0 /* no alignment requirements */, | ||
| 3687 | 0 /* or page-crossing issues */); | ||
| 3688 | if (!dev->requests) { | ||
| 3689 | ep_dbg(dev, "can't get request pool\n"); | ||
| 3690 | retval = -ENOMEM; | ||
| 3691 | goto done; | ||
| 3692 | } | ||
| 3693 | for (i = 1; i < 5; i++) { | ||
| 3694 | struct net2280_dma *td; | ||
| 3695 | |||
| 3696 | td = pci_pool_alloc(dev->requests, GFP_KERNEL, | ||
| 3697 | &dev->ep[i].td_dma); | ||
| 3698 | if (!td) { | ||
| 3699 | ep_dbg(dev, "can't get dummy %d\n", i); | ||
| 3700 | retval = -ENOMEM; | ||
| 3701 | goto done; | ||
| 3702 | } | ||
| 3703 | td->dmacount = 0; /* not VALID */ | ||
| 3704 | td->dmadesc = td->dmaaddr; | ||
| 3705 | dev->ep[i].dummy = td; | ||
| 3706 | } | ||
| 3707 | |||
| 3708 | /* enable lower-overhead pci memory bursts during DMA */ | ||
| 3709 | if (dev->quirks & PLX_LEGACY) | ||
| 3710 | writel(BIT(DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) | | ||
| 3711 | /* | ||
| 3712 | * 256 write retries may not be enough... | ||
| 3713 | BIT(PCI_RETRY_ABORT_ENABLE) | | ||
| 3714 | */ | ||
| 3715 | BIT(DMA_READ_MULTIPLE_ENABLE) | | ||
| 3716 | BIT(DMA_READ_LINE_ENABLE), | ||
| 3717 | &dev->pci->pcimstctl); | ||
| 3718 | /* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */ | ||
| 3719 | pci_set_master(pdev); | ||
| 3720 | pci_try_set_mwi(pdev); | ||
| 3721 | |||
| 3722 | /* ... also flushes any posted pci writes */ | ||
| 3723 | dev->chiprev = get_idx_reg(dev->regs, REG_CHIPREV) & 0xffff; | ||
| 3724 | |||
| 3725 | /* done */ | ||
| 3726 | ep_info(dev, "%s\n", driver_desc); | ||
| 3727 | ep_info(dev, "irq %d, pci mem %p, chip rev %04x\n", | ||
| 3728 | pdev->irq, base, dev->chiprev); | ||
| 3729 | ep_info(dev, "version: " DRIVER_VERSION "; dma %s %s\n", | ||
| 3730 | use_dma ? (use_dma_chaining ? "chaining" : "enabled") | ||
| 3731 | : "disabled", | ||
| 3732 | dev->enhanced_mode ? "enhanced mode" : "legacy mode"); | ||
| 3733 | retval = device_create_file(&pdev->dev, &dev_attr_registers); | ||
| 3734 | if (retval) | ||
| 3735 | goto done; | ||
| 3736 | |||
| 3737 | retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget, | ||
| 3738 | gadget_release); | ||
| 3739 | if (retval) | ||
| 3740 | goto done; | ||
| 3741 | return 0; | ||
| 3742 | |||
| 3743 | done: | ||
| 3744 | if (dev) | ||
| 3745 | net2280_remove(pdev); | ||
| 3746 | return retval; | ||
| 3747 | } | ||
| 3748 | |||
| 3749 | /* make sure the board is quiescent; otherwise it will continue | ||
| 3750 | * generating IRQs across the upcoming reboot. | ||
| 3751 | */ | ||
| 3752 | |||
| 3753 | static void net2280_shutdown(struct pci_dev *pdev) | ||
| 3754 | { | ||
| 3755 | struct net2280 *dev = pci_get_drvdata(pdev); | ||
| 3756 | |||
| 3757 | /* disable IRQs */ | ||
| 3758 | writel(0, &dev->regs->pciirqenb0); | ||
| 3759 | writel(0, &dev->regs->pciirqenb1); | ||
| 3760 | |||
| 3761 | /* disable the pullup so the host will think we're gone */ | ||
| 3762 | writel(0, &dev->usb->usbctl); | ||
| 3763 | |||
| 3764 | /* Disable full-speed test mode */ | ||
| 3765 | if (dev->quirks & PLX_LEGACY) | ||
| 3766 | writel(0, &dev->usb->xcvrdiag); | ||
| 3767 | } | ||
| 3768 | |||
| 3769 | |||
| 3770 | /*-------------------------------------------------------------------------*/ | ||
| 3771 | |||
| 3772 | static const struct pci_device_id pci_ids[] = { { | ||
| 3773 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3774 | .class_mask = ~0, | ||
| 3775 | .vendor = PCI_VENDOR_ID_PLX_LEGACY, | ||
| 3776 | .device = 0x2280, | ||
| 3777 | .subvendor = PCI_ANY_ID, | ||
| 3778 | .subdevice = PCI_ANY_ID, | ||
| 3779 | .driver_data = PLX_LEGACY | PLX_2280, | ||
| 3780 | }, { | ||
| 3781 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3782 | .class_mask = ~0, | ||
| 3783 | .vendor = PCI_VENDOR_ID_PLX_LEGACY, | ||
| 3784 | .device = 0x2282, | ||
| 3785 | .subvendor = PCI_ANY_ID, | ||
| 3786 | .subdevice = PCI_ANY_ID, | ||
| 3787 | .driver_data = PLX_LEGACY, | ||
| 3788 | }, | ||
| 3789 | { | ||
| 3790 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3791 | .class_mask = ~0, | ||
| 3792 | .vendor = PCI_VENDOR_ID_PLX, | ||
| 3793 | .device = 0x3380, | ||
| 3794 | .subvendor = PCI_ANY_ID, | ||
| 3795 | .subdevice = PCI_ANY_ID, | ||
| 3796 | .driver_data = PLX_SUPERSPEED, | ||
| 3797 | }, | ||
| 3798 | { | ||
| 3799 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 3800 | .class_mask = ~0, | ||
| 3801 | .vendor = PCI_VENDOR_ID_PLX, | ||
| 3802 | .device = 0x3382, | ||
| 3803 | .subvendor = PCI_ANY_ID, | ||
| 3804 | .subdevice = PCI_ANY_ID, | ||
| 3805 | .driver_data = PLX_SUPERSPEED, | ||
| 3806 | }, | ||
| 3807 | { /* end: all zeroes */ } | ||
| 3808 | }; | ||
| 3809 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
| 3810 | |||
| 3811 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
| 3812 | static struct pci_driver net2280_pci_driver = { | ||
| 3813 | .name = (char *) driver_name, | ||
| 3814 | .id_table = pci_ids, | ||
| 3815 | |||
| 3816 | .probe = net2280_probe, | ||
| 3817 | .remove = net2280_remove, | ||
| 3818 | .shutdown = net2280_shutdown, | ||
| 3819 | |||
| 3820 | /* FIXME add power management support */ | ||
| 3821 | }; | ||
| 3822 | |||
| 3823 | module_pci_driver(net2280_pci_driver); | ||
| 3824 | |||
| 3825 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 3826 | MODULE_AUTHOR("David Brownell"); | ||
| 3827 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/udc/net2280.h b/drivers/usb/gadget/udc/net2280.h new file mode 100644 index 000000000000..03f15242d794 --- /dev/null +++ b/drivers/usb/gadget/udc/net2280.h | |||
| @@ -0,0 +1,403 @@ | |||
| 1 | /* | ||
| 2 | * NetChip 2280 high/full speed USB device controller. | ||
| 3 | * Unlike many such controllers, this one talks PCI. | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* | ||
| 7 | * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) | ||
| 8 | * Copyright (C) 2003 David Brownell | ||
| 9 | * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/usb/net2280.h> | ||
| 18 | #include <linux/usb/usb338x.h> | ||
| 19 | |||
| 20 | /*-------------------------------------------------------------------------*/ | ||
| 21 | |||
| 22 | #ifdef __KERNEL__ | ||
| 23 | |||
| 24 | /* indexed registers [11.10] are accessed indirectly | ||
| 25 | * caller must own the device lock. | ||
| 26 | */ | ||
| 27 | |||
| 28 | static inline u32 get_idx_reg(struct net2280_regs __iomem *regs, u32 index) | ||
| 29 | { | ||
| 30 | writel(index, ®s->idxaddr); | ||
| 31 | /* NOTE: synchs device/cpu memory views */ | ||
| 32 | return readl(®s->idxdata); | ||
| 33 | } | ||
| 34 | |||
| 35 | static inline void | ||
| 36 | set_idx_reg(struct net2280_regs __iomem *regs, u32 index, u32 value) | ||
| 37 | { | ||
| 38 | writel(index, ®s->idxaddr); | ||
| 39 | writel(value, ®s->idxdata); | ||
| 40 | /* posted, may not be visible yet */ | ||
| 41 | } | ||
| 42 | |||
| 43 | #endif /* __KERNEL__ */ | ||
| 44 | |||
| 45 | #define PCI_VENDOR_ID_PLX_LEGACY 0x17cc | ||
| 46 | |||
| 47 | #define PLX_LEGACY BIT(0) | ||
| 48 | #define PLX_2280 BIT(1) | ||
| 49 | #define PLX_SUPERSPEED BIT(2) | ||
| 50 | |||
| 51 | #define REG_DIAG 0x0 | ||
| 52 | #define RETRY_COUNTER 16 | ||
| 53 | #define FORCE_PCI_SERR 11 | ||
| 54 | #define FORCE_PCI_INTERRUPT 10 | ||
| 55 | #define FORCE_USB_INTERRUPT 9 | ||
| 56 | #define FORCE_CPU_INTERRUPT 8 | ||
| 57 | #define ILLEGAL_BYTE_ENABLES 5 | ||
| 58 | #define FAST_TIMES 4 | ||
| 59 | #define FORCE_RECEIVE_ERROR 2 | ||
| 60 | #define FORCE_TRANSMIT_CRC_ERROR 0 | ||
| 61 | #define REG_FRAME 0x02 /* from last sof */ | ||
| 62 | #define REG_CHIPREV 0x03 /* in bcd */ | ||
| 63 | #define REG_HS_NAK_RATE 0x0a /* NAK per N uframes */ | ||
| 64 | |||
| 65 | #define CHIPREV_1 0x0100 | ||
| 66 | #define CHIPREV_1A 0x0110 | ||
| 67 | |||
| 68 | /* DEFECT 7374 */ | ||
| 69 | #define DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS 200 | ||
| 70 | #define DEFECT_7374_PROCESSOR_WAIT_TIME 10 | ||
| 71 | |||
| 72 | /* ep0 max packet size */ | ||
| 73 | #define EP0_SS_MAX_PACKET_SIZE 0x200 | ||
| 74 | #define EP0_HS_MAX_PACKET_SIZE 0x40 | ||
| 75 | #ifdef __KERNEL__ | ||
| 76 | |||
| 77 | /*-------------------------------------------------------------------------*/ | ||
| 78 | |||
| 79 | /* [8.3] for scatter/gather i/o | ||
| 80 | * use struct net2280_dma_regs bitfields | ||
| 81 | */ | ||
| 82 | struct net2280_dma { | ||
| 83 | __le32 dmacount; | ||
| 84 | __le32 dmaaddr; /* the buffer */ | ||
| 85 | __le32 dmadesc; /* next dma descriptor */ | ||
| 86 | __le32 _reserved; | ||
| 87 | } __aligned(16); | ||
| 88 | |||
| 89 | /*-------------------------------------------------------------------------*/ | ||
| 90 | |||
| 91 | /* DRIVER DATA STRUCTURES and UTILITIES */ | ||
| 92 | |||
| 93 | struct net2280_ep { | ||
| 94 | struct usb_ep ep; | ||
| 95 | struct net2280_ep_regs __iomem *cfg; | ||
| 96 | struct net2280_ep_regs __iomem *regs; | ||
| 97 | struct net2280_dma_regs __iomem *dma; | ||
| 98 | struct net2280_dma *dummy; | ||
| 99 | struct usb338x_fifo_regs __iomem *fiforegs; | ||
| 100 | dma_addr_t td_dma; /* of dummy */ | ||
| 101 | struct net2280 *dev; | ||
| 102 | unsigned long irqs; | ||
| 103 | unsigned is_halt:1, dma_started:1; | ||
| 104 | |||
| 105 | /* analogous to a host-side qh */ | ||
| 106 | struct list_head queue; | ||
| 107 | const struct usb_endpoint_descriptor *desc; | ||
| 108 | unsigned num : 8, | ||
| 109 | fifo_size : 12, | ||
| 110 | in_fifo_validate : 1, | ||
| 111 | out_overflow : 1, | ||
| 112 | stopped : 1, | ||
| 113 | wedged : 1, | ||
| 114 | is_in : 1, | ||
| 115 | is_iso : 1, | ||
| 116 | responded : 1; | ||
| 117 | }; | ||
| 118 | |||
| 119 | static inline void allow_status(struct net2280_ep *ep) | ||
| 120 | { | ||
| 121 | /* ep0 only */ | ||
| 122 | writel(BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | | ||
| 123 | BIT(CLEAR_NAK_OUT_PACKETS) | | ||
| 124 | BIT(CLEAR_NAK_OUT_PACKETS_MODE), | ||
| 125 | &ep->regs->ep_rsp); | ||
| 126 | ep->stopped = 1; | ||
| 127 | } | ||
| 128 | |||
| 129 | static void allow_status_338x(struct net2280_ep *ep) | ||
| 130 | { | ||
| 131 | /* | ||
| 132 | * Control Status Phase Handshake was set by the chip when the setup | ||
| 133 | * packet arrived. While set, the chip automatically NAKs the host's | ||
| 134 | * Status Phase tokens. | ||
| 135 | */ | ||
| 136 | writel(BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE), &ep->regs->ep_rsp); | ||
| 137 | |||
| 138 | ep->stopped = 1; | ||
| 139 | |||
| 140 | /* TD 9.9 Halt Endpoint test. TD 9.22 set feature test. */ | ||
| 141 | ep->responded = 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | struct net2280_request { | ||
| 145 | struct usb_request req; | ||
| 146 | struct net2280_dma *td; | ||
| 147 | dma_addr_t td_dma; | ||
| 148 | struct list_head queue; | ||
| 149 | unsigned mapped : 1, | ||
| 150 | valid : 1; | ||
| 151 | }; | ||
| 152 | |||
| 153 | struct net2280 { | ||
| 154 | /* each pci device provides one gadget, several endpoints */ | ||
| 155 | struct usb_gadget gadget; | ||
| 156 | spinlock_t lock; | ||
| 157 | struct net2280_ep ep[9]; | ||
| 158 | struct usb_gadget_driver *driver; | ||
| 159 | unsigned enabled : 1, | ||
| 160 | protocol_stall : 1, | ||
| 161 | softconnect : 1, | ||
| 162 | got_irq : 1, | ||
| 163 | region:1, | ||
| 164 | u1_enable:1, | ||
| 165 | u2_enable:1, | ||
| 166 | ltm_enable:1, | ||
| 167 | wakeup_enable:1, | ||
| 168 | selfpowered:1, | ||
| 169 | addressed_state:1; | ||
| 170 | u16 chiprev; | ||
| 171 | int enhanced_mode; | ||
| 172 | int n_ep; | ||
| 173 | kernel_ulong_t quirks; | ||
| 174 | |||
| 175 | |||
| 176 | /* pci state used to access those endpoints */ | ||
| 177 | struct pci_dev *pdev; | ||
| 178 | struct net2280_regs __iomem *regs; | ||
| 179 | struct net2280_usb_regs __iomem *usb; | ||
| 180 | struct usb338x_usb_ext_regs __iomem *usb_ext; | ||
| 181 | struct net2280_pci_regs __iomem *pci; | ||
| 182 | struct net2280_dma_regs __iomem *dma; | ||
| 183 | struct net2280_dep_regs __iomem *dep; | ||
| 184 | struct net2280_ep_regs __iomem *epregs; | ||
| 185 | struct usb338x_fifo_regs __iomem *fiforegs; | ||
| 186 | struct usb338x_ll_regs __iomem *llregs; | ||
| 187 | struct usb338x_ll_lfps_regs __iomem *ll_lfps_regs; | ||
| 188 | struct usb338x_ll_tsn_regs __iomem *ll_tsn_regs; | ||
| 189 | struct usb338x_ll_chi_regs __iomem *ll_chicken_reg; | ||
| 190 | struct usb338x_pl_regs __iomem *plregs; | ||
| 191 | |||
| 192 | struct pci_pool *requests; | ||
| 193 | /* statistics...*/ | ||
| 194 | }; | ||
| 195 | |||
| 196 | static inline void set_halt(struct net2280_ep *ep) | ||
| 197 | { | ||
| 198 | /* ep0 and bulk/intr endpoints */ | ||
| 199 | writel(BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) | | ||
| 200 | /* set NAK_OUT for erratum 0114 */ | ||
| 201 | ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS) | | ||
| 202 | BIT(SET_ENDPOINT_HALT), | ||
| 203 | &ep->regs->ep_rsp); | ||
| 204 | } | ||
| 205 | |||
| 206 | static inline void clear_halt(struct net2280_ep *ep) | ||
| 207 | { | ||
| 208 | /* ep0 and bulk/intr endpoints */ | ||
| 209 | writel(BIT(CLEAR_ENDPOINT_HALT) | | ||
| 210 | BIT(CLEAR_ENDPOINT_TOGGLE) | | ||
| 211 | /* | ||
| 212 | * unless the gadget driver left a short packet in the | ||
| 213 | * fifo, this reverses the erratum 0114 workaround. | ||
| 214 | */ | ||
| 215 | ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS), | ||
| 216 | &ep->regs->ep_rsp); | ||
| 217 | } | ||
| 218 | |||
| 219 | /* | ||
| 220 | * FSM value for Defect 7374 (U1U2 Test) is managed in | ||
| 221 | * chip's SCRATCH register: | ||
| 222 | */ | ||
| 223 | #define DEFECT7374_FSM_FIELD 28 | ||
| 224 | |||
| 225 | /* Waiting for Control Read: | ||
| 226 | * - A transition to this state indicates a fresh USB connection, | ||
| 227 | * before the first Setup Packet. The connection speed is not | ||
| 228 | * known. Firmware is waiting for the first Control Read. | ||
| 229 | * - Starting state: This state can be thought of as the FSM's typical | ||
| 230 | * starting state. | ||
| 231 | * - Tip: Upon the first SS Control Read the FSM never | ||
| 232 | * returns to this state. | ||
| 233 | */ | ||
| 234 | #define DEFECT7374_FSM_WAITING_FOR_CONTROL_READ BIT(DEFECT7374_FSM_FIELD) | ||
| 235 | |||
| 236 | /* Non-SS Control Read: | ||
| 237 | * - A transition to this state indicates detection of the first HS | ||
| 238 | * or FS Control Read. | ||
| 239 | * - Tip: Upon the first SS Control Read the FSM never | ||
| 240 | * returns to this state. | ||
| 241 | */ | ||
| 242 | #define DEFECT7374_FSM_NON_SS_CONTROL_READ (2 << DEFECT7374_FSM_FIELD) | ||
| 243 | |||
| 244 | /* SS Control Read: | ||
| 245 | * - A transition to this state indicates detection of the | ||
| 246 | * first SS Control Read. | ||
| 247 | * - This state indicates workaround completion. Workarounds no longer | ||
| 248 | * need to be applied (as long as the chip remains powered up). | ||
| 249 | * - Tip: Once in this state the FSM state does not change (until | ||
| 250 | * the chip's power is lost and restored). | ||
| 251 | * - This can be thought of as the final state of the FSM; | ||
| 252 | * the FSM 'locks-up' in this state until the chip loses power. | ||
| 253 | */ | ||
| 254 | #define DEFECT7374_FSM_SS_CONTROL_READ (3 << DEFECT7374_FSM_FIELD) | ||
| 255 | |||
| 256 | #ifdef USE_RDK_LEDS | ||
| 257 | |||
| 258 | static inline void net2280_led_init(struct net2280 *dev) | ||
| 259 | { | ||
| 260 | /* LED3 (green) is on during USB activity. note erratum 0113. */ | ||
| 261 | writel(BIT(GPIO3_LED_SELECT) | | ||
| 262 | BIT(GPIO3_OUTPUT_ENABLE) | | ||
| 263 | BIT(GPIO2_OUTPUT_ENABLE) | | ||
| 264 | BIT(GPIO1_OUTPUT_ENABLE) | | ||
| 265 | BIT(GPIO0_OUTPUT_ENABLE), | ||
| 266 | &dev->regs->gpioctl); | ||
| 267 | } | ||
| 268 | |||
| 269 | /* indicate speed with bi-color LED 0/1 */ | ||
| 270 | static inline | ||
| 271 | void net2280_led_speed(struct net2280 *dev, enum usb_device_speed speed) | ||
| 272 | { | ||
| 273 | u32 val = readl(&dev->regs->gpioctl); | ||
| 274 | switch (speed) { | ||
| 275 | case USB_SPEED_SUPER: /* green + red */ | ||
| 276 | val |= BIT(GPIO0_DATA) | BIT(GPIO1_DATA); | ||
| 277 | break; | ||
| 278 | case USB_SPEED_HIGH: /* green */ | ||
| 279 | val &= ~BIT(GPIO0_DATA); | ||
| 280 | val |= BIT(GPIO1_DATA); | ||
| 281 | break; | ||
| 282 | case USB_SPEED_FULL: /* red */ | ||
| 283 | val &= ~BIT(GPIO1_DATA); | ||
| 284 | val |= BIT(GPIO0_DATA); | ||
| 285 | break; | ||
| 286 | default: /* (off/black) */ | ||
| 287 | val &= ~(BIT(GPIO1_DATA) | BIT(GPIO0_DATA)); | ||
| 288 | break; | ||
| 289 | } | ||
| 290 | writel(val, &dev->regs->gpioctl); | ||
| 291 | } | ||
| 292 | |||
| 293 | /* indicate power with LED 2 */ | ||
| 294 | static inline void net2280_led_active(struct net2280 *dev, int is_active) | ||
| 295 | { | ||
| 296 | u32 val = readl(&dev->regs->gpioctl); | ||
| 297 | |||
| 298 | /* FIXME this LED never seems to turn on.*/ | ||
| 299 | if (is_active) | ||
| 300 | val |= GPIO2_DATA; | ||
| 301 | else | ||
| 302 | val &= ~GPIO2_DATA; | ||
| 303 | writel(val, &dev->regs->gpioctl); | ||
| 304 | } | ||
| 305 | |||
| 306 | static inline void net2280_led_shutdown(struct net2280 *dev) | ||
| 307 | { | ||
| 308 | /* turn off all four GPIO*_DATA bits */ | ||
| 309 | writel(readl(&dev->regs->gpioctl) & ~0x0f, | ||
| 310 | &dev->regs->gpioctl); | ||
| 311 | } | ||
| 312 | |||
| 313 | #else | ||
| 314 | |||
| 315 | #define net2280_led_init(dev) do { } while (0) | ||
| 316 | #define net2280_led_speed(dev, speed) do { } while (0) | ||
| 317 | #define net2280_led_shutdown(dev) do { } while (0) | ||
| 318 | |||
| 319 | #endif | ||
| 320 | |||
| 321 | /*-------------------------------------------------------------------------*/ | ||
| 322 | |||
| 323 | #define ep_dbg(ndev, fmt, args...) \ | ||
| 324 | dev_dbg((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 325 | |||
| 326 | #define ep_vdbg(ndev, fmt, args...) \ | ||
| 327 | dev_vdbg((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 328 | |||
| 329 | #define ep_info(ndev, fmt, args...) \ | ||
| 330 | dev_info((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 331 | |||
| 332 | #define ep_warn(ndev, fmt, args...) \ | ||
| 333 | dev_warn((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 334 | |||
| 335 | #define ep_err(ndev, fmt, args...) \ | ||
| 336 | dev_err((&((ndev)->pdev->dev)), fmt, ##args) | ||
| 337 | |||
| 338 | /*-------------------------------------------------------------------------*/ | ||
| 339 | |||
| 340 | static inline void set_fifo_bytecount(struct net2280_ep *ep, unsigned count) | ||
| 341 | { | ||
| 342 | if (ep->dev->pdev->vendor == 0x17cc) | ||
| 343 | writeb(count, 2 + (u8 __iomem *) &ep->regs->ep_cfg); | ||
| 344 | else{ | ||
| 345 | u32 tmp = readl(&ep->cfg->ep_cfg) & | ||
| 346 | (~(0x07 << EP_FIFO_BYTE_COUNT)); | ||
| 347 | writel(tmp | (count << EP_FIFO_BYTE_COUNT), &ep->cfg->ep_cfg); | ||
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 351 | static inline void start_out_naking(struct net2280_ep *ep) | ||
| 352 | { | ||
| 353 | /* NOTE: hardware races lurk here, and PING protocol issues */ | ||
| 354 | writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 355 | /* synch with device */ | ||
| 356 | readl(&ep->regs->ep_rsp); | ||
| 357 | } | ||
| 358 | |||
| 359 | #ifdef DEBUG | ||
| 360 | static inline void assert_out_naking(struct net2280_ep *ep, const char *where) | ||
| 361 | { | ||
| 362 | u32 tmp = readl(&ep->regs->ep_stat); | ||
| 363 | |||
| 364 | if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) { | ||
| 365 | ep_dbg(ep->dev, "%s %s %08x !NAK\n", | ||
| 366 | ep->ep.name, where, tmp); | ||
| 367 | writel(BIT(SET_NAK_OUT_PACKETS), | ||
| 368 | &ep->regs->ep_rsp); | ||
| 369 | } | ||
| 370 | } | ||
| 371 | #define ASSERT_OUT_NAKING(ep) assert_out_naking(ep, __func__) | ||
| 372 | #else | ||
| 373 | #define ASSERT_OUT_NAKING(ep) do {} while (0) | ||
| 374 | #endif | ||
| 375 | |||
| 376 | static inline void stop_out_naking(struct net2280_ep *ep) | ||
| 377 | { | ||
| 378 | u32 tmp; | ||
| 379 | |||
| 380 | tmp = readl(&ep->regs->ep_stat); | ||
| 381 | if ((tmp & BIT(NAK_OUT_PACKETS)) != 0) | ||
| 382 | writel(BIT(CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
| 383 | } | ||
| 384 | |||
| 385 | |||
| 386 | static inline void set_max_speed(struct net2280_ep *ep, u32 max) | ||
| 387 | { | ||
| 388 | u32 reg; | ||
| 389 | static const u32 ep_enhanced[9] = { 0x10, 0x60, 0x30, 0x80, | ||
| 390 | 0x50, 0x20, 0x70, 0x40, 0x90 }; | ||
| 391 | |||
| 392 | if (ep->dev->enhanced_mode) | ||
| 393 | reg = ep_enhanced[ep->num]; | ||
| 394 | else{ | ||
| 395 | reg = (ep->num + 1) * 0x10; | ||
| 396 | if (ep->dev->gadget.speed != USB_SPEED_HIGH) | ||
| 397 | reg += 1; | ||
| 398 | } | ||
| 399 | |||
| 400 | set_idx_reg(ep->dev->regs, reg, max); | ||
| 401 | } | ||
| 402 | |||
| 403 | #endif /* __KERNEL__ */ | ||
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index 2ae4f6d69f74..e731373fd4d7 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c | |||
| @@ -2079,10 +2079,7 @@ static int omap_udc_start(struct usb_gadget *g, | |||
| 2079 | &udc->gadget); | 2079 | &udc->gadget); |
| 2080 | if (status < 0) { | 2080 | if (status < 0) { |
| 2081 | ERR("can't bind to transceiver\n"); | 2081 | ERR("can't bind to transceiver\n"); |
| 2082 | if (driver->unbind) { | 2082 | udc->driver = NULL; |
| 2083 | driver->unbind(&udc->gadget); | ||
| 2084 | udc->driver = NULL; | ||
| 2085 | } | ||
| 2086 | goto done; | 2083 | goto done; |
| 2087 | } | 2084 | } |
| 2088 | } else { | 2085 | } else { |
diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/udc/omap_udc.h index cfadeb5fc5de..cfadeb5fc5de 100644 --- a/drivers/usb/gadget/omap_udc.h +++ b/drivers/usb/gadget/udc/omap_udc.h | |||
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index eb8c3bedb57a..460d953c91b6 100644 --- a/drivers/usb/gadget/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/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 9984437d2952..251e4d5ee152 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | /* #define VERBOSE_DEBUG */ | 16 | /* #define VERBOSE_DEBUG */ |
| 17 | 17 | ||
| 18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
| 19 | #include <linux/gpio.h> | ||
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 21 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
| @@ -40,7 +41,6 @@ | |||
| 40 | 41 | ||
| 41 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
| 42 | #include <asm/dma.h> | 43 | #include <asm/dma.h> |
| 43 | #include <asm/gpio.h> | ||
| 44 | #include <asm/mach-types.h> | 44 | #include <asm/mach-types.h> |
| 45 | #include <asm/unaligned.h> | 45 | #include <asm/unaligned.h> |
| 46 | 46 | ||
| @@ -2105,11 +2105,9 @@ static int pxa25x_udc_probe(struct platform_device *pdev) | |||
| 2105 | if (irq < 0) | 2105 | if (irq < 0) |
| 2106 | return -ENODEV; | 2106 | return -ENODEV; |
| 2107 | 2107 | ||
| 2108 | dev->clk = clk_get(&pdev->dev, NULL); | 2108 | dev->clk = devm_clk_get(&pdev->dev, NULL); |
| 2109 | if (IS_ERR(dev->clk)) { | 2109 | if (IS_ERR(dev->clk)) |
| 2110 | retval = PTR_ERR(dev->clk); | 2110 | return PTR_ERR(dev->clk); |
| 2111 | goto err_clk; | ||
| 2112 | } | ||
| 2113 | 2111 | ||
| 2114 | pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, | 2112 | pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, |
| 2115 | dev->has_cfr ? "" : " (!cfr)", | 2113 | dev->has_cfr ? "" : " (!cfr)", |
| @@ -2120,15 +2118,16 @@ static int pxa25x_udc_probe(struct platform_device *pdev) | |||
| 2120 | dev->dev = &pdev->dev; | 2118 | dev->dev = &pdev->dev; |
| 2121 | dev->mach = dev_get_platdata(&pdev->dev); | 2119 | dev->mach = dev_get_platdata(&pdev->dev); |
| 2122 | 2120 | ||
| 2123 | dev->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | 2121 | dev->transceiver = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); |
| 2124 | 2122 | ||
| 2125 | if (gpio_is_valid(dev->mach->gpio_pullup)) { | 2123 | if (gpio_is_valid(dev->mach->gpio_pullup)) { |
| 2126 | if ((retval = gpio_request(dev->mach->gpio_pullup, | 2124 | retval = devm_gpio_request(&pdev->dev, dev->mach->gpio_pullup, |
| 2127 | "pca25x_udc GPIO PULLUP"))) { | 2125 | "pca25x_udc GPIO PULLUP"); |
| 2126 | if (retval) { | ||
| 2128 | dev_dbg(&pdev->dev, | 2127 | dev_dbg(&pdev->dev, |
| 2129 | "can't get pullup gpio %d, err: %d\n", | 2128 | "can't get pullup gpio %d, err: %d\n", |
| 2130 | dev->mach->gpio_pullup, retval); | 2129 | dev->mach->gpio_pullup, retval); |
| 2131 | goto err_gpio_pullup; | 2130 | goto err; |
| 2132 | } | 2131 | } |
| 2133 | gpio_direction_output(dev->mach->gpio_pullup, 0); | 2132 | gpio_direction_output(dev->mach->gpio_pullup, 0); |
| 2134 | } | 2133 | } |
| @@ -2146,30 +2145,32 @@ static int pxa25x_udc_probe(struct platform_device *pdev) | |||
| 2146 | dev->vbus = 0; | 2145 | dev->vbus = 0; |
| 2147 | 2146 | ||
| 2148 | /* irq setup after old hardware state is cleaned up */ | 2147 | /* irq setup after old hardware state is cleaned up */ |
| 2149 | retval = request_irq(irq, pxa25x_udc_irq, | 2148 | retval = devm_request_irq(&pdev->dev, irq, pxa25x_udc_irq, 0, |
| 2150 | 0, driver_name, dev); | 2149 | driver_name, dev); |
| 2151 | if (retval != 0) { | 2150 | if (retval != 0) { |
| 2152 | pr_err("%s: can't get irq %d, err %d\n", | 2151 | pr_err("%s: can't get irq %d, err %d\n", |
| 2153 | driver_name, irq, retval); | 2152 | driver_name, irq, retval); |
| 2154 | goto err_irq1; | 2153 | goto err; |
| 2155 | } | 2154 | } |
| 2156 | dev->got_irq = 1; | 2155 | dev->got_irq = 1; |
| 2157 | 2156 | ||
| 2158 | #ifdef CONFIG_ARCH_LUBBOCK | 2157 | #ifdef CONFIG_ARCH_LUBBOCK |
| 2159 | if (machine_is_lubbock()) { | 2158 | if (machine_is_lubbock()) { |
| 2160 | retval = request_irq(LUBBOCK_USB_DISC_IRQ, lubbock_vbus_irq, | 2159 | retval = devm_request_irq(&pdev->dev, LUBBOCK_USB_DISC_IRQ, |
| 2161 | 0, driver_name, dev); | 2160 | lubbock_vbus_irq, 0, driver_name, |
| 2161 | dev); | ||
| 2162 | if (retval != 0) { | 2162 | if (retval != 0) { |
| 2163 | pr_err("%s: can't get irq %i, err %d\n", | 2163 | pr_err("%s: can't get irq %i, err %d\n", |
| 2164 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); | 2164 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); |
| 2165 | goto err_irq_lub; | 2165 | goto err; |
| 2166 | } | 2166 | } |
| 2167 | retval = request_irq(LUBBOCK_USB_IRQ, lubbock_vbus_irq, | 2167 | retval = devm_request_irq(&pdev->dev, LUBBOCK_USB_IRQ, |
| 2168 | 0, driver_name, dev); | 2168 | lubbock_vbus_irq, 0, driver_name, |
| 2169 | dev); | ||
| 2169 | if (retval != 0) { | 2170 | if (retval != 0) { |
| 2170 | pr_err("%s: can't get irq %i, err %d\n", | 2171 | pr_err("%s: can't get irq %i, err %d\n", |
| 2171 | driver_name, LUBBOCK_USB_IRQ, retval); | 2172 | driver_name, LUBBOCK_USB_IRQ, retval); |
| 2172 | goto lubbock_fail0; | 2173 | goto err; |
| 2173 | } | 2174 | } |
| 2174 | } else | 2175 | } else |
| 2175 | #endif | 2176 | #endif |
| @@ -2180,22 +2181,9 @@ static int pxa25x_udc_probe(struct platform_device *pdev) | |||
| 2180 | return retval; | 2181 | return retval; |
| 2181 | 2182 | ||
| 2182 | remove_debug_files(dev); | 2183 | remove_debug_files(dev); |
| 2183 | #ifdef CONFIG_ARCH_LUBBOCK | 2184 | err: |
| 2184 | lubbock_fail0: | 2185 | if (!IS_ERR_OR_NULL(dev->transceiver)) |
| 2185 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | ||
| 2186 | err_irq_lub: | ||
| 2187 | free_irq(irq, dev); | ||
| 2188 | #endif | ||
| 2189 | err_irq1: | ||
| 2190 | if (gpio_is_valid(dev->mach->gpio_pullup)) | ||
| 2191 | gpio_free(dev->mach->gpio_pullup); | ||
| 2192 | err_gpio_pullup: | ||
| 2193 | if (!IS_ERR_OR_NULL(dev->transceiver)) { | ||
| 2194 | usb_put_phy(dev->transceiver); | ||
| 2195 | dev->transceiver = NULL; | 2186 | dev->transceiver = NULL; |
| 2196 | } | ||
| 2197 | clk_put(dev->clk); | ||
| 2198 | err_clk: | ||
| 2199 | return retval; | 2187 | return retval; |
| 2200 | } | 2188 | } |
| 2201 | 2189 | ||
| @@ -2217,25 +2205,8 @@ static int pxa25x_udc_remove(struct platform_device *pdev) | |||
| 2217 | 2205 | ||
| 2218 | remove_debug_files(dev); | 2206 | remove_debug_files(dev); |
| 2219 | 2207 | ||
| 2220 | if (dev->got_irq) { | 2208 | if (!IS_ERR_OR_NULL(dev->transceiver)) |
| 2221 | free_irq(platform_get_irq(pdev, 0), dev); | ||
| 2222 | dev->got_irq = 0; | ||
| 2223 | } | ||
| 2224 | #ifdef CONFIG_ARCH_LUBBOCK | ||
| 2225 | if (machine_is_lubbock()) { | ||
| 2226 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | ||
| 2227 | free_irq(LUBBOCK_USB_IRQ, dev); | ||
| 2228 | } | ||
| 2229 | #endif | ||
| 2230 | if (gpio_is_valid(dev->mach->gpio_pullup)) | ||
| 2231 | gpio_free(dev->mach->gpio_pullup); | ||
| 2232 | |||
| 2233 | clk_put(dev->clk); | ||
| 2234 | |||
| 2235 | if (!IS_ERR_OR_NULL(dev->transceiver)) { | ||
| 2236 | usb_put_phy(dev->transceiver); | ||
| 2237 | dev->transceiver = NULL; | 2209 | dev->transceiver = NULL; |
| 2238 | } | ||
| 2239 | 2210 | ||
| 2240 | the_controller = NULL; | 2211 | the_controller = NULL; |
| 2241 | return 0; | 2212 | return 0; |
diff --git a/drivers/usb/gadget/pxa25x_udc.h b/drivers/usb/gadget/udc/pxa25x_udc.h index 3fe5931dc21a..3fe5931dc21a 100644 --- a/drivers/usb/gadget/pxa25x_udc.h +++ b/drivers/usb/gadget/udc/pxa25x_udc.h | |||
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index cdf4d678be96..597d39f89420 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c | |||
| @@ -2446,6 +2446,9 @@ static int pxa_udc_probe(struct platform_device *pdev) | |||
| 2446 | retval = PTR_ERR(udc->clk); | 2446 | retval = PTR_ERR(udc->clk); |
| 2447 | goto err_clk; | 2447 | goto err_clk; |
| 2448 | } | 2448 | } |
| 2449 | retval = clk_prepare(udc->clk); | ||
| 2450 | if (retval) | ||
| 2451 | goto err_clk_prepare; | ||
| 2449 | 2452 | ||
| 2450 | retval = -ENOMEM; | 2453 | retval = -ENOMEM; |
| 2451 | udc->regs = ioremap(regs->start, resource_size(regs)); | 2454 | udc->regs = ioremap(regs->start, resource_size(regs)); |
| @@ -2483,6 +2486,8 @@ err_add_udc: | |||
| 2483 | err_irq: | 2486 | err_irq: |
| 2484 | iounmap(udc->regs); | 2487 | iounmap(udc->regs); |
| 2485 | err_map: | 2488 | err_map: |
| 2489 | clk_unprepare(udc->clk); | ||
| 2490 | err_clk_prepare: | ||
| 2486 | clk_put(udc->clk); | 2491 | clk_put(udc->clk); |
| 2487 | udc->clk = NULL; | 2492 | udc->clk = NULL; |
| 2488 | err_clk: | 2493 | err_clk: |
| @@ -2509,6 +2514,7 @@ static int pxa_udc_remove(struct platform_device *_dev) | |||
| 2509 | 2514 | ||
| 2510 | udc->transceiver = NULL; | 2515 | udc->transceiver = NULL; |
| 2511 | the_controller = NULL; | 2516 | the_controller = NULL; |
| 2517 | clk_unprepare(udc->clk); | ||
| 2512 | clk_put(udc->clk); | 2518 | clk_put(udc->clk); |
| 2513 | iounmap(udc->regs); | 2519 | iounmap(udc->regs); |
| 2514 | 2520 | ||
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/udc/pxa27x_udc.h index 28f2b53530f5..28f2b53530f5 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/udc/pxa27x_udc.h | |||
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index b698a490cc7d..de2a8713b428 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c | |||
| @@ -1826,18 +1826,12 @@ static int __exit r8a66597_remove(struct platform_device *pdev) | |||
| 1826 | 1826 | ||
| 1827 | usb_del_gadget_udc(&r8a66597->gadget); | 1827 | usb_del_gadget_udc(&r8a66597->gadget); |
| 1828 | del_timer_sync(&r8a66597->timer); | 1828 | del_timer_sync(&r8a66597->timer); |
| 1829 | iounmap(r8a66597->reg); | ||
| 1830 | if (r8a66597->pdata->sudmac) | ||
| 1831 | iounmap(r8a66597->sudmac_reg); | ||
| 1832 | free_irq(platform_get_irq(pdev, 0), r8a66597); | ||
| 1833 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); | 1829 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); |
| 1834 | 1830 | ||
| 1835 | if (r8a66597->pdata->on_chip) { | 1831 | if (r8a66597->pdata->on_chip) { |
| 1836 | clk_disable_unprepare(r8a66597->clk); | 1832 | clk_disable_unprepare(r8a66597->clk); |
| 1837 | clk_put(r8a66597->clk); | ||
| 1838 | } | 1833 | } |
| 1839 | 1834 | ||
| 1840 | kfree(r8a66597); | ||
| 1841 | return 0; | 1835 | return 0; |
| 1842 | } | 1836 | } |
| 1843 | 1837 | ||
| @@ -1845,28 +1839,24 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r) | |||
| 1845 | { | 1839 | { |
| 1846 | } | 1840 | } |
| 1847 | 1841 | ||
| 1848 | static int __init r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, | 1842 | static int r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, |
| 1849 | struct platform_device *pdev) | 1843 | struct platform_device *pdev) |
| 1850 | { | 1844 | { |
| 1851 | struct resource *res; | 1845 | struct resource *res; |
| 1852 | 1846 | ||
| 1853 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); | 1847 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); |
| 1854 | if (!res) { | 1848 | r8a66597->sudmac_reg = devm_ioremap_resource(&pdev->dev, res); |
| 1855 | dev_err(&pdev->dev, "platform_get_resource error(sudmac).\n"); | 1849 | if (IS_ERR(r8a66597->sudmac_reg)) { |
| 1856 | return -ENODEV; | ||
| 1857 | } | ||
| 1858 | |||
| 1859 | r8a66597->sudmac_reg = ioremap(res->start, resource_size(res)); | ||
| 1860 | if (r8a66597->sudmac_reg == NULL) { | ||
| 1861 | dev_err(&pdev->dev, "ioremap error(sudmac).\n"); | 1850 | dev_err(&pdev->dev, "ioremap error(sudmac).\n"); |
| 1862 | return -ENOMEM; | 1851 | return PTR_ERR(r8a66597->sudmac_reg); |
| 1863 | } | 1852 | } |
| 1864 | 1853 | ||
| 1865 | return 0; | 1854 | return 0; |
| 1866 | } | 1855 | } |
| 1867 | 1856 | ||
| 1868 | static int __init r8a66597_probe(struct platform_device *pdev) | 1857 | static int r8a66597_probe(struct platform_device *pdev) |
| 1869 | { | 1858 | { |
| 1859 | struct device *dev = &pdev->dev; | ||
| 1870 | char clk_name[8]; | 1860 | char clk_name[8]; |
| 1871 | struct resource *res, *ires; | 1861 | struct resource *res, *ires; |
| 1872 | int irq; | 1862 | int irq; |
| @@ -1877,39 +1867,27 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
| 1877 | unsigned long irq_trigger; | 1867 | unsigned long irq_trigger; |
| 1878 | 1868 | ||
| 1879 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1869 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1880 | if (!res) { | 1870 | reg = devm_ioremap_resource(&pdev->dev, res); |
| 1881 | ret = -ENODEV; | 1871 | if (IS_ERR(reg)) |
| 1882 | dev_err(&pdev->dev, "platform_get_resource error.\n"); | 1872 | return PTR_ERR(reg); |
| 1883 | goto clean_up; | ||
| 1884 | } | ||
| 1885 | 1873 | ||
| 1886 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1874 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 1887 | irq = ires->start; | 1875 | irq = ires->start; |
| 1888 | irq_trigger = ires->flags & IRQF_TRIGGER_MASK; | 1876 | irq_trigger = ires->flags & IRQF_TRIGGER_MASK; |
| 1889 | 1877 | ||
| 1890 | if (irq < 0) { | 1878 | if (irq < 0) { |
| 1891 | ret = -ENODEV; | 1879 | dev_err(dev, "platform_get_irq error.\n"); |
| 1892 | dev_err(&pdev->dev, "platform_get_irq error.\n"); | 1880 | return -ENODEV; |
| 1893 | goto clean_up; | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | reg = ioremap(res->start, resource_size(res)); | ||
| 1897 | if (reg == NULL) { | ||
| 1898 | ret = -ENOMEM; | ||
| 1899 | dev_err(&pdev->dev, "ioremap error.\n"); | ||
| 1900 | goto clean_up; | ||
| 1901 | } | 1881 | } |
| 1902 | 1882 | ||
| 1903 | /* initialize ucd */ | 1883 | /* initialize ucd */ |
| 1904 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); | 1884 | r8a66597 = devm_kzalloc(dev, sizeof(struct r8a66597), GFP_KERNEL); |
| 1905 | if (r8a66597 == NULL) { | 1885 | if (r8a66597 == NULL) |
| 1906 | ret = -ENOMEM; | 1886 | return -ENOMEM; |
| 1907 | goto clean_up; | ||
| 1908 | } | ||
| 1909 | 1887 | ||
| 1910 | spin_lock_init(&r8a66597->lock); | 1888 | spin_lock_init(&r8a66597->lock); |
| 1911 | platform_set_drvdata(pdev, r8a66597); | 1889 | platform_set_drvdata(pdev, r8a66597); |
| 1912 | r8a66597->pdata = dev_get_platdata(&pdev->dev); | 1890 | r8a66597->pdata = dev_get_platdata(dev); |
| 1913 | r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; | 1891 | r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; |
| 1914 | 1892 | ||
| 1915 | r8a66597->gadget.ops = &r8a66597_gadget_ops; | 1893 | r8a66597->gadget.ops = &r8a66597_gadget_ops; |
| @@ -1923,12 +1901,10 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
| 1923 | 1901 | ||
| 1924 | if (r8a66597->pdata->on_chip) { | 1902 | if (r8a66597->pdata->on_chip) { |
| 1925 | snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); | 1903 | snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); |
| 1926 | r8a66597->clk = clk_get(&pdev->dev, clk_name); | 1904 | r8a66597->clk = devm_clk_get(dev, clk_name); |
| 1927 | if (IS_ERR(r8a66597->clk)) { | 1905 | if (IS_ERR(r8a66597->clk)) { |
| 1928 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", | 1906 | dev_err(dev, "cannot get clock \"%s\"\n", clk_name); |
| 1929 | clk_name); | 1907 | return PTR_ERR(r8a66597->clk); |
| 1930 | ret = PTR_ERR(r8a66597->clk); | ||
| 1931 | goto clean_up; | ||
| 1932 | } | 1908 | } |
| 1933 | clk_prepare_enable(r8a66597->clk); | 1909 | clk_prepare_enable(r8a66597->clk); |
| 1934 | } | 1910 | } |
| @@ -1941,10 +1917,10 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
| 1941 | 1917 | ||
| 1942 | disable_controller(r8a66597); /* make sure controller is disabled */ | 1918 | disable_controller(r8a66597); /* make sure controller is disabled */ |
| 1943 | 1919 | ||
| 1944 | ret = request_irq(irq, r8a66597_irq, IRQF_SHARED, | 1920 | ret = devm_request_irq(dev, irq, r8a66597_irq, IRQF_SHARED, |
| 1945 | udc_name, r8a66597); | 1921 | udc_name, r8a66597); |
| 1946 | if (ret < 0) { | 1922 | if (ret < 0) { |
| 1947 | dev_err(&pdev->dev, "request_irq error (%d)\n", ret); | 1923 | dev_err(dev, "request_irq error (%d)\n", ret); |
| 1948 | goto clean_up2; | 1924 | goto clean_up2; |
| 1949 | } | 1925 | } |
| 1950 | 1926 | ||
| @@ -1978,37 +1954,25 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
| 1978 | GFP_KERNEL); | 1954 | GFP_KERNEL); |
| 1979 | if (r8a66597->ep0_req == NULL) { | 1955 | if (r8a66597->ep0_req == NULL) { |
| 1980 | ret = -ENOMEM; | 1956 | ret = -ENOMEM; |
| 1981 | goto clean_up3; | 1957 | goto clean_up2; |
| 1982 | } | 1958 | } |
| 1983 | r8a66597->ep0_req->complete = nop_completion; | 1959 | r8a66597->ep0_req->complete = nop_completion; |
| 1984 | 1960 | ||
| 1985 | ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget); | 1961 | ret = usb_add_gadget_udc(dev, &r8a66597->gadget); |
| 1986 | if (ret) | 1962 | if (ret) |
| 1987 | goto err_add_udc; | 1963 | goto err_add_udc; |
| 1988 | 1964 | ||
| 1989 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); | 1965 | dev_info(dev, "version %s\n", DRIVER_VERSION); |
| 1990 | return 0; | 1966 | return 0; |
| 1991 | 1967 | ||
| 1992 | err_add_udc: | 1968 | err_add_udc: |
| 1993 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); | 1969 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); |
| 1994 | clean_up3: | ||
| 1995 | free_irq(irq, r8a66597); | ||
| 1996 | clean_up2: | 1970 | clean_up2: |
| 1997 | if (r8a66597->pdata->on_chip) { | 1971 | if (r8a66597->pdata->on_chip) |
| 1998 | clk_disable_unprepare(r8a66597->clk); | 1972 | clk_disable_unprepare(r8a66597->clk); |
| 1999 | clk_put(r8a66597->clk); | 1973 | |
| 2000 | } | 1974 | if (r8a66597->ep0_req) |
| 2001 | clean_up: | 1975 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); |
| 2002 | if (r8a66597) { | ||
| 2003 | if (r8a66597->sudmac_reg) | ||
| 2004 | iounmap(r8a66597->sudmac_reg); | ||
| 2005 | if (r8a66597->ep0_req) | ||
| 2006 | r8a66597_free_request(&r8a66597->ep[0].ep, | ||
| 2007 | r8a66597->ep0_req); | ||
| 2008 | kfree(r8a66597); | ||
| 2009 | } | ||
| 2010 | if (reg) | ||
| 2011 | iounmap(reg); | ||
| 2012 | 1976 | ||
| 2013 | return ret; | 1977 | return ret; |
| 2014 | } | 1978 | } |
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/udc/r8a66597-udc.h index 45c4b2df1785..45c4b2df1785 100644 --- a/drivers/usb/gadget/r8a66597-udc.h +++ b/drivers/usb/gadget/udc/r8a66597-udc.h | |||
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index 10c6a128250c..10c6a128250c 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c | |||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index 7987aa049fab..357b58e0087b 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c | |||
| @@ -1788,7 +1788,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) | |||
| 1788 | return PTR_ERR(usb_bus_clock); | 1788 | return PTR_ERR(usb_bus_clock); |
| 1789 | } | 1789 | } |
| 1790 | 1790 | ||
| 1791 | clk_enable(usb_bus_clock); | 1791 | clk_prepare_enable(usb_bus_clock); |
| 1792 | 1792 | ||
| 1793 | udc_clock = clk_get(NULL, "usb-device"); | 1793 | udc_clock = clk_get(NULL, "usb-device"); |
| 1794 | if (IS_ERR(udc_clock)) { | 1794 | if (IS_ERR(udc_clock)) { |
| @@ -1796,7 +1796,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) | |||
| 1796 | return PTR_ERR(udc_clock); | 1796 | return PTR_ERR(udc_clock); |
| 1797 | } | 1797 | } |
| 1798 | 1798 | ||
| 1799 | clk_enable(udc_clock); | 1799 | clk_prepare_enable(udc_clock); |
| 1800 | 1800 | ||
| 1801 | mdelay(10); | 1801 | mdelay(10); |
| 1802 | 1802 | ||
| @@ -1952,13 +1952,13 @@ static int s3c2410_udc_remove(struct platform_device *pdev) | |||
| 1952 | release_mem_region(rsrc_start, rsrc_len); | 1952 | release_mem_region(rsrc_start, rsrc_len); |
| 1953 | 1953 | ||
| 1954 | if (!IS_ERR(udc_clock) && udc_clock != NULL) { | 1954 | if (!IS_ERR(udc_clock) && udc_clock != NULL) { |
| 1955 | clk_disable(udc_clock); | 1955 | clk_disable_unprepare(udc_clock); |
| 1956 | clk_put(udc_clock); | 1956 | clk_put(udc_clock); |
| 1957 | udc_clock = NULL; | 1957 | udc_clock = NULL; |
| 1958 | } | 1958 | } |
| 1959 | 1959 | ||
| 1960 | if (!IS_ERR(usb_bus_clock) && usb_bus_clock != NULL) { | 1960 | if (!IS_ERR(usb_bus_clock) && usb_bus_clock != NULL) { |
| 1961 | clk_disable(usb_bus_clock); | 1961 | clk_disable_unprepare(usb_bus_clock); |
| 1962 | clk_put(usb_bus_clock); | 1962 | clk_put(usb_bus_clock); |
| 1963 | usb_bus_clock = NULL; | 1963 | usb_bus_clock = NULL; |
| 1964 | } | 1964 | } |
diff --git a/drivers/usb/gadget/s3c2410_udc.h b/drivers/usb/gadget/udc/s3c2410_udc.h index 93bf225f1969..93bf225f1969 100644 --- a/drivers/usb/gadget/s3c2410_udc.h +++ b/drivers/usb/gadget/udc/s3c2410_udc.h | |||
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index b0d98172bc07..b0d98172bc07 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c | |||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 03314f861bee..82800a775501 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
| @@ -37,6 +37,14 @@ config USB_XHCI_MVEBU | |||
| 37 | Say 'Y' to enable the support for the xHCI host controller | 37 | Say 'Y' to enable the support for the xHCI host controller |
| 38 | found in Marvell Armada 375/38x ARM SOCs. | 38 | found in Marvell Armada 375/38x ARM SOCs. |
| 39 | 39 | ||
| 40 | config USB_XHCI_RCAR | ||
| 41 | tristate "xHCI support for Renesas R-Car SoCs" | ||
| 42 | select USB_XHCI_PLATFORM | ||
| 43 | depends on ARCH_SHMOBILE || COMPILE_TEST | ||
| 44 | ---help--- | ||
| 45 | Say 'Y' to enable the support for the xHCI host controller | ||
| 46 | found in Renesas R-Car ARM SoCs. | ||
| 47 | |||
| 40 | endif # USB_XHCI_HCD | 48 | endif # USB_XHCI_HCD |
| 41 | 49 | ||
| 42 | config USB_EHCI_HCD | 50 | config USB_EHCI_HCD |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index af89a903d97e..144c038ef70f 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
| @@ -22,6 +22,9 @@ ifneq ($(CONFIG_USB_XHCI_PLATFORM), ) | |||
| 22 | ifneq ($(CONFIG_USB_XHCI_MVEBU), ) | 22 | ifneq ($(CONFIG_USB_XHCI_MVEBU), ) |
| 23 | xhci-hcd-y += xhci-mvebu.o | 23 | xhci-hcd-y += xhci-mvebu.o |
| 24 | endif | 24 | endif |
| 25 | ifneq ($(CONFIG_USB_XHCI_RCAR), ) | ||
| 26 | xhci-hcd-y += xhci-rcar.o | ||
| 27 | endif | ||
| 25 | endif | 28 | endif |
| 26 | 29 | ||
| 27 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ | 30 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ |
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index d1c76216350f..cda0a2f5c467 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c | |||
| @@ -88,7 +88,7 @@ static int exynos_ehci_get_phy(struct device *dev, | |||
| 88 | return -EINVAL; | 88 | return -EINVAL; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | phy = devm_of_phy_get(dev, child, 0); | 91 | phy = devm_of_phy_get(dev, child, NULL); |
| 92 | of_node_put(child); | 92 | of_node_put(child); |
| 93 | if (IS_ERR(phy)) { | 93 | if (IS_ERR(phy)) { |
| 94 | ret = PTR_ERR(phy); | 94 | ret = PTR_ERR(phy); |
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/ehci-mem.c b/drivers/usb/host/ehci-mem.c index c0fb6a8ae6a3..b6205fac3567 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
| @@ -209,7 +209,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) | |||
| 209 | ehci->periodic = (__le32 *) | 209 | ehci->periodic = (__le32 *) |
| 210 | dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller, | 210 | dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller, |
| 211 | ehci->periodic_size * sizeof(__le32), | 211 | ehci->periodic_size * sizeof(__le32), |
| 212 | &ehci->periodic_dma, 0); | 212 | &ehci->periodic_dma, flags); |
| 213 | if (ehci->periodic == NULL) { | 213 | if (ehci->periodic == NULL) { |
| 214 | goto fail; | 214 | goto fail; |
| 215 | } | 215 | } |
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 982c09bebe0f..934b39d5e44a 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c | |||
| @@ -190,7 +190,7 @@ static const struct dev_pm_ops ehci_msm_dev_pm_ops = { | |||
| 190 | .resume = ehci_msm_pm_resume, | 190 | .resume = ehci_msm_pm_resume, |
| 191 | }; | 191 | }; |
| 192 | 192 | ||
| 193 | static struct of_device_id msm_ehci_dt_match[] = { | 193 | static const struct of_device_id msm_ehci_dt_match[] = { |
| 194 | { .compatible = "qcom,ehci-host", }, | 194 | { .compatible = "qcom,ehci-host", }, |
| 195 | {} | 195 | {} |
| 196 | }; | 196 | }; |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 3e86bf4371b3..ca7b964124af 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
| @@ -35,6 +35,21 @@ static const char hcd_name[] = "ehci-pci"; | |||
| 35 | #define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70 | 35 | #define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70 |
| 36 | 36 | ||
| 37 | /*-------------------------------------------------------------------------*/ | 37 | /*-------------------------------------------------------------------------*/ |
| 38 | #define PCI_DEVICE_ID_INTEL_QUARK_X1000_SOC 0x0939 | ||
| 39 | static inline bool is_intel_quark_x1000(struct pci_dev *pdev) | ||
| 40 | { | ||
| 41 | return pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
| 42 | pdev->device == PCI_DEVICE_ID_INTEL_QUARK_X1000_SOC; | ||
| 43 | } | ||
| 44 | |||
| 45 | /* | ||
| 46 | * 0x84 is the offset of in/out threshold register, | ||
| 47 | * and it is the same offset as the register of 'hostpc'. | ||
| 48 | */ | ||
| 49 | #define intel_quark_x1000_insnreg01 hostpc | ||
| 50 | |||
| 51 | /* Maximum usable threshold value is 0x7f dwords for both IN and OUT */ | ||
| 52 | #define INTEL_QUARK_X1000_EHCI_MAX_THRESHOLD 0x007f007f | ||
| 38 | 53 | ||
| 39 | /* called after powerup, by probe or system-pm "wakeup" */ | 54 | /* called after powerup, by probe or system-pm "wakeup" */ |
| 40 | static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | 55 | static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) |
| @@ -50,6 +65,16 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | |||
| 50 | if (!retval) | 65 | if (!retval) |
| 51 | ehci_dbg(ehci, "MWI active\n"); | 66 | ehci_dbg(ehci, "MWI active\n"); |
| 52 | 67 | ||
| 68 | /* Reset the threshold limit */ | ||
| 69 | if (is_intel_quark_x1000(pdev)) { | ||
| 70 | /* | ||
| 71 | * For the Intel QUARK X1000, raise the I/O threshold to the | ||
| 72 | * maximum usable value in order to improve performance. | ||
| 73 | */ | ||
| 74 | ehci_writel(ehci, INTEL_QUARK_X1000_EHCI_MAX_THRESHOLD, | ||
| 75 | ehci->regs->intel_quark_x1000_insnreg01); | ||
| 76 | } | ||
| 77 | |||
| 53 | return 0; | 78 | return 0; |
| 54 | } | 79 | } |
| 55 | 80 | ||
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 1d59958ad0ce..1355ff0946b9 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c | |||
| @@ -150,7 +150,7 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev) | |||
| 150 | return 0; | 150 | return 0; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | static struct of_device_id spear_ehci_id_table[] = { | 153 | static const struct of_device_id spear_ehci_id_table[] = { |
| 154 | { .compatible = "st,spear600-ehci", }, | 154 | { .compatible = "st,spear600-ehci", }, |
| 155 | { }, | 155 | { }, |
| 156 | }; | 156 | }; |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 6fdcb8ad2296..7aafb05e7a40 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #define DRV_NAME "tegra-ehci" | 46 | #define DRV_NAME "tegra-ehci" |
| 47 | 47 | ||
| 48 | static struct hc_driver __read_mostly tegra_ehci_hc_driver; | 48 | static struct hc_driver __read_mostly tegra_ehci_hc_driver; |
| 49 | static bool usb1_reset_attempted; | ||
| 49 | 50 | ||
| 50 | struct tegra_ehci_soc_config { | 51 | struct tegra_ehci_soc_config { |
| 51 | bool has_hostpc; | 52 | bool has_hostpc; |
| @@ -60,6 +61,61 @@ struct tegra_ehci_hcd { | |||
| 60 | enum tegra_usb_phy_port_speed port_speed; | 61 | enum tegra_usb_phy_port_speed port_speed; |
| 61 | }; | 62 | }; |
| 62 | 63 | ||
| 64 | /* | ||
| 65 | * The 1st USB controller contains some UTMI pad registers that are global for | ||
| 66 | * all the controllers on the chip. Those registers are also cleared when | ||
| 67 | * reset is asserted to the 1st controller. This means that the 1st controller | ||
| 68 | * can only be reset when no other controlled has finished probing. So we'll | ||
| 69 | * reset the 1st controller before doing any other setup on any of the | ||
| 70 | * controllers, and then never again. | ||
| 71 | * | ||
| 72 | * Since this is a PHY issue, the Tegra PHY driver should probably be doing | ||
| 73 | * the resetting of the USB controllers. But to keep compatibility with old | ||
| 74 | * device trees that don't have reset phandles in the PHYs, do it here. | ||
| 75 | * Those old DTs will be vulnerable to total USB breakage if the 1st EHCI | ||
| 76 | * device isn't the first one to finish probing, so warn them. | ||
| 77 | */ | ||
| 78 | static int tegra_reset_usb_controller(struct platform_device *pdev) | ||
| 79 | { | ||
| 80 | struct device_node *phy_np; | ||
| 81 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
| 82 | struct tegra_ehci_hcd *tegra = | ||
| 83 | (struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv; | ||
| 84 | |||
| 85 | phy_np = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0); | ||
| 86 | if (!phy_np) | ||
| 87 | return -ENOENT; | ||
| 88 | |||
| 89 | if (!usb1_reset_attempted) { | ||
| 90 | struct reset_control *usb1_reset; | ||
| 91 | |||
| 92 | usb1_reset = of_reset_control_get(phy_np, "usb"); | ||
| 93 | if (IS_ERR(usb1_reset)) { | ||
| 94 | dev_warn(&pdev->dev, | ||
| 95 | "can't get utmi-pads reset from the PHY\n"); | ||
| 96 | dev_warn(&pdev->dev, | ||
| 97 | "continuing, but please update your DT\n"); | ||
| 98 | } else { | ||
| 99 | reset_control_assert(usb1_reset); | ||
| 100 | udelay(1); | ||
| 101 | reset_control_deassert(usb1_reset); | ||
| 102 | } | ||
| 103 | |||
| 104 | reset_control_put(usb1_reset); | ||
| 105 | usb1_reset_attempted = true; | ||
| 106 | } | ||
| 107 | |||
| 108 | if (!of_property_read_bool(phy_np, "nvidia,has-utmi-pad-registers")) { | ||
| 109 | reset_control_assert(tegra->rst); | ||
| 110 | udelay(1); | ||
| 111 | reset_control_deassert(tegra->rst); | ||
| 112 | } | ||
| 113 | |||
| 114 | of_node_put(phy_np); | ||
| 115 | |||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 63 | static int tegra_ehci_internal_port_reset( | 119 | static int tegra_ehci_internal_port_reset( |
| 64 | struct ehci_hcd *ehci, | 120 | struct ehci_hcd *ehci, |
| 65 | u32 __iomem *portsc_reg | 121 | u32 __iomem *portsc_reg |
| @@ -326,7 +382,7 @@ static const struct tegra_ehci_soc_config tegra20_soc_config = { | |||
| 326 | .has_hostpc = false, | 382 | .has_hostpc = false, |
| 327 | }; | 383 | }; |
| 328 | 384 | ||
| 329 | static struct of_device_id tegra_ehci_of_match[] = { | 385 | static const struct of_device_id tegra_ehci_of_match[] = { |
| 330 | { .compatible = "nvidia,tegra30-ehci", .data = &tegra30_soc_config }, | 386 | { .compatible = "nvidia,tegra30-ehci", .data = &tegra30_soc_config }, |
| 331 | { .compatible = "nvidia,tegra20-ehci", .data = &tegra20_soc_config }, | 387 | { .compatible = "nvidia,tegra20-ehci", .data = &tegra20_soc_config }, |
| 332 | { }, | 388 | { }, |
| @@ -389,9 +445,9 @@ static int tegra_ehci_probe(struct platform_device *pdev) | |||
| 389 | if (err) | 445 | if (err) |
| 390 | goto cleanup_hcd_create; | 446 | goto cleanup_hcd_create; |
| 391 | 447 | ||
| 392 | reset_control_assert(tegra->rst); | 448 | err = tegra_reset_usb_controller(pdev); |
| 393 | udelay(1); | 449 | if (err) |
| 394 | reset_control_deassert(tegra->rst); | 450 | goto cleanup_clk_en; |
| 395 | 451 | ||
| 396 | u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); | 452 | u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); |
| 397 | if (IS_ERR(u_phy)) { | 453 | if (IS_ERR(u_phy)) { |
| @@ -479,10 +535,11 @@ static int tegra_ehci_remove(struct platform_device *pdev) | |||
| 479 | 535 | ||
| 480 | usb_phy_shutdown(hcd->phy); | 536 | usb_phy_shutdown(hcd->phy); |
| 481 | usb_remove_hcd(hcd); | 537 | usb_remove_hcd(hcd); |
| 482 | usb_put_hcd(hcd); | ||
| 483 | 538 | ||
| 484 | clk_disable_unprepare(tegra->clk); | 539 | clk_disable_unprepare(tegra->clk); |
| 485 | 540 | ||
| 541 | usb_put_hcd(hcd); | ||
| 542 | |||
| 486 | return 0; | 543 | return 0; |
| 487 | } | 544 | } |
| 488 | 545 | ||
diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c index f238cb37305c..b58e7a60913a 100644 --- a/drivers/usb/host/fhci-dbg.c +++ b/drivers/usb/host/fhci-dbg.c | |||
| @@ -129,11 +129,7 @@ void fhci_dfs_destroy(struct fhci_hcd *fhci) | |||
| 129 | if (!fhci->dfs_root) | 129 | if (!fhci->dfs_root) |
| 130 | return; | 130 | return; |
| 131 | 131 | ||
| 132 | if (fhci->dfs_irq_stat) | 132 | debugfs_remove(fhci->dfs_irq_stat); |
| 133 | debugfs_remove(fhci->dfs_irq_stat); | 133 | debugfs_remove(fhci->dfs_regs); |
| 134 | |||
| 135 | if (fhci->dfs_regs) | ||
| 136 | debugfs_remove(fhci->dfs_regs); | ||
| 137 | |||
| 138 | debugfs_remove(fhci->dfs_root); | 134 | debugfs_remove(fhci->dfs_root); |
| 139 | } | 135 | } |
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index 98a89d16cc3e..adcd2050dced 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c | |||
| @@ -5838,41 +5838,17 @@ static int fotg210_hcd_probe(struct platform_device *pdev) | |||
| 5838 | goto fail_create_hcd; | 5838 | goto fail_create_hcd; |
| 5839 | } | 5839 | } |
| 5840 | 5840 | ||
| 5841 | hcd->has_tt = 1; | ||
| 5842 | |||
| 5841 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 5843 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 5842 | if (!res) { | 5844 | hcd->regs = devm_ioremap_resource(&pdev->dev, res); |
| 5843 | dev_err(dev, | 5845 | if (IS_ERR(hcd->regs)) { |
| 5844 | "Found HC with no register addr. Check %s setup!\n", | 5846 | retval = PTR_ERR(hcd->regs); |
| 5845 | dev_name(dev)); | 5847 | goto failed; |
| 5846 | retval = -ENODEV; | ||
| 5847 | goto fail_request_resource; | ||
| 5848 | } | 5848 | } |
| 5849 | 5849 | ||
| 5850 | hcd->rsrc_start = res->start; | 5850 | hcd->rsrc_start = res->start; |
| 5851 | hcd->rsrc_len = resource_size(res); | 5851 | hcd->rsrc_len = resource_size(res); |
| 5852 | hcd->has_tt = 1; | ||
| 5853 | |||
| 5854 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
| 5855 | fotg210_fotg210_hc_driver.description)) { | ||
| 5856 | dev_dbg(dev, "controller already in use\n"); | ||
| 5857 | retval = -EBUSY; | ||
| 5858 | goto fail_request_resource; | ||
| 5859 | } | ||
| 5860 | |||
| 5861 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
| 5862 | if (!res) { | ||
| 5863 | dev_err(dev, | ||
| 5864 | "Found HC with no register addr. Check %s setup!\n", | ||
| 5865 | dev_name(dev)); | ||
| 5866 | retval = -ENODEV; | ||
| 5867 | goto fail_request_resource; | ||
| 5868 | } | ||
| 5869 | |||
| 5870 | hcd->regs = ioremap_nocache(res->start, resource_size(res)); | ||
| 5871 | if (hcd->regs == NULL) { | ||
| 5872 | dev_dbg(dev, "error mapping memory\n"); | ||
| 5873 | retval = -EFAULT; | ||
| 5874 | goto fail_ioremap; | ||
| 5875 | } | ||
| 5876 | 5852 | ||
| 5877 | fotg210 = hcd_to_fotg210(hcd); | 5853 | fotg210 = hcd_to_fotg210(hcd); |
| 5878 | 5854 | ||
| @@ -5880,24 +5856,20 @@ static int fotg210_hcd_probe(struct platform_device *pdev) | |||
| 5880 | 5856 | ||
| 5881 | retval = fotg210_setup(hcd); | 5857 | retval = fotg210_setup(hcd); |
| 5882 | if (retval) | 5858 | if (retval) |
| 5883 | goto fail_add_hcd; | 5859 | goto failed; |
| 5884 | 5860 | ||
| 5885 | fotg210_init(fotg210); | 5861 | fotg210_init(fotg210); |
| 5886 | 5862 | ||
| 5887 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | 5863 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 5888 | if (retval) { | 5864 | if (retval) { |
| 5889 | dev_err(dev, "failed to add hcd with err %d\n", retval); | 5865 | dev_err(dev, "failed to add hcd with err %d\n", retval); |
| 5890 | goto fail_add_hcd; | 5866 | goto failed; |
| 5891 | } | 5867 | } |
| 5892 | device_wakeup_enable(hcd->self.controller); | 5868 | device_wakeup_enable(hcd->self.controller); |
| 5893 | 5869 | ||
| 5894 | return retval; | 5870 | return retval; |
| 5895 | 5871 | ||
| 5896 | fail_add_hcd: | 5872 | failed: |
| 5897 | iounmap(hcd->regs); | ||
| 5898 | fail_ioremap: | ||
| 5899 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 5900 | fail_request_resource: | ||
| 5901 | usb_put_hcd(hcd); | 5873 | usb_put_hcd(hcd); |
| 5902 | fail_create_hcd: | 5874 | fail_create_hcd: |
| 5903 | dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval); | 5875 | dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval); |
| @@ -5918,8 +5890,6 @@ static int fotg210_hcd_remove(struct platform_device *pdev) | |||
| 5918 | return 0; | 5890 | return 0; |
| 5919 | 5891 | ||
| 5920 | usb_remove_hcd(hcd); | 5892 | usb_remove_hcd(hcd); |
| 5921 | iounmap(hcd->regs); | ||
| 5922 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 5923 | usb_put_hcd(hcd); | 5893 | usb_put_hcd(hcd); |
| 5924 | 5894 | ||
| 5925 | return 0; | 5895 | return 0; |
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 858efcfda50b..6234c75da33f 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c | |||
| @@ -102,6 +102,15 @@ enum scheduling_pass { | |||
| 102 | SCHED_PASS_DONE | 102 | SCHED_PASS_DONE |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | /* Bit numbers for max3421_hcd->todo: */ | ||
| 106 | enum { | ||
| 107 | ENABLE_IRQ = 0, | ||
| 108 | RESET_HCD, | ||
| 109 | RESET_PORT, | ||
| 110 | CHECK_UNLINK, | ||
| 111 | IOPIN_UPDATE | ||
| 112 | }; | ||
| 113 | |||
| 105 | struct max3421_dma_buf { | 114 | struct max3421_dma_buf { |
| 106 | u8 data[2]; | 115 | u8 data[2]; |
| 107 | }; | 116 | }; |
| @@ -146,11 +155,7 @@ struct max3421_hcd { | |||
| 146 | u8 hien; | 155 | u8 hien; |
| 147 | u8 mode; | 156 | u8 mode; |
| 148 | u8 iopins[2]; | 157 | u8 iopins[2]; |
| 149 | unsigned int do_enable_irq:1; | 158 | unsigned long todo; |
| 150 | unsigned int do_reset_hcd:1; | ||
| 151 | unsigned int do_reset_port:1; | ||
| 152 | unsigned int do_check_unlink:1; | ||
| 153 | unsigned int do_iopin_update:1; | ||
| 154 | #ifdef DEBUG | 159 | #ifdef DEBUG |
| 155 | unsigned long err_stat[16]; | 160 | unsigned long err_stat[16]; |
| 156 | #endif | 161 | #endif |
| @@ -1165,10 +1170,8 @@ max3421_irq_handler(int irq, void *dev_id) | |||
| 1165 | if (max3421_hcd->spi_thread && | 1170 | if (max3421_hcd->spi_thread && |
| 1166 | max3421_hcd->spi_thread->state != TASK_RUNNING) | 1171 | max3421_hcd->spi_thread->state != TASK_RUNNING) |
| 1167 | wake_up_process(max3421_hcd->spi_thread); | 1172 | wake_up_process(max3421_hcd->spi_thread); |
| 1168 | if (!max3421_hcd->do_enable_irq) { | 1173 | if (!test_and_set_bit(ENABLE_IRQ, &max3421_hcd->todo)) |
| 1169 | max3421_hcd->do_enable_irq = 1; | ||
| 1170 | disable_irq_nosync(spi->irq); | 1174 | disable_irq_nosync(spi->irq); |
| 1171 | } | ||
| 1172 | return IRQ_HANDLED; | 1175 | return IRQ_HANDLED; |
| 1173 | } | 1176 | } |
| 1174 | 1177 | ||
| @@ -1423,10 +1426,8 @@ max3421_spi_thread(void *dev_id) | |||
| 1423 | spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien); | 1426 | spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien); |
| 1424 | 1427 | ||
| 1425 | set_current_state(TASK_INTERRUPTIBLE); | 1428 | set_current_state(TASK_INTERRUPTIBLE); |
| 1426 | if (max3421_hcd->do_enable_irq) { | 1429 | if (test_and_clear_bit(ENABLE_IRQ, &max3421_hcd->todo)) |
| 1427 | max3421_hcd->do_enable_irq = 0; | ||
| 1428 | enable_irq(spi->irq); | 1430 | enable_irq(spi->irq); |
| 1429 | } | ||
| 1430 | schedule(); | 1431 | schedule(); |
| 1431 | __set_current_state(TASK_RUNNING); | 1432 | __set_current_state(TASK_RUNNING); |
| 1432 | } | 1433 | } |
| @@ -1440,23 +1441,18 @@ max3421_spi_thread(void *dev_id) | |||
| 1440 | else if (!max3421_hcd->curr_urb) | 1441 | else if (!max3421_hcd->curr_urb) |
| 1441 | i_worked |= max3421_select_and_start_urb(hcd); | 1442 | i_worked |= max3421_select_and_start_urb(hcd); |
| 1442 | 1443 | ||
| 1443 | if (max3421_hcd->do_reset_hcd) { | 1444 | if (test_and_clear_bit(RESET_HCD, &max3421_hcd->todo)) |
| 1444 | /* reset the HCD: */ | 1445 | /* reset the HCD: */ |
| 1445 | max3421_hcd->do_reset_hcd = 0; | ||
| 1446 | i_worked |= max3421_reset_hcd(hcd); | 1446 | i_worked |= max3421_reset_hcd(hcd); |
| 1447 | } | 1447 | if (test_and_clear_bit(RESET_PORT, &max3421_hcd->todo)) { |
| 1448 | if (max3421_hcd->do_reset_port) { | ||
| 1449 | /* perform a USB bus reset: */ | 1448 | /* perform a USB bus reset: */ |
| 1450 | max3421_hcd->do_reset_port = 0; | ||
| 1451 | spi_wr8(hcd, MAX3421_REG_HCTL, | 1449 | spi_wr8(hcd, MAX3421_REG_HCTL, |
| 1452 | BIT(MAX3421_HCTL_BUSRST_BIT)); | 1450 | BIT(MAX3421_HCTL_BUSRST_BIT)); |
| 1453 | i_worked = 1; | 1451 | i_worked = 1; |
| 1454 | } | 1452 | } |
| 1455 | if (max3421_hcd->do_check_unlink) { | 1453 | if (test_and_clear_bit(CHECK_UNLINK, &max3421_hcd->todo)) |
| 1456 | max3421_hcd->do_check_unlink = 0; | ||
| 1457 | i_worked |= max3421_check_unlink(hcd); | 1454 | i_worked |= max3421_check_unlink(hcd); |
| 1458 | } | 1455 | if (test_and_clear_bit(IOPIN_UPDATE, &max3421_hcd->todo)) { |
| 1459 | if (max3421_hcd->do_iopin_update) { | ||
| 1460 | /* | 1456 | /* |
| 1461 | * IOPINS1/IOPINS2 do not auto-increment, so we can't | 1457 | * IOPINS1/IOPINS2 do not auto-increment, so we can't |
| 1462 | * use spi_wr_buf(). | 1458 | * use spi_wr_buf(). |
| @@ -1469,7 +1465,6 @@ max3421_spi_thread(void *dev_id) | |||
| 1469 | spi_wr8(hcd, MAX3421_REG_IOPINS1 + i, val); | 1465 | spi_wr8(hcd, MAX3421_REG_IOPINS1 + i, val); |
| 1470 | max3421_hcd->iopins[i] = val; | 1466 | max3421_hcd->iopins[i] = val; |
| 1471 | } | 1467 | } |
| 1472 | max3421_hcd->do_iopin_update = 0; | ||
| 1473 | i_worked = 1; | 1468 | i_worked = 1; |
| 1474 | } | 1469 | } |
| 1475 | } | 1470 | } |
| @@ -1485,7 +1480,8 @@ max3421_reset_port(struct usb_hcd *hcd) | |||
| 1485 | 1480 | ||
| 1486 | max3421_hcd->port_status &= ~(USB_PORT_STAT_ENABLE | | 1481 | max3421_hcd->port_status &= ~(USB_PORT_STAT_ENABLE | |
| 1487 | USB_PORT_STAT_LOW_SPEED); | 1482 | USB_PORT_STAT_LOW_SPEED); |
| 1488 | max3421_hcd->do_reset_port = 1; | 1483 | max3421_hcd->port_status |= USB_PORT_STAT_RESET; |
| 1484 | set_bit(RESET_PORT, &max3421_hcd->todo); | ||
| 1489 | wake_up_process(max3421_hcd->spi_thread); | 1485 | wake_up_process(max3421_hcd->spi_thread); |
| 1490 | return 0; | 1486 | return 0; |
| 1491 | } | 1487 | } |
| @@ -1498,7 +1494,7 @@ max3421_reset(struct usb_hcd *hcd) | |||
| 1498 | hcd->self.sg_tablesize = 0; | 1494 | hcd->self.sg_tablesize = 0; |
| 1499 | hcd->speed = HCD_USB2; | 1495 | hcd->speed = HCD_USB2; |
| 1500 | hcd->self.root_hub->speed = USB_SPEED_FULL; | 1496 | hcd->self.root_hub->speed = USB_SPEED_FULL; |
| 1501 | max3421_hcd->do_reset_hcd = 1; | 1497 | set_bit(RESET_HCD, &max3421_hcd->todo); |
| 1502 | wake_up_process(max3421_hcd->spi_thread); | 1498 | wake_up_process(max3421_hcd->spi_thread); |
| 1503 | return 0; | 1499 | return 0; |
| 1504 | } | 1500 | } |
| @@ -1551,7 +1547,7 @@ max3421_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) | |||
| 1551 | max3421_ep = urb->ep->hcpriv; | 1547 | max3421_ep = urb->ep->hcpriv; |
| 1552 | if (!max3421_ep) { | 1548 | if (!max3421_ep) { |
| 1553 | /* gets freed in max3421_endpoint_disable: */ | 1549 | /* gets freed in max3421_endpoint_disable: */ |
| 1554 | max3421_ep = kzalloc(sizeof(struct max3421_ep), mem_flags); | 1550 | max3421_ep = kzalloc(sizeof(struct max3421_ep), GFP_ATOMIC); |
| 1555 | if (!max3421_ep) { | 1551 | if (!max3421_ep) { |
| 1556 | retval = -ENOMEM; | 1552 | retval = -ENOMEM; |
| 1557 | goto out; | 1553 | goto out; |
| @@ -1590,7 +1586,7 @@ max3421_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 1590 | */ | 1586 | */ |
| 1591 | retval = usb_hcd_check_unlink_urb(hcd, urb, status); | 1587 | retval = usb_hcd_check_unlink_urb(hcd, urb, status); |
| 1592 | if (retval == 0) { | 1588 | if (retval == 0) { |
| 1593 | max3421_hcd->do_check_unlink = 1; | 1589 | set_bit(CHECK_UNLINK, &max3421_hcd->todo); |
| 1594 | wake_up_process(max3421_hcd->spi_thread); | 1590 | wake_up_process(max3421_hcd->spi_thread); |
| 1595 | } | 1591 | } |
| 1596 | spin_unlock_irqrestore(&max3421_hcd->lock, flags); | 1592 | spin_unlock_irqrestore(&max3421_hcd->lock, flags); |
| @@ -1690,7 +1686,7 @@ max3421_gpout_set_value(struct usb_hcd *hcd, u8 pin_number, u8 value) | |||
| 1690 | max3421_hcd->iopins[idx] |= mask; | 1686 | max3421_hcd->iopins[idx] |= mask; |
| 1691 | else | 1687 | else |
| 1692 | max3421_hcd->iopins[idx] &= ~mask; | 1688 | max3421_hcd->iopins[idx] &= ~mask; |
| 1693 | max3421_hcd->do_iopin_update = 1; | 1689 | set_bit(IOPIN_UPDATE, &max3421_hcd->todo); |
| 1694 | wake_up_process(max3421_hcd->spi_thread); | 1690 | wake_up_process(max3421_hcd->spi_thread); |
| 1695 | } | 1691 | } |
| 1696 | 1692 | ||
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 45032e933e18..04f2186939d2 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
| @@ -236,7 +236,7 @@ ohci_dump_roothub ( | |||
| 236 | } | 236 | } |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | static void ohci_dump (struct ohci_hcd *controller, int verbose) | 239 | static void ohci_dump(struct ohci_hcd *controller) |
| 240 | { | 240 | { |
| 241 | ohci_dbg (controller, "OHCI controller state\n"); | 241 | ohci_dbg (controller, "OHCI controller state\n"); |
| 242 | 242 | ||
| @@ -464,15 +464,16 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) | |||
| 464 | static ssize_t fill_async_buffer(struct debug_buffer *buf) | 464 | static ssize_t fill_async_buffer(struct debug_buffer *buf) |
| 465 | { | 465 | { |
| 466 | struct ohci_hcd *ohci; | 466 | struct ohci_hcd *ohci; |
| 467 | size_t temp; | 467 | size_t temp, size; |
| 468 | unsigned long flags; | 468 | unsigned long flags; |
| 469 | 469 | ||
| 470 | ohci = buf->ohci; | 470 | ohci = buf->ohci; |
| 471 | size = PAGE_SIZE; | ||
| 471 | 472 | ||
| 472 | /* display control and bulk lists together, for simplicity */ | 473 | /* display control and bulk lists together, for simplicity */ |
| 473 | spin_lock_irqsave (&ohci->lock, flags); | 474 | spin_lock_irqsave (&ohci->lock, flags); |
| 474 | temp = show_list(ohci, buf->page, buf->count, ohci->ed_controltail); | 475 | temp = show_list(ohci, buf->page, size, ohci->ed_controltail); |
| 475 | temp += show_list(ohci, buf->page + temp, buf->count - temp, | 476 | temp += show_list(ohci, buf->page + temp, size - temp, |
| 476 | ohci->ed_bulktail); | 477 | ohci->ed_bulktail); |
| 477 | spin_unlock_irqrestore (&ohci->lock, flags); | 478 | spin_unlock_irqrestore (&ohci->lock, flags); |
| 478 | 479 | ||
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 060a6a414750..a72ab8fe8cd3 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c | |||
| @@ -87,7 +87,7 @@ static int exynos_ohci_get_phy(struct device *dev, | |||
| 87 | return -EINVAL; | 87 | return -EINVAL; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | phy = devm_of_phy_get(dev, child, 0); | 90 | phy = devm_of_phy_get(dev, child, NULL); |
| 91 | of_node_put(child); | 91 | of_node_put(child); |
| 92 | if (IS_ERR(phy)) { | 92 | if (IS_ERR(phy)) { |
| 93 | ret = PTR_ERR(phy); | 93 | ret = PTR_ERR(phy); |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index f98d03f3144c..46987735a2e3 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
| @@ -72,12 +72,14 @@ | |||
| 72 | static const char hcd_name [] = "ohci_hcd"; | 72 | static const char hcd_name [] = "ohci_hcd"; |
| 73 | 73 | ||
| 74 | #define STATECHANGE_DELAY msecs_to_jiffies(300) | 74 | #define STATECHANGE_DELAY msecs_to_jiffies(300) |
| 75 | #define IO_WATCHDOG_DELAY msecs_to_jiffies(250) | ||
| 75 | 76 | ||
| 76 | #include "ohci.h" | 77 | #include "ohci.h" |
| 77 | #include "pci-quirks.h" | 78 | #include "pci-quirks.h" |
| 78 | 79 | ||
| 79 | static void ohci_dump (struct ohci_hcd *ohci, int verbose); | 80 | static void ohci_dump(struct ohci_hcd *ohci); |
| 80 | static void ohci_stop (struct usb_hcd *hcd); | 81 | static void ohci_stop(struct usb_hcd *hcd); |
| 82 | static void io_watchdog_func(unsigned long _ohci); | ||
| 81 | 83 | ||
| 82 | #include "ohci-hub.c" | 84 | #include "ohci-hub.c" |
| 83 | #include "ohci-dbg.c" | 85 | #include "ohci-dbg.c" |
| @@ -109,6 +111,33 @@ MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake"); | |||
| 109 | 111 | ||
| 110 | /*-------------------------------------------------------------------------*/ | 112 | /*-------------------------------------------------------------------------*/ |
| 111 | 113 | ||
| 114 | static int number_of_tds(struct urb *urb) | ||
| 115 | { | ||
| 116 | int len, i, num, this_sg_len; | ||
| 117 | struct scatterlist *sg; | ||
| 118 | |||
| 119 | len = urb->transfer_buffer_length; | ||
| 120 | i = urb->num_mapped_sgs; | ||
| 121 | |||
| 122 | if (len > 0 && i > 0) { /* Scatter-gather transfer */ | ||
| 123 | num = 0; | ||
| 124 | sg = urb->sg; | ||
| 125 | for (;;) { | ||
| 126 | this_sg_len = min_t(int, sg_dma_len(sg), len); | ||
| 127 | num += DIV_ROUND_UP(this_sg_len, 4096); | ||
| 128 | len -= this_sg_len; | ||
| 129 | if (--i <= 0 || len <= 0) | ||
| 130 | break; | ||
| 131 | sg = sg_next(sg); | ||
| 132 | } | ||
| 133 | |||
| 134 | } else { /* Non-SG transfer */ | ||
| 135 | /* one TD for every 4096 Bytes (could be up to 8K) */ | ||
| 136 | num = DIV_ROUND_UP(len, 4096); | ||
| 137 | } | ||
| 138 | return num; | ||
| 139 | } | ||
| 140 | |||
| 112 | /* | 141 | /* |
| 113 | * queue up an urb for anything except the root hub | 142 | * queue up an urb for anything except the root hub |
| 114 | */ | 143 | */ |
| @@ -142,12 +171,8 @@ static int ohci_urb_enqueue ( | |||
| 142 | // case PIPE_INTERRUPT: | 171 | // case PIPE_INTERRUPT: |
| 143 | // case PIPE_BULK: | 172 | // case PIPE_BULK: |
| 144 | default: | 173 | default: |
| 145 | /* one TD for every 4096 Bytes (can be up to 8K) */ | 174 | size += number_of_tds(urb); |
| 146 | size += urb->transfer_buffer_length / 4096; | 175 | /* maybe a zero-length packet to wrap it up */ |
| 147 | /* ... and for any remaining bytes ... */ | ||
| 148 | if ((urb->transfer_buffer_length % 4096) != 0) | ||
| 149 | size++; | ||
| 150 | /* ... and maybe a zero length packet to wrap it up */ | ||
| 151 | if (size == 0) | 176 | if (size == 0) |
| 152 | size++; | 177 | size++; |
| 153 | else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0 | 178 | else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0 |
| @@ -202,6 +227,16 @@ static int ohci_urb_enqueue ( | |||
| 202 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 227 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
| 203 | goto fail; | 228 | goto fail; |
| 204 | } | 229 | } |
| 230 | |||
| 231 | /* Start up the I/O watchdog timer, if it's not running */ | ||
| 232 | if (!timer_pending(&ohci->io_watchdog) && | ||
| 233 | list_empty(&ohci->eds_in_use)) { | ||
| 234 | ohci->prev_frame_no = ohci_frame_no(ohci); | ||
| 235 | mod_timer(&ohci->io_watchdog, | ||
| 236 | jiffies + IO_WATCHDOG_DELAY); | ||
| 237 | } | ||
| 238 | list_add(&ed->in_use_list, &ohci->eds_in_use); | ||
| 239 | |||
| 205 | if (ed->type == PIPE_ISOCHRONOUS) { | 240 | if (ed->type == PIPE_ISOCHRONOUS) { |
| 206 | u16 frame = ohci_frame_no(ohci); | 241 | u16 frame = ohci_frame_no(ohci); |
| 207 | 242 | ||
| @@ -277,30 +312,24 @@ static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 277 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 312 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
| 278 | unsigned long flags; | 313 | unsigned long flags; |
| 279 | int rc; | 314 | int rc; |
| 315 | urb_priv_t *urb_priv; | ||
| 280 | 316 | ||
| 281 | spin_lock_irqsave (&ohci->lock, flags); | 317 | spin_lock_irqsave (&ohci->lock, flags); |
| 282 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | 318 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
| 283 | if (rc) { | 319 | if (rc == 0) { |
| 284 | ; /* Do nothing */ | ||
| 285 | } else if (ohci->rh_state == OHCI_RH_RUNNING) { | ||
| 286 | urb_priv_t *urb_priv; | ||
| 287 | 320 | ||
| 288 | /* Unless an IRQ completed the unlink while it was being | 321 | /* Unless an IRQ completed the unlink while it was being |
| 289 | * handed to us, flag it for unlink and giveback, and force | 322 | * handed to us, flag it for unlink and giveback, and force |
| 290 | * some upcoming INTR_SF to call finish_unlinks() | 323 | * some upcoming INTR_SF to call finish_unlinks() |
| 291 | */ | 324 | */ |
| 292 | urb_priv = urb->hcpriv; | 325 | urb_priv = urb->hcpriv; |
| 293 | if (urb_priv) { | 326 | if (urb_priv->ed->state == ED_OPER) |
| 294 | if (urb_priv->ed->state == ED_OPER) | 327 | start_ed_unlink(ohci, urb_priv->ed); |
| 295 | start_ed_unlink (ohci, urb_priv->ed); | 328 | |
| 329 | if (ohci->rh_state != OHCI_RH_RUNNING) { | ||
| 330 | /* With HC dead, we can clean up right away */ | ||
| 331 | ohci_work(ohci); | ||
| 296 | } | 332 | } |
| 297 | } else { | ||
| 298 | /* | ||
| 299 | * with HC dead, we won't respect hc queue pointers | ||
| 300 | * any more ... just clean up every urb's memory. | ||
| 301 | */ | ||
| 302 | if (urb->hcpriv) | ||
| 303 | finish_urb(ohci, urb, status); | ||
| 304 | } | 333 | } |
| 305 | spin_unlock_irqrestore (&ohci->lock, flags); | 334 | spin_unlock_irqrestore (&ohci->lock, flags); |
| 306 | return rc; | 335 | return rc; |
| @@ -332,9 +361,7 @@ rescan: | |||
| 332 | if (ohci->rh_state != OHCI_RH_RUNNING) { | 361 | if (ohci->rh_state != OHCI_RH_RUNNING) { |
| 333 | sanitize: | 362 | sanitize: |
| 334 | ed->state = ED_IDLE; | 363 | ed->state = ED_IDLE; |
| 335 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | 364 | ohci_work(ohci); |
| 336 | ohci->eds_scheduled--; | ||
| 337 | finish_unlinks (ohci, 0); | ||
| 338 | } | 365 | } |
| 339 | 366 | ||
| 340 | switch (ed->state) { | 367 | switch (ed->state) { |
| @@ -342,11 +369,6 @@ sanitize: | |||
| 342 | /* major IRQ delivery trouble loses INTR_SF too... */ | 369 | /* major IRQ delivery trouble loses INTR_SF too... */ |
| 343 | if (limit-- == 0) { | 370 | if (limit-- == 0) { |
| 344 | ohci_warn(ohci, "ED unlink timeout\n"); | 371 | ohci_warn(ohci, "ED unlink timeout\n"); |
| 345 | if (quirk_zfmicro(ohci)) { | ||
| 346 | ohci_warn(ohci, "Attempting ZF TD recovery\n"); | ||
| 347 | ohci->ed_to_check = ed; | ||
| 348 | ohci->zf_delay = 2; | ||
| 349 | } | ||
| 350 | goto sanitize; | 372 | goto sanitize; |
| 351 | } | 373 | } |
| 352 | spin_unlock_irqrestore (&ohci->lock, flags); | 374 | spin_unlock_irqrestore (&ohci->lock, flags); |
| @@ -406,93 +428,7 @@ ohci_shutdown (struct usb_hcd *hcd) | |||
| 406 | udelay(10); | 428 | udelay(10); |
| 407 | 429 | ||
| 408 | ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval); | 430 | ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval); |
| 409 | } | 431 | ohci->rh_state = OHCI_RH_HALTED; |
| 410 | |||
| 411 | static int check_ed(struct ohci_hcd *ohci, struct ed *ed) | ||
| 412 | { | ||
| 413 | return (hc32_to_cpu(ohci, ed->hwINFO) & ED_IN) != 0 | ||
| 414 | && (hc32_to_cpu(ohci, ed->hwHeadP) & TD_MASK) | ||
| 415 | == (hc32_to_cpu(ohci, ed->hwTailP) & TD_MASK) | ||
| 416 | && !list_empty(&ed->td_list); | ||
| 417 | } | ||
| 418 | |||
| 419 | /* ZF Micro watchdog timer callback. The ZF Micro chipset sometimes completes | ||
| 420 | * an interrupt TD but neglects to add it to the donelist. On systems with | ||
| 421 | * this chipset, we need to periodically check the state of the queues to look | ||
| 422 | * for such "lost" TDs. | ||
| 423 | */ | ||
| 424 | static void unlink_watchdog_func(unsigned long _ohci) | ||
| 425 | { | ||
| 426 | unsigned long flags; | ||
| 427 | unsigned max; | ||
| 428 | unsigned seen_count = 0; | ||
| 429 | unsigned i; | ||
| 430 | struct ed **seen = NULL; | ||
| 431 | struct ohci_hcd *ohci = (struct ohci_hcd *) _ohci; | ||
| 432 | |||
| 433 | spin_lock_irqsave(&ohci->lock, flags); | ||
| 434 | max = ohci->eds_scheduled; | ||
| 435 | if (!max) | ||
| 436 | goto done; | ||
| 437 | |||
| 438 | if (ohci->ed_to_check) | ||
| 439 | goto out; | ||
| 440 | |||
| 441 | seen = kcalloc(max, sizeof *seen, GFP_ATOMIC); | ||
| 442 | if (!seen) | ||
| 443 | goto out; | ||
| 444 | |||
| 445 | for (i = 0; i < NUM_INTS; i++) { | ||
| 446 | struct ed *ed = ohci->periodic[i]; | ||
| 447 | |||
| 448 | while (ed) { | ||
| 449 | unsigned temp; | ||
| 450 | |||
| 451 | /* scan this branch of the periodic schedule tree */ | ||
| 452 | for (temp = 0; temp < seen_count; temp++) { | ||
| 453 | if (seen[temp] == ed) { | ||
| 454 | /* we've checked it and what's after */ | ||
| 455 | ed = NULL; | ||
| 456 | break; | ||
| 457 | } | ||
| 458 | } | ||
| 459 | if (!ed) | ||
| 460 | break; | ||
| 461 | seen[seen_count++] = ed; | ||
| 462 | if (!check_ed(ohci, ed)) { | ||
| 463 | ed = ed->ed_next; | ||
| 464 | continue; | ||
| 465 | } | ||
| 466 | |||
| 467 | /* HC's TD list is empty, but HCD sees at least one | ||
| 468 | * TD that's not been sent through the donelist. | ||
| 469 | */ | ||
| 470 | ohci->ed_to_check = ed; | ||
| 471 | ohci->zf_delay = 2; | ||
| 472 | |||
| 473 | /* The HC may wait until the next frame to report the | ||
| 474 | * TD as done through the donelist and INTR_WDH. (We | ||
| 475 | * just *assume* it's not a multi-TD interrupt URB; | ||
| 476 | * those could defer the IRQ more than one frame, using | ||
| 477 | * DI...) Check again after the next INTR_SF. | ||
| 478 | */ | ||
| 479 | ohci_writel(ohci, OHCI_INTR_SF, | ||
| 480 | &ohci->regs->intrstatus); | ||
| 481 | ohci_writel(ohci, OHCI_INTR_SF, | ||
| 482 | &ohci->regs->intrenable); | ||
| 483 | |||
| 484 | /* flush those writes */ | ||
| 485 | (void) ohci_readl(ohci, &ohci->regs->control); | ||
| 486 | |||
| 487 | goto out; | ||
| 488 | } | ||
| 489 | } | ||
| 490 | out: | ||
| 491 | kfree(seen); | ||
| 492 | if (ohci->eds_scheduled) | ||
| 493 | mod_timer(&ohci->unlink_watchdog, round_jiffies(jiffies + HZ)); | ||
| 494 | done: | ||
| 495 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
| 496 | } | 432 | } |
| 497 | 433 | ||
| 498 | /*-------------------------------------------------------------------------* | 434 | /*-------------------------------------------------------------------------* |
| @@ -506,6 +442,9 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
| 506 | int ret; | 442 | int ret; |
| 507 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | 443 | struct usb_hcd *hcd = ohci_to_hcd(ohci); |
| 508 | 444 | ||
| 445 | /* Accept arbitrarily long scatter-gather lists */ | ||
| 446 | hcd->self.sg_tablesize = ~0; | ||
| 447 | |||
| 509 | if (distrust_firmware) | 448 | if (distrust_firmware) |
| 510 | ohci->flags |= OHCI_QUIRK_HUB_POWER; | 449 | ohci->flags |= OHCI_QUIRK_HUB_POWER; |
| 511 | 450 | ||
| @@ -558,8 +497,12 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
| 558 | if (ohci->hcca) | 497 | if (ohci->hcca) |
| 559 | return 0; | 498 | return 0; |
| 560 | 499 | ||
| 500 | setup_timer(&ohci->io_watchdog, io_watchdog_func, | ||
| 501 | (unsigned long) ohci); | ||
| 502 | set_timer_slack(&ohci->io_watchdog, msecs_to_jiffies(20)); | ||
| 503 | |||
| 561 | ohci->hcca = dma_alloc_coherent (hcd->self.controller, | 504 | ohci->hcca = dma_alloc_coherent (hcd->self.controller, |
| 562 | sizeof *ohci->hcca, &ohci->hcca_dma, 0); | 505 | sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL); |
| 563 | if (!ohci->hcca) | 506 | if (!ohci->hcca) |
| 564 | return -ENOMEM; | 507 | return -ENOMEM; |
| 565 | 508 | ||
| @@ -735,16 +678,7 @@ retry: | |||
| 735 | // POTPGT delay is bits 24-31, in 2 ms units. | 678 | // POTPGT delay is bits 24-31, in 2 ms units. |
| 736 | mdelay ((val >> 23) & 0x1fe); | 679 | mdelay ((val >> 23) & 0x1fe); |
| 737 | 680 | ||
| 738 | if (quirk_zfmicro(ohci)) { | 681 | ohci_dump(ohci); |
| 739 | /* Create timer to watch for bad queue state on ZF Micro */ | ||
| 740 | setup_timer(&ohci->unlink_watchdog, unlink_watchdog_func, | ||
| 741 | (unsigned long) ohci); | ||
| 742 | |||
| 743 | ohci->eds_scheduled = 0; | ||
| 744 | ohci->ed_to_check = NULL; | ||
| 745 | } | ||
| 746 | |||
| 747 | ohci_dump (ohci, 1); | ||
| 748 | 682 | ||
| 749 | return 0; | 683 | return 0; |
| 750 | } | 684 | } |
| @@ -777,6 +711,142 @@ static int ohci_start(struct usb_hcd *hcd) | |||
| 777 | 711 | ||
| 778 | /*-------------------------------------------------------------------------*/ | 712 | /*-------------------------------------------------------------------------*/ |
| 779 | 713 | ||
| 714 | /* | ||
| 715 | * Some OHCI controllers are known to lose track of completed TDs. They | ||
| 716 | * don't add the TDs to the hardware done queue, which means we never see | ||
| 717 | * them as being completed. | ||
| 718 | * | ||
| 719 | * This watchdog routine checks for such problems. Without some way to | ||
| 720 | * tell when those TDs have completed, we would never take their EDs off | ||
| 721 | * the unlink list. As a result, URBs could never be dequeued and | ||
| 722 | * endpoints could never be released. | ||
| 723 | */ | ||
| 724 | static void io_watchdog_func(unsigned long _ohci) | ||
| 725 | { | ||
| 726 | struct ohci_hcd *ohci = (struct ohci_hcd *) _ohci; | ||
| 727 | bool takeback_all_pending = false; | ||
| 728 | u32 status; | ||
| 729 | u32 head; | ||
| 730 | struct ed *ed; | ||
| 731 | struct td *td, *td_start, *td_next; | ||
| 732 | unsigned frame_no; | ||
| 733 | unsigned long flags; | ||
| 734 | |||
| 735 | spin_lock_irqsave(&ohci->lock, flags); | ||
| 736 | |||
| 737 | /* | ||
| 738 | * One way to lose track of completed TDs is if the controller | ||
| 739 | * never writes back the done queue head. If it hasn't been | ||
| 740 | * written back since the last time this function ran and if it | ||
| 741 | * was non-empty at that time, something is badly wrong with the | ||
| 742 | * hardware. | ||
| 743 | */ | ||
| 744 | status = ohci_readl(ohci, &ohci->regs->intrstatus); | ||
| 745 | if (!(status & OHCI_INTR_WDH) && ohci->wdh_cnt == ohci->prev_wdh_cnt) { | ||
| 746 | if (ohci->prev_donehead) { | ||
| 747 | ohci_err(ohci, "HcDoneHead not written back; disabled\n"); | ||
| 748 | died: | ||
| 749 | usb_hc_died(ohci_to_hcd(ohci)); | ||
| 750 | ohci_dump(ohci); | ||
| 751 | ohci_shutdown(ohci_to_hcd(ohci)); | ||
| 752 | goto done; | ||
| 753 | } else { | ||
| 754 | /* No write back because the done queue was empty */ | ||
| 755 | takeback_all_pending = true; | ||
| 756 | } | ||
| 757 | } | ||
| 758 | |||
| 759 | /* Check every ED which might have pending TDs */ | ||
| 760 | list_for_each_entry(ed, &ohci->eds_in_use, in_use_list) { | ||
| 761 | if (ed->pending_td) { | ||
| 762 | if (takeback_all_pending || | ||
| 763 | OKAY_TO_TAKEBACK(ohci, ed)) { | ||
| 764 | unsigned tmp = hc32_to_cpu(ohci, ed->hwINFO); | ||
| 765 | |||
| 766 | ohci_dbg(ohci, "takeback pending TD for dev %d ep 0x%x\n", | ||
| 767 | 0x007f & tmp, | ||
| 768 | (0x000f & (tmp >> 7)) + | ||
| 769 | ((tmp & ED_IN) >> 5)); | ||
| 770 | add_to_done_list(ohci, ed->pending_td); | ||
| 771 | } | ||
| 772 | } | ||
| 773 | |||
| 774 | /* Starting from the latest pending TD, */ | ||
| 775 | td = ed->pending_td; | ||
| 776 | |||
| 777 | /* or the last TD on the done list, */ | ||
| 778 | if (!td) { | ||
| 779 | list_for_each_entry(td_next, &ed->td_list, td_list) { | ||
| 780 | if (!td_next->next_dl_td) | ||
| 781 | break; | ||
| 782 | td = td_next; | ||
| 783 | } | ||
| 784 | } | ||
| 785 | |||
| 786 | /* find the last TD processed by the controller. */ | ||
| 787 | head = hc32_to_cpu(ohci, ACCESS_ONCE(ed->hwHeadP)) & TD_MASK; | ||
| 788 | td_start = td; | ||
| 789 | td_next = list_prepare_entry(td, &ed->td_list, td_list); | ||
| 790 | list_for_each_entry_continue(td_next, &ed->td_list, td_list) { | ||
| 791 | if (head == (u32) td_next->td_dma) | ||
| 792 | break; | ||
| 793 | td = td_next; /* head pointer has passed this TD */ | ||
| 794 | } | ||
| 795 | if (td != td_start) { | ||
| 796 | /* | ||
| 797 | * In case a WDH cycle is in progress, we will wait | ||
| 798 | * for the next two cycles to complete before assuming | ||
| 799 | * this TD will never get on the done queue. | ||
| 800 | */ | ||
| 801 | ed->takeback_wdh_cnt = ohci->wdh_cnt + 2; | ||
| 802 | ed->pending_td = td; | ||
| 803 | } | ||
| 804 | } | ||
| 805 | |||
| 806 | ohci_work(ohci); | ||
| 807 | |||
| 808 | if (ohci->rh_state == OHCI_RH_RUNNING) { | ||
| 809 | |||
| 810 | /* | ||
| 811 | * Sometimes a controller just stops working. We can tell | ||
| 812 | * by checking that the frame counter has advanced since | ||
| 813 | * the last time we ran. | ||
| 814 | * | ||
| 815 | * But be careful: Some controllers violate the spec by | ||
| 816 | * stopping their frame counter when no ports are active. | ||
| 817 | */ | ||
| 818 | frame_no = ohci_frame_no(ohci); | ||
| 819 | if (frame_no == ohci->prev_frame_no) { | ||
| 820 | int active_cnt = 0; | ||
| 821 | int i; | ||
| 822 | unsigned tmp; | ||
| 823 | |||
| 824 | for (i = 0; i < ohci->num_ports; ++i) { | ||
| 825 | tmp = roothub_portstatus(ohci, i); | ||
| 826 | /* Enabled and not suspended? */ | ||
| 827 | if ((tmp & RH_PS_PES) && !(tmp & RH_PS_PSS)) | ||
| 828 | ++active_cnt; | ||
| 829 | } | ||
| 830 | |||
| 831 | if (active_cnt > 0) { | ||
| 832 | ohci_err(ohci, "frame counter not updating; disabled\n"); | ||
| 833 | goto died; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | if (!list_empty(&ohci->eds_in_use)) { | ||
| 837 | ohci->prev_frame_no = frame_no; | ||
| 838 | ohci->prev_wdh_cnt = ohci->wdh_cnt; | ||
| 839 | ohci->prev_donehead = ohci_readl(ohci, | ||
| 840 | &ohci->regs->donehead); | ||
| 841 | mod_timer(&ohci->io_watchdog, | ||
| 842 | jiffies + IO_WATCHDOG_DELAY); | ||
| 843 | } | ||
| 844 | } | ||
| 845 | |||
| 846 | done: | ||
| 847 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
| 848 | } | ||
| 849 | |||
| 780 | /* an interrupt happens */ | 850 | /* an interrupt happens */ |
| 781 | 851 | ||
| 782 | static irqreturn_t ohci_irq (struct usb_hcd *hcd) | 852 | static irqreturn_t ohci_irq (struct usb_hcd *hcd) |
| @@ -825,7 +895,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
| 825 | usb_hc_died(hcd); | 895 | usb_hc_died(hcd); |
| 826 | } | 896 | } |
| 827 | 897 | ||
| 828 | ohci_dump (ohci, 1); | 898 | ohci_dump(ohci); |
| 829 | ohci_usb_reset (ohci); | 899 | ohci_usb_reset (ohci); |
| 830 | } | 900 | } |
| 831 | 901 | ||
| @@ -863,58 +933,30 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
| 863 | usb_hcd_resume_root_hub(hcd); | 933 | usb_hcd_resume_root_hub(hcd); |
| 864 | } | 934 | } |
| 865 | 935 | ||
| 866 | if (ints & OHCI_INTR_WDH) { | 936 | spin_lock(&ohci->lock); |
| 867 | spin_lock (&ohci->lock); | 937 | if (ints & OHCI_INTR_WDH) |
| 868 | dl_done_list (ohci); | 938 | update_done_list(ohci); |
| 869 | spin_unlock (&ohci->lock); | ||
| 870 | } | ||
| 871 | |||
| 872 | if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) { | ||
| 873 | spin_lock(&ohci->lock); | ||
| 874 | if (ohci->ed_to_check) { | ||
| 875 | struct ed *ed = ohci->ed_to_check; | ||
| 876 | |||
| 877 | if (check_ed(ohci, ed)) { | ||
| 878 | /* HC thinks the TD list is empty; HCD knows | ||
| 879 | * at least one TD is outstanding | ||
| 880 | */ | ||
| 881 | if (--ohci->zf_delay == 0) { | ||
| 882 | struct td *td = list_entry( | ||
| 883 | ed->td_list.next, | ||
| 884 | struct td, td_list); | ||
| 885 | ohci_warn(ohci, | ||
| 886 | "Reclaiming orphan TD %p\n", | ||
| 887 | td); | ||
| 888 | takeback_td(ohci, td); | ||
| 889 | ohci->ed_to_check = NULL; | ||
| 890 | } | ||
| 891 | } else | ||
| 892 | ohci->ed_to_check = NULL; | ||
| 893 | } | ||
| 894 | spin_unlock(&ohci->lock); | ||
| 895 | } | ||
| 896 | 939 | ||
| 897 | /* could track INTR_SO to reduce available PCI/... bandwidth */ | 940 | /* could track INTR_SO to reduce available PCI/... bandwidth */ |
| 898 | 941 | ||
| 899 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled | 942 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled |
| 900 | * when there's still unlinking to be done (next frame). | 943 | * when there's still unlinking to be done (next frame). |
| 901 | */ | 944 | */ |
| 902 | spin_lock (&ohci->lock); | 945 | ohci_work(ohci); |
| 903 | if (ohci->ed_rm_list) | 946 | if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list |
| 904 | finish_unlinks (ohci, ohci_frame_no(ohci)); | ||
| 905 | if ((ints & OHCI_INTR_SF) != 0 | ||
| 906 | && !ohci->ed_rm_list | ||
| 907 | && !ohci->ed_to_check | ||
| 908 | && ohci->rh_state == OHCI_RH_RUNNING) | 947 | && ohci->rh_state == OHCI_RH_RUNNING) |
| 909 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); | 948 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); |
| 910 | spin_unlock (&ohci->lock); | ||
| 911 | 949 | ||
| 912 | if (ohci->rh_state == OHCI_RH_RUNNING) { | 950 | if (ohci->rh_state == OHCI_RH_RUNNING) { |
| 913 | ohci_writel (ohci, ints, ®s->intrstatus); | 951 | ohci_writel (ohci, ints, ®s->intrstatus); |
| 952 | if (ints & OHCI_INTR_WDH) | ||
| 953 | ++ohci->wdh_cnt; | ||
| 954 | |||
| 914 | ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); | 955 | ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); |
| 915 | // flush those writes | 956 | // flush those writes |
| 916 | (void) ohci_readl (ohci, &ohci->regs->control); | 957 | (void) ohci_readl (ohci, &ohci->regs->control); |
| 917 | } | 958 | } |
| 959 | spin_unlock(&ohci->lock); | ||
| 918 | 960 | ||
| 919 | return IRQ_HANDLED; | 961 | return IRQ_HANDLED; |
| 920 | } | 962 | } |
| @@ -925,18 +967,17 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
| 925 | { | 967 | { |
| 926 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 968 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
| 927 | 969 | ||
| 928 | ohci_dump (ohci, 1); | 970 | ohci_dump(ohci); |
| 929 | 971 | ||
| 930 | if (quirk_nec(ohci)) | 972 | if (quirk_nec(ohci)) |
| 931 | flush_work(&ohci->nec_work); | 973 | flush_work(&ohci->nec_work); |
| 974 | del_timer_sync(&ohci->io_watchdog); | ||
| 932 | 975 | ||
| 933 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 976 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
| 934 | ohci_usb_reset(ohci); | 977 | ohci_usb_reset(ohci); |
| 935 | free_irq(hcd->irq, hcd); | 978 | free_irq(hcd->irq, hcd); |
| 936 | hcd->irq = 0; | 979 | hcd->irq = 0; |
| 937 | 980 | ||
| 938 | if (quirk_zfmicro(ohci)) | ||
| 939 | del_timer(&ohci->unlink_watchdog); | ||
| 940 | if (quirk_amdiso(ohci)) | 981 | if (quirk_amdiso(ohci)) |
| 941 | usb_amd_dev_put(); | 982 | usb_amd_dev_put(); |
| 942 | 983 | ||
| @@ -993,7 +1034,7 @@ int ohci_restart(struct ohci_hcd *ohci) | |||
| 993 | if (!urb->unlinked) | 1034 | if (!urb->unlinked) |
| 994 | urb->unlinked = -ESHUTDOWN; | 1035 | urb->unlinked = -ESHUTDOWN; |
| 995 | } | 1036 | } |
| 996 | finish_unlinks (ohci, 0); | 1037 | ohci_work(ohci); |
| 997 | spin_unlock_irq(&ohci->lock); | 1038 | spin_unlock_irq(&ohci->lock); |
| 998 | 1039 | ||
| 999 | /* paranoia, in case that didn't work: */ | 1040 | /* paranoia, in case that didn't work: */ |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index b4940de1eba3..17d32b0ea565 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
| @@ -39,8 +39,8 @@ | |||
| 39 | #define OHCI_SCHED_ENABLES \ | 39 | #define OHCI_SCHED_ENABLES \ |
| 40 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) | 40 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) |
| 41 | 41 | ||
| 42 | static void dl_done_list (struct ohci_hcd *); | 42 | static void update_done_list(struct ohci_hcd *); |
| 43 | static void finish_unlinks (struct ohci_hcd *, u16); | 43 | static void ohci_work(struct ohci_hcd *); |
| 44 | 44 | ||
| 45 | #ifdef CONFIG_PM | 45 | #ifdef CONFIG_PM |
| 46 | static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) | 46 | static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) |
| @@ -87,8 +87,8 @@ __acquires(ohci->lock) | |||
| 87 | msleep (8); | 87 | msleep (8); |
| 88 | spin_lock_irq (&ohci->lock); | 88 | spin_lock_irq (&ohci->lock); |
| 89 | } | 89 | } |
| 90 | dl_done_list (ohci); | 90 | update_done_list(ohci); |
| 91 | finish_unlinks (ohci, ohci_frame_no(ohci)); | 91 | ohci_work(ohci); |
| 92 | 92 | ||
| 93 | /* | 93 | /* |
| 94 | * Some controllers don't handle "global" suspend properly if | 94 | * Some controllers don't handle "global" suspend properly if |
| @@ -309,6 +309,9 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) | |||
| 309 | else | 309 | else |
| 310 | rc = ohci_rh_suspend (ohci, 0); | 310 | rc = ohci_rh_suspend (ohci, 0); |
| 311 | spin_unlock_irq (&ohci->lock); | 311 | spin_unlock_irq (&ohci->lock); |
| 312 | |||
| 313 | if (rc == 0) | ||
| 314 | del_timer_sync(&ohci->io_watchdog); | ||
| 312 | return rc; | 315 | return rc; |
| 313 | } | 316 | } |
| 314 | 317 | ||
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 2f20d3dc895b..c9e315c6808a 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
| @@ -28,6 +28,7 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
| 28 | ohci->next_statechange = jiffies; | 28 | ohci->next_statechange = jiffies; |
| 29 | spin_lock_init (&ohci->lock); | 29 | spin_lock_init (&ohci->lock); |
| 30 | INIT_LIST_HEAD (&ohci->pending); | 30 | INIT_LIST_HEAD (&ohci->pending); |
| 31 | INIT_LIST_HEAD(&ohci->eds_in_use); | ||
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | /*-------------------------------------------------------------------------*/ | 34 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index d4253e319428..1463c398d322 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
| @@ -187,10 +187,6 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | |||
| 187 | ed->ed_prev = NULL; | 187 | ed->ed_prev = NULL; |
| 188 | ed->ed_next = NULL; | 188 | ed->ed_next = NULL; |
| 189 | ed->hwNextED = 0; | 189 | ed->hwNextED = 0; |
| 190 | if (quirk_zfmicro(ohci) | ||
| 191 | && (ed->type == PIPE_INTERRUPT) | ||
| 192 | && !(ohci->eds_scheduled++)) | ||
| 193 | mod_timer(&ohci->unlink_watchdog, round_jiffies(jiffies + HZ)); | ||
| 194 | wmb (); | 190 | wmb (); |
| 195 | 191 | ||
| 196 | /* we care about rm_list when setting CLE/BLE in case the HC was at | 192 | /* we care about rm_list when setting CLE/BLE in case the HC was at |
| @@ -311,8 +307,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed) | |||
| 311 | * - ED_OPER: when there's any request queued, the ED gets rescheduled | 307 | * - ED_OPER: when there's any request queued, the ED gets rescheduled |
| 312 | * immediately. HC should be working on them. | 308 | * immediately. HC should be working on them. |
| 313 | * | 309 | * |
| 314 | * - ED_IDLE: when there's no TD queue. there's no reason for the HC | 310 | * - ED_IDLE: when there's no TD queue or the HC isn't running. |
| 315 | * to care about this ED; safe to disable the endpoint. | ||
| 316 | * | 311 | * |
| 317 | * When finish_unlinks() runs later, after SOF interrupt, it will often | 312 | * When finish_unlinks() runs later, after SOF interrupt, it will often |
| 318 | * complete one or more URB unlinks before making that state change. | 313 | * complete one or more URB unlinks before making that state change. |
| @@ -602,6 +597,8 @@ static void td_submit_urb ( | |||
| 602 | u32 info = 0; | 597 | u32 info = 0; |
| 603 | int is_out = usb_pipeout (urb->pipe); | 598 | int is_out = usb_pipeout (urb->pipe); |
| 604 | int periodic = 0; | 599 | int periodic = 0; |
| 600 | int i, this_sg_len, n; | ||
| 601 | struct scatterlist *sg; | ||
| 605 | 602 | ||
| 606 | /* OHCI handles the bulk/interrupt data toggles itself. We just | 603 | /* OHCI handles the bulk/interrupt data toggles itself. We just |
| 607 | * use the device toggle bits for resetting, and rely on the fact | 604 | * use the device toggle bits for resetting, and rely on the fact |
| @@ -615,10 +612,24 @@ static void td_submit_urb ( | |||
| 615 | 612 | ||
| 616 | list_add (&urb_priv->pending, &ohci->pending); | 613 | list_add (&urb_priv->pending, &ohci->pending); |
| 617 | 614 | ||
| 618 | if (data_len) | 615 | i = urb->num_mapped_sgs; |
| 619 | data = urb->transfer_dma; | 616 | if (data_len > 0 && i > 0) { |
| 620 | else | 617 | sg = urb->sg; |
| 621 | data = 0; | 618 | data = sg_dma_address(sg); |
| 619 | |||
| 620 | /* | ||
| 621 | * urb->transfer_buffer_length may be smaller than the | ||
| 622 | * size of the scatterlist (or vice versa) | ||
| 623 | */ | ||
| 624 | this_sg_len = min_t(int, sg_dma_len(sg), data_len); | ||
| 625 | } else { | ||
| 626 | sg = NULL; | ||
| 627 | if (data_len) | ||
| 628 | data = urb->transfer_dma; | ||
| 629 | else | ||
| 630 | data = 0; | ||
| 631 | this_sg_len = data_len; | ||
| 632 | } | ||
| 622 | 633 | ||
| 623 | /* NOTE: TD_CC is set so we can tell which TDs the HC processed by | 634 | /* NOTE: TD_CC is set so we can tell which TDs the HC processed by |
| 624 | * using TD_CC_GET, as well as by seeing them on the done list. | 635 | * using TD_CC_GET, as well as by seeing them on the done list. |
| @@ -639,17 +650,29 @@ static void td_submit_urb ( | |||
| 639 | ? TD_T_TOGGLE | TD_CC | TD_DP_OUT | 650 | ? TD_T_TOGGLE | TD_CC | TD_DP_OUT |
| 640 | : TD_T_TOGGLE | TD_CC | TD_DP_IN; | 651 | : TD_T_TOGGLE | TD_CC | TD_DP_IN; |
| 641 | /* TDs _could_ transfer up to 8K each */ | 652 | /* TDs _could_ transfer up to 8K each */ |
| 642 | while (data_len > 4096) { | 653 | for (;;) { |
| 643 | td_fill (ohci, info, data, 4096, urb, cnt); | 654 | n = min(this_sg_len, 4096); |
| 644 | data += 4096; | 655 | |
| 645 | data_len -= 4096; | 656 | /* maybe avoid ED halt on final TD short read */ |
| 657 | if (n >= data_len || (i == 1 && n >= this_sg_len)) { | ||
| 658 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) | ||
| 659 | info |= TD_R; | ||
| 660 | } | ||
| 661 | td_fill(ohci, info, data, n, urb, cnt); | ||
| 662 | this_sg_len -= n; | ||
| 663 | data_len -= n; | ||
| 664 | data += n; | ||
| 646 | cnt++; | 665 | cnt++; |
| 666 | |||
| 667 | if (this_sg_len <= 0) { | ||
| 668 | if (--i <= 0 || data_len <= 0) | ||
| 669 | break; | ||
| 670 | sg = sg_next(sg); | ||
| 671 | data = sg_dma_address(sg); | ||
| 672 | this_sg_len = min_t(int, sg_dma_len(sg), | ||
| 673 | data_len); | ||
| 674 | } | ||
| 647 | } | 675 | } |
| 648 | /* maybe avoid ED halt on final TD short read */ | ||
| 649 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) | ||
| 650 | info |= TD_R; | ||
| 651 | td_fill (ohci, info, data, data_len, urb, cnt); | ||
| 652 | cnt++; | ||
| 653 | if ((urb->transfer_flags & URB_ZERO_PACKET) | 676 | if ((urb->transfer_flags & URB_ZERO_PACKET) |
| 654 | && cnt < urb_priv->length) { | 677 | && cnt < urb_priv->length) { |
| 655 | td_fill (ohci, info, 0, 0, urb, cnt); | 678 | td_fill (ohci, info, 0, 0, urb, cnt); |
| @@ -869,13 +892,46 @@ static void ed_halted(struct ohci_hcd *ohci, struct td *td, int cc) | |||
| 869 | } | 892 | } |
| 870 | } | 893 | } |
| 871 | 894 | ||
| 872 | /* replies to the request have to be on a FIFO basis so | 895 | /* Add a TD to the done list */ |
| 873 | * we unreverse the hc-reversed done-list | 896 | static void add_to_done_list(struct ohci_hcd *ohci, struct td *td) |
| 874 | */ | 897 | { |
| 875 | static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | 898 | struct td *td2, *td_prev; |
| 899 | struct ed *ed; | ||
| 900 | |||
| 901 | if (td->next_dl_td) | ||
| 902 | return; /* Already on the list */ | ||
| 903 | |||
| 904 | /* Add all the TDs going back until we reach one that's on the list */ | ||
| 905 | ed = td->ed; | ||
| 906 | td2 = td_prev = td; | ||
| 907 | list_for_each_entry_continue_reverse(td2, &ed->td_list, td_list) { | ||
| 908 | if (td2->next_dl_td) | ||
| 909 | break; | ||
| 910 | td2->next_dl_td = td_prev; | ||
| 911 | td_prev = td2; | ||
| 912 | } | ||
| 913 | |||
| 914 | if (ohci->dl_end) | ||
| 915 | ohci->dl_end->next_dl_td = td_prev; | ||
| 916 | else | ||
| 917 | ohci->dl_start = td_prev; | ||
| 918 | |||
| 919 | /* | ||
| 920 | * Make td->next_dl_td point to td itself, to mark the fact | ||
| 921 | * that td is on the done list. | ||
| 922 | */ | ||
| 923 | ohci->dl_end = td->next_dl_td = td; | ||
| 924 | |||
| 925 | /* Did we just add the latest pending TD? */ | ||
| 926 | td2 = ed->pending_td; | ||
| 927 | if (td2 && td2->next_dl_td) | ||
| 928 | ed->pending_td = NULL; | ||
| 929 | } | ||
| 930 | |||
| 931 | /* Get the entries on the hardware done queue and put them on our list */ | ||
| 932 | static void update_done_list(struct ohci_hcd *ohci) | ||
| 876 | { | 933 | { |
| 877 | u32 td_dma; | 934 | u32 td_dma; |
| 878 | struct td *td_rev = NULL; | ||
| 879 | struct td *td = NULL; | 935 | struct td *td = NULL; |
| 880 | 936 | ||
| 881 | td_dma = hc32_to_cpup (ohci, &ohci->hcca->done_head); | 937 | td_dma = hc32_to_cpup (ohci, &ohci->hcca->done_head); |
| @@ -883,7 +939,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
| 883 | wmb(); | 939 | wmb(); |
| 884 | 940 | ||
| 885 | /* get TD from hc's singly linked list, and | 941 | /* get TD from hc's singly linked list, and |
| 886 | * prepend to ours. ed->td_list changes later. | 942 | * add to ours. ed->td_list changes later. |
| 887 | */ | 943 | */ |
| 888 | while (td_dma) { | 944 | while (td_dma) { |
| 889 | int cc; | 945 | int cc; |
| @@ -905,19 +961,17 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
| 905 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) | 961 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) |
| 906 | ed_halted(ohci, td, cc); | 962 | ed_halted(ohci, td, cc); |
| 907 | 963 | ||
| 908 | td->next_dl_td = td_rev; | ||
| 909 | td_rev = td; | ||
| 910 | td_dma = hc32_to_cpup (ohci, &td->hwNextTD); | 964 | td_dma = hc32_to_cpup (ohci, &td->hwNextTD); |
| 965 | add_to_done_list(ohci, td); | ||
| 911 | } | 966 | } |
| 912 | return td_rev; | ||
| 913 | } | 967 | } |
| 914 | 968 | ||
| 915 | /*-------------------------------------------------------------------------*/ | 969 | /*-------------------------------------------------------------------------*/ |
| 916 | 970 | ||
| 917 | /* there are some urbs/eds to unlink; called in_irq(), with HCD locked */ | 971 | /* there are some urbs/eds to unlink; called in_irq(), with HCD locked */ |
| 918 | static void | 972 | static void finish_unlinks(struct ohci_hcd *ohci) |
| 919 | finish_unlinks (struct ohci_hcd *ohci, u16 tick) | ||
| 920 | { | 973 | { |
| 974 | unsigned tick = ohci_frame_no(ohci); | ||
| 921 | struct ed *ed, **last; | 975 | struct ed *ed, **last; |
| 922 | 976 | ||
| 923 | rescan_all: | 977 | rescan_all: |
| @@ -926,41 +980,48 @@ rescan_all: | |||
| 926 | int completed, modified; | 980 | int completed, modified; |
| 927 | __hc32 *prev; | 981 | __hc32 *prev; |
| 928 | 982 | ||
| 983 | /* Is this ED already invisible to the hardware? */ | ||
| 984 | if (ed->state == ED_IDLE) | ||
| 985 | goto ed_idle; | ||
| 986 | |||
| 929 | /* only take off EDs that the HC isn't using, accounting for | 987 | /* only take off EDs that the HC isn't using, accounting for |
| 930 | * frame counter wraps and EDs with partially retired TDs | 988 | * frame counter wraps and EDs with partially retired TDs |
| 931 | */ | 989 | */ |
| 932 | if (likely(ohci->rh_state == OHCI_RH_RUNNING)) { | 990 | if (likely(ohci->rh_state == OHCI_RH_RUNNING) && |
| 933 | if (tick_before (tick, ed->tick)) { | 991 | tick_before(tick, ed->tick)) { |
| 934 | skip_ed: | 992 | skip_ed: |
| 935 | last = &ed->ed_next; | 993 | last = &ed->ed_next; |
| 936 | continue; | 994 | continue; |
| 937 | } | 995 | } |
| 996 | if (!list_empty(&ed->td_list)) { | ||
| 997 | struct td *td; | ||
| 998 | u32 head; | ||
| 938 | 999 | ||
| 939 | if (!list_empty (&ed->td_list)) { | 1000 | td = list_first_entry(&ed->td_list, struct td, td_list); |
| 940 | struct td *td; | 1001 | |
| 941 | u32 head; | 1002 | /* INTR_WDH may need to clean up first */ |
| 942 | 1003 | head = hc32_to_cpu(ohci, ed->hwHeadP) & TD_MASK; | |
| 943 | td = list_entry (ed->td_list.next, struct td, | 1004 | if (td->td_dma != head && |
| 944 | td_list); | 1005 | ohci->rh_state == OHCI_RH_RUNNING) |
| 945 | head = hc32_to_cpu (ohci, ed->hwHeadP) & | 1006 | goto skip_ed; |
| 946 | TD_MASK; | 1007 | |
| 947 | 1008 | /* Don't mess up anything already on the done list */ | |
| 948 | /* INTR_WDH may need to clean up first */ | 1009 | if (td->next_dl_td) |
| 949 | if (td->td_dma != head) { | 1010 | goto skip_ed; |
| 950 | if (ed == ohci->ed_to_check) | ||
| 951 | ohci->ed_to_check = NULL; | ||
| 952 | else | ||
| 953 | goto skip_ed; | ||
| 954 | } | ||
| 955 | } | ||
| 956 | } | 1011 | } |
| 957 | 1012 | ||
| 1013 | /* ED's now officially unlinked, hc doesn't see */ | ||
| 1014 | ed->state = ED_IDLE; | ||
| 1015 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); | ||
| 1016 | ed->hwNextED = 0; | ||
| 1017 | wmb(); | ||
| 1018 | ed->hwINFO &= ~cpu_to_hc32(ohci, ED_SKIP | ED_DEQUEUE); | ||
| 1019 | ed_idle: | ||
| 1020 | |||
| 958 | /* reentrancy: if we drop the schedule lock, someone might | 1021 | /* reentrancy: if we drop the schedule lock, someone might |
| 959 | * have modified this list. normally it's just prepending | 1022 | * have modified this list. normally it's just prepending |
| 960 | * entries (which we'd ignore), but paranoia won't hurt. | 1023 | * entries (which we'd ignore), but paranoia won't hurt. |
| 961 | */ | 1024 | */ |
| 962 | *last = ed->ed_next; | ||
| 963 | ed->ed_next = NULL; | ||
| 964 | modified = 0; | 1025 | modified = 0; |
| 965 | 1026 | ||
| 966 | /* unlink urbs as requested, but rescan the list after | 1027 | /* unlink urbs as requested, but rescan the list after |
| @@ -1018,19 +1079,21 @@ rescan_this: | |||
| 1018 | if (completed && !list_empty (&ed->td_list)) | 1079 | if (completed && !list_empty (&ed->td_list)) |
| 1019 | goto rescan_this; | 1080 | goto rescan_this; |
| 1020 | 1081 | ||
| 1021 | /* ED's now officially unlinked, hc doesn't see */ | 1082 | /* |
| 1022 | ed->state = ED_IDLE; | 1083 | * If no TDs are queued, take ED off the ed_rm_list. |
| 1023 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | 1084 | * Otherwise, if the HC is running, reschedule. |
| 1024 | ohci->eds_scheduled--; | 1085 | * If not, leave it on the list for further dequeues. |
| 1025 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); | 1086 | */ |
| 1026 | ed->hwNextED = 0; | 1087 | if (list_empty(&ed->td_list)) { |
| 1027 | wmb (); | 1088 | *last = ed->ed_next; |
| 1028 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE); | 1089 | ed->ed_next = NULL; |
| 1029 | 1090 | list_del(&ed->in_use_list); | |
| 1030 | /* but if there's work queued, reschedule */ | 1091 | } else if (ohci->rh_state == OHCI_RH_RUNNING) { |
| 1031 | if (!list_empty (&ed->td_list)) { | 1092 | *last = ed->ed_next; |
| 1032 | if (ohci->rh_state == OHCI_RH_RUNNING) | 1093 | ed->ed_next = NULL; |
| 1033 | ed_schedule (ohci, ed); | 1094 | ed_schedule(ohci, ed); |
| 1095 | } else { | ||
| 1096 | last = &ed->ed_next; | ||
| 1034 | } | 1097 | } |
| 1035 | 1098 | ||
| 1036 | if (modified) | 1099 | if (modified) |
| @@ -1082,12 +1145,7 @@ rescan_this: | |||
| 1082 | 1145 | ||
| 1083 | /*-------------------------------------------------------------------------*/ | 1146 | /*-------------------------------------------------------------------------*/ |
| 1084 | 1147 | ||
| 1085 | /* | 1148 | /* Take back a TD from the host controller */ |
| 1086 | * Used to take back a TD from the host controller. This would normally be | ||
| 1087 | * called from within dl_done_list, however it may be called directly if the | ||
| 1088 | * HC no longer sees the TD and it has not appeared on the donelist (after | ||
| 1089 | * two frames). This bug has been observed on ZF Micro systems. | ||
| 1090 | */ | ||
| 1091 | static void takeback_td(struct ohci_hcd *ohci, struct td *td) | 1149 | static void takeback_td(struct ohci_hcd *ohci, struct td *td) |
| 1092 | { | 1150 | { |
| 1093 | struct urb *urb = td->urb; | 1151 | struct urb *urb = td->urb; |
| @@ -1134,37 +1192,43 @@ static void takeback_td(struct ohci_hcd *ohci, struct td *td) | |||
| 1134 | * | 1192 | * |
| 1135 | * This is the main path for handing urbs back to drivers. The only other | 1193 | * This is the main path for handing urbs back to drivers. The only other |
| 1136 | * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list, | 1194 | * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list, |
| 1137 | * instead of scanning the (re-reversed) donelist as this does. There's | 1195 | * instead of scanning the (re-reversed) donelist as this does. |
| 1138 | * an abnormal path too, handling a quirk in some Compaq silicon: URBs | ||
| 1139 | * with TDs that appear to be orphaned are directly reclaimed. | ||
| 1140 | */ | 1196 | */ |
| 1141 | static void | 1197 | static void process_done_list(struct ohci_hcd *ohci) |
| 1142 | dl_done_list (struct ohci_hcd *ohci) | ||
| 1143 | { | 1198 | { |
| 1144 | struct td *td = dl_reverse_done_list (ohci); | 1199 | struct td *td; |
| 1145 | 1200 | ||
| 1146 | while (td) { | 1201 | while (ohci->dl_start) { |
| 1147 | struct td *td_next = td->next_dl_td; | 1202 | td = ohci->dl_start; |
| 1148 | struct ed *ed = td->ed; | 1203 | if (td == ohci->dl_end) |
| 1204 | ohci->dl_start = ohci->dl_end = NULL; | ||
| 1205 | else | ||
| 1206 | ohci->dl_start = td->next_dl_td; | ||
| 1149 | 1207 | ||
| 1150 | /* | 1208 | takeback_td(ohci, td); |
| 1151 | * Some OHCI controllers (NVIDIA for sure, maybe others) | 1209 | } |
| 1152 | * occasionally forget to add TDs to the done queue. Since | 1210 | } |
| 1153 | * TDs for a given endpoint are always processed in order, | ||
| 1154 | * if we find a TD on the donelist then all of its | ||
| 1155 | * predecessors must be finished as well. | ||
| 1156 | */ | ||
| 1157 | for (;;) { | ||
| 1158 | struct td *td2; | ||
| 1159 | 1211 | ||
| 1160 | td2 = list_first_entry(&ed->td_list, struct td, | 1212 | /* |
| 1161 | td_list); | 1213 | * TD takeback and URB giveback must be single-threaded. |
| 1162 | if (td2 == td) | 1214 | * This routine takes care of it all. |
| 1163 | break; | 1215 | */ |
| 1164 | takeback_td(ohci, td2); | 1216 | static void ohci_work(struct ohci_hcd *ohci) |
| 1165 | } | 1217 | { |
| 1218 | if (ohci->working) { | ||
| 1219 | ohci->restart_work = 1; | ||
| 1220 | return; | ||
| 1221 | } | ||
| 1222 | ohci->working = 1; | ||
| 1166 | 1223 | ||
| 1167 | takeback_td(ohci, td); | 1224 | restart: |
| 1168 | td = td_next; | 1225 | process_done_list(ohci); |
| 1226 | if (ohci->ed_rm_list) | ||
| 1227 | finish_unlinks(ohci); | ||
| 1228 | |||
| 1229 | if (ohci->restart_work) { | ||
| 1230 | ohci->restart_work = 0; | ||
| 1231 | goto restart; | ||
| 1169 | } | 1232 | } |
| 1233 | ohci->working = 0; | ||
| 1170 | } | 1234 | } |
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 8b29a0c04c23..8d5876692e7c 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c | |||
| @@ -162,7 +162,7 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev) | |||
| 162 | } | 162 | } |
| 163 | #endif | 163 | #endif |
| 164 | 164 | ||
| 165 | static struct of_device_id spear_ohci_id_table[] = { | 165 | static const struct of_device_id spear_ohci_id_table[] = { |
| 166 | { .compatible = "st,spear600-ohci", }, | 166 | { .compatible = "st,spear600-ohci", }, |
| 167 | { }, | 167 | { }, |
| 168 | }; | 168 | }; |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 05e02a709d4f..59f424567a8d 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
| @@ -47,6 +47,7 @@ struct ed { | |||
| 47 | struct ed *ed_next; /* on schedule or rm_list */ | 47 | struct ed *ed_next; /* on schedule or rm_list */ |
| 48 | struct ed *ed_prev; /* for non-interrupt EDs */ | 48 | struct ed *ed_prev; /* for non-interrupt EDs */ |
| 49 | struct list_head td_list; /* "shadow list" of our TDs */ | 49 | struct list_head td_list; /* "shadow list" of our TDs */ |
| 50 | struct list_head in_use_list; | ||
| 50 | 51 | ||
| 51 | /* create --> IDLE --> OPER --> ... --> IDLE --> destroy | 52 | /* create --> IDLE --> OPER --> ... --> IDLE --> destroy |
| 52 | * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... | 53 | * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... |
| @@ -66,6 +67,13 @@ struct ed { | |||
| 66 | 67 | ||
| 67 | /* HC may see EDs on rm_list until next frame (frame_no == tick) */ | 68 | /* HC may see EDs on rm_list until next frame (frame_no == tick) */ |
| 68 | u16 tick; | 69 | u16 tick; |
| 70 | |||
| 71 | /* Detect TDs not added to the done queue */ | ||
| 72 | unsigned takeback_wdh_cnt; | ||
| 73 | struct td *pending_td; | ||
| 74 | #define OKAY_TO_TAKEBACK(ohci, ed) \ | ||
| 75 | ((int) (ohci->wdh_cnt - ed->takeback_wdh_cnt) >= 0) | ||
| 76 | |||
| 69 | } __attribute__ ((aligned(16))); | 77 | } __attribute__ ((aligned(16))); |
| 70 | 78 | ||
| 71 | #define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */ | 79 | #define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */ |
| @@ -380,7 +388,9 @@ struct ohci_hcd { | |||
| 380 | struct dma_pool *td_cache; | 388 | struct dma_pool *td_cache; |
| 381 | struct dma_pool *ed_cache; | 389 | struct dma_pool *ed_cache; |
| 382 | struct td *td_hash [TD_HASH_SIZE]; | 390 | struct td *td_hash [TD_HASH_SIZE]; |
| 391 | struct td *dl_start, *dl_end; /* the done list */ | ||
| 383 | struct list_head pending; | 392 | struct list_head pending; |
| 393 | struct list_head eds_in_use; /* all EDs with at least 1 TD */ | ||
| 384 | 394 | ||
| 385 | /* | 395 | /* |
| 386 | * driver state | 396 | * driver state |
| @@ -392,6 +402,8 @@ struct ohci_hcd { | |||
| 392 | unsigned long next_statechange; /* suspend/resume */ | 402 | unsigned long next_statechange; /* suspend/resume */ |
| 393 | u32 fminterval; /* saved register */ | 403 | u32 fminterval; /* saved register */ |
| 394 | unsigned autostop:1; /* rh auto stopping/stopped */ | 404 | unsigned autostop:1; /* rh auto stopping/stopped */ |
| 405 | unsigned working:1; | ||
| 406 | unsigned restart_work:1; | ||
| 395 | 407 | ||
| 396 | unsigned long flags; /* for HC bugs */ | 408 | unsigned long flags; /* for HC bugs */ |
| 397 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ | 409 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ |
| @@ -409,13 +421,12 @@ struct ohci_hcd { | |||
| 409 | 421 | ||
| 410 | // there are also chip quirks/bugs in init logic | 422 | // there are also chip quirks/bugs in init logic |
| 411 | 423 | ||
| 412 | struct work_struct nec_work; /* Worker for NEC quirk */ | 424 | unsigned prev_frame_no; |
| 425 | unsigned wdh_cnt, prev_wdh_cnt; | ||
| 426 | u32 prev_donehead; | ||
| 427 | struct timer_list io_watchdog; | ||
| 413 | 428 | ||
| 414 | /* Needed for ZF Micro quirk */ | 429 | struct work_struct nec_work; /* Worker for NEC quirk */ |
| 415 | struct timer_list unlink_watchdog; | ||
| 416 | unsigned eds_scheduled; | ||
| 417 | struct ed *ed_to_check; | ||
| 418 | unsigned zf_delay; | ||
| 419 | 430 | ||
| 420 | struct dentry *debug_dir; | 431 | struct dentry *debug_dir; |
| 421 | struct dentry *debug_async; | 432 | struct dentry *debug_async; |
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index e07248b6ab67..da5fb0e3c363 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c | |||
| @@ -3826,49 +3826,36 @@ static int oxu_drv_probe(struct platform_device *pdev) | |||
| 3826 | dev_dbg(&pdev->dev, "IRQ resource %d\n", irq); | 3826 | dev_dbg(&pdev->dev, "IRQ resource %d\n", irq); |
| 3827 | 3827 | ||
| 3828 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 3828 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 3829 | if (!res) { | 3829 | base = devm_ioremap_resource(&pdev->dev, res); |
| 3830 | dev_err(&pdev->dev, "no registers address! Check %s setup!\n", | 3830 | if (IS_ERR(base)) { |
| 3831 | dev_name(&pdev->dev)); | 3831 | ret = PTR_ERR(base); |
| 3832 | return -ENODEV; | 3832 | goto error; |
| 3833 | } | 3833 | } |
| 3834 | memstart = res->start; | 3834 | memstart = res->start; |
| 3835 | memlen = resource_size(res); | 3835 | memlen = resource_size(res); |
| 3836 | dev_dbg(&pdev->dev, "MEM resource %lx-%lx\n", memstart, memlen); | ||
| 3837 | if (!request_mem_region(memstart, memlen, | ||
| 3838 | oxu_hc_driver.description)) { | ||
| 3839 | dev_dbg(&pdev->dev, "memory area already in use\n"); | ||
| 3840 | return -EBUSY; | ||
| 3841 | } | ||
| 3842 | 3836 | ||
| 3843 | ret = irq_set_irq_type(irq, IRQF_TRIGGER_FALLING); | 3837 | ret = irq_set_irq_type(irq, IRQF_TRIGGER_FALLING); |
| 3844 | if (ret) { | 3838 | if (ret) { |
| 3845 | dev_err(&pdev->dev, "error setting irq type\n"); | 3839 | dev_err(&pdev->dev, "error setting irq type\n"); |
| 3846 | ret = -EFAULT; | 3840 | ret = -EFAULT; |
| 3847 | goto error_set_irq_type; | 3841 | goto error; |
| 3848 | } | ||
| 3849 | |||
| 3850 | base = ioremap(memstart, memlen); | ||
| 3851 | if (!base) { | ||
| 3852 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
| 3853 | ret = -EFAULT; | ||
| 3854 | goto error_ioremap; | ||
| 3855 | } | 3842 | } |
| 3856 | 3843 | ||
| 3857 | /* Allocate a driver data struct to hold useful info for both | 3844 | /* Allocate a driver data struct to hold useful info for both |
| 3858 | * SPH & OTG devices | 3845 | * SPH & OTG devices |
| 3859 | */ | 3846 | */ |
| 3860 | info = kzalloc(sizeof(struct oxu_info), GFP_KERNEL); | 3847 | info = devm_kzalloc(&pdev->dev, sizeof(struct oxu_info), GFP_KERNEL); |
| 3861 | if (!info) { | 3848 | if (!info) { |
| 3862 | dev_dbg(&pdev->dev, "error allocating memory\n"); | 3849 | dev_dbg(&pdev->dev, "error allocating memory\n"); |
| 3863 | ret = -EFAULT; | 3850 | ret = -EFAULT; |
| 3864 | goto error_alloc; | 3851 | goto error; |
| 3865 | } | 3852 | } |
| 3866 | platform_set_drvdata(pdev, info); | 3853 | platform_set_drvdata(pdev, info); |
| 3867 | 3854 | ||
| 3868 | ret = oxu_init(pdev, memstart, memlen, base, irq); | 3855 | ret = oxu_init(pdev, memstart, memlen, base, irq); |
| 3869 | if (ret < 0) { | 3856 | if (ret < 0) { |
| 3870 | dev_dbg(&pdev->dev, "cannot init USB devices\n"); | 3857 | dev_dbg(&pdev->dev, "cannot init USB devices\n"); |
| 3871 | goto error_init; | 3858 | goto error; |
| 3872 | } | 3859 | } |
| 3873 | 3860 | ||
| 3874 | dev_info(&pdev->dev, "devices enabled and running\n"); | 3861 | dev_info(&pdev->dev, "devices enabled and running\n"); |
| @@ -3876,16 +3863,7 @@ static int oxu_drv_probe(struct platform_device *pdev) | |||
| 3876 | 3863 | ||
| 3877 | return 0; | 3864 | return 0; |
| 3878 | 3865 | ||
| 3879 | error_init: | 3866 | error: |
| 3880 | kfree(info); | ||
| 3881 | |||
| 3882 | error_alloc: | ||
| 3883 | iounmap(base); | ||
| 3884 | |||
| 3885 | error_set_irq_type: | ||
| 3886 | error_ioremap: | ||
| 3887 | release_mem_region(memstart, memlen); | ||
| 3888 | |||
| 3889 | dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), ret); | 3867 | dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), ret); |
| 3890 | return ret; | 3868 | return ret; |
| 3891 | } | 3869 | } |
| @@ -3899,18 +3877,10 @@ static void oxu_remove(struct platform_device *pdev, struct usb_hcd *hcd) | |||
| 3899 | static int oxu_drv_remove(struct platform_device *pdev) | 3877 | static int oxu_drv_remove(struct platform_device *pdev) |
| 3900 | { | 3878 | { |
| 3901 | struct oxu_info *info = platform_get_drvdata(pdev); | 3879 | struct oxu_info *info = platform_get_drvdata(pdev); |
| 3902 | unsigned long memstart = info->hcd[0]->rsrc_start, | ||
| 3903 | memlen = info->hcd[0]->rsrc_len; | ||
| 3904 | void *base = info->hcd[0]->regs; | ||
| 3905 | 3880 | ||
| 3906 | oxu_remove(pdev, info->hcd[0]); | 3881 | oxu_remove(pdev, info->hcd[0]); |
| 3907 | oxu_remove(pdev, info->hcd[1]); | 3882 | oxu_remove(pdev, info->hcd[1]); |
| 3908 | 3883 | ||
| 3909 | iounmap(base); | ||
| 3910 | release_mem_region(memstart, memlen); | ||
| 3911 | |||
| 3912 | kfree(info); | ||
| 3913 | |||
| 3914 | return 0; | 3884 | return 0; |
| 3915 | } | 3885 | } |
| 3916 | 3886 | ||
diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index ab25dc397e8b..05f57ffdf9ab 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu | 17 | * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/device.h> | ||
| 20 | #include <linux/of_irq.h> | 21 | #include <linux/of_irq.h> |
| 21 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
| 22 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
| @@ -113,24 +114,17 @@ static int uhci_hcd_grlib_probe(struct platform_device *op) | |||
| 113 | hcd->rsrc_start = res.start; | 114 | hcd->rsrc_start = res.start; |
| 114 | hcd->rsrc_len = resource_size(&res); | 115 | hcd->rsrc_len = resource_size(&res); |
| 115 | 116 | ||
| 116 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
| 117 | printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); | ||
| 118 | rv = -EBUSY; | ||
| 119 | goto err_rmr; | ||
| 120 | } | ||
| 121 | |||
| 122 | irq = irq_of_parse_and_map(dn, 0); | 117 | irq = irq_of_parse_and_map(dn, 0); |
| 123 | if (irq == NO_IRQ) { | 118 | if (irq == NO_IRQ) { |
| 124 | printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); | 119 | printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); |
| 125 | rv = -EBUSY; | 120 | rv = -EBUSY; |
| 126 | goto err_irq; | 121 | goto err_usb; |
| 127 | } | 122 | } |
| 128 | 123 | ||
| 129 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 124 | hcd->regs = devm_ioremap_resource(&op->dev, &res); |
| 130 | if (!hcd->regs) { | 125 | if (IS_ERR(hcd->regs)) { |
| 131 | printk(KERN_ERR "%s: ioremap failed\n", __FILE__); | 126 | rv = PTR_ERR(hcd->regs); |
| 132 | rv = -ENOMEM; | 127 | goto err_irq; |
| 133 | goto err_ioremap; | ||
| 134 | } | 128 | } |
| 135 | 129 | ||
| 136 | uhci = hcd_to_uhci(hcd); | 130 | uhci = hcd_to_uhci(hcd); |
| @@ -139,18 +133,14 @@ static int uhci_hcd_grlib_probe(struct platform_device *op) | |||
| 139 | 133 | ||
| 140 | rv = usb_add_hcd(hcd, irq, 0); | 134 | rv = usb_add_hcd(hcd, irq, 0); |
| 141 | if (rv) | 135 | if (rv) |
| 142 | goto err_uhci; | 136 | goto err_irq; |
| 143 | 137 | ||
| 144 | device_wakeup_enable(hcd->self.controller); | 138 | device_wakeup_enable(hcd->self.controller); |
| 145 | return 0; | 139 | return 0; |
| 146 | 140 | ||
| 147 | err_uhci: | ||
| 148 | iounmap(hcd->regs); | ||
| 149 | err_ioremap: | ||
| 150 | irq_dispose_mapping(irq); | ||
| 151 | err_irq: | 141 | err_irq: |
| 152 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 142 | irq_dispose_mapping(irq); |
| 153 | err_rmr: | 143 | err_usb: |
| 154 | usb_put_hcd(hcd); | 144 | usb_put_hcd(hcd); |
| 155 | 145 | ||
| 156 | return rv; | 146 | return rv; |
| @@ -164,10 +154,7 @@ static int uhci_hcd_grlib_remove(struct platform_device *op) | |||
| 164 | 154 | ||
| 165 | usb_remove_hcd(hcd); | 155 | usb_remove_hcd(hcd); |
| 166 | 156 | ||
| 167 | iounmap(hcd->regs); | ||
| 168 | irq_dispose_mapping(hcd->irq); | 157 | irq_dispose_mapping(hcd->irq); |
| 169 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 170 | |||
| 171 | usb_put_hcd(hcd); | 158 | usb_put_hcd(hcd); |
| 172 | 159 | ||
| 173 | return 0; | 160 | return 0; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 27f35e8f161b..a7de8e8bb458 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
| @@ -591,7 +591,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
| 591 | 591 | ||
| 592 | uhci->frame = dma_alloc_coherent(uhci_dev(uhci), | 592 | uhci->frame = dma_alloc_coherent(uhci_dev(uhci), |
| 593 | UHCI_NUMFRAMES * sizeof(*uhci->frame), | 593 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
| 594 | &uhci->frame_dma_handle, 0); | 594 | &uhci->frame_dma_handle, GFP_KERNEL); |
| 595 | if (!uhci->frame) { | 595 | if (!uhci->frame) { |
| 596 | dev_err(uhci_dev(uhci), | 596 | dev_err(uhci_dev(uhci), |
| 597 | "unable to allocate consistent memory for frame list\n"); | 597 | "unable to allocate consistent memory for frame list\n"); |
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index 01833ab2b5c3..b987f1d10058 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/of.h> | 10 | #include <linux/of.h> |
| 11 | #include <linux/device.h> | ||
| 11 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
| 12 | 13 | ||
| 13 | static int uhci_platform_init(struct usb_hcd *hcd) | 14 | static int uhci_platform_init(struct usb_hcd *hcd) |
| @@ -88,33 +89,22 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev) | |||
| 88 | hcd->rsrc_start = res->start; | 89 | hcd->rsrc_start = res->start; |
| 89 | hcd->rsrc_len = resource_size(res); | 90 | hcd->rsrc_len = resource_size(res); |
| 90 | 91 | ||
| 91 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 92 | hcd->regs = devm_ioremap_resource(&pdev->dev, res); |
| 92 | pr_err("%s: request_mem_region failed\n", __func__); | 93 | if (IS_ERR(hcd->regs)) { |
| 93 | ret = -EBUSY; | 94 | ret = PTR_ERR(hcd->regs); |
| 94 | goto err_rmr; | 95 | goto err_rmr; |
| 95 | } | 96 | } |
| 96 | |||
| 97 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
| 98 | if (!hcd->regs) { | ||
| 99 | pr_err("%s: ioremap failed\n", __func__); | ||
| 100 | ret = -ENOMEM; | ||
| 101 | goto err_irq; | ||
| 102 | } | ||
| 103 | uhci = hcd_to_uhci(hcd); | 97 | uhci = hcd_to_uhci(hcd); |
| 104 | 98 | ||
| 105 | uhci->regs = hcd->regs; | 99 | uhci->regs = hcd->regs; |
| 106 | 100 | ||
| 107 | ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED); | 101 | ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED); |
| 108 | if (ret) | 102 | if (ret) |
| 109 | goto err_uhci; | 103 | goto err_rmr; |
| 110 | 104 | ||
| 111 | device_wakeup_enable(hcd->self.controller); | 105 | device_wakeup_enable(hcd->self.controller); |
| 112 | return 0; | 106 | return 0; |
| 113 | 107 | ||
| 114 | err_uhci: | ||
| 115 | iounmap(hcd->regs); | ||
| 116 | err_irq: | ||
| 117 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 118 | err_rmr: | 108 | err_rmr: |
| 119 | usb_put_hcd(hcd); | 109 | usb_put_hcd(hcd); |
| 120 | 110 | ||
| @@ -126,8 +116,6 @@ static int uhci_hcd_platform_remove(struct platform_device *pdev) | |||
| 126 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 116 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
| 127 | 117 | ||
| 128 | usb_remove_hcd(hcd); | 118 | usb_remove_hcd(hcd); |
| 129 | iounmap(hcd->regs); | ||
| 130 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 131 | usb_put_hcd(hcd); | 119 | usb_put_hcd(hcd); |
| 132 | 120 | ||
| 133 | return 0; | 121 | return 0; |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index e20520f42753..c22a3e15a16e 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400 | 33 | #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400 |
| 34 | 34 | ||
| 35 | #define PCI_VENDOR_ID_ETRON 0x1b6f | 35 | #define PCI_VENDOR_ID_ETRON 0x1b6f |
| 36 | #define PCI_DEVICE_ID_ASROCK_P67 0x7023 | 36 | #define PCI_DEVICE_ID_EJ168 0x7023 |
| 37 | 37 | ||
| 38 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 | 38 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 |
| 39 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 | 39 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 |
| @@ -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; |
| @@ -140,9 +144,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 140 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; | 144 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; |
| 141 | } | 145 | } |
| 142 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 146 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
| 143 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { | 147 | pdev->device == PCI_DEVICE_ID_EJ168) { |
| 144 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 148 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
| 145 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | 149 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; |
| 150 | xhci->quirks |= XHCI_BROKEN_STREAMS; | ||
| 146 | } | 151 | } |
| 147 | if (pdev->vendor == PCI_VENDOR_ID_RENESAS && | 152 | if (pdev->vendor == PCI_VENDOR_ID_RENESAS && |
| 148 | pdev->device == 0x0015) | 153 | pdev->device == 0x0015) |
| @@ -150,6 +155,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 150 | if (pdev->vendor == PCI_VENDOR_ID_VIA) | 155 | if (pdev->vendor == PCI_VENDOR_ID_VIA) |
| 151 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 156 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
| 152 | 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 | |||
| 153 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 163 | if (xhci->quirks & XHCI_RESET_ON_RESUME) |
| 154 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, | 164 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, |
| 155 | "QUIRK: Resetting on resume"); | 165 | "QUIRK: Resetting on resume"); |
| @@ -230,7 +240,8 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 230 | goto put_usb3_hcd; | 240 | goto put_usb3_hcd; |
| 231 | /* Roothub already marked as USB 3.0 speed */ | 241 | /* Roothub already marked as USB 3.0 speed */ |
| 232 | 242 | ||
| 233 | if (HCC_MAX_PSA(xhci->hcc_params) >= 4) | 243 | if (!(xhci->quirks & XHCI_BROKEN_STREAMS) && |
| 244 | HCC_MAX_PSA(xhci->hcc_params) >= 4) | ||
| 234 | xhci->shared_hcd->can_do_streams = 1; | 245 | xhci->shared_hcd->can_do_streams = 1; |
| 235 | 246 | ||
| 236 | /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ | 247 | /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 29d8adb5c8d1..1a0cf9f31e43 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
| @@ -17,9 +17,11 @@ | |||
| 17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <linux/usb/xhci_pdriver.h> | ||
| 20 | 21 | ||
| 21 | #include "xhci.h" | 22 | #include "xhci.h" |
| 22 | #include "xhci-mvebu.h" | 23 | #include "xhci-mvebu.h" |
| 24 | #include "xhci-rcar.h" | ||
| 23 | 25 | ||
| 24 | static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) | 26 | static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) |
| 25 | { | 27 | { |
| @@ -34,11 +36,27 @@ static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 34 | /* called during probe() after chip reset completes */ | 36 | /* called during probe() after chip reset completes */ |
| 35 | static int xhci_plat_setup(struct usb_hcd *hcd) | 37 | static int xhci_plat_setup(struct usb_hcd *hcd) |
| 36 | { | 38 | { |
| 39 | struct device_node *of_node = hcd->self.controller->of_node; | ||
| 40 | int ret; | ||
| 41 | |||
| 42 | if (of_device_is_compatible(of_node, "renesas,xhci-r8a7790") || | ||
| 43 | of_device_is_compatible(of_node, "renesas,xhci-r8a7791")) { | ||
| 44 | ret = xhci_rcar_init_quirk(hcd); | ||
| 45 | if (ret) | ||
| 46 | return ret; | ||
| 47 | } | ||
| 48 | |||
| 37 | return xhci_gen_setup(hcd, xhci_plat_quirks); | 49 | return xhci_gen_setup(hcd, xhci_plat_quirks); |
| 38 | } | 50 | } |
| 39 | 51 | ||
| 40 | static int xhci_plat_start(struct usb_hcd *hcd) | 52 | static int xhci_plat_start(struct usb_hcd *hcd) |
| 41 | { | 53 | { |
| 54 | struct device_node *of_node = hcd->self.controller->of_node; | ||
| 55 | |||
| 56 | if (of_device_is_compatible(of_node, "renesas,xhci-r8a7790") || | ||
| 57 | of_device_is_compatible(of_node, "renesas,xhci-r8a7791")) | ||
| 58 | xhci_rcar_start(hcd); | ||
| 59 | |||
| 42 | return xhci_run(hcd); | 60 | return xhci_run(hcd); |
| 43 | } | 61 | } |
| 44 | 62 | ||
| @@ -90,10 +108,15 @@ static const struct hc_driver xhci_plat_xhci_driver = { | |||
| 90 | .hub_status_data = xhci_hub_status_data, | 108 | .hub_status_data = xhci_hub_status_data, |
| 91 | .bus_suspend = xhci_bus_suspend, | 109 | .bus_suspend = xhci_bus_suspend, |
| 92 | .bus_resume = xhci_bus_resume, | 110 | .bus_resume = xhci_bus_resume, |
| 111 | |||
| 112 | .enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout, | ||
| 113 | .disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout, | ||
| 93 | }; | 114 | }; |
| 94 | 115 | ||
| 95 | static int xhci_plat_probe(struct platform_device *pdev) | 116 | static int xhci_plat_probe(struct platform_device *pdev) |
| 96 | { | 117 | { |
| 118 | struct device_node *node = pdev->dev.of_node; | ||
| 119 | struct usb_xhci_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
| 97 | const struct hc_driver *driver; | 120 | const struct hc_driver *driver; |
| 98 | struct xhci_hcd *xhci; | 121 | struct xhci_hcd *xhci; |
| 99 | struct resource *res; | 122 | struct resource *res; |
| @@ -140,20 +163,12 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
| 140 | hcd->rsrc_start = res->start; | 163 | hcd->rsrc_start = res->start; |
| 141 | hcd->rsrc_len = resource_size(res); | 164 | hcd->rsrc_len = resource_size(res); |
| 142 | 165 | ||
| 143 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | 166 | hcd->regs = devm_ioremap_resource(&pdev->dev, res); |
| 144 | driver->description)) { | 167 | if (IS_ERR(hcd->regs)) { |
| 145 | dev_dbg(&pdev->dev, "controller already in use\n"); | 168 | ret = PTR_ERR(hcd->regs); |
| 146 | ret = -EBUSY; | ||
| 147 | goto put_hcd; | 169 | goto put_hcd; |
| 148 | } | 170 | } |
| 149 | 171 | ||
| 150 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
| 151 | if (!hcd->regs) { | ||
| 152 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
| 153 | ret = -EFAULT; | ||
| 154 | goto release_mem_region; | ||
| 155 | } | ||
| 156 | |||
| 157 | /* | 172 | /* |
| 158 | * Not all platforms have a clk so it is not an error if the | 173 | * Not all platforms have a clk so it is not an error if the |
| 159 | * clock does not exists. | 174 | * clock does not exists. |
| @@ -162,7 +177,7 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
| 162 | if (!IS_ERR(clk)) { | 177 | if (!IS_ERR(clk)) { |
| 163 | ret = clk_prepare_enable(clk); | 178 | ret = clk_prepare_enable(clk); |
| 164 | if (ret) | 179 | if (ret) |
| 165 | goto unmap_registers; | 180 | goto put_hcd; |
| 166 | } | 181 | } |
| 167 | 182 | ||
| 168 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); | 183 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| @@ -182,6 +197,9 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
| 182 | goto dealloc_usb2_hcd; | 197 | goto dealloc_usb2_hcd; |
| 183 | } | 198 | } |
| 184 | 199 | ||
| 200 | if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || | ||
| 201 | (pdata && pdata->usb3_lpm_capable)) | ||
| 202 | xhci->quirks |= XHCI_LPM_SUPPORT; | ||
| 185 | /* | 203 | /* |
| 186 | * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset) | 204 | * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset) |
| 187 | * is called by usb_add_hcd(). | 205 | * is called by usb_add_hcd(). |
| @@ -207,12 +225,6 @@ disable_clk: | |||
| 207 | if (!IS_ERR(clk)) | 225 | if (!IS_ERR(clk)) |
| 208 | clk_disable_unprepare(clk); | 226 | clk_disable_unprepare(clk); |
| 209 | 227 | ||
| 210 | unmap_registers: | ||
| 211 | iounmap(hcd->regs); | ||
| 212 | |||
| 213 | release_mem_region: | ||
| 214 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 215 | |||
| 216 | put_hcd: | 228 | put_hcd: |
| 217 | usb_put_hcd(hcd); | 229 | usb_put_hcd(hcd); |
| 218 | 230 | ||
| @@ -231,8 +243,6 @@ static int xhci_plat_remove(struct platform_device *dev) | |||
| 231 | usb_remove_hcd(hcd); | 243 | usb_remove_hcd(hcd); |
| 232 | if (!IS_ERR(clk)) | 244 | if (!IS_ERR(clk)) |
| 233 | clk_disable_unprepare(clk); | 245 | clk_disable_unprepare(clk); |
| 234 | iounmap(hcd->regs); | ||
| 235 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 236 | usb_put_hcd(hcd); | 246 | usb_put_hcd(hcd); |
| 237 | kfree(xhci); | 247 | kfree(xhci); |
| 238 | 248 | ||
| @@ -270,6 +280,8 @@ static const struct of_device_id usb_xhci_of_match[] = { | |||
| 270 | { .compatible = "xhci-platform" }, | 280 | { .compatible = "xhci-platform" }, |
| 271 | { .compatible = "marvell,armada-375-xhci"}, | 281 | { .compatible = "marvell,armada-375-xhci"}, |
| 272 | { .compatible = "marvell,armada-380-xhci"}, | 282 | { .compatible = "marvell,armada-380-xhci"}, |
| 283 | { .compatible = "renesas,xhci-r8a7790"}, | ||
| 284 | { .compatible = "renesas,xhci-r8a7791"}, | ||
| 273 | { }, | 285 | { }, |
| 274 | }; | 286 | }; |
| 275 | MODULE_DEVICE_TABLE(of, usb_xhci_of_match); | 287 | MODULE_DEVICE_TABLE(of, usb_xhci_of_match); |
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c new file mode 100644 index 000000000000..ff0d1b44ea58 --- /dev/null +++ b/drivers/usb/host/xhci-rcar.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* | ||
| 2 | * xHCI host controller driver for R-Car SoCs | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Renesas Electronics Corporation | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * version 2 as published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/firmware.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/usb/phy.h> | ||
| 15 | |||
| 16 | #include "xhci.h" | ||
| 17 | #include "xhci-rcar.h" | ||
| 18 | |||
| 19 | #define FIRMWARE_NAME "r8a779x_usb3_v1.dlmem" | ||
| 20 | MODULE_FIRMWARE(FIRMWARE_NAME); | ||
| 21 | |||
| 22 | /*** Register Offset ***/ | ||
| 23 | #define RCAR_USB3_INT_ENA 0x224 /* Interrupt Enable */ | ||
| 24 | #define RCAR_USB3_DL_CTRL 0x250 /* FW Download Control & Status */ | ||
| 25 | #define RCAR_USB3_FW_DATA0 0x258 /* FW Data0 */ | ||
| 26 | |||
| 27 | #define RCAR_USB3_LCLK 0xa44 /* LCLK Select */ | ||
| 28 | #define RCAR_USB3_CONF1 0xa48 /* USB3.0 Configuration1 */ | ||
| 29 | #define RCAR_USB3_CONF2 0xa5c /* USB3.0 Configuration2 */ | ||
| 30 | #define RCAR_USB3_CONF3 0xaa8 /* USB3.0 Configuration3 */ | ||
| 31 | #define RCAR_USB3_RX_POL 0xab0 /* USB3.0 RX Polarity */ | ||
| 32 | #define RCAR_USB3_TX_POL 0xab8 /* USB3.0 TX Polarity */ | ||
| 33 | |||
| 34 | /*** Register Settings ***/ | ||
| 35 | /* Interrupt Enable */ | ||
| 36 | #define RCAR_USB3_INT_XHC_ENA 0x00000001 | ||
| 37 | #define RCAR_USB3_INT_PME_ENA 0x00000002 | ||
| 38 | #define RCAR_USB3_INT_HSE_ENA 0x00000004 | ||
| 39 | #define RCAR_USB3_INT_ENA_VAL (RCAR_USB3_INT_XHC_ENA | \ | ||
| 40 | RCAR_USB3_INT_PME_ENA | RCAR_USB3_INT_HSE_ENA) | ||
| 41 | |||
| 42 | /* FW Download Control & Status */ | ||
| 43 | #define RCAR_USB3_DL_CTRL_ENABLE 0x00000001 | ||
| 44 | #define RCAR_USB3_DL_CTRL_FW_SUCCESS 0x00000010 | ||
| 45 | #define RCAR_USB3_DL_CTRL_FW_SET_DATA0 0x00000100 | ||
| 46 | |||
| 47 | /* LCLK Select */ | ||
| 48 | #define RCAR_USB3_LCLK_ENA_VAL 0x01030001 | ||
| 49 | |||
| 50 | /* USB3.0 Configuration */ | ||
| 51 | #define RCAR_USB3_CONF1_VAL 0x00030204 | ||
| 52 | #define RCAR_USB3_CONF2_VAL 0x00030300 | ||
| 53 | #define RCAR_USB3_CONF3_VAL 0x13802007 | ||
| 54 | |||
| 55 | /* USB3.0 Polarity */ | ||
| 56 | #define RCAR_USB3_RX_POL_VAL BIT(21) | ||
| 57 | #define RCAR_USB3_TX_POL_VAL BIT(4) | ||
| 58 | |||
| 59 | void xhci_rcar_start(struct usb_hcd *hcd) | ||
| 60 | { | ||
| 61 | u32 temp; | ||
| 62 | |||
| 63 | if (hcd->regs != NULL) { | ||
| 64 | /* Interrupt Enable */ | ||
| 65 | temp = readl(hcd->regs + RCAR_USB3_INT_ENA); | ||
| 66 | temp |= RCAR_USB3_INT_ENA_VAL; | ||
| 67 | writel(temp, hcd->regs + RCAR_USB3_INT_ENA); | ||
| 68 | /* LCLK Select */ | ||
| 69 | writel(RCAR_USB3_LCLK_ENA_VAL, hcd->regs + RCAR_USB3_LCLK); | ||
| 70 | /* USB3.0 Configuration */ | ||
| 71 | writel(RCAR_USB3_CONF1_VAL, hcd->regs + RCAR_USB3_CONF1); | ||
| 72 | writel(RCAR_USB3_CONF2_VAL, hcd->regs + RCAR_USB3_CONF2); | ||
| 73 | writel(RCAR_USB3_CONF3_VAL, hcd->regs + RCAR_USB3_CONF3); | ||
| 74 | /* USB3.0 Polarity */ | ||
| 75 | writel(RCAR_USB3_RX_POL_VAL, hcd->regs + RCAR_USB3_RX_POL); | ||
| 76 | writel(RCAR_USB3_TX_POL_VAL, hcd->regs + RCAR_USB3_TX_POL); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | static int xhci_rcar_download_firmware(struct device *dev, void __iomem *regs) | ||
| 81 | { | ||
| 82 | const struct firmware *fw; | ||
| 83 | int retval, index, j, time; | ||
| 84 | int timeout = 10000; | ||
| 85 | u32 data, val, temp; | ||
| 86 | |||
| 87 | /* request R-Car USB3.0 firmware */ | ||
| 88 | retval = request_firmware(&fw, FIRMWARE_NAME, dev); | ||
| 89 | if (retval) | ||
| 90 | return retval; | ||
| 91 | |||
| 92 | /* download R-Car USB3.0 firmware */ | ||
| 93 | temp = readl(regs + RCAR_USB3_DL_CTRL); | ||
| 94 | temp |= RCAR_USB3_DL_CTRL_ENABLE; | ||
| 95 | writel(temp, regs + RCAR_USB3_DL_CTRL); | ||
| 96 | |||
| 97 | for (index = 0; index < fw->size; index += 4) { | ||
| 98 | /* to avoid reading beyond the end of the buffer */ | ||
| 99 | for (data = 0, j = 3; j >= 0; j--) { | ||
| 100 | if ((j + index) < fw->size) | ||
| 101 | data |= fw->data[index + j] << (8 * j); | ||
| 102 | } | ||
| 103 | writel(data, regs + RCAR_USB3_FW_DATA0); | ||
| 104 | temp = readl(regs + RCAR_USB3_DL_CTRL); | ||
| 105 | temp |= RCAR_USB3_DL_CTRL_FW_SET_DATA0; | ||
| 106 | writel(temp, regs + RCAR_USB3_DL_CTRL); | ||
| 107 | |||
| 108 | for (time = 0; time < timeout; time++) { | ||
| 109 | val = readl(regs + RCAR_USB3_DL_CTRL); | ||
| 110 | if ((val & RCAR_USB3_DL_CTRL_FW_SET_DATA0) == 0) | ||
| 111 | break; | ||
| 112 | udelay(1); | ||
| 113 | } | ||
| 114 | if (time == timeout) { | ||
| 115 | retval = -ETIMEDOUT; | ||
| 116 | break; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | temp = readl(regs + RCAR_USB3_DL_CTRL); | ||
| 121 | temp &= ~RCAR_USB3_DL_CTRL_ENABLE; | ||
| 122 | writel(temp, regs + RCAR_USB3_DL_CTRL); | ||
| 123 | |||
| 124 | for (time = 0; time < timeout; time++) { | ||
| 125 | val = readl(regs + RCAR_USB3_DL_CTRL); | ||
| 126 | if (val & RCAR_USB3_DL_CTRL_FW_SUCCESS) { | ||
| 127 | retval = 0; | ||
| 128 | break; | ||
| 129 | } | ||
| 130 | udelay(1); | ||
| 131 | } | ||
| 132 | if (time == timeout) | ||
| 133 | retval = -ETIMEDOUT; | ||
| 134 | |||
| 135 | release_firmware(fw); | ||
| 136 | |||
| 137 | return retval; | ||
| 138 | } | ||
| 139 | |||
| 140 | /* This function needs to initialize a "phy" of usb before */ | ||
| 141 | int xhci_rcar_init_quirk(struct usb_hcd *hcd) | ||
| 142 | { | ||
| 143 | /* If hcd->regs is NULL, we don't just call the following function */ | ||
| 144 | if (!hcd->regs) | ||
| 145 | return 0; | ||
| 146 | |||
| 147 | return xhci_rcar_download_firmware(hcd->self.controller, hcd->regs); | ||
| 148 | } | ||
diff --git a/drivers/usb/host/xhci-rcar.h b/drivers/usb/host/xhci-rcar.h new file mode 100644 index 000000000000..58501256715d --- /dev/null +++ b/drivers/usb/host/xhci-rcar.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* | ||
| 2 | * drivers/usb/host/xhci-rcar.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Renesas Electronics Corporation | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * version 2 as published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef _XHCI_RCAR_H | ||
| 12 | #define _XHCI_RCAR_H | ||
| 13 | |||
| 14 | #if IS_ENABLED(CONFIG_USB_XHCI_RCAR) | ||
| 15 | void xhci_rcar_start(struct usb_hcd *hcd); | ||
| 16 | int xhci_rcar_init_quirk(struct usb_hcd *hcd); | ||
| 17 | #else | ||
| 18 | static inline void xhci_rcar_start(struct usb_hcd *hcd) | ||
| 19 | { | ||
| 20 | } | ||
| 21 | |||
| 22 | static inline int xhci_rcar_init_quirk(struct usb_hcd *hcd) | ||
| 23 | { | ||
| 24 | return 0; | ||
| 25 | } | ||
| 26 | #endif | ||
| 27 | #endif /* _XHCI_RCAR_H */ | ||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 749fc68eb5c1..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); | ||
| 517 | if (!state->new_deq_seg) { | ||
| 518 | WARN_ON(1); | ||
| 519 | return; | ||
| 520 | } | ||
| 521 | 490 | ||
| 522 | /* Increment to find next TRB after last_trb. Cycle if appropriate. */ | 491 | next_trb(xhci, ep_ring, &new_seg, &new_deq); |
| 523 | trb = &state->new_deq_ptr->generic; | 492 | |
| 524 | if (TRB_TYPE_LINK_LE32(trb->field[3]) && | 493 | /* Search wrapped around, bail out */ |
| 525 | (trb->field[3] & cpu_to_le32(LINK_TOGGLE))) | 494 | if (new_deq == ep->ring->dequeue) { |
| 526 | state->new_cycle_state ^= 0x1; | 495 | xhci_err(xhci, "Error: Failed finding new dequeue state\n"); |
| 527 | next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); | 496 | state->new_deq_seg = NULL; |
| 497 | state->new_deq_ptr = NULL; | ||
| 498 | return; | ||
| 499 | } | ||
| 500 | |||
| 501 | } while (!cycle_found || !td_last_trb_found); | ||
| 502 | |||
| 503 | state->new_deq_seg = new_seg; | ||
| 504 | state->new_deq_ptr = new_deq; | ||
| 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, |
| @@ -1118,6 +1095,10 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id, | |||
| 1118 | if (xhci->quirks & XHCI_RESET_EP_QUIRK) { | 1095 | if (xhci->quirks & XHCI_RESET_EP_QUIRK) { |
| 1119 | struct xhci_command *command; | 1096 | struct xhci_command *command; |
| 1120 | command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); | 1097 | command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); |
| 1098 | if (!command) { | ||
| 1099 | xhci_warn(xhci, "WARN Cannot submit cfg ep: ENOMEM\n"); | ||
| 1100 | return; | ||
| 1101 | } | ||
| 1121 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, | 1102 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, |
| 1122 | "Queueing configure endpoint command"); | 1103 | "Queueing configure endpoint command"); |
| 1123 | xhci_queue_configure_endpoint(xhci, command, | 1104 | xhci_queue_configure_endpoint(xhci, command, |
| @@ -2483,7 +2464,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
| 2483 | * last TRB of the previous TD. The command completion handle | 2464 | * last TRB of the previous TD. The command completion handle |
| 2484 | * will take care the rest. | 2465 | * will take care the rest. |
| 2485 | */ | 2466 | */ |
| 2486 | 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)) { | ||
| 2487 | ret = 0; | 2469 | ret = 0; |
| 2488 | goto cleanup; | 2470 | goto cleanup; |
| 2489 | } | 2471 | } |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7436d5f5e67a..c020b094fe7d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -1553,6 +1553,10 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 1553 | */ | 1553 | */ |
| 1554 | if (!(ep->ep_state & EP_HALT_PENDING)) { | 1554 | if (!(ep->ep_state & EP_HALT_PENDING)) { |
| 1555 | command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); | 1555 | command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); |
| 1556 | if (!command) { | ||
| 1557 | ret = -ENOMEM; | ||
| 1558 | goto done; | ||
| 1559 | } | ||
| 1556 | ep->ep_state |= EP_HALT_PENDING; | 1560 | ep->ep_state |= EP_HALT_PENDING; |
| 1557 | ep->stop_cmds_pending++; | 1561 | ep->stop_cmds_pending++; |
| 1558 | ep->stop_cmd_timer.expires = jiffies + | 1562 | ep->stop_cmd_timer.expires = jiffies + |
| @@ -1586,12 +1590,10 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 1586 | struct xhci_hcd *xhci; | 1590 | struct xhci_hcd *xhci; |
| 1587 | struct xhci_container_ctx *in_ctx, *out_ctx; | 1591 | struct xhci_container_ctx *in_ctx, *out_ctx; |
| 1588 | struct xhci_input_control_ctx *ctrl_ctx; | 1592 | struct xhci_input_control_ctx *ctrl_ctx; |
| 1589 | struct xhci_slot_ctx *slot_ctx; | ||
| 1590 | unsigned int last_ctx; | ||
| 1591 | unsigned int ep_index; | 1593 | unsigned int ep_index; |
| 1592 | struct xhci_ep_ctx *ep_ctx; | 1594 | struct xhci_ep_ctx *ep_ctx; |
| 1593 | u32 drop_flag; | 1595 | u32 drop_flag; |
| 1594 | u32 new_add_flags, new_drop_flags, new_slot_info; | 1596 | u32 new_add_flags, new_drop_flags; |
| 1595 | int ret; | 1597 | int ret; |
| 1596 | 1598 | ||
| 1597 | ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); | 1599 | ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); |
| @@ -1638,24 +1640,13 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 1638 | ctrl_ctx->add_flags &= cpu_to_le32(~drop_flag); | 1640 | ctrl_ctx->add_flags &= cpu_to_le32(~drop_flag); |
| 1639 | new_add_flags = le32_to_cpu(ctrl_ctx->add_flags); | 1641 | new_add_flags = le32_to_cpu(ctrl_ctx->add_flags); |
| 1640 | 1642 | ||
| 1641 | last_ctx = xhci_last_valid_endpoint(le32_to_cpu(ctrl_ctx->add_flags)); | ||
| 1642 | slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); | ||
| 1643 | /* Update the last valid endpoint context, if we deleted the last one */ | ||
| 1644 | if ((le32_to_cpu(slot_ctx->dev_info) & LAST_CTX_MASK) > | ||
| 1645 | LAST_CTX(last_ctx)) { | ||
| 1646 | slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK); | ||
| 1647 | slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(last_ctx)); | ||
| 1648 | } | ||
| 1649 | new_slot_info = le32_to_cpu(slot_ctx->dev_info); | ||
| 1650 | |||
| 1651 | xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); | 1643 | xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); |
| 1652 | 1644 | ||
| 1653 | xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", | 1645 | xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n", |
| 1654 | (unsigned int) ep->desc.bEndpointAddress, | 1646 | (unsigned int) ep->desc.bEndpointAddress, |
| 1655 | udev->slot_id, | 1647 | udev->slot_id, |
| 1656 | (unsigned int) new_drop_flags, | 1648 | (unsigned int) new_drop_flags, |
| 1657 | (unsigned int) new_add_flags, | 1649 | (unsigned int) new_add_flags); |
| 1658 | (unsigned int) new_slot_info); | ||
| 1659 | return 0; | 1650 | return 0; |
| 1660 | } | 1651 | } |
| 1661 | 1652 | ||
| @@ -1678,11 +1669,9 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 1678 | struct xhci_hcd *xhci; | 1669 | struct xhci_hcd *xhci; |
| 1679 | struct xhci_container_ctx *in_ctx, *out_ctx; | 1670 | struct xhci_container_ctx *in_ctx, *out_ctx; |
| 1680 | unsigned int ep_index; | 1671 | unsigned int ep_index; |
| 1681 | struct xhci_slot_ctx *slot_ctx; | ||
| 1682 | struct xhci_input_control_ctx *ctrl_ctx; | 1672 | struct xhci_input_control_ctx *ctrl_ctx; |
| 1683 | u32 added_ctxs; | 1673 | u32 added_ctxs; |
| 1684 | unsigned int last_ctx; | 1674 | u32 new_add_flags, new_drop_flags; |
| 1685 | u32 new_add_flags, new_drop_flags, new_slot_info; | ||
| 1686 | struct xhci_virt_device *virt_dev; | 1675 | struct xhci_virt_device *virt_dev; |
| 1687 | int ret = 0; | 1676 | int ret = 0; |
| 1688 | 1677 | ||
| @@ -1697,7 +1686,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 1697 | return -ENODEV; | 1686 | return -ENODEV; |
| 1698 | 1687 | ||
| 1699 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); | 1688 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); |
| 1700 | last_ctx = xhci_last_valid_endpoint(added_ctxs); | ||
| 1701 | if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { | 1689 | if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { |
| 1702 | /* FIXME when we have to issue an evaluate endpoint command to | 1690 | /* FIXME when we have to issue an evaluate endpoint command to |
| 1703 | * deal with ep0 max packet size changing once we get the | 1691 | * deal with ep0 max packet size changing once we get the |
| @@ -1763,24 +1751,14 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 1763 | */ | 1751 | */ |
| 1764 | new_drop_flags = le32_to_cpu(ctrl_ctx->drop_flags); | 1752 | new_drop_flags = le32_to_cpu(ctrl_ctx->drop_flags); |
| 1765 | 1753 | ||
| 1766 | slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); | ||
| 1767 | /* Update the last valid endpoint context, if we just added one past */ | ||
| 1768 | if ((le32_to_cpu(slot_ctx->dev_info) & LAST_CTX_MASK) < | ||
| 1769 | LAST_CTX(last_ctx)) { | ||
| 1770 | slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK); | ||
| 1771 | slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(last_ctx)); | ||
| 1772 | } | ||
| 1773 | new_slot_info = le32_to_cpu(slot_ctx->dev_info); | ||
| 1774 | |||
| 1775 | /* Store the usb_device pointer for later use */ | 1754 | /* Store the usb_device pointer for later use */ |
| 1776 | ep->hcpriv = udev; | 1755 | ep->hcpriv = udev; |
| 1777 | 1756 | ||
| 1778 | xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", | 1757 | xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n", |
| 1779 | (unsigned int) ep->desc.bEndpointAddress, | 1758 | (unsigned int) ep->desc.bEndpointAddress, |
| 1780 | udev->slot_id, | 1759 | udev->slot_id, |
| 1781 | (unsigned int) new_drop_flags, | 1760 | (unsigned int) new_drop_flags, |
| 1782 | (unsigned int) new_add_flags, | 1761 | (unsigned int) new_add_flags); |
| 1783 | (unsigned int) new_slot_info); | ||
| 1784 | return 0; | 1762 | return 0; |
| 1785 | } | 1763 | } |
| 1786 | 1764 | ||
| @@ -1830,15 +1808,15 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, | |||
| 1830 | ret = -ETIME; | 1808 | ret = -ETIME; |
| 1831 | break; | 1809 | break; |
| 1832 | case COMP_ENOMEM: | 1810 | case COMP_ENOMEM: |
| 1833 | dev_warn(&udev->dev, "Not enough host controller resources " | 1811 | dev_warn(&udev->dev, |
| 1834 | "for new device state.\n"); | 1812 | "Not enough host controller resources for new device state.\n"); |
| 1835 | ret = -ENOMEM; | 1813 | ret = -ENOMEM; |
| 1836 | /* FIXME: can we allocate more resources for the HC? */ | 1814 | /* FIXME: can we allocate more resources for the HC? */ |
| 1837 | break; | 1815 | break; |
| 1838 | case COMP_BW_ERR: | 1816 | case COMP_BW_ERR: |
| 1839 | case COMP_2ND_BW_ERR: | 1817 | case COMP_2ND_BW_ERR: |
| 1840 | dev_warn(&udev->dev, "Not enough bandwidth " | 1818 | dev_warn(&udev->dev, |
| 1841 | "for new device state.\n"); | 1819 | "Not enough bandwidth for new device state.\n"); |
| 1842 | ret = -ENOSPC; | 1820 | ret = -ENOSPC; |
| 1843 | /* FIXME: can we go back to the old state? */ | 1821 | /* FIXME: can we go back to the old state? */ |
| 1844 | break; | 1822 | break; |
| @@ -1850,8 +1828,8 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, | |||
| 1850 | ret = -EINVAL; | 1828 | ret = -EINVAL; |
| 1851 | break; | 1829 | break; |
| 1852 | case COMP_DEV_ERR: | 1830 | case COMP_DEV_ERR: |
| 1853 | dev_warn(&udev->dev, "ERROR: Incompatible device for endpoint " | 1831 | dev_warn(&udev->dev, |
| 1854 | "configure command.\n"); | 1832 | "ERROR: Incompatible device for endpoint configure command.\n"); |
| 1855 | ret = -ENODEV; | 1833 | ret = -ENODEV; |
| 1856 | break; | 1834 | break; |
| 1857 | case COMP_SUCCESS: | 1835 | case COMP_SUCCESS: |
| @@ -1860,8 +1838,8 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, | |||
| 1860 | ret = 0; | 1838 | ret = 0; |
| 1861 | break; | 1839 | break; |
| 1862 | default: | 1840 | default: |
| 1863 | xhci_err(xhci, "ERROR: unexpected command completion " | 1841 | xhci_err(xhci, "ERROR: unexpected command completion code 0x%x.\n", |
| 1864 | "code 0x%x.\n", *cmd_status); | 1842 | *cmd_status); |
| 1865 | ret = -EINVAL; | 1843 | ret = -EINVAL; |
| 1866 | break; | 1844 | break; |
| 1867 | } | 1845 | } |
| @@ -1881,24 +1859,24 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
| 1881 | ret = -ETIME; | 1859 | ret = -ETIME; |
| 1882 | break; | 1860 | break; |
| 1883 | case COMP_EINVAL: | 1861 | case COMP_EINVAL: |
| 1884 | dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " | 1862 | dev_warn(&udev->dev, |
| 1885 | "context command.\n"); | 1863 | "WARN: xHCI driver setup invalid evaluate context command.\n"); |
| 1886 | ret = -EINVAL; | 1864 | ret = -EINVAL; |
| 1887 | break; | 1865 | break; |
| 1888 | case COMP_EBADSLT: | 1866 | case COMP_EBADSLT: |
| 1889 | dev_warn(&udev->dev, "WARN: slot not enabled for" | 1867 | dev_warn(&udev->dev, |
| 1890 | "evaluate context command.\n"); | 1868 | "WARN: slot not enabled for evaluate context command.\n"); |
| 1891 | ret = -EINVAL; | 1869 | ret = -EINVAL; |
| 1892 | break; | 1870 | break; |
| 1893 | case COMP_CTX_STATE: | 1871 | case COMP_CTX_STATE: |
| 1894 | dev_warn(&udev->dev, "WARN: invalid context state for " | 1872 | dev_warn(&udev->dev, |
| 1895 | "evaluate context command.\n"); | 1873 | "WARN: invalid context state for evaluate context command.\n"); |
| 1896 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); | 1874 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); |
| 1897 | ret = -EINVAL; | 1875 | ret = -EINVAL; |
| 1898 | break; | 1876 | break; |
| 1899 | case COMP_DEV_ERR: | 1877 | case COMP_DEV_ERR: |
| 1900 | dev_warn(&udev->dev, "ERROR: Incompatible device for evaluate " | 1878 | dev_warn(&udev->dev, |
| 1901 | "context command.\n"); | 1879 | "ERROR: Incompatible device for evaluate context command.\n"); |
| 1902 | ret = -ENODEV; | 1880 | ret = -ENODEV; |
| 1903 | break; | 1881 | break; |
| 1904 | case COMP_MEL_ERR: | 1882 | case COMP_MEL_ERR: |
| @@ -1912,8 +1890,8 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
| 1912 | ret = 0; | 1890 | ret = 0; |
| 1913 | break; | 1891 | break; |
| 1914 | default: | 1892 | default: |
| 1915 | xhci_err(xhci, "ERROR: unexpected command completion " | 1893 | xhci_err(xhci, "ERROR: unexpected command completion code 0x%x.\n", |
| 1916 | "code 0x%x.\n", *cmd_status); | 1894 | *cmd_status); |
| 1917 | ret = -EINVAL; | 1895 | ret = -EINVAL; |
| 1918 | break; | 1896 | break; |
| 1919 | } | 1897 | } |
| @@ -2750,8 +2728,19 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
| 2750 | ret = 0; | 2728 | ret = 0; |
| 2751 | goto command_cleanup; | 2729 | goto command_cleanup; |
| 2752 | } | 2730 | } |
| 2753 | xhci_dbg(xhci, "New Input Control Context:\n"); | 2731 | /* Fix up Context Entries field. Minimum value is EP0 == BIT(1). */ |
| 2754 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); | 2732 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); |
| 2733 | for (i = 31; i >= 1; i--) { | ||
| 2734 | __le32 le32 = cpu_to_le32(BIT(i)); | ||
| 2735 | |||
| 2736 | if ((virt_dev->eps[i-1].ring && !(ctrl_ctx->drop_flags & le32)) | ||
| 2737 | || (ctrl_ctx->add_flags & le32) || i == 1) { | ||
| 2738 | slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK); | ||
| 2739 | slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(i)); | ||
| 2740 | break; | ||
| 2741 | } | ||
| 2742 | } | ||
| 2743 | xhci_dbg(xhci, "New Input Control Context:\n"); | ||
| 2755 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, | 2744 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, |
| 2756 | LAST_CTX_TO_EP_NUM(le32_to_cpu(slot_ctx->dev_info))); | 2745 | LAST_CTX_TO_EP_NUM(le32_to_cpu(slot_ctx->dev_info))); |
| 2757 | 2746 | ||
| @@ -2891,6 +2880,9 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, | |||
| 2891 | ep_index, ep->stopped_stream, ep->stopped_td, | 2880 | ep_index, ep->stopped_stream, ep->stopped_td, |
| 2892 | &deq_state); | 2881 | &deq_state); |
| 2893 | 2882 | ||
| 2883 | if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg) | ||
| 2884 | return; | ||
| 2885 | |||
| 2894 | /* 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 |
| 2895 | * issue a configure endpoint command later. | 2887 | * issue a configure endpoint command later. |
| 2896 | */ | 2888 | */ |
| @@ -3163,7 +3155,8 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 3163 | num_streams); | 3155 | num_streams); |
| 3164 | 3156 | ||
| 3165 | /* MaxPSASize value 0 (2 streams) means streams are not supported */ | 3157 | /* MaxPSASize value 0 (2 streams) means streams are not supported */ |
| 3166 | if (HCC_MAX_PSA(xhci->hcc_params) < 4) { | 3158 | if ((xhci->quirks & XHCI_BROKEN_STREAMS) || |
| 3159 | HCC_MAX_PSA(xhci->hcc_params) < 4) { | ||
| 3167 | xhci_dbg(xhci, "xHCI controller does not support streams.\n"); | 3160 | xhci_dbg(xhci, "xHCI controller does not support streams.\n"); |
| 3168 | return -ENOSYS; | 3161 | return -ENOSYS; |
| 3169 | } | 3162 | } |
| @@ -4303,8 +4296,7 @@ static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, | |||
| 4303 | return USB3_LPM_DISABLED; | 4296 | return USB3_LPM_DISABLED; |
| 4304 | } | 4297 | } |
| 4305 | 4298 | ||
| 4306 | /* Returns the hub-encoded U1 timeout value. | 4299 | /* The U1 timeout should be the maximum of the following values: |
| 4307 | * The U1 timeout should be the maximum of the following values: | ||
| 4308 | * - For control endpoints, U1 system exit latency (SEL) * 3 | 4300 | * - For control endpoints, U1 system exit latency (SEL) * 3 |
| 4309 | * - For bulk endpoints, U1 SEL * 5 | 4301 | * - For bulk endpoints, U1 SEL * 5 |
| 4310 | * - For interrupt endpoints: | 4302 | * - For interrupt endpoints: |
| @@ -4312,7 +4304,8 @@ static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, | |||
| 4312 | * - Periodic EPs, max(105% of bInterval, U1 SEL * 2) | 4304 | * - Periodic EPs, max(105% of bInterval, U1 SEL * 2) |
| 4313 | * - For isochronous endpoints, max(105% of bInterval, U1 SEL * 2) | 4305 | * - For isochronous endpoints, max(105% of bInterval, U1 SEL * 2) |
| 4314 | */ | 4306 | */ |
| 4315 | static u16 xhci_calculate_intel_u1_timeout(struct usb_device *udev, | 4307 | static unsigned long long xhci_calculate_intel_u1_timeout( |
| 4308 | struct usb_device *udev, | ||
| 4316 | struct usb_endpoint_descriptor *desc) | 4309 | struct usb_endpoint_descriptor *desc) |
| 4317 | { | 4310 | { |
| 4318 | unsigned long long timeout_ns; | 4311 | unsigned long long timeout_ns; |
| @@ -4344,11 +4337,28 @@ static u16 xhci_calculate_intel_u1_timeout(struct usb_device *udev, | |||
| 4344 | return 0; | 4337 | return 0; |
| 4345 | } | 4338 | } |
| 4346 | 4339 | ||
| 4347 | /* The U1 timeout is encoded in 1us intervals. */ | 4340 | return timeout_ns; |
| 4348 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 1000); | 4341 | } |
| 4349 | /* Don't return a timeout of zero, because that's USB3_LPM_DISABLED. */ | 4342 | |
| 4343 | /* Returns the hub-encoded U1 timeout value. */ | ||
| 4344 | static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, | ||
| 4345 | struct usb_device *udev, | ||
| 4346 | struct usb_endpoint_descriptor *desc) | ||
| 4347 | { | ||
| 4348 | unsigned long long timeout_ns; | ||
| 4349 | |||
| 4350 | if (xhci->quirks & XHCI_INTEL_HOST) | ||
| 4351 | timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); | ||
| 4352 | else | ||
| 4353 | timeout_ns = udev->u1_params.sel; | ||
| 4354 | |||
| 4355 | /* The U1 timeout is encoded in 1us intervals. | ||
| 4356 | * Don't return a timeout of zero, because that's USB3_LPM_DISABLED. | ||
| 4357 | */ | ||
| 4350 | if (timeout_ns == USB3_LPM_DISABLED) | 4358 | if (timeout_ns == USB3_LPM_DISABLED) |
| 4351 | timeout_ns++; | 4359 | timeout_ns = 1; |
| 4360 | else | ||
| 4361 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 1000); | ||
| 4352 | 4362 | ||
| 4353 | /* If the necessary timeout value is bigger than what we can set in the | 4363 | /* If the necessary timeout value is bigger than what we can set in the |
| 4354 | * USB 3.0 hub, we have to disable hub-initiated U1. | 4364 | * USB 3.0 hub, we have to disable hub-initiated U1. |
| @@ -4360,14 +4370,14 @@ static u16 xhci_calculate_intel_u1_timeout(struct usb_device *udev, | |||
| 4360 | return xhci_get_timeout_no_hub_lpm(udev, USB3_LPM_U1); | 4370 | return xhci_get_timeout_no_hub_lpm(udev, USB3_LPM_U1); |
| 4361 | } | 4371 | } |
| 4362 | 4372 | ||
| 4363 | /* Returns the hub-encoded U2 timeout value. | 4373 | /* The U2 timeout should be the maximum of: |
| 4364 | * The U2 timeout should be the maximum of: | ||
| 4365 | * - 10 ms (to avoid the bandwidth impact on the scheduler) | 4374 | * - 10 ms (to avoid the bandwidth impact on the scheduler) |
| 4366 | * - largest bInterval of any active periodic endpoint (to avoid going | 4375 | * - largest bInterval of any active periodic endpoint (to avoid going |
| 4367 | * into lower power link states between intervals). | 4376 | * into lower power link states between intervals). |
| 4368 | * - the U2 Exit Latency of the device | 4377 | * - the U2 Exit Latency of the device |
| 4369 | */ | 4378 | */ |
| 4370 | static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev, | 4379 | static unsigned long long xhci_calculate_intel_u2_timeout( |
| 4380 | struct usb_device *udev, | ||
| 4371 | struct usb_endpoint_descriptor *desc) | 4381 | struct usb_endpoint_descriptor *desc) |
| 4372 | { | 4382 | { |
| 4373 | unsigned long long timeout_ns; | 4383 | unsigned long long timeout_ns; |
| @@ -4383,6 +4393,21 @@ static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev, | |||
| 4383 | if (u2_del_ns > timeout_ns) | 4393 | if (u2_del_ns > timeout_ns) |
| 4384 | timeout_ns = u2_del_ns; | 4394 | timeout_ns = u2_del_ns; |
| 4385 | 4395 | ||
| 4396 | return timeout_ns; | ||
| 4397 | } | ||
| 4398 | |||
| 4399 | /* Returns the hub-encoded U2 timeout value. */ | ||
| 4400 | static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, | ||
| 4401 | struct usb_device *udev, | ||
| 4402 | struct usb_endpoint_descriptor *desc) | ||
| 4403 | { | ||
| 4404 | unsigned long long timeout_ns; | ||
| 4405 | |||
| 4406 | if (xhci->quirks & XHCI_INTEL_HOST) | ||
| 4407 | timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); | ||
| 4408 | else | ||
| 4409 | timeout_ns = udev->u2_params.sel; | ||
| 4410 | |||
| 4386 | /* The U2 timeout is encoded in 256us intervals */ | 4411 | /* The U2 timeout is encoded in 256us intervals */ |
| 4387 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); | 4412 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); |
| 4388 | /* If the necessary timeout value is bigger than what we can set in the | 4413 | /* If the necessary timeout value is bigger than what we can set in the |
| @@ -4401,13 +4426,10 @@ static u16 xhci_call_host_update_timeout_for_endpoint(struct xhci_hcd *xhci, | |||
| 4401 | enum usb3_link_state state, | 4426 | enum usb3_link_state state, |
| 4402 | u16 *timeout) | 4427 | u16 *timeout) |
| 4403 | { | 4428 | { |
| 4404 | if (state == USB3_LPM_U1) { | 4429 | if (state == USB3_LPM_U1) |
| 4405 | if (xhci->quirks & XHCI_INTEL_HOST) | 4430 | return xhci_calculate_u1_timeout(xhci, udev, desc); |
| 4406 | return xhci_calculate_intel_u1_timeout(udev, desc); | 4431 | else if (state == USB3_LPM_U2) |
| 4407 | } else { | 4432 | return xhci_calculate_u2_timeout(xhci, udev, desc); |
| 4408 | if (xhci->quirks & XHCI_INTEL_HOST) | ||
| 4409 | return xhci_calculate_intel_u2_timeout(udev, desc); | ||
| 4410 | } | ||
| 4411 | 4433 | ||
| 4412 | return USB3_LPM_DISABLED; | 4434 | return USB3_LPM_DISABLED; |
| 4413 | } | 4435 | } |
| @@ -4484,7 +4506,8 @@ static int xhci_check_tier_policy(struct xhci_hcd *xhci, | |||
| 4484 | { | 4506 | { |
| 4485 | if (xhci->quirks & XHCI_INTEL_HOST) | 4507 | if (xhci->quirks & XHCI_INTEL_HOST) |
| 4486 | return xhci_check_intel_tier_policy(udev, state); | 4508 | return xhci_check_intel_tier_policy(udev, state); |
| 4487 | return -EINVAL; | 4509 | else |
| 4510 | return 0; | ||
| 4488 | } | 4511 | } |
| 4489 | 4512 | ||
| 4490 | /* Returns the U1 or U2 timeout that should be enabled. | 4513 | /* Returns the U1 or U2 timeout that should be enabled. |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 9ffecd56600d..dace5152e179 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
| @@ -1558,6 +1558,8 @@ struct xhci_hcd { | |||
| 1558 | #define XHCI_PLAT (1 << 16) | 1558 | #define XHCI_PLAT (1 << 16) |
| 1559 | #define XHCI_SLOW_SUSPEND (1 << 17) | 1559 | #define XHCI_SLOW_SUSPEND (1 << 17) |
| 1560 | #define XHCI_SPURIOUS_WAKEUP (1 << 18) | 1560 | #define XHCI_SPURIOUS_WAKEUP (1 << 18) |
| 1561 | /* For controllers with a broken beyond repair streams implementation */ | ||
| 1562 | #define XHCI_BROKEN_STREAMS (1 << 19) | ||
| 1561 | unsigned int num_active_eps; | 1563 | unsigned int num_active_eps; |
| 1562 | unsigned int limit_active_eps; | 1564 | unsigned int limit_active_eps; |
| 1563 | /* There are two roothubs to keep track of bus suspend info for */ | 1565 | /* There are two roothubs to keep track of bus suspend info for */ |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 1bca274dc3b5..76d77206e011 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
| @@ -248,3 +248,10 @@ config USB_HSIC_USB3503 | |||
| 248 | select REGMAP_I2C | 248 | select REGMAP_I2C |
| 249 | help | 249 | help |
| 250 | This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver. | 250 | This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver. |
| 251 | |||
| 252 | config USB_LINK_LAYER_TEST | ||
| 253 | tristate "USB Link Layer Test driver" | ||
| 254 | help | ||
| 255 | This driver is for generating specific traffic for Super Speed Link | ||
| 256 | Layer Test Device. Say Y only when you want to conduct USB Super Speed | ||
| 257 | Link Layer Test for host controllers. | ||
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index e748fd5dbe94..65b0402c1ca1 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
| @@ -27,3 +27,4 @@ obj-$(CONFIG_USB_YUREX) += yurex.o | |||
| 27 | obj-$(CONFIG_USB_HSIC_USB3503) += usb3503.o | 27 | obj-$(CONFIG_USB_HSIC_USB3503) += usb3503.o |
| 28 | 28 | ||
| 29 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ | 29 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ |
| 30 | obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o | ||
diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c new file mode 100644 index 000000000000..7d589c156fb1 --- /dev/null +++ b/drivers/usb/misc/lvstest.c | |||
| @@ -0,0 +1,460 @@ | |||
| 1 | /* | ||
| 2 | * drivers/usb/misc/lvstest.c | ||
| 3 | * | ||
| 4 | * Test pattern generation for Link Layer Validation System Tests | ||
| 5 | * | ||
| 6 | * Copyright (C) 2014 ST Microelectronics | ||
| 7 | * Pratyush Anand <pratyush.anand@st.com> | ||
| 8 | * | ||
| 9 | * This file is licensed under the terms of the GNU General Public | ||
| 10 | * License version 2. This program is licensed "as is" without any | ||
| 11 | * warranty of any kind, whether express or implied. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/usb.h> | ||
| 20 | #include <linux/usb/ch11.h> | ||
| 21 | #include <linux/usb/hcd.h> | ||
| 22 | #include <linux/usb/phy.h> | ||
| 23 | |||
| 24 | struct lvs_rh { | ||
| 25 | /* root hub interface */ | ||
| 26 | struct usb_interface *intf; | ||
| 27 | /* if lvs device connected */ | ||
| 28 | bool present; | ||
| 29 | /* port no at which lvs device is present */ | ||
| 30 | int portnum; | ||
| 31 | /* urb buffer */ | ||
| 32 | u8 buffer[8]; | ||
| 33 | /* class descriptor */ | ||
| 34 | struct usb_hub_descriptor descriptor; | ||
| 35 | /* urb for polling interrupt pipe */ | ||
| 36 | struct urb *urb; | ||
| 37 | /* LVS RH work queue */ | ||
| 38 | struct workqueue_struct *rh_queue; | ||
| 39 | /* LVH RH work */ | ||
| 40 | struct work_struct rh_work; | ||
| 41 | /* RH port status */ | ||
| 42 | struct usb_port_status port_status; | ||
| 43 | }; | ||
| 44 | |||
| 45 | static struct usb_device *create_lvs_device(struct usb_interface *intf) | ||
| 46 | { | ||
| 47 | struct usb_device *udev, *hdev; | ||
| 48 | struct usb_hcd *hcd; | ||
| 49 | struct lvs_rh *lvs = usb_get_intfdata(intf); | ||
| 50 | |||
| 51 | if (!lvs->present) { | ||
| 52 | dev_err(&intf->dev, "No LVS device is present\n"); | ||
| 53 | return NULL; | ||
| 54 | } | ||
| 55 | |||
| 56 | hdev = interface_to_usbdev(intf); | ||
| 57 | hcd = bus_to_hcd(hdev->bus); | ||
| 58 | |||
| 59 | udev = usb_alloc_dev(hdev, hdev->bus, lvs->portnum); | ||
| 60 | if (!udev) { | ||
| 61 | dev_err(&intf->dev, "Could not allocate lvs udev\n"); | ||
| 62 | return NULL; | ||
| 63 | } | ||
| 64 | udev->speed = USB_SPEED_SUPER; | ||
| 65 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); | ||
| 66 | usb_set_device_state(udev, USB_STATE_DEFAULT); | ||
| 67 | |||
| 68 | if (hcd->driver->enable_device) { | ||
| 69 | if (hcd->driver->enable_device(hcd, udev) < 0) { | ||
| 70 | dev_err(&intf->dev, "Failed to enable\n"); | ||
| 71 | usb_put_dev(udev); | ||
| 72 | return NULL; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | return udev; | ||
| 77 | } | ||
| 78 | |||
| 79 | static void destroy_lvs_device(struct usb_device *udev) | ||
| 80 | { | ||
| 81 | struct usb_device *hdev = udev->parent; | ||
| 82 | struct usb_hcd *hcd = bus_to_hcd(hdev->bus); | ||
| 83 | |||
| 84 | if (hcd->driver->free_dev) | ||
| 85 | hcd->driver->free_dev(hcd, udev); | ||
| 86 | |||
| 87 | usb_put_dev(udev); | ||
| 88 | } | ||
| 89 | |||
| 90 | static int lvs_rh_clear_port_feature(struct usb_device *hdev, | ||
| 91 | int port1, int feature) | ||
| 92 | { | ||
| 93 | return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), | ||
| 94 | USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1, | ||
| 95 | NULL, 0, 1000); | ||
| 96 | } | ||
| 97 | |||
| 98 | static int lvs_rh_set_port_feature(struct usb_device *hdev, | ||
| 99 | int port1, int feature) | ||
| 100 | { | ||
| 101 | return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), | ||
| 102 | USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1, | ||
| 103 | NULL, 0, 1000); | ||
| 104 | } | ||
| 105 | |||
| 106 | static ssize_t u3_entry_store(struct device *dev, | ||
| 107 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 108 | { | ||
| 109 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 110 | struct usb_device *hdev = interface_to_usbdev(intf); | ||
| 111 | struct lvs_rh *lvs = usb_get_intfdata(intf); | ||
| 112 | struct usb_device *udev; | ||
| 113 | int ret; | ||
| 114 | |||
| 115 | udev = create_lvs_device(intf); | ||
| 116 | if (!udev) { | ||
| 117 | dev_err(dev, "failed to create lvs device\n"); | ||
| 118 | return -ENOMEM; | ||
| 119 | } | ||
| 120 | |||
| 121 | ret = lvs_rh_set_port_feature(hdev, lvs->portnum, | ||
| 122 | USB_PORT_FEAT_SUSPEND); | ||
| 123 | if (ret < 0) | ||
| 124 | dev_err(dev, "can't issue U3 entry %d\n", ret); | ||
| 125 | |||
| 126 | destroy_lvs_device(udev); | ||
| 127 | |||
| 128 | if (ret < 0) | ||
| 129 | return ret; | ||
| 130 | |||
| 131 | return count; | ||
| 132 | } | ||
| 133 | static DEVICE_ATTR_WO(u3_entry); | ||
| 134 | |||
| 135 | static ssize_t u3_exit_store(struct device *dev, | ||
| 136 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 137 | { | ||
| 138 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 139 | struct usb_device *hdev = interface_to_usbdev(intf); | ||
| 140 | struct lvs_rh *lvs = usb_get_intfdata(intf); | ||
| 141 | struct usb_device *udev; | ||
| 142 | int ret; | ||
| 143 | |||
| 144 | udev = create_lvs_device(intf); | ||
| 145 | if (!udev) { | ||
| 146 | dev_err(dev, "failed to create lvs device\n"); | ||
| 147 | return -ENOMEM; | ||
| 148 | } | ||
| 149 | |||
| 150 | ret = lvs_rh_clear_port_feature(hdev, lvs->portnum, | ||
| 151 | USB_PORT_FEAT_SUSPEND); | ||
| 152 | if (ret < 0) | ||
| 153 | dev_err(dev, "can't issue U3 exit %d\n", ret); | ||
| 154 | |||
| 155 | destroy_lvs_device(udev); | ||
| 156 | |||
| 157 | if (ret < 0) | ||
| 158 | return ret; | ||
| 159 | |||
| 160 | return count; | ||
| 161 | } | ||
| 162 | static DEVICE_ATTR_WO(u3_exit); | ||
| 163 | |||
| 164 | static ssize_t hot_reset_store(struct device *dev, | ||
| 165 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 166 | { | ||
| 167 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 168 | struct usb_device *hdev = interface_to_usbdev(intf); | ||
| 169 | struct lvs_rh *lvs = usb_get_intfdata(intf); | ||
| 170 | int ret; | ||
| 171 | |||
| 172 | ret = lvs_rh_set_port_feature(hdev, lvs->portnum, | ||
| 173 | USB_PORT_FEAT_RESET); | ||
| 174 | if (ret < 0) { | ||
| 175 | dev_err(dev, "can't issue hot reset %d\n", ret); | ||
| 176 | return ret; | ||
| 177 | } | ||
| 178 | |||
| 179 | return count; | ||
| 180 | } | ||
| 181 | static DEVICE_ATTR_WO(hot_reset); | ||
| 182 | |||
| 183 | static ssize_t u2_timeout_store(struct device *dev, | ||
| 184 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 185 | { | ||
| 186 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 187 | struct usb_device *hdev = interface_to_usbdev(intf); | ||
| 188 | struct lvs_rh *lvs = usb_get_intfdata(intf); | ||
| 189 | unsigned long val; | ||
| 190 | int ret; | ||
| 191 | |||
| 192 | ret = kstrtoul(buf, 10, &val); | ||
| 193 | if (ret < 0) { | ||
| 194 | dev_err(dev, "couldn't parse string %d\n", ret); | ||
| 195 | return ret; | ||
| 196 | } | ||
| 197 | |||
| 198 | if (val < 0 || val > 127) | ||
| 199 | return -EINVAL; | ||
| 200 | |||
| 201 | ret = lvs_rh_set_port_feature(hdev, lvs->portnum | (val << 8), | ||
| 202 | USB_PORT_FEAT_U2_TIMEOUT); | ||
| 203 | if (ret < 0) { | ||
| 204 | dev_err(dev, "Error %d while setting U2 timeout %ld\n", ret, val); | ||
| 205 | return ret; | ||
| 206 | } | ||
| 207 | |||
| 208 | return count; | ||
| 209 | } | ||
| 210 | static DEVICE_ATTR_WO(u2_timeout); | ||
| 211 | |||
| 212 | static ssize_t u1_timeout_store(struct device *dev, | ||
| 213 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 214 | { | ||
| 215 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 216 | struct usb_device *hdev = interface_to_usbdev(intf); | ||
| 217 | struct lvs_rh *lvs = usb_get_intfdata(intf); | ||
| 218 | unsigned long val; | ||
| 219 | int ret; | ||
| 220 | |||
| 221 | ret = kstrtoul(buf, 10, &val); | ||
| 222 | if (ret < 0) { | ||
| 223 | dev_err(dev, "couldn't parse string %d\n", ret); | ||
| 224 | return ret; | ||
| 225 | } | ||
| 226 | |||
| 227 | if (val < 0 || val > 127) | ||
| 228 | return -EINVAL; | ||
| 229 | |||
| 230 | ret = lvs_rh_set_port_feature(hdev, lvs->portnum | (val << 8), | ||
| 231 | USB_PORT_FEAT_U1_TIMEOUT); | ||
| 232 | if (ret < 0) { | ||
| 233 | dev_err(dev, "Error %d while setting U1 timeout %ld\n", ret, val); | ||
| 234 | return ret; | ||
| 235 | } | ||
| 236 | |||
| 237 | return count; | ||
| 238 | } | ||
| 239 | static DEVICE_ATTR_WO(u1_timeout); | ||
| 240 | |||
| 241 | static ssize_t get_dev_desc_store(struct device *dev, | ||
| 242 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 243 | { | ||
| 244 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 245 | struct usb_device *udev; | ||
| 246 | struct usb_device_descriptor *descriptor; | ||
| 247 | int ret; | ||
| 248 | |||
| 249 | descriptor = kmalloc(sizeof(*descriptor), GFP_KERNEL); | ||
| 250 | if (!descriptor) { | ||
| 251 | dev_err(dev, "failed to allocate descriptor memory\n"); | ||
| 252 | return -ENOMEM; | ||
| 253 | } | ||
| 254 | |||
| 255 | udev = create_lvs_device(intf); | ||
| 256 | if (!udev) { | ||
| 257 | dev_err(dev, "failed to create lvs device\n"); | ||
| 258 | ret = -ENOMEM; | ||
| 259 | goto free_desc; | ||
| 260 | } | ||
| 261 | |||
| 262 | ret = usb_control_msg(udev, (PIPE_CONTROL << 30) | USB_DIR_IN, | ||
| 263 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, USB_DT_DEVICE << 8, | ||
| 264 | 0, descriptor, sizeof(*descriptor), | ||
| 265 | USB_CTRL_GET_TIMEOUT); | ||
| 266 | if (ret < 0) | ||
| 267 | dev_err(dev, "can't read device descriptor %d\n", ret); | ||
| 268 | |||
| 269 | destroy_lvs_device(udev); | ||
| 270 | |||
| 271 | free_desc: | ||
| 272 | kfree(descriptor); | ||
| 273 | |||
| 274 | if (ret < 0) | ||
| 275 | return ret; | ||
| 276 | |||
| 277 | return count; | ||
| 278 | } | ||
| 279 | static DEVICE_ATTR_WO(get_dev_desc); | ||
| 280 | |||
| 281 | static struct attribute *lvs_attributes[] = { | ||
| 282 | &dev_attr_get_dev_desc.attr, | ||
| 283 | &dev_attr_u1_timeout.attr, | ||
| 284 | &dev_attr_u2_timeout.attr, | ||
| 285 | &dev_attr_hot_reset.attr, | ||
| 286 | &dev_attr_u3_entry.attr, | ||
| 287 | &dev_attr_u3_exit.attr, | ||
| 288 | NULL | ||
| 289 | }; | ||
| 290 | |||
| 291 | static const struct attribute_group lvs_attr_group = { | ||
| 292 | .attrs = lvs_attributes, | ||
| 293 | }; | ||
| 294 | |||
| 295 | static void lvs_rh_work(struct work_struct *work) | ||
| 296 | { | ||
| 297 | struct lvs_rh *lvs = container_of(work, struct lvs_rh, rh_work); | ||
| 298 | struct usb_interface *intf = lvs->intf; | ||
| 299 | struct usb_device *hdev = interface_to_usbdev(intf); | ||
| 300 | struct usb_hcd *hcd = bus_to_hcd(hdev->bus); | ||
| 301 | struct usb_hub_descriptor *descriptor = &lvs->descriptor; | ||
| 302 | struct usb_port_status *port_status = &lvs->port_status; | ||
| 303 | int i, ret = 0; | ||
| 304 | u16 portchange; | ||
| 305 | |||
| 306 | /* Examine each root port */ | ||
| 307 | for (i = 1; i <= descriptor->bNbrPorts; i++) { | ||
| 308 | ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0), | ||
| 309 | USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, i, | ||
| 310 | port_status, sizeof(*port_status), 1000); | ||
| 311 | if (ret < 4) | ||
| 312 | continue; | ||
| 313 | |||
| 314 | portchange = le16_to_cpu(port_status->wPortChange); | ||
| 315 | |||
| 316 | if (portchange & USB_PORT_STAT_C_LINK_STATE) | ||
| 317 | lvs_rh_clear_port_feature(hdev, i, | ||
| 318 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
| 319 | if (portchange & USB_PORT_STAT_C_ENABLE) | ||
| 320 | lvs_rh_clear_port_feature(hdev, i, | ||
| 321 | USB_PORT_FEAT_C_ENABLE); | ||
| 322 | if (portchange & USB_PORT_STAT_C_RESET) | ||
| 323 | lvs_rh_clear_port_feature(hdev, i, | ||
| 324 | USB_PORT_FEAT_C_RESET); | ||
| 325 | if (portchange & USB_PORT_STAT_C_BH_RESET) | ||
| 326 | lvs_rh_clear_port_feature(hdev, i, | ||
| 327 | USB_PORT_FEAT_C_BH_PORT_RESET); | ||
| 328 | if (portchange & USB_PORT_STAT_C_CONNECTION) { | ||
| 329 | lvs_rh_clear_port_feature(hdev, i, | ||
| 330 | USB_PORT_FEAT_C_CONNECTION); | ||
| 331 | |||
| 332 | if (le16_to_cpu(port_status->wPortStatus) & | ||
| 333 | USB_PORT_STAT_CONNECTION) { | ||
| 334 | lvs->present = true; | ||
| 335 | lvs->portnum = i; | ||
| 336 | if (hcd->phy) | ||
| 337 | usb_phy_notify_connect(hcd->phy, | ||
| 338 | USB_SPEED_SUPER); | ||
| 339 | } else { | ||
| 340 | lvs->present = false; | ||
| 341 | if (hcd->phy) | ||
| 342 | usb_phy_notify_disconnect(hcd->phy, | ||
| 343 | USB_SPEED_SUPER); | ||
| 344 | } | ||
| 345 | break; | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | ret = usb_submit_urb(lvs->urb, GFP_KERNEL); | ||
| 350 | if (ret != 0 && ret != -ENODEV && ret != -EPERM) | ||
| 351 | dev_err(&intf->dev, "urb resubmit error %d\n", ret); | ||
| 352 | } | ||
| 353 | |||
| 354 | static void lvs_rh_irq(struct urb *urb) | ||
| 355 | { | ||
| 356 | struct lvs_rh *lvs = urb->context; | ||
| 357 | |||
| 358 | queue_work(lvs->rh_queue, &lvs->rh_work); | ||
| 359 | } | ||
| 360 | |||
| 361 | static int lvs_rh_probe(struct usb_interface *intf, | ||
| 362 | const struct usb_device_id *id) | ||
| 363 | { | ||
| 364 | struct usb_device *hdev; | ||
| 365 | struct usb_host_interface *desc; | ||
| 366 | struct usb_endpoint_descriptor *endpoint; | ||
| 367 | struct lvs_rh *lvs; | ||
| 368 | unsigned int pipe; | ||
| 369 | int ret, maxp; | ||
| 370 | |||
| 371 | hdev = interface_to_usbdev(intf); | ||
| 372 | desc = intf->cur_altsetting; | ||
| 373 | endpoint = &desc->endpoint[0].desc; | ||
| 374 | |||
| 375 | /* valid only for SS root hub */ | ||
| 376 | if (hdev->descriptor.bDeviceProtocol != USB_HUB_PR_SS || hdev->parent) { | ||
| 377 | dev_err(&intf->dev, "Bind LVS driver with SS root Hub only\n"); | ||
| 378 | return -EINVAL; | ||
| 379 | } | ||
| 380 | |||
| 381 | lvs = devm_kzalloc(&intf->dev, sizeof(*lvs), GFP_KERNEL); | ||
| 382 | if (!lvs) | ||
| 383 | return -ENOMEM; | ||
| 384 | |||
| 385 | lvs->intf = intf; | ||
| 386 | usb_set_intfdata(intf, lvs); | ||
| 387 | |||
| 388 | /* how many number of ports this root hub has */ | ||
| 389 | ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0), | ||
| 390 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, | ||
| 391 | USB_DT_SS_HUB << 8, 0, &lvs->descriptor, | ||
| 392 | USB_DT_SS_HUB_SIZE, USB_CTRL_GET_TIMEOUT); | ||
| 393 | if (ret < (USB_DT_HUB_NONVAR_SIZE + 2)) { | ||
| 394 | dev_err(&hdev->dev, "wrong root hub descriptor read %d\n", ret); | ||
| 395 | return ret; | ||
| 396 | } | ||
| 397 | |||
| 398 | /* submit urb to poll interrupt endpoint */ | ||
| 399 | lvs->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 400 | if (!lvs->urb) { | ||
| 401 | dev_err(&intf->dev, "couldn't allocate lvs urb\n"); | ||
| 402 | return -ENOMEM; | ||
| 403 | } | ||
| 404 | |||
| 405 | lvs->rh_queue = create_singlethread_workqueue("lvs_rh_queue"); | ||
| 406 | if (!lvs->rh_queue) { | ||
| 407 | dev_err(&intf->dev, "couldn't create workqueue\n"); | ||
| 408 | ret = -ENOMEM; | ||
| 409 | goto free_urb; | ||
| 410 | } | ||
| 411 | |||
| 412 | INIT_WORK(&lvs->rh_work, lvs_rh_work); | ||
| 413 | |||
| 414 | ret = sysfs_create_group(&intf->dev.kobj, &lvs_attr_group); | ||
| 415 | if (ret < 0) { | ||
| 416 | dev_err(&intf->dev, "Failed to create sysfs node %d\n", ret); | ||
| 417 | goto destroy_queue; | ||
| 418 | } | ||
| 419 | |||
| 420 | pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress); | ||
| 421 | maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe)); | ||
| 422 | usb_fill_int_urb(lvs->urb, hdev, pipe, &lvs->buffer[0], maxp, | ||
| 423 | lvs_rh_irq, lvs, endpoint->bInterval); | ||
| 424 | |||
| 425 | ret = usb_submit_urb(lvs->urb, GFP_KERNEL); | ||
| 426 | if (ret < 0) { | ||
| 427 | dev_err(&intf->dev, "couldn't submit lvs urb %d\n", ret); | ||
| 428 | goto sysfs_remove; | ||
| 429 | } | ||
| 430 | |||
| 431 | return ret; | ||
| 432 | |||
| 433 | sysfs_remove: | ||
| 434 | sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); | ||
| 435 | destroy_queue: | ||
| 436 | destroy_workqueue(lvs->rh_queue); | ||
| 437 | free_urb: | ||
| 438 | usb_free_urb(lvs->urb); | ||
| 439 | return ret; | ||
| 440 | } | ||
| 441 | |||
| 442 | static void lvs_rh_disconnect(struct usb_interface *intf) | ||
| 443 | { | ||
| 444 | struct lvs_rh *lvs = usb_get_intfdata(intf); | ||
| 445 | |||
| 446 | sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); | ||
| 447 | destroy_workqueue(lvs->rh_queue); | ||
| 448 | usb_free_urb(lvs->urb); | ||
| 449 | } | ||
| 450 | |||
| 451 | static struct usb_driver lvs_driver = { | ||
| 452 | .name = "lvs", | ||
| 453 | .probe = lvs_rh_probe, | ||
| 454 | .disconnect = lvs_rh_disconnect, | ||
| 455 | }; | ||
| 456 | |||
| 457 | module_usb_driver(lvs_driver); | ||
| 458 | |||
| 459 | MODULE_DESCRIPTION("Link Layer Validation System Driver"); | ||
| 460 | MODULE_LICENSE("GPL"); | ||
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/misc/usb3503.c b/drivers/usb/misc/usb3503.c index f43c61989cef..47cb143716a1 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c | |||
| @@ -149,8 +149,6 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode) | |||
| 149 | 149 | ||
| 150 | case USB3503_MODE_STANDBY: | 150 | case USB3503_MODE_STANDBY: |
| 151 | usb3503_reset(hub, 0); | 151 | usb3503_reset(hub, 0); |
| 152 | |||
| 153 | hub->mode = mode; | ||
| 154 | dev_info(dev, "switched to STANDBY mode\n"); | 152 | dev_info(dev, "switched to STANDBY mode\n"); |
| 155 | break; | 153 | break; |
| 156 | 154 | ||
| @@ -192,7 +190,8 @@ static int usb3503_probe(struct usb3503 *hub) | |||
| 192 | 190 | ||
| 193 | clk = devm_clk_get(dev, "refclk"); | 191 | clk = devm_clk_get(dev, "refclk"); |
| 194 | if (IS_ERR(clk) && PTR_ERR(clk) != -ENOENT) { | 192 | if (IS_ERR(clk) && PTR_ERR(clk) != -ENOENT) { |
| 195 | dev_err(dev, "unable to request refclk (%d)\n", err); | 193 | dev_err(dev, "unable to request refclk (%ld)\n", |
| 194 | PTR_ERR(clk)); | ||
| 196 | return PTR_ERR(clk); | 195 | return PTR_ERR(clk); |
| 197 | } | 196 | } |
| 198 | 197 | ||
| @@ -346,6 +345,37 @@ static int usb3503_platform_probe(struct platform_device *pdev) | |||
| 346 | return usb3503_probe(hub); | 345 | return usb3503_probe(hub); |
| 347 | } | 346 | } |
| 348 | 347 | ||
| 348 | #ifdef CONFIG_PM_SLEEP | ||
| 349 | static int usb3503_i2c_suspend(struct device *dev) | ||
| 350 | { | ||
| 351 | struct i2c_client *client = to_i2c_client(dev); | ||
| 352 | struct usb3503 *hub = i2c_get_clientdata(client); | ||
| 353 | |||
| 354 | usb3503_switch_mode(hub, USB3503_MODE_STANDBY); | ||
| 355 | |||
| 356 | if (hub->clk) | ||
| 357 | clk_disable_unprepare(hub->clk); | ||
| 358 | |||
| 359 | return 0; | ||
| 360 | } | ||
| 361 | |||
| 362 | static int usb3503_i2c_resume(struct device *dev) | ||
| 363 | { | ||
| 364 | struct i2c_client *client = to_i2c_client(dev); | ||
| 365 | struct usb3503 *hub = i2c_get_clientdata(client); | ||
| 366 | |||
| 367 | if (hub->clk) | ||
| 368 | clk_prepare_enable(hub->clk); | ||
| 369 | |||
| 370 | usb3503_switch_mode(hub, hub->mode); | ||
| 371 | |||
| 372 | return 0; | ||
| 373 | } | ||
| 374 | #endif | ||
| 375 | |||
| 376 | static SIMPLE_DEV_PM_OPS(usb3503_i2c_pm_ops, usb3503_i2c_suspend, | ||
| 377 | usb3503_i2c_resume); | ||
| 378 | |||
| 349 | static const struct i2c_device_id usb3503_id[] = { | 379 | static const struct i2c_device_id usb3503_id[] = { |
| 350 | { USB3503_I2C_NAME, 0 }, | 380 | { USB3503_I2C_NAME, 0 }, |
| 351 | { } | 381 | { } |
| @@ -364,6 +394,7 @@ MODULE_DEVICE_TABLE(of, usb3503_of_match); | |||
| 364 | static struct i2c_driver usb3503_i2c_driver = { | 394 | static struct i2c_driver usb3503_i2c_driver = { |
| 365 | .driver = { | 395 | .driver = { |
| 366 | .name = USB3503_I2C_NAME, | 396 | .name = USB3503_I2C_NAME, |
| 397 | .pm = &usb3503_i2c_pm_ops, | ||
| 367 | .of_match_table = of_match_ptr(usb3503_of_match), | 398 | .of_match_table = of_match_ptr(usb3503_of_match), |
| 368 | }, | 399 | }, |
| 369 | .probe = usb3503_i2c_probe, | 400 | .probe = usb3503_i2c_probe, |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index d40d5f0b5528..ac4422b33dcd 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
| @@ -455,7 +455,7 @@ static int bfin_probe(struct platform_device *pdev) | |||
| 455 | 455 | ||
| 456 | int ret = -ENOMEM; | 456 | int ret = -ENOMEM; |
| 457 | 457 | ||
| 458 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 458 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
| 459 | if (!glue) { | 459 | if (!glue) { |
| 460 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 460 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 461 | goto err0; | 461 | goto err0; |
| @@ -464,7 +464,7 @@ static int bfin_probe(struct platform_device *pdev) | |||
| 464 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); | 464 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); |
| 465 | if (!musb) { | 465 | if (!musb) { |
| 466 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | 466 | dev_err(&pdev->dev, "failed to allocate musb device\n"); |
| 467 | goto err1; | 467 | goto err0; |
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | musb->dev.parent = &pdev->dev; | 470 | musb->dev.parent = &pdev->dev; |
| @@ -478,7 +478,7 @@ static int bfin_probe(struct platform_device *pdev) | |||
| 478 | 478 | ||
| 479 | glue->phy = usb_phy_generic_register(); | 479 | glue->phy = usb_phy_generic_register(); |
| 480 | if (IS_ERR(glue->phy)) | 480 | if (IS_ERR(glue->phy)) |
| 481 | goto err2; | 481 | goto err1; |
| 482 | platform_set_drvdata(pdev, glue); | 482 | platform_set_drvdata(pdev, glue); |
| 483 | 483 | ||
| 484 | memset(musb_resources, 0x00, sizeof(*musb_resources) * | 484 | memset(musb_resources, 0x00, sizeof(*musb_resources) * |
| @@ -498,31 +498,28 @@ static int bfin_probe(struct platform_device *pdev) | |||
| 498 | ARRAY_SIZE(musb_resources)); | 498 | ARRAY_SIZE(musb_resources)); |
| 499 | if (ret) { | 499 | if (ret) { |
| 500 | dev_err(&pdev->dev, "failed to add resources\n"); | 500 | dev_err(&pdev->dev, "failed to add resources\n"); |
| 501 | goto err3; | 501 | goto err2; |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | 504 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); |
| 505 | if (ret) { | 505 | if (ret) { |
| 506 | dev_err(&pdev->dev, "failed to add platform_data\n"); | 506 | dev_err(&pdev->dev, "failed to add platform_data\n"); |
| 507 | goto err3; | 507 | goto err2; |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | ret = platform_device_add(musb); | 510 | ret = platform_device_add(musb); |
| 511 | if (ret) { | 511 | if (ret) { |
| 512 | dev_err(&pdev->dev, "failed to register musb device\n"); | 512 | dev_err(&pdev->dev, "failed to register musb device\n"); |
| 513 | goto err3; | 513 | goto err2; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | return 0; | 516 | return 0; |
| 517 | 517 | ||
| 518 | err3: | ||
| 519 | usb_phy_generic_unregister(glue->phy); | ||
| 520 | |||
| 521 | err2: | 518 | err2: |
| 522 | platform_device_put(musb); | 519 | usb_phy_generic_unregister(glue->phy); |
| 523 | 520 | ||
| 524 | err1: | 521 | err1: |
| 525 | kfree(glue); | 522 | platform_device_put(musb); |
| 526 | 523 | ||
| 527 | err0: | 524 | err0: |
| 528 | return ret; | 525 | return ret; |
| @@ -534,7 +531,6 @@ static int bfin_remove(struct platform_device *pdev) | |||
| 534 | 531 | ||
| 535 | platform_device_unregister(glue->musb); | 532 | platform_device_unregister(glue->musb); |
| 536 | usb_phy_generic_unregister(glue->phy); | 533 | usb_phy_generic_unregister(glue->phy); |
| 537 | kfree(glue); | ||
| 538 | 534 | ||
| 539 | return 0; | 535 | return 0; |
| 540 | } | 536 | } |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index de8492b06e46..110b78415bf0 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
| @@ -519,23 +519,23 @@ static int davinci_probe(struct platform_device *pdev) | |||
| 519 | 519 | ||
| 520 | int ret = -ENOMEM; | 520 | int ret = -ENOMEM; |
| 521 | 521 | ||
| 522 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 522 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
| 523 | if (!glue) { | 523 | if (!glue) { |
| 524 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 524 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 525 | goto err0; | 525 | goto err0; |
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | clk = clk_get(&pdev->dev, "usb"); | 528 | clk = devm_clk_get(&pdev->dev, "usb"); |
| 529 | if (IS_ERR(clk)) { | 529 | if (IS_ERR(clk)) { |
| 530 | dev_err(&pdev->dev, "failed to get clock\n"); | 530 | dev_err(&pdev->dev, "failed to get clock\n"); |
| 531 | ret = PTR_ERR(clk); | 531 | ret = PTR_ERR(clk); |
| 532 | goto err3; | 532 | goto err0; |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | ret = clk_enable(clk); | 535 | ret = clk_enable(clk); |
| 536 | if (ret) { | 536 | if (ret) { |
| 537 | dev_err(&pdev->dev, "failed to enable clock\n"); | 537 | dev_err(&pdev->dev, "failed to enable clock\n"); |
| 538 | goto err4; | 538 | goto err0; |
| 539 | } | 539 | } |
| 540 | 540 | ||
| 541 | glue->dev = &pdev->dev; | 541 | glue->dev = &pdev->dev; |
| @@ -579,20 +579,14 @@ static int davinci_probe(struct platform_device *pdev) | |||
| 579 | if (IS_ERR(musb)) { | 579 | if (IS_ERR(musb)) { |
| 580 | ret = PTR_ERR(musb); | 580 | ret = PTR_ERR(musb); |
| 581 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); | 581 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); |
| 582 | goto err5; | 582 | goto err1; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | return 0; | 585 | return 0; |
| 586 | 586 | ||
| 587 | err5: | 587 | err1: |
| 588 | clk_disable(clk); | 588 | clk_disable(clk); |
| 589 | 589 | ||
| 590 | err4: | ||
| 591 | clk_put(clk); | ||
| 592 | |||
| 593 | err3: | ||
| 594 | kfree(glue); | ||
| 595 | |||
| 596 | err0: | 590 | err0: |
| 597 | return ret; | 591 | return ret; |
| 598 | } | 592 | } |
| @@ -604,8 +598,6 @@ static int davinci_remove(struct platform_device *pdev) | |||
| 604 | platform_device_unregister(glue->musb); | 598 | platform_device_unregister(glue->musb); |
| 605 | usb_phy_generic_unregister(); | 599 | usb_phy_generic_unregister(); |
| 606 | clk_disable(glue->clk); | 600 | clk_disable(glue->clk); |
| 607 | clk_put(glue->clk); | ||
| 608 | kfree(glue); | ||
| 609 | 601 | ||
| 610 | return 0; | 602 | return 0; |
| 611 | } | 603 | } |
diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index 5f30537f1927..d1187290d4e3 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/usb/usb_phy_generic.h> | ||
| 22 | 23 | ||
| 23 | #include "musb_core.h" | 24 | #include "musb_core.h" |
| 24 | 25 | ||
| @@ -80,6 +81,7 @@ static struct musb_hdrc_platform_data jz4740_musb_platform_data = { | |||
| 80 | 81 | ||
| 81 | static int jz4740_musb_init(struct musb *musb) | 82 | static int jz4740_musb_init(struct musb *musb) |
| 82 | { | 83 | { |
| 84 | usb_phy_generic_register(); | ||
| 83 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 85 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
| 84 | if (!musb->xceiv) { | 86 | if (!musb->xceiv) { |
| 85 | pr_err("HS UDC: no transceiver configured\n"); | 87 | pr_err("HS UDC: no transceiver configured\n"); |
| @@ -182,6 +184,7 @@ static int jz4740_remove(struct platform_device *pdev) | |||
| 182 | struct jz4740_glue *glue = platform_get_drvdata(pdev); | 184 | struct jz4740_glue *glue = platform_get_drvdata(pdev); |
| 183 | 185 | ||
| 184 | platform_device_unregister(glue->musb); | 186 | platform_device_unregister(glue->musb); |
| 187 | usb_phy_generic_unregister(pdev); | ||
| 185 | clk_disable_unprepare(glue->clk); | 188 | clk_disable_unprepare(glue->clk); |
| 186 | 189 | ||
| 187 | return 0; | 190 | return 0; |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index eff3c5cf84f4..b841ee0bff06 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -850,7 +850,8 @@ b_host: | |||
| 850 | 850 | ||
| 851 | /* handle babble condition */ | 851 | /* handle babble condition */ |
| 852 | if (int_usb & MUSB_INTR_BABBLE && is_host_active(musb)) | 852 | if (int_usb & MUSB_INTR_BABBLE && is_host_active(musb)) |
| 853 | schedule_work(&musb->recover_work); | 853 | schedule_delayed_work(&musb->recover_work, |
| 854 | msecs_to_jiffies(100)); | ||
| 854 | 855 | ||
| 855 | #if 0 | 856 | #if 0 |
| 856 | /* REVISIT ... this would be for multiplexing periodic endpoints, or | 857 | /* REVISIT ... this would be for multiplexing periodic endpoints, or |
| @@ -1517,7 +1518,7 @@ irqreturn_t musb_interrupt(struct musb *musb) | |||
| 1517 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 1518 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
| 1518 | 1519 | ||
| 1519 | dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", | 1520 | dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", |
| 1520 | (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", | 1521 | is_host_active(musb) ? "host" : "peripheral", |
| 1521 | musb->int_usb, musb->int_tx, musb->int_rx); | 1522 | musb->int_usb, musb->int_tx, musb->int_rx); |
| 1522 | 1523 | ||
| 1523 | /* the core can interrupt us for multiple reasons; docs have | 1524 | /* the core can interrupt us for multiple reasons; docs have |
| @@ -1531,7 +1532,7 @@ irqreturn_t musb_interrupt(struct musb *musb) | |||
| 1531 | 1532 | ||
| 1532 | /* handle endpoint 0 first */ | 1533 | /* handle endpoint 0 first */ |
| 1533 | if (musb->int_tx & 1) { | 1534 | if (musb->int_tx & 1) { |
| 1534 | if (devctl & MUSB_DEVCTL_HM) | 1535 | if (is_host_active(musb)) |
| 1535 | retval |= musb_h_ep0_irq(musb); | 1536 | retval |= musb_h_ep0_irq(musb); |
| 1536 | else | 1537 | else |
| 1537 | retval |= musb_g_ep0_irq(musb); | 1538 | retval |= musb_g_ep0_irq(musb); |
| @@ -1545,7 +1546,7 @@ irqreturn_t musb_interrupt(struct musb *musb) | |||
| 1545 | /* musb_ep_select(musb->mregs, ep_num); */ | 1546 | /* musb_ep_select(musb->mregs, ep_num); */ |
| 1546 | /* REVISIT just retval = ep->rx_irq(...) */ | 1547 | /* REVISIT just retval = ep->rx_irq(...) */ |
| 1547 | retval = IRQ_HANDLED; | 1548 | retval = IRQ_HANDLED; |
| 1548 | if (devctl & MUSB_DEVCTL_HM) | 1549 | if (is_host_active(musb)) |
| 1549 | musb_host_rx(musb, ep_num); | 1550 | musb_host_rx(musb, ep_num); |
| 1550 | else | 1551 | else |
| 1551 | musb_g_rx(musb, ep_num); | 1552 | musb_g_rx(musb, ep_num); |
| @@ -1563,7 +1564,7 @@ irqreturn_t musb_interrupt(struct musb *musb) | |||
| 1563 | /* musb_ep_select(musb->mregs, ep_num); */ | 1564 | /* musb_ep_select(musb->mregs, ep_num); */ |
| 1564 | /* REVISIT just retval |= ep->tx_irq(...) */ | 1565 | /* REVISIT just retval |= ep->tx_irq(...) */ |
| 1565 | retval = IRQ_HANDLED; | 1566 | retval = IRQ_HANDLED; |
| 1566 | if (devctl & MUSB_DEVCTL_HM) | 1567 | if (is_host_active(musb)) |
| 1567 | musb_host_tx(musb, ep_num); | 1568 | musb_host_tx(musb, ep_num); |
| 1568 | else | 1569 | else |
| 1569 | musb_g_tx(musb, ep_num); | 1570 | musb_g_tx(musb, ep_num); |
| @@ -1585,15 +1586,13 @@ MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); | |||
| 1585 | 1586 | ||
| 1586 | void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) | 1587 | void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) |
| 1587 | { | 1588 | { |
| 1588 | u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
| 1589 | |||
| 1590 | /* called with controller lock already held */ | 1589 | /* called with controller lock already held */ |
| 1591 | 1590 | ||
| 1592 | if (!epnum) { | 1591 | if (!epnum) { |
| 1593 | #ifndef CONFIG_USB_TUSB_OMAP_DMA | 1592 | #ifndef CONFIG_USB_TUSB_OMAP_DMA |
| 1594 | if (!is_cppi_enabled()) { | 1593 | if (!is_cppi_enabled()) { |
| 1595 | /* endpoint 0 */ | 1594 | /* endpoint 0 */ |
| 1596 | if (devctl & MUSB_DEVCTL_HM) | 1595 | if (is_host_active(musb)) |
| 1597 | musb_h_ep0_irq(musb); | 1596 | musb_h_ep0_irq(musb); |
| 1598 | else | 1597 | else |
| 1599 | musb_g_ep0_irq(musb); | 1598 | musb_g_ep0_irq(musb); |
| @@ -1602,13 +1601,13 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) | |||
| 1602 | } else { | 1601 | } else { |
| 1603 | /* endpoints 1..15 */ | 1602 | /* endpoints 1..15 */ |
| 1604 | if (transmit) { | 1603 | if (transmit) { |
| 1605 | if (devctl & MUSB_DEVCTL_HM) | 1604 | if (is_host_active(musb)) |
| 1606 | musb_host_tx(musb, epnum); | 1605 | musb_host_tx(musb, epnum); |
| 1607 | else | 1606 | else |
| 1608 | musb_g_tx(musb, epnum); | 1607 | musb_g_tx(musb, epnum); |
| 1609 | } else { | 1608 | } else { |
| 1610 | /* receive */ | 1609 | /* receive */ |
| 1611 | if (devctl & MUSB_DEVCTL_HM) | 1610 | if (is_host_active(musb)) |
| 1612 | musb_host_rx(musb, epnum); | 1611 | musb_host_rx(musb, epnum); |
| 1613 | else | 1612 | else |
| 1614 | musb_g_rx(musb, epnum); | 1613 | musb_g_rx(musb, epnum); |
| @@ -1753,20 +1752,22 @@ static void musb_irq_work(struct work_struct *data) | |||
| 1753 | /* Recover from babble interrupt conditions */ | 1752 | /* Recover from babble interrupt conditions */ |
| 1754 | static void musb_recover_work(struct work_struct *data) | 1753 | static void musb_recover_work(struct work_struct *data) |
| 1755 | { | 1754 | { |
| 1756 | struct musb *musb = container_of(data, struct musb, recover_work); | 1755 | struct musb *musb = container_of(data, struct musb, recover_work.work); |
| 1757 | int status; | 1756 | int status, ret; |
| 1758 | 1757 | ||
| 1759 | musb_platform_reset(musb); | 1758 | ret = musb_platform_reset(musb); |
| 1759 | if (ret) | ||
| 1760 | return; | ||
| 1760 | 1761 | ||
| 1761 | usb_phy_vbus_off(musb->xceiv); | 1762 | usb_phy_vbus_off(musb->xceiv); |
| 1762 | udelay(100); | 1763 | usleep_range(100, 200); |
| 1763 | 1764 | ||
| 1764 | usb_phy_vbus_on(musb->xceiv); | 1765 | usb_phy_vbus_on(musb->xceiv); |
| 1765 | udelay(100); | 1766 | usleep_range(100, 200); |
| 1766 | 1767 | ||
| 1767 | /* | 1768 | /* |
| 1768 | * When a babble condition occurs, the musb controller removes the | 1769 | * When a babble condition occurs, the musb controller |
| 1769 | * session bit and the endpoint config is lost. | 1770 | * removes the session bit and the endpoint config is lost. |
| 1770 | */ | 1771 | */ |
| 1771 | if (musb->dyn_fifo) | 1772 | if (musb->dyn_fifo) |
| 1772 | status = ep_config_from_table(musb); | 1773 | status = ep_config_from_table(musb); |
| @@ -1945,7 +1946,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
| 1945 | 1946 | ||
| 1946 | /* Init IRQ workqueue before request_irq */ | 1947 | /* Init IRQ workqueue before request_irq */ |
| 1947 | INIT_WORK(&musb->irq_work, musb_irq_work); | 1948 | INIT_WORK(&musb->irq_work, musb_irq_work); |
| 1948 | INIT_WORK(&musb->recover_work, musb_recover_work); | 1949 | INIT_DELAYED_WORK(&musb->recover_work, musb_recover_work); |
| 1949 | INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); | 1950 | INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); |
| 1950 | INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume); | 1951 | INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume); |
| 1951 | 1952 | ||
| @@ -2041,7 +2042,7 @@ fail4: | |||
| 2041 | 2042 | ||
| 2042 | fail3: | 2043 | fail3: |
| 2043 | cancel_work_sync(&musb->irq_work); | 2044 | cancel_work_sync(&musb->irq_work); |
| 2044 | cancel_work_sync(&musb->recover_work); | 2045 | cancel_delayed_work_sync(&musb->recover_work); |
| 2045 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2046 | cancel_delayed_work_sync(&musb->finish_resume_work); |
| 2046 | cancel_delayed_work_sync(&musb->deassert_reset_work); | 2047 | cancel_delayed_work_sync(&musb->deassert_reset_work); |
| 2047 | if (musb->dma_controller) | 2048 | if (musb->dma_controller) |
| @@ -2107,7 +2108,7 @@ static int musb_remove(struct platform_device *pdev) | |||
| 2107 | dma_controller_destroy(musb->dma_controller); | 2108 | dma_controller_destroy(musb->dma_controller); |
| 2108 | 2109 | ||
| 2109 | cancel_work_sync(&musb->irq_work); | 2110 | cancel_work_sync(&musb->irq_work); |
| 2110 | cancel_work_sync(&musb->recover_work); | 2111 | cancel_delayed_work_sync(&musb->recover_work); |
| 2111 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2112 | cancel_delayed_work_sync(&musb->finish_resume_work); |
| 2112 | cancel_delayed_work_sync(&musb->deassert_reset_work); | 2113 | cancel_delayed_work_sync(&musb->deassert_reset_work); |
| 2113 | musb_free(musb); | 2114 | musb_free(musb); |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d155a156f240..414e57a984bb 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
| @@ -192,7 +192,7 @@ struct musb_platform_ops { | |||
| 192 | 192 | ||
| 193 | int (*set_mode)(struct musb *musb, u8 mode); | 193 | int (*set_mode)(struct musb *musb, u8 mode); |
| 194 | void (*try_idle)(struct musb *musb, unsigned long timeout); | 194 | void (*try_idle)(struct musb *musb, unsigned long timeout); |
| 195 | void (*reset)(struct musb *musb); | 195 | int (*reset)(struct musb *musb); |
| 196 | 196 | ||
| 197 | int (*vbus_status)(struct musb *musb); | 197 | int (*vbus_status)(struct musb *musb); |
| 198 | void (*set_vbus)(struct musb *musb, int on); | 198 | void (*set_vbus)(struct musb *musb, int on); |
| @@ -297,7 +297,7 @@ struct musb { | |||
| 297 | 297 | ||
| 298 | irqreturn_t (*isr)(int, void *); | 298 | irqreturn_t (*isr)(int, void *); |
| 299 | struct work_struct irq_work; | 299 | struct work_struct irq_work; |
| 300 | struct work_struct recover_work; | 300 | struct delayed_work recover_work; |
| 301 | struct delayed_work deassert_reset_work; | 301 | struct delayed_work deassert_reset_work; |
| 302 | struct delayed_work finish_resume_work; | 302 | struct delayed_work finish_resume_work; |
| 303 | u16 hwvers; | 303 | u16 hwvers; |
| @@ -555,10 +555,12 @@ static inline void musb_platform_try_idle(struct musb *musb, | |||
| 555 | musb->ops->try_idle(musb, timeout); | 555 | musb->ops->try_idle(musb, timeout); |
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | static inline void musb_platform_reset(struct musb *musb) | 558 | static inline int musb_platform_reset(struct musb *musb) |
| 559 | { | 559 | { |
| 560 | if (musb->ops->reset) | 560 | if (!musb->ops->reset) |
| 561 | musb->ops->reset(musb); | 561 | return -EINVAL; |
| 562 | |||
| 563 | return musb->ops->reset(musb); | ||
| 562 | } | 564 | } |
| 563 | 565 | ||
| 564 | static inline int musb_platform_get_vbus_status(struct musb *musb) | 566 | static inline int musb_platform_get_vbus_status(struct musb *musb) |
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 5341bb223b7c..47ae6455d073 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
| @@ -39,7 +39,6 @@ struct cppi41_dma_channel { | |||
| 39 | u32 transferred; | 39 | u32 transferred; |
| 40 | u32 packet_sz; | 40 | u32 packet_sz; |
| 41 | struct list_head tx_check; | 41 | struct list_head tx_check; |
| 42 | struct work_struct dma_completion; | ||
| 43 | }; | 42 | }; |
| 44 | 43 | ||
| 45 | #define MUSB_DMA_NUM_CHANNELS 15 | 44 | #define MUSB_DMA_NUM_CHANNELS 15 |
| @@ -74,15 +73,18 @@ static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel) | |||
| 74 | 73 | ||
| 75 | static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel) | 74 | static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel) |
| 76 | { | 75 | { |
| 76 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | ||
| 77 | struct musb *musb = hw_ep->musb; | ||
| 77 | u16 csr; | 78 | u16 csr; |
| 78 | u8 toggle; | 79 | u8 toggle; |
| 79 | 80 | ||
| 80 | if (cppi41_channel->is_tx) | 81 | if (cppi41_channel->is_tx) |
| 81 | return; | 82 | return; |
| 82 | if (!is_host_active(cppi41_channel->controller->musb)) | 83 | if (!is_host_active(musb)) |
| 83 | return; | 84 | return; |
| 84 | 85 | ||
| 85 | csr = musb_readw(cppi41_channel->hw_ep->regs, MUSB_RXCSR); | 86 | musb_ep_select(musb->mregs, hw_ep->epnum); |
| 87 | csr = musb_readw(hw_ep->regs, MUSB_RXCSR); | ||
| 86 | toggle = csr & MUSB_RXCSR_H_DATATOGGLE ? 1 : 0; | 88 | toggle = csr & MUSB_RXCSR_H_DATATOGGLE ? 1 : 0; |
| 87 | 89 | ||
| 88 | /* | 90 | /* |
| @@ -107,24 +109,13 @@ static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep) | |||
| 107 | void __iomem *epio = musb->endpoints[epnum].regs; | 109 | void __iomem *epio = musb->endpoints[epnum].regs; |
| 108 | u16 csr; | 110 | u16 csr; |
| 109 | 111 | ||
| 112 | musb_ep_select(musb->mregs, hw_ep->epnum); | ||
| 110 | csr = musb_readw(epio, MUSB_TXCSR); | 113 | csr = musb_readw(epio, MUSB_TXCSR); |
| 111 | if (csr & MUSB_TXCSR_TXPKTRDY) | 114 | if (csr & MUSB_TXCSR_TXPKTRDY) |
| 112 | return false; | 115 | return false; |
| 113 | return true; | 116 | return true; |
| 114 | } | 117 | } |
| 115 | 118 | ||
| 116 | static bool is_isoc(struct musb_hw_ep *hw_ep, bool in) | ||
| 117 | { | ||
| 118 | if (in && hw_ep->in_qh) { | ||
| 119 | if (hw_ep->in_qh->type == USB_ENDPOINT_XFER_ISOC) | ||
| 120 | return true; | ||
| 121 | } else if (hw_ep->out_qh) { | ||
| 122 | if (hw_ep->out_qh->type == USB_ENDPOINT_XFER_ISOC) | ||
| 123 | return true; | ||
| 124 | } | ||
| 125 | return false; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void cppi41_dma_callback(void *private_data); | 119 | static void cppi41_dma_callback(void *private_data); |
| 129 | 120 | ||
| 130 | static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | 121 | static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) |
| @@ -139,6 +130,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
| 139 | cppi41_channel->channel.actual_len = | 130 | cppi41_channel->channel.actual_len = |
| 140 | cppi41_channel->transferred; | 131 | cppi41_channel->transferred; |
| 141 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; | 132 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; |
| 133 | cppi41_channel->channel.rx_packet_done = true; | ||
| 142 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); | 134 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); |
| 143 | } else { | 135 | } else { |
| 144 | /* next iteration, reload */ | 136 | /* next iteration, reload */ |
| @@ -172,6 +164,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
| 172 | dma_async_issue_pending(dc); | 164 | dma_async_issue_pending(dc); |
| 173 | 165 | ||
| 174 | if (!cppi41_channel->is_tx) { | 166 | if (!cppi41_channel->is_tx) { |
| 167 | musb_ep_select(musb->mregs, hw_ep->epnum); | ||
| 175 | csr = musb_readw(epio, MUSB_RXCSR); | 168 | csr = musb_readw(epio, MUSB_RXCSR); |
| 176 | csr |= MUSB_RXCSR_H_REQPKT; | 169 | csr |= MUSB_RXCSR_H_REQPKT; |
| 177 | musb_writew(epio, MUSB_RXCSR, csr); | 170 | musb_writew(epio, MUSB_RXCSR, csr); |
| @@ -179,32 +172,6 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
| 179 | } | 172 | } |
| 180 | } | 173 | } |
| 181 | 174 | ||
| 182 | static void cppi_trans_done_work(struct work_struct *work) | ||
| 183 | { | ||
| 184 | unsigned long flags; | ||
| 185 | struct cppi41_dma_channel *cppi41_channel = | ||
| 186 | container_of(work, struct cppi41_dma_channel, dma_completion); | ||
| 187 | struct cppi41_dma_controller *controller = cppi41_channel->controller; | ||
| 188 | struct musb *musb = controller->musb; | ||
| 189 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | ||
| 190 | bool empty; | ||
| 191 | |||
| 192 | if (!cppi41_channel->is_tx && is_isoc(hw_ep, 1)) { | ||
| 193 | spin_lock_irqsave(&musb->lock, flags); | ||
| 194 | cppi41_trans_done(cppi41_channel); | ||
| 195 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 196 | } else { | ||
| 197 | empty = musb_is_tx_fifo_empty(hw_ep); | ||
| 198 | if (empty) { | ||
| 199 | spin_lock_irqsave(&musb->lock, flags); | ||
| 200 | cppi41_trans_done(cppi41_channel); | ||
| 201 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 202 | } else { | ||
| 203 | schedule_work(&cppi41_channel->dma_completion); | ||
| 204 | } | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) | 175 | static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) |
| 209 | { | 176 | { |
| 210 | struct cppi41_dma_controller *controller; | 177 | struct cppi41_dma_controller *controller; |
| @@ -233,7 +200,7 @@ static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) | |||
| 233 | if (!list_empty(&controller->early_tx_list)) { | 200 | if (!list_empty(&controller->early_tx_list)) { |
| 234 | ret = HRTIMER_RESTART; | 201 | ret = HRTIMER_RESTART; |
| 235 | hrtimer_forward_now(&controller->early_tx, | 202 | hrtimer_forward_now(&controller->early_tx, |
| 236 | ktime_set(0, 150 * NSEC_PER_USEC)); | 203 | ktime_set(0, 50 * NSEC_PER_USEC)); |
| 237 | } | 204 | } |
| 238 | 205 | ||
| 239 | spin_unlock_irqrestore(&musb->lock, flags); | 206 | spin_unlock_irqrestore(&musb->lock, flags); |
| @@ -268,14 +235,6 @@ static void cppi41_dma_callback(void *private_data) | |||
| 268 | transferred < cppi41_channel->packet_sz) | 235 | transferred < cppi41_channel->packet_sz) |
| 269 | cppi41_channel->prog_len = 0; | 236 | cppi41_channel->prog_len = 0; |
| 270 | 237 | ||
| 271 | if (!cppi41_channel->is_tx) { | ||
| 272 | if (is_isoc(hw_ep, 1)) | ||
| 273 | schedule_work(&cppi41_channel->dma_completion); | ||
| 274 | else | ||
| 275 | cppi41_trans_done(cppi41_channel); | ||
| 276 | goto out; | ||
| 277 | } | ||
| 278 | |||
| 279 | empty = musb_is_tx_fifo_empty(hw_ep); | 238 | empty = musb_is_tx_fifo_empty(hw_ep); |
| 280 | if (empty) { | 239 | if (empty) { |
| 281 | cppi41_trans_done(cppi41_channel); | 240 | cppi41_trans_done(cppi41_channel); |
| @@ -312,15 +271,13 @@ static void cppi41_dma_callback(void *private_data) | |||
| 312 | goto out; | 271 | goto out; |
| 313 | } | 272 | } |
| 314 | } | 273 | } |
| 315 | if (is_isoc(hw_ep, 0)) { | ||
| 316 | schedule_work(&cppi41_channel->dma_completion); | ||
| 317 | goto out; | ||
| 318 | } | ||
| 319 | list_add_tail(&cppi41_channel->tx_check, | 274 | list_add_tail(&cppi41_channel->tx_check, |
| 320 | &controller->early_tx_list); | 275 | &controller->early_tx_list); |
| 321 | if (!hrtimer_is_queued(&controller->early_tx)) { | 276 | if (!hrtimer_is_queued(&controller->early_tx)) { |
| 277 | unsigned long usecs = cppi41_channel->total_len / 10; | ||
| 278 | |||
| 322 | hrtimer_start_range_ns(&controller->early_tx, | 279 | hrtimer_start_range_ns(&controller->early_tx, |
| 323 | ktime_set(0, 140 * NSEC_PER_USEC), | 280 | ktime_set(0, usecs * NSEC_PER_USEC), |
| 324 | 40 * NSEC_PER_USEC, | 281 | 40 * NSEC_PER_USEC, |
| 325 | HRTIMER_MODE_REL); | 282 | HRTIMER_MODE_REL); |
| 326 | } | 283 | } |
| @@ -450,6 +407,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, | |||
| 450 | dma_desc->callback = cppi41_dma_callback; | 407 | dma_desc->callback = cppi41_dma_callback; |
| 451 | dma_desc->callback_param = channel; | 408 | dma_desc->callback_param = channel; |
| 452 | cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); | 409 | cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); |
| 410 | cppi41_channel->channel.rx_packet_done = false; | ||
| 453 | 411 | ||
| 454 | save_rx_toggle(cppi41_channel); | 412 | save_rx_toggle(cppi41_channel); |
| 455 | dma_async_issue_pending(dc); | 413 | dma_async_issue_pending(dc); |
| @@ -672,8 +630,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) | |||
| 672 | cppi41_channel->port_num = port; | 630 | cppi41_channel->port_num = port; |
| 673 | cppi41_channel->is_tx = is_tx; | 631 | cppi41_channel->is_tx = is_tx; |
| 674 | INIT_LIST_HEAD(&cppi41_channel->tx_check); | 632 | INIT_LIST_HEAD(&cppi41_channel->tx_check); |
| 675 | INIT_WORK(&cppi41_channel->dma_completion, | ||
| 676 | cppi_trans_done_work); | ||
| 677 | 633 | ||
| 678 | musb_dma = &cppi41_channel->channel; | 634 | musb_dma = &cppi41_channel->channel; |
| 679 | musb_dma->private_data = cppi41_channel; | 635 | musb_dma->private_data = cppi41_channel; |
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h index 1345a4ff041a..1d44faa86252 100644 --- a/drivers/usb/musb/musb_dma.h +++ b/drivers/usb/musb/musb_dma.h | |||
| @@ -129,6 +129,7 @@ struct dma_channel { | |||
| 129 | size_t actual_len; | 129 | size_t actual_len; |
| 130 | enum dma_channel_status status; | 130 | enum dma_channel_status status; |
| 131 | bool desired_mode; | 131 | bool desired_mode; |
| 132 | bool rx_packet_done; | ||
| 132 | }; | 133 | }; |
| 133 | 134 | ||
| 134 | /* | 135 | /* |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 09529f94e72d..c791ba5da91a 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
| @@ -56,16 +56,24 @@ static const struct of_device_id musb_dsps_of_match[]; | |||
| 56 | * dependent on musb core layer symbols. | 56 | * dependent on musb core layer symbols. |
| 57 | */ | 57 | */ |
| 58 | static inline u8 dsps_readb(const void __iomem *addr, unsigned offset) | 58 | static inline u8 dsps_readb(const void __iomem *addr, unsigned offset) |
| 59 | { return __raw_readb(addr + offset); } | 59 | { |
| 60 | return __raw_readb(addr + offset); | ||
| 61 | } | ||
| 60 | 62 | ||
| 61 | static inline u32 dsps_readl(const void __iomem *addr, unsigned offset) | 63 | static inline u32 dsps_readl(const void __iomem *addr, unsigned offset) |
| 62 | { return __raw_readl(addr + offset); } | 64 | { |
| 65 | return __raw_readl(addr + offset); | ||
| 66 | } | ||
| 63 | 67 | ||
| 64 | static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data) | 68 | static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data) |
| 65 | { __raw_writeb(data, addr + offset); } | 69 | { |
| 70 | __raw_writeb(data, addr + offset); | ||
| 71 | } | ||
| 66 | 72 | ||
| 67 | static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data) | 73 | static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data) |
| 68 | { __raw_writel(data, addr + offset); } | 74 | { |
| 75 | __raw_writel(data, addr + offset); | ||
| 76 | } | ||
| 69 | 77 | ||
| 70 | /** | 78 | /** |
| 71 | * DSPS musb wrapper register offset. | 79 | * DSPS musb wrapper register offset. |
| @@ -136,6 +144,7 @@ struct dsps_glue { | |||
| 136 | const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ | 144 | const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ |
| 137 | struct timer_list timer; /* otg_workaround timer */ | 145 | struct timer_list timer; /* otg_workaround timer */ |
| 138 | unsigned long last_timer; /* last timer data for each instance */ | 146 | unsigned long last_timer; /* last timer data for each instance */ |
| 147 | bool sw_babble_enabled; | ||
| 139 | 148 | ||
| 140 | struct dsps_context context; | 149 | struct dsps_context context; |
| 141 | struct debugfs_regset32 regset; | 150 | struct debugfs_regset32 regset; |
| @@ -469,6 +478,19 @@ static int dsps_musb_init(struct musb *musb) | |||
| 469 | val &= ~(1 << wrp->otg_disable); | 478 | val &= ~(1 << wrp->otg_disable); |
| 470 | dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); | 479 | dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); |
| 471 | 480 | ||
| 481 | /* | ||
| 482 | * Check whether the dsps version has babble control enabled. | ||
| 483 | * In latest silicon revision the babble control logic is enabled. | ||
| 484 | * If MUSB_BABBLE_CTL returns 0x4 then we have the babble control | ||
| 485 | * logic enabled. | ||
| 486 | */ | ||
| 487 | val = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | ||
| 488 | if (val == MUSB_BABBLE_RCV_DISABLE) { | ||
| 489 | glue->sw_babble_enabled = true; | ||
| 490 | val |= MUSB_BABBLE_SW_SESSION_CTRL; | ||
| 491 | dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val); | ||
| 492 | } | ||
| 493 | |||
| 472 | ret = dsps_musb_dbg_init(musb, glue); | 494 | ret = dsps_musb_dbg_init(musb, glue); |
| 473 | if (ret) | 495 | if (ret) |
| 474 | return ret; | 496 | return ret; |
| @@ -535,14 +557,82 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) | |||
| 535 | return 0; | 557 | return 0; |
| 536 | } | 558 | } |
| 537 | 559 | ||
| 538 | static void dsps_musb_reset(struct musb *musb) | 560 | static bool sw_babble_control(struct musb *musb) |
| 561 | { | ||
| 562 | u8 babble_ctl; | ||
| 563 | bool session_restart = false; | ||
| 564 | |||
| 565 | babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | ||
| 566 | dev_dbg(musb->controller, "babble: MUSB_BABBLE_CTL value %x\n", | ||
| 567 | babble_ctl); | ||
| 568 | /* | ||
| 569 | * check line monitor flag to check whether babble is | ||
| 570 | * due to noise | ||
| 571 | */ | ||
| 572 | dev_dbg(musb->controller, "STUCK_J is %s\n", | ||
| 573 | babble_ctl & MUSB_BABBLE_STUCK_J ? "set" : "reset"); | ||
| 574 | |||
| 575 | if (babble_ctl & MUSB_BABBLE_STUCK_J) { | ||
| 576 | int timeout = 10; | ||
| 577 | |||
| 578 | /* | ||
| 579 | * babble is due to noise, then set transmit idle (d7 bit) | ||
| 580 | * to resume normal operation | ||
| 581 | */ | ||
| 582 | babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | ||
| 583 | babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE; | ||
| 584 | dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, babble_ctl); | ||
| 585 | |||
| 586 | /* wait till line monitor flag cleared */ | ||
| 587 | dev_dbg(musb->controller, "Set TXIDLE, wait J to clear\n"); | ||
| 588 | do { | ||
| 589 | babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | ||
| 590 | udelay(1); | ||
| 591 | } while ((babble_ctl & MUSB_BABBLE_STUCK_J) && timeout--); | ||
| 592 | |||
| 593 | /* check whether stuck_at_j bit cleared */ | ||
| 594 | if (babble_ctl & MUSB_BABBLE_STUCK_J) { | ||
| 595 | /* | ||
| 596 | * real babble condition has occurred | ||
| 597 | * restart the controller to start the | ||
| 598 | * session again | ||
| 599 | */ | ||
| 600 | dev_dbg(musb->controller, "J not cleared, misc (%x)\n", | ||
| 601 | babble_ctl); | ||
| 602 | session_restart = true; | ||
| 603 | } | ||
| 604 | } else { | ||
| 605 | session_restart = true; | ||
| 606 | } | ||
| 607 | |||
| 608 | return session_restart; | ||
| 609 | } | ||
| 610 | |||
| 611 | static int dsps_musb_reset(struct musb *musb) | ||
| 539 | { | 612 | { |
| 540 | struct device *dev = musb->controller; | 613 | struct device *dev = musb->controller; |
| 541 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); | 614 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); |
| 542 | const struct dsps_musb_wrapper *wrp = glue->wrp; | 615 | const struct dsps_musb_wrapper *wrp = glue->wrp; |
| 616 | int session_restart = 0; | ||
| 617 | |||
| 618 | if (glue->sw_babble_enabled) | ||
| 619 | session_restart = sw_babble_control(musb); | ||
| 620 | /* | ||
| 621 | * In case of new silicon version babble condition can be recovered | ||
| 622 | * without resetting the MUSB. But for older silicon versions, MUSB | ||
| 623 | * reset is needed | ||
| 624 | */ | ||
| 625 | if (session_restart || !glue->sw_babble_enabled) { | ||
| 626 | dev_info(musb->controller, "Restarting MUSB to recover from Babble\n"); | ||
| 627 | dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); | ||
| 628 | usleep_range(100, 200); | ||
| 629 | usb_phy_shutdown(musb->xceiv); | ||
| 630 | usleep_range(100, 200); | ||
| 631 | usb_phy_init(musb->xceiv); | ||
| 632 | session_restart = 1; | ||
| 633 | } | ||
| 543 | 634 | ||
| 544 | dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); | 635 | return !session_restart; |
| 545 | udelay(100); | ||
| 546 | } | 636 | } |
| 547 | 637 | ||
| 548 | static struct musb_platform_ops dsps_ops = { | 638 | static struct musb_platform_ops dsps_ops = { |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index eb06291a40c8..855793d701bb 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -120,7 +120,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) | |||
| 120 | if (csr != lastcsr) | 120 | if (csr != lastcsr) |
| 121 | dev_dbg(musb->controller, "Host TX FIFONOTEMPTY csr: %02x\n", csr); | 121 | dev_dbg(musb->controller, "Host TX FIFONOTEMPTY csr: %02x\n", csr); |
| 122 | lastcsr = csr; | 122 | lastcsr = csr; |
| 123 | csr |= MUSB_TXCSR_FLUSHFIFO; | 123 | csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_TXPKTRDY; |
| 124 | musb_writew(epio, MUSB_TXCSR, csr); | 124 | musb_writew(epio, MUSB_TXCSR, csr); |
| 125 | csr = musb_readw(epio, MUSB_TXCSR); | 125 | csr = musb_readw(epio, MUSB_TXCSR); |
| 126 | if (WARN(retries-- < 1, | 126 | if (WARN(retries-- < 1, |
| @@ -1295,7 +1295,7 @@ done: | |||
| 1295 | if (status) { | 1295 | if (status) { |
| 1296 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 1296 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { |
| 1297 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; | 1297 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; |
| 1298 | (void) musb->dma_controller->channel_abort(dma); | 1298 | musb->dma_controller->channel_abort(dma); |
| 1299 | } | 1299 | } |
| 1300 | 1300 | ||
| 1301 | /* do the proper sequence to abort the transfer in the | 1301 | /* do the proper sequence to abort the transfer in the |
| @@ -1640,7 +1640,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1640 | /* clean up dma and collect transfer count */ | 1640 | /* clean up dma and collect transfer count */ |
| 1641 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 1641 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { |
| 1642 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; | 1642 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; |
| 1643 | (void) musb->dma_controller->channel_abort(dma); | 1643 | musb->dma_controller->channel_abort(dma); |
| 1644 | xfer_len = dma->actual_len; | 1644 | xfer_len = dma->actual_len; |
| 1645 | } | 1645 | } |
| 1646 | musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG); | 1646 | musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG); |
| @@ -1671,7 +1671,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1671 | */ | 1671 | */ |
| 1672 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 1672 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { |
| 1673 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; | 1673 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; |
| 1674 | (void) musb->dma_controller->channel_abort(dma); | 1674 | musb->dma_controller->channel_abort(dma); |
| 1675 | xfer_len = dma->actual_len; | 1675 | xfer_len = dma->actual_len; |
| 1676 | done = true; | 1676 | done = true; |
| 1677 | } | 1677 | } |
| @@ -1734,10 +1734,11 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1734 | } | 1734 | } |
| 1735 | 1735 | ||
| 1736 | } else { | 1736 | } else { |
| 1737 | /* done if urb buffer is full or short packet is recd */ | 1737 | /* done if urb buffer is full or short packet is recd */ |
| 1738 | done = (urb->actual_length + xfer_len >= | 1738 | done = (urb->actual_length + xfer_len >= |
| 1739 | urb->transfer_buffer_length | 1739 | urb->transfer_buffer_length |
| 1740 | || dma->actual_len < qh->maxpacket); | 1740 | || dma->actual_len < qh->maxpacket |
| 1741 | || dma->rx_packet_done); | ||
| 1741 | } | 1742 | } |
| 1742 | 1743 | ||
| 1743 | /* send IN token for next packet, without AUTOREQ */ | 1744 | /* send IN token for next packet, without AUTOREQ */ |
| @@ -1957,7 +1958,7 @@ static int musb_schedule( | |||
| 1957 | struct musb_qh *qh, | 1958 | struct musb_qh *qh, |
| 1958 | int is_in) | 1959 | int is_in) |
| 1959 | { | 1960 | { |
| 1960 | int idle; | 1961 | int idle = 0; |
| 1961 | int best_diff; | 1962 | int best_diff; |
| 1962 | int best_end, epnum; | 1963 | int best_end, epnum; |
| 1963 | struct musb_hw_ep *hw_ep = NULL; | 1964 | struct musb_hw_ep *hw_ep = NULL; |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 03f2655af290..b9bcda5e3945 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
| @@ -72,6 +72,12 @@ | |||
| 72 | #define MUSB_DEVCTL_HR 0x02 | 72 | #define MUSB_DEVCTL_HR 0x02 |
| 73 | #define MUSB_DEVCTL_SESSION 0x01 | 73 | #define MUSB_DEVCTL_SESSION 0x01 |
| 74 | 74 | ||
| 75 | /* BABBLE_CTL */ | ||
| 76 | #define MUSB_BABBLE_FORCE_TXIDLE 0x80 | ||
| 77 | #define MUSB_BABBLE_SW_SESSION_CTRL 0x40 | ||
| 78 | #define MUSB_BABBLE_STUCK_J 0x20 | ||
| 79 | #define MUSB_BABBLE_RCV_DISABLE 0x04 | ||
| 80 | |||
| 75 | /* MUSB ULPI VBUSCONTROL */ | 81 | /* MUSB ULPI VBUSCONTROL */ |
| 76 | #define MUSB_ULPI_USE_EXTVBUS 0x01 | 82 | #define MUSB_ULPI_USE_EXTVBUS 0x01 |
| 77 | #define MUSB_ULPI_USE_EXTVBUSIND 0x02 | 83 | #define MUSB_ULPI_USE_EXTVBUSIND 0x02 |
| @@ -246,6 +252,7 @@ | |||
| 246 | */ | 252 | */ |
| 247 | 253 | ||
| 248 | #define MUSB_DEVCTL 0x60 /* 8 bit */ | 254 | #define MUSB_DEVCTL 0x60 /* 8 bit */ |
| 255 | #define MUSB_BABBLE_CTL 0x61 /* 8 bit */ | ||
| 249 | 256 | ||
| 250 | /* These are always controlled through the INDEX register */ | 257 | /* These are always controlled through the INDEX register */ |
| 251 | #define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ | 258 | #define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 159ef4be1ef2..7dfc6cb732c9 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
| 23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
| 24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
| 25 | #include <linux/device.h> | ||
| 25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 26 | #include <linux/dma-mapping.h> | 27 | #include <linux/dma-mapping.h> |
| 27 | #include <linux/usb/usb_phy_generic.h> | 28 | #include <linux/usb/usb_phy_generic.h> |
| @@ -1160,12 +1161,12 @@ static int tusb_probe(struct platform_device *pdev) | |||
| 1160 | struct platform_device *musb; | 1161 | struct platform_device *musb; |
| 1161 | struct tusb6010_glue *glue; | 1162 | struct tusb6010_glue *glue; |
| 1162 | struct platform_device_info pinfo; | 1163 | struct platform_device_info pinfo; |
| 1163 | int ret = -ENOMEM; | 1164 | int ret; |
| 1164 | 1165 | ||
| 1165 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 1166 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
| 1166 | if (!glue) { | 1167 | if (!glue) { |
| 1167 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 1168 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 1168 | goto err0; | 1169 | return -ENOMEM; |
| 1169 | } | 1170 | } |
| 1170 | 1171 | ||
| 1171 | glue->dev = &pdev->dev; | 1172 | glue->dev = &pdev->dev; |
| @@ -1204,16 +1205,10 @@ static int tusb_probe(struct platform_device *pdev) | |||
| 1204 | if (IS_ERR(musb)) { | 1205 | if (IS_ERR(musb)) { |
| 1205 | ret = PTR_ERR(musb); | 1206 | ret = PTR_ERR(musb); |
| 1206 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); | 1207 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); |
| 1207 | goto err3; | 1208 | return ret; |
| 1208 | } | 1209 | } |
| 1209 | 1210 | ||
| 1210 | return 0; | 1211 | return 0; |
| 1211 | |||
| 1212 | err3: | ||
| 1213 | kfree(glue); | ||
| 1214 | |||
| 1215 | err0: | ||
| 1216 | return ret; | ||
| 1217 | } | 1212 | } |
| 1218 | 1213 | ||
| 1219 | static int tusb_remove(struct platform_device *pdev) | 1214 | static int tusb_remove(struct platform_device *pdev) |
| @@ -1222,7 +1217,6 @@ static int tusb_remove(struct platform_device *pdev) | |||
| 1222 | 1217 | ||
| 1223 | platform_device_unregister(glue->musb); | 1218 | platform_device_unregister(glue->musb); |
| 1224 | usb_phy_generic_unregister(glue->phy); | 1219 | usb_phy_generic_unregister(glue->phy); |
| 1225 | kfree(glue); | ||
| 1226 | 1220 | ||
| 1227 | return 0; | 1221 | return 0; |
| 1228 | } | 1222 | } |
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index f202e5088461..dc666e96f45f 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
| @@ -246,7 +246,7 @@ static int ux500_probe(struct platform_device *pdev) | |||
| 246 | } | 246 | } |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 249 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
| 250 | if (!glue) { | 250 | if (!glue) { |
| 251 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 251 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 252 | goto err0; | 252 | goto err0; |
| @@ -255,20 +255,20 @@ static int ux500_probe(struct platform_device *pdev) | |||
| 255 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); | 255 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); |
| 256 | if (!musb) { | 256 | if (!musb) { |
| 257 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | 257 | dev_err(&pdev->dev, "failed to allocate musb device\n"); |
| 258 | goto err1; | 258 | goto err0; |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | clk = clk_get(&pdev->dev, NULL); | 261 | clk = devm_clk_get(&pdev->dev, NULL); |
| 262 | if (IS_ERR(clk)) { | 262 | if (IS_ERR(clk)) { |
| 263 | dev_err(&pdev->dev, "failed to get clock\n"); | 263 | dev_err(&pdev->dev, "failed to get clock\n"); |
| 264 | ret = PTR_ERR(clk); | 264 | ret = PTR_ERR(clk); |
| 265 | goto err3; | 265 | goto err1; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | ret = clk_prepare_enable(clk); | 268 | ret = clk_prepare_enable(clk); |
| 269 | if (ret) { | 269 | if (ret) { |
| 270 | dev_err(&pdev->dev, "failed to enable clock\n"); | 270 | dev_err(&pdev->dev, "failed to enable clock\n"); |
| 271 | goto err4; | 271 | goto err1; |
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | musb->dev.parent = &pdev->dev; | 274 | musb->dev.parent = &pdev->dev; |
| @@ -301,34 +301,28 @@ static int ux500_probe(struct platform_device *pdev) | |||
| 301 | ARRAY_SIZE(musb_resources)); | 301 | ARRAY_SIZE(musb_resources)); |
| 302 | if (ret) { | 302 | if (ret) { |
| 303 | dev_err(&pdev->dev, "failed to add resources\n"); | 303 | dev_err(&pdev->dev, "failed to add resources\n"); |
| 304 | goto err5; | 304 | goto err2; |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | 307 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); |
| 308 | if (ret) { | 308 | if (ret) { |
| 309 | dev_err(&pdev->dev, "failed to add platform_data\n"); | 309 | dev_err(&pdev->dev, "failed to add platform_data\n"); |
| 310 | goto err5; | 310 | goto err2; |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | ret = platform_device_add(musb); | 313 | ret = platform_device_add(musb); |
| 314 | if (ret) { | 314 | if (ret) { |
| 315 | dev_err(&pdev->dev, "failed to register musb device\n"); | 315 | dev_err(&pdev->dev, "failed to register musb device\n"); |
| 316 | goto err5; | 316 | goto err2; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | return 0; | 319 | return 0; |
| 320 | 320 | ||
| 321 | err5: | 321 | err2: |
| 322 | clk_disable_unprepare(clk); | 322 | clk_disable_unprepare(clk); |
| 323 | 323 | ||
| 324 | err4: | ||
| 325 | clk_put(clk); | ||
| 326 | |||
| 327 | err3: | ||
| 328 | platform_device_put(musb); | ||
| 329 | |||
| 330 | err1: | 324 | err1: |
| 331 | kfree(glue); | 325 | platform_device_put(musb); |
| 332 | 326 | ||
| 333 | err0: | 327 | err0: |
| 334 | return ret; | 328 | return ret; |
| @@ -340,8 +334,6 @@ static int ux500_remove(struct platform_device *pdev) | |||
| 340 | 334 | ||
| 341 | platform_device_unregister(glue->musb); | 335 | platform_device_unregister(glue->musb); |
| 342 | clk_disable_unprepare(glue->clk); | 336 | clk_disable_unprepare(glue->clk); |
| 343 | clk_put(glue->clk); | ||
| 344 | kfree(glue); | ||
| 345 | 337 | ||
| 346 | return 0; | 338 | return 0; |
| 347 | } | 339 | } |
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-am335x.c b/drivers/usb/phy/phy-am335x.c index 585e50cb1980..b70e05537180 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c | |||
| @@ -122,16 +122,10 @@ static int am335x_phy_resume(struct device *dev) | |||
| 122 | 122 | ||
| 123 | return 0; | 123 | return 0; |
| 124 | } | 124 | } |
| 125 | |||
| 126 | static const struct dev_pm_ops am335x_pm_ops = { | ||
| 127 | SET_SYSTEM_SLEEP_PM_OPS(am335x_phy_suspend, am335x_phy_resume) | ||
| 128 | }; | ||
| 129 | |||
| 130 | #define DEV_PM_OPS (&am335x_pm_ops) | ||
| 131 | #else | ||
| 132 | #define DEV_PM_OPS NULL | ||
| 133 | #endif | 125 | #endif |
| 134 | 126 | ||
| 127 | static SIMPLE_DEV_PM_OPS(am335x_pm_ops, am335x_phy_suspend, am335x_phy_resume); | ||
| 128 | |||
| 135 | static const struct of_device_id am335x_phy_ids[] = { | 129 | static const struct of_device_id am335x_phy_ids[] = { |
| 136 | { .compatible = "ti,am335x-usb-phy" }, | 130 | { .compatible = "ti,am335x-usb-phy" }, |
| 137 | { } | 131 | { } |
| @@ -144,7 +138,7 @@ static struct platform_driver am335x_phy_driver = { | |||
| 144 | .driver = { | 138 | .driver = { |
| 145 | .name = "am335x-phy-driver", | 139 | .name = "am335x-phy-driver", |
| 146 | .owner = THIS_MODULE, | 140 | .owner = THIS_MODULE, |
| 147 | .pm = DEV_PM_OPS, | 141 | .pm = &am335x_pm_ops, |
| 148 | .of_match_table = am335x_phy_ids, | 142 | .of_match_table = am335x_phy_ids, |
| 149 | }, | 143 | }, |
| 150 | }; | 144 | }; |
diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index 69462e09d014..f4b14bd97e14 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c | |||
| @@ -253,15 +253,15 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
| 253 | return -EINVAL; | 253 | return -EINVAL; |
| 254 | gpio = pdata->gpio_vbus; | 254 | gpio = pdata->gpio_vbus; |
| 255 | 255 | ||
| 256 | gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL); | 256 | gpio_vbus = devm_kzalloc(&pdev->dev, sizeof(struct gpio_vbus_data), |
| 257 | GFP_KERNEL); | ||
| 257 | if (!gpio_vbus) | 258 | if (!gpio_vbus) |
| 258 | return -ENOMEM; | 259 | return -ENOMEM; |
| 259 | 260 | ||
| 260 | gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); | 261 | gpio_vbus->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), |
| 261 | if (!gpio_vbus->phy.otg) { | 262 | GFP_KERNEL); |
| 262 | kfree(gpio_vbus); | 263 | if (!gpio_vbus->phy.otg) |
| 263 | return -ENOMEM; | 264 | return -ENOMEM; |
| 264 | } | ||
| 265 | 265 | ||
| 266 | platform_set_drvdata(pdev, gpio_vbus); | 266 | platform_set_drvdata(pdev, gpio_vbus); |
| 267 | gpio_vbus->dev = &pdev->dev; | 267 | gpio_vbus->dev = &pdev->dev; |
| @@ -274,11 +274,11 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
| 274 | gpio_vbus->phy.otg->phy = &gpio_vbus->phy; | 274 | gpio_vbus->phy.otg->phy = &gpio_vbus->phy; |
| 275 | gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; | 275 | gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; |
| 276 | 276 | ||
| 277 | err = gpio_request(gpio, "vbus_detect"); | 277 | err = devm_gpio_request(&pdev->dev, gpio, "vbus_detect"); |
| 278 | if (err) { | 278 | if (err) { |
| 279 | dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", | 279 | dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", |
| 280 | gpio, err); | 280 | gpio, err); |
| 281 | goto err_gpio; | 281 | return err; |
| 282 | } | 282 | } |
| 283 | gpio_direction_input(gpio); | 283 | gpio_direction_input(gpio); |
| 284 | 284 | ||
| @@ -296,27 +296,27 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
| 296 | /* if data line pullup is in use, initialize it to "not pulling up" */ | 296 | /* if data line pullup is in use, initialize it to "not pulling up" */ |
| 297 | gpio = pdata->gpio_pullup; | 297 | gpio = pdata->gpio_pullup; |
| 298 | if (gpio_is_valid(gpio)) { | 298 | if (gpio_is_valid(gpio)) { |
| 299 | err = gpio_request(gpio, "udc_pullup"); | 299 | err = devm_gpio_request(&pdev->dev, gpio, "udc_pullup"); |
| 300 | if (err) { | 300 | if (err) { |
| 301 | dev_err(&pdev->dev, | 301 | dev_err(&pdev->dev, |
| 302 | "can't request pullup gpio %d, err: %d\n", | 302 | "can't request pullup gpio %d, err: %d\n", |
| 303 | gpio, err); | 303 | gpio, err); |
| 304 | gpio_free(pdata->gpio_vbus); | 304 | return err; |
| 305 | goto err_gpio; | ||
| 306 | } | 305 | } |
| 307 | gpio_direction_output(gpio, pdata->gpio_pullup_inverted); | 306 | gpio_direction_output(gpio, pdata->gpio_pullup_inverted); |
| 308 | } | 307 | } |
| 309 | 308 | ||
| 310 | err = request_irq(irq, gpio_vbus_irq, irqflags, "vbus_detect", pdev); | 309 | err = devm_request_irq(&pdev->dev, irq, gpio_vbus_irq, irqflags, |
| 310 | "vbus_detect", pdev); | ||
| 311 | if (err) { | 311 | if (err) { |
| 312 | dev_err(&pdev->dev, "can't request irq %i, err: %d\n", | 312 | dev_err(&pdev->dev, "can't request irq %i, err: %d\n", |
| 313 | irq, err); | 313 | irq, err); |
| 314 | goto err_irq; | 314 | return err; |
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); | 317 | INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); |
| 318 | 318 | ||
| 319 | gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); | 319 | gpio_vbus->vbus_draw = devm_regulator_get(&pdev->dev, "vbus_draw"); |
| 320 | if (IS_ERR(gpio_vbus->vbus_draw)) { | 320 | if (IS_ERR(gpio_vbus->vbus_draw)) { |
| 321 | dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", | 321 | dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", |
| 322 | PTR_ERR(gpio_vbus->vbus_draw)); | 322 | PTR_ERR(gpio_vbus->vbus_draw)); |
| @@ -328,44 +328,23 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
| 328 | if (err) { | 328 | if (err) { |
| 329 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", | 329 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", |
| 330 | err); | 330 | err); |
| 331 | goto err_otg; | 331 | return err; |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 334 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
| 335 | 335 | ||
| 336 | return 0; | 336 | return 0; |
| 337 | err_otg: | ||
| 338 | regulator_put(gpio_vbus->vbus_draw); | ||
| 339 | free_irq(irq, pdev); | ||
| 340 | err_irq: | ||
| 341 | if (gpio_is_valid(pdata->gpio_pullup)) | ||
| 342 | gpio_free(pdata->gpio_pullup); | ||
| 343 | gpio_free(pdata->gpio_vbus); | ||
| 344 | err_gpio: | ||
| 345 | kfree(gpio_vbus->phy.otg); | ||
| 346 | kfree(gpio_vbus); | ||
| 347 | return err; | ||
| 348 | } | 337 | } |
| 349 | 338 | ||
| 350 | static int gpio_vbus_remove(struct platform_device *pdev) | 339 | static int gpio_vbus_remove(struct platform_device *pdev) |
| 351 | { | 340 | { |
| 352 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | 341 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); |
| 353 | struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev); | ||
| 354 | int gpio = pdata->gpio_vbus; | ||
| 355 | 342 | ||
| 356 | device_init_wakeup(&pdev->dev, 0); | 343 | device_init_wakeup(&pdev->dev, 0); |
| 357 | cancel_delayed_work_sync(&gpio_vbus->work); | 344 | cancel_delayed_work_sync(&gpio_vbus->work); |
| 358 | regulator_put(gpio_vbus->vbus_draw); | ||
| 359 | 345 | ||
| 360 | usb_remove_phy(&gpio_vbus->phy); | 346 | usb_remove_phy(&gpio_vbus->phy); |
| 361 | 347 | ||
| 362 | free_irq(gpio_vbus->irq, pdev); | ||
| 363 | if (gpio_is_valid(pdata->gpio_pullup)) | ||
| 364 | gpio_free(pdata->gpio_pullup); | ||
| 365 | gpio_free(gpio); | ||
| 366 | kfree(gpio_vbus->phy.otg); | ||
| 367 | kfree(gpio_vbus); | ||
| 368 | |||
| 369 | return 0; | 348 | return 0; |
| 370 | } | 349 | } |
| 371 | 350 | ||
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index c929370cdaa6..afc09087ec36 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
| @@ -279,11 +279,11 @@ static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) | |||
| 279 | 279 | ||
| 280 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) | 280 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) |
| 281 | { | 281 | { |
| 282 | int ret; | 282 | int ret = 0; |
| 283 | 283 | ||
| 284 | if (motg->pdata->phy_clk_reset) | 284 | if (motg->pdata->phy_clk_reset && motg->phy_reset_clk) |
| 285 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); | 285 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); |
| 286 | else | 286 | else if (motg->phy_rst) |
| 287 | ret = reset_control_reset(motg->phy_rst); | 287 | ret = reset_control_reset(motg->phy_rst); |
| 288 | 288 | ||
| 289 | if (ret) | 289 | if (ret) |
| @@ -1429,7 +1429,7 @@ static void msm_otg_debugfs_cleanup(void) | |||
| 1429 | debugfs_remove(msm_otg_dbg_root); | 1429 | debugfs_remove(msm_otg_dbg_root); |
| 1430 | } | 1430 | } |
| 1431 | 1431 | ||
| 1432 | static struct of_device_id msm_otg_dt_match[] = { | 1432 | static const struct of_device_id msm_otg_dt_match[] = { |
| 1433 | { | 1433 | { |
| 1434 | .compatible = "qcom,usb-otg-ci", | 1434 | .compatible = "qcom,usb-otg-ci", |
| 1435 | .data = (void *) CI_45NM_INTEGRATED_PHY | 1435 | .data = (void *) CI_45NM_INTEGRATED_PHY |
| @@ -1466,7 +1466,7 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) | |||
| 1466 | 1466 | ||
| 1467 | motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy"); | 1467 | motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy"); |
| 1468 | if (IS_ERR(motg->phy_rst)) | 1468 | if (IS_ERR(motg->phy_rst)) |
| 1469 | return PTR_ERR(motg->phy_rst); | 1469 | motg->phy_rst = NULL; |
| 1470 | 1470 | ||
| 1471 | pdata->mode = of_usb_get_dr_mode(node); | 1471 | pdata->mode = of_usb_get_dr_mode(node); |
| 1472 | if (pdata->mode == USB_DR_MODE_UNKNOWN) | 1472 | if (pdata->mode == USB_DR_MODE_UNKNOWN) |
| @@ -1558,7 +1558,7 @@ static int msm_otg_probe(struct platform_device *pdev) | |||
| 1558 | np ? "phy" : "usb_phy_clk"); | 1558 | np ? "phy" : "usb_phy_clk"); |
| 1559 | if (IS_ERR(motg->phy_reset_clk)) { | 1559 | if (IS_ERR(motg->phy_reset_clk)) { |
| 1560 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); | 1560 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); |
| 1561 | return PTR_ERR(motg->phy_reset_clk); | 1561 | motg->phy_reset_clk = NULL; |
| 1562 | } | 1562 | } |
| 1563 | 1563 | ||
| 1564 | motg->clk = devm_clk_get(&pdev->dev, np ? "core" : "usb_hs_clk"); | 1564 | motg->clk = devm_clk_get(&pdev->dev, np ? "core" : "usb_hs_clk"); |
| @@ -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-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index bbe4f8e6e8d7..13b4fa287da8 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #include <linux/usb/otg.h> | 33 | #include <linux/usb/otg.h> |
| 34 | #include <linux/usb/ulpi.h> | 34 | #include <linux/usb/ulpi.h> |
| 35 | #include <linux/usb/of.h> | 35 | #include <linux/usb/of.h> |
| 36 | #include <asm/mach-types.h> | ||
| 37 | #include <linux/usb/ehci_def.h> | 36 | #include <linux/usb/ehci_def.h> |
| 38 | #include <linux/usb/tegra_usb_phy.h> | 37 | #include <linux/usb/tegra_usb_phy.h> |
| 39 | #include <linux/regulator/consumer.h> | 38 | #include <linux/regulator/consumer.h> |
| @@ -686,10 +685,8 @@ static int ulpi_phy_power_off(struct tegra_usb_phy *phy) | |||
| 686 | return gpio_direction_output(phy->reset_gpio, 0); | 685 | return gpio_direction_output(phy->reset_gpio, 0); |
| 687 | } | 686 | } |
| 688 | 687 | ||
| 689 | static void tegra_usb_phy_close(struct usb_phy *x) | 688 | static void tegra_usb_phy_close(struct tegra_usb_phy *phy) |
| 690 | { | 689 | { |
| 691 | struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); | ||
| 692 | |||
| 693 | if (!IS_ERR(phy->vbus)) | 690 | if (!IS_ERR(phy->vbus)) |
| 694 | regulator_disable(phy->vbus); | 691 | regulator_disable(phy->vbus); |
| 695 | 692 | ||
| @@ -965,7 +962,7 @@ static const struct tegra_phy_soc_config tegra30_soc_config = { | |||
| 965 | .requires_extra_tuning_parameters = true, | 962 | .requires_extra_tuning_parameters = true, |
| 966 | }; | 963 | }; |
| 967 | 964 | ||
| 968 | static struct of_device_id tegra_usb_phy_id_table[] = { | 965 | static const struct of_device_id tegra_usb_phy_id_table[] = { |
| 969 | { .compatible = "nvidia,tegra30-usb-phy", .data = &tegra30_soc_config }, | 966 | { .compatible = "nvidia,tegra30-usb-phy", .data = &tegra30_soc_config }, |
| 970 | { .compatible = "nvidia,tegra20-usb-phy", .data = &tegra20_soc_config }, | 967 | { .compatible = "nvidia,tegra20-usb-phy", .data = &tegra20_soc_config }, |
| 971 | { }, | 968 | { }, |
| @@ -1061,14 +1058,13 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) | |||
| 1061 | if (err < 0) | 1058 | if (err < 0) |
| 1062 | return err; | 1059 | return err; |
| 1063 | 1060 | ||
| 1064 | tegra_phy->u_phy.shutdown = tegra_usb_phy_close; | ||
| 1065 | tegra_phy->u_phy.set_suspend = tegra_usb_phy_suspend; | 1061 | tegra_phy->u_phy.set_suspend = tegra_usb_phy_suspend; |
| 1066 | 1062 | ||
| 1067 | platform_set_drvdata(pdev, tegra_phy); | 1063 | platform_set_drvdata(pdev, tegra_phy); |
| 1068 | 1064 | ||
| 1069 | err = usb_add_phy_dev(&tegra_phy->u_phy); | 1065 | err = usb_add_phy_dev(&tegra_phy->u_phy); |
| 1070 | if (err < 0) { | 1066 | if (err < 0) { |
| 1071 | tegra_usb_phy_close(&tegra_phy->u_phy); | 1067 | tegra_usb_phy_close(tegra_phy); |
| 1072 | return err; | 1068 | return err; |
| 1073 | } | 1069 | } |
| 1074 | 1070 | ||
| @@ -1080,6 +1076,7 @@ static int tegra_usb_phy_remove(struct platform_device *pdev) | |||
| 1080 | struct tegra_usb_phy *tegra_phy = platform_get_drvdata(pdev); | 1076 | struct tegra_usb_phy *tegra_phy = platform_get_drvdata(pdev); |
| 1081 | 1077 | ||
| 1082 | usb_remove_phy(&tegra_phy->u_phy); | 1078 | usb_remove_phy(&tegra_phy->u_phy); |
| 1079 | tegra_usb_phy_close(tegra_phy); | ||
| 1083 | 1080 | ||
| 1084 | return 0; | 1081 | return 0; |
| 1085 | } | 1082 | } |
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 36b6bce33b20..045cd309367a 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c | |||
| @@ -147,7 +147,7 @@ err0: | |||
| 147 | } | 147 | } |
| 148 | EXPORT_SYMBOL_GPL(usb_get_phy); | 148 | EXPORT_SYMBOL_GPL(usb_get_phy); |
| 149 | 149 | ||
| 150 | /** | 150 | /** |
| 151 | * devm_usb_get_phy_by_phandle - find the USB PHY by phandle | 151 | * devm_usb_get_phy_by_phandle - find the USB PHY by phandle |
| 152 | * @dev - device that requests this phy | 152 | * @dev - device that requests this phy |
| 153 | * @phandle - name of the property holding the phy phandle value | 153 | * @phandle - name of the property holding the phy phandle value |
| @@ -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/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile index bc8aef4311a1..9e47f477b6d2 100644 --- a/drivers/usb/renesas_usbhs/Makefile +++ b/drivers/usb/renesas_usbhs/Makefile | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o | 5 | obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o |
| 6 | 6 | ||
| 7 | renesas_usbhs-y := common.o mod.o pipe.o fifo.o | 7 | renesas_usbhs-y := common.o mod.o pipe.o fifo.o rcar2.o |
| 8 | 8 | ||
| 9 | ifneq ($(CONFIG_USB_RENESAS_USBHS_HCD),) | 9 | ifneq ($(CONFIG_USB_RENESAS_USBHS_HCD),) |
| 10 | renesas_usbhs-y += mod_host.o | 10 | renesas_usbhs-y += mod_host.o |
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 17267b0a2e95..1b9bf8d83235 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
| @@ -15,12 +15,14 @@ | |||
| 15 | * | 15 | * |
| 16 | */ | 16 | */ |
| 17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
| 18 | #include <linux/gpio.h> | ||
| 18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
| 21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 22 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
| 23 | #include "common.h" | 24 | #include "common.h" |
| 25 | #include "rcar2.h" | ||
| 24 | 26 | ||
| 25 | /* | 27 | /* |
| 26 | * image of renesas_usbhs | 28 | * image of renesas_usbhs |
| @@ -284,6 +286,8 @@ static void usbhsc_set_buswait(struct usbhs_priv *priv) | |||
| 284 | /* | 286 | /* |
| 285 | * platform default param | 287 | * platform default param |
| 286 | */ | 288 | */ |
| 289 | |||
| 290 | /* commonly used on old SH-Mobile SoCs */ | ||
| 287 | static u32 usbhsc_default_pipe_type[] = { | 291 | static u32 usbhsc_default_pipe_type[] = { |
| 288 | USB_ENDPOINT_XFER_CONTROL, | 292 | USB_ENDPOINT_XFER_CONTROL, |
| 289 | USB_ENDPOINT_XFER_ISOC, | 293 | USB_ENDPOINT_XFER_ISOC, |
| @@ -297,6 +301,26 @@ static u32 usbhsc_default_pipe_type[] = { | |||
| 297 | USB_ENDPOINT_XFER_INT, | 301 | USB_ENDPOINT_XFER_INT, |
| 298 | }; | 302 | }; |
| 299 | 303 | ||
| 304 | /* commonly used on newer SH-Mobile and R-Car SoCs */ | ||
| 305 | static u32 usbhsc_new_pipe_type[] = { | ||
| 306 | USB_ENDPOINT_XFER_CONTROL, | ||
| 307 | USB_ENDPOINT_XFER_ISOC, | ||
| 308 | USB_ENDPOINT_XFER_ISOC, | ||
| 309 | USB_ENDPOINT_XFER_BULK, | ||
| 310 | USB_ENDPOINT_XFER_BULK, | ||
| 311 | USB_ENDPOINT_XFER_BULK, | ||
| 312 | USB_ENDPOINT_XFER_INT, | ||
| 313 | USB_ENDPOINT_XFER_INT, | ||
| 314 | USB_ENDPOINT_XFER_INT, | ||
| 315 | USB_ENDPOINT_XFER_BULK, | ||
| 316 | USB_ENDPOINT_XFER_BULK, | ||
| 317 | USB_ENDPOINT_XFER_BULK, | ||
| 318 | USB_ENDPOINT_XFER_BULK, | ||
| 319 | USB_ENDPOINT_XFER_BULK, | ||
| 320 | USB_ENDPOINT_XFER_BULK, | ||
| 321 | USB_ENDPOINT_XFER_BULK, | ||
| 322 | }; | ||
| 323 | |||
| 300 | /* | 324 | /* |
| 301 | * power control | 325 | * power control |
| 302 | */ | 326 | */ |
| @@ -423,8 +447,7 @@ static int usbhs_probe(struct platform_device *pdev) | |||
| 423 | int ret; | 447 | int ret; |
| 424 | 448 | ||
| 425 | /* check platform information */ | 449 | /* check platform information */ |
| 426 | if (!info || | 450 | if (!info) { |
| 427 | !info->platform_callback.get_id) { | ||
| 428 | dev_err(&pdev->dev, "no platform information\n"); | 451 | dev_err(&pdev->dev, "no platform information\n"); |
| 429 | return -EINVAL; | 452 | return -EINVAL; |
| 430 | } | 453 | } |
| @@ -451,13 +474,32 @@ static int usbhs_probe(struct platform_device *pdev) | |||
| 451 | /* | 474 | /* |
| 452 | * care platform info | 475 | * care platform info |
| 453 | */ | 476 | */ |
| 454 | memcpy(&priv->pfunc, | 477 | |
| 455 | &info->platform_callback, | ||
| 456 | sizeof(struct renesas_usbhs_platform_callback)); | ||
| 457 | memcpy(&priv->dparam, | 478 | memcpy(&priv->dparam, |
| 458 | &info->driver_param, | 479 | &info->driver_param, |
| 459 | sizeof(struct renesas_usbhs_driver_param)); | 480 | sizeof(struct renesas_usbhs_driver_param)); |
| 460 | 481 | ||
| 482 | switch (priv->dparam.type) { | ||
| 483 | case USBHS_TYPE_R8A7790: | ||
| 484 | case USBHS_TYPE_R8A7791: | ||
| 485 | priv->pfunc = usbhs_rcar2_ops; | ||
| 486 | if (!priv->dparam.pipe_type) { | ||
| 487 | priv->dparam.pipe_type = usbhsc_new_pipe_type; | ||
| 488 | priv->dparam.pipe_size = | ||
| 489 | ARRAY_SIZE(usbhsc_new_pipe_type); | ||
| 490 | } | ||
| 491 | break; | ||
| 492 | default: | ||
| 493 | if (!info->platform_callback.get_id) { | ||
| 494 | dev_err(&pdev->dev, "no platform callbacks"); | ||
| 495 | return -EINVAL; | ||
| 496 | } | ||
| 497 | memcpy(&priv->pfunc, | ||
| 498 | &info->platform_callback, | ||
| 499 | sizeof(struct renesas_usbhs_platform_callback)); | ||
| 500 | break; | ||
| 501 | } | ||
| 502 | |||
| 461 | /* set driver callback functions for platform */ | 503 | /* set driver callback functions for platform */ |
| 462 | dfunc = &info->driver_callback; | 504 | dfunc = &info->driver_callback; |
| 463 | dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; | 505 | dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; |
| @@ -507,6 +549,20 @@ static int usbhs_probe(struct platform_device *pdev) | |||
| 507 | */ | 549 | */ |
| 508 | usbhs_sys_clock_ctrl(priv, 0); | 550 | usbhs_sys_clock_ctrl(priv, 0); |
| 509 | 551 | ||
| 552 | /* check GPIO determining if USB function should be enabled */ | ||
| 553 | if (priv->dparam.enable_gpio) { | ||
| 554 | gpio_request_one(priv->dparam.enable_gpio, GPIOF_IN, NULL); | ||
| 555 | ret = !gpio_get_value(priv->dparam.enable_gpio); | ||
| 556 | gpio_free(priv->dparam.enable_gpio); | ||
| 557 | if (ret) { | ||
| 558 | dev_warn(&pdev->dev, | ||
| 559 | "USB function not selected (GPIO %d)\n", | ||
| 560 | priv->dparam.enable_gpio); | ||
| 561 | ret = -ENOTSUPP; | ||
| 562 | goto probe_end_mod_exit; | ||
| 563 | } | ||
| 564 | } | ||
| 565 | |||
| 510 | /* | 566 | /* |
| 511 | * platform call | 567 | * platform call |
| 512 | * | 568 | * |
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index c69dd2fba360..a7996da6a1bd 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h | |||
| @@ -268,6 +268,8 @@ struct usbhs_priv { | |||
| 268 | * fifo control | 268 | * fifo control |
| 269 | */ | 269 | */ |
| 270 | struct usbhs_fifo_info fifo_info; | 270 | struct usbhs_fifo_info fifo_info; |
| 271 | |||
| 272 | struct usb_phy *phy; | ||
| 271 | }; | 273 | }; |
| 272 | 274 | ||
| 273 | /* | 275 | /* |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 458f3766bef1..04e6505777d0 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
| @@ -600,8 +600,10 @@ static int usbhsg_ep_enable(struct usb_ep *ep, | |||
| 600 | static int usbhsg_ep_disable(struct usb_ep *ep) | 600 | static int usbhsg_ep_disable(struct usb_ep *ep) |
| 601 | { | 601 | { |
| 602 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | 602 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
| 603 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
| 603 | 604 | ||
| 604 | usbhsg_pipe_disable(uep); | 605 | usbhsg_pipe_disable(uep); |
| 606 | usbhs_pipe_free(pipe); | ||
| 605 | 607 | ||
| 606 | uep->pipe->mod_private = NULL; | 608 | uep->pipe->mod_private = NULL; |
| 607 | uep->pipe = NULL; | 609 | uep->pipe = NULL; |
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 7926e1c700f1..75fbcf6b102e 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c | |||
| @@ -640,6 +640,11 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type) | |||
| 640 | return pipe; | 640 | return pipe; |
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | static void usbhsp_put_pipe(struct usbhs_pipe *pipe) | ||
| 644 | { | ||
| 645 | usbhsp_flags_init(pipe); | ||
| 646 | } | ||
| 647 | |||
| 643 | void usbhs_pipe_init(struct usbhs_priv *priv, | 648 | void usbhs_pipe_init(struct usbhs_priv *priv, |
| 644 | int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map)) | 649 | int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map)) |
| 645 | { | 650 | { |
| @@ -710,6 +715,7 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, | |||
| 710 | usbhsp_pipe_select(pipe); | 715 | usbhsp_pipe_select(pipe); |
| 711 | usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); | 716 | usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); |
| 712 | usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); | 717 | usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); |
| 718 | usbhs_pipe_clear(pipe); | ||
| 713 | 719 | ||
| 714 | usbhs_pipe_sequence_data0(pipe); | 720 | usbhs_pipe_sequence_data0(pipe); |
| 715 | 721 | ||
| @@ -726,6 +732,11 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, | |||
| 726 | return pipe; | 732 | return pipe; |
| 727 | } | 733 | } |
| 728 | 734 | ||
| 735 | void usbhs_pipe_free(struct usbhs_pipe *pipe) | ||
| 736 | { | ||
| 737 | usbhsp_put_pipe(pipe); | ||
| 738 | } | ||
| 739 | |||
| 729 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo) | 740 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo) |
| 730 | { | 741 | { |
| 731 | if (pipe->fifo) | 742 | if (pipe->fifo) |
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 3e5349879838..406f36d050e4 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h | |||
| @@ -75,6 +75,7 @@ struct usbhs_pipe_info { | |||
| 75 | char *usbhs_pipe_name(struct usbhs_pipe *pipe); | 75 | char *usbhs_pipe_name(struct usbhs_pipe *pipe); |
| 76 | struct usbhs_pipe | 76 | struct usbhs_pipe |
| 77 | *usbhs_pipe_malloc(struct usbhs_priv *priv, int endpoint_type, int dir_in); | 77 | *usbhs_pipe_malloc(struct usbhs_priv *priv, int endpoint_type, int dir_in); |
| 78 | void usbhs_pipe_free(struct usbhs_pipe *pipe); | ||
| 78 | int usbhs_pipe_probe(struct usbhs_priv *priv); | 79 | int usbhs_pipe_probe(struct usbhs_priv *priv); |
| 79 | void usbhs_pipe_remove(struct usbhs_priv *priv); | 80 | void usbhs_pipe_remove(struct usbhs_priv *priv); |
| 80 | int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); | 81 | int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); |
diff --git a/drivers/usb/renesas_usbhs/rcar2.c b/drivers/usb/renesas_usbhs/rcar2.c new file mode 100644 index 000000000000..e6b9dcc1c289 --- /dev/null +++ b/drivers/usb/renesas_usbhs/rcar2.c | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | /* | ||
| 2 | * Renesas USB driver R-Car Gen. 2 initialization and power control | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Ulrich Hecht | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/gpio.h> | ||
| 14 | #include <linux/of_gpio.h> | ||
| 15 | #include <linux/platform_data/gpio-rcar.h> | ||
| 16 | #include <linux/usb/phy.h> | ||
| 17 | #include "common.h" | ||
| 18 | #include "rcar2.h" | ||
| 19 | |||
| 20 | static int usbhs_rcar2_hardware_init(struct platform_device *pdev) | ||
| 21 | { | ||
| 22 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | ||
| 23 | struct usb_phy *phy; | ||
| 24 | |||
| 25 | phy = usb_get_phy_dev(&pdev->dev, 0); | ||
| 26 | if (IS_ERR(phy)) | ||
| 27 | return PTR_ERR(phy); | ||
| 28 | |||
| 29 | priv->phy = phy; | ||
| 30 | return 0; | ||
| 31 | } | ||
| 32 | |||
| 33 | static int usbhs_rcar2_hardware_exit(struct platform_device *pdev) | ||
| 34 | { | ||
| 35 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | ||
| 36 | |||
| 37 | if (!priv->phy) | ||
| 38 | return 0; | ||
| 39 | |||
| 40 | usb_put_phy(priv->phy); | ||
| 41 | priv->phy = NULL; | ||
| 42 | |||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | |||
| 46 | static int usbhs_rcar2_power_ctrl(struct platform_device *pdev, | ||
| 47 | void __iomem *base, int enable) | ||
| 48 | { | ||
| 49 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | ||
| 50 | |||
| 51 | if (!priv->phy) | ||
| 52 | return -ENODEV; | ||
| 53 | |||
| 54 | if (enable) { | ||
| 55 | int retval = usb_phy_init(priv->phy); | ||
| 56 | |||
| 57 | if (!retval) | ||
| 58 | retval = usb_phy_set_suspend(priv->phy, 0); | ||
| 59 | return retval; | ||
| 60 | } | ||
| 61 | |||
| 62 | usb_phy_set_suspend(priv->phy, 1); | ||
| 63 | usb_phy_shutdown(priv->phy); | ||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | |||
| 67 | static int usbhs_rcar2_get_id(struct platform_device *pdev) | ||
| 68 | { | ||
| 69 | return USBHS_GADGET; | ||
| 70 | } | ||
| 71 | |||
| 72 | const struct renesas_usbhs_platform_callback usbhs_rcar2_ops = { | ||
| 73 | .hardware_init = usbhs_rcar2_hardware_init, | ||
| 74 | .hardware_exit = usbhs_rcar2_hardware_exit, | ||
| 75 | .power_ctrl = usbhs_rcar2_power_ctrl, | ||
| 76 | .get_id = usbhs_rcar2_get_id, | ||
| 77 | }; | ||
diff --git a/drivers/usb/renesas_usbhs/rcar2.h b/drivers/usb/renesas_usbhs/rcar2.h new file mode 100644 index 000000000000..f07f10d9b3b2 --- /dev/null +++ b/drivers/usb/renesas_usbhs/rcar2.h | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | extern const struct renesas_usbhs_platform_callback | ||
| 4 | usbhs_rcar2_ops; | ||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 330df5ce435b..e4bb62225cb9 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
| @@ -856,9 +856,6 @@ static int cp210x_startup(struct usb_serial *serial) | |||
| 856 | struct usb_host_interface *cur_altsetting; | 856 | struct usb_host_interface *cur_altsetting; |
| 857 | struct cp210x_serial_private *spriv; | 857 | struct cp210x_serial_private *spriv; |
| 858 | 858 | ||
| 859 | /* cp210x buffers behave strangely unless device is reset */ | ||
| 860 | usb_reset_device(serial->dev); | ||
| 861 | |||
| 862 | spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); | 859 | spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); |
| 863 | if (!spriv) | 860 | if (!spriv) |
| 864 | return -ENOMEM; | 861 | return -ENOMEM; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8a3813be1b28..824ea5e7ec8b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -87,7 +87,6 @@ struct ftdi_sio_quirk { | |||
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | static int ftdi_jtag_probe(struct usb_serial *serial); | 89 | static int ftdi_jtag_probe(struct usb_serial *serial); |
| 90 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); | ||
| 91 | static int ftdi_NDI_device_setup(struct usb_serial *serial); | 90 | static int ftdi_NDI_device_setup(struct usb_serial *serial); |
| 92 | static int ftdi_stmclite_probe(struct usb_serial *serial); | 91 | static int ftdi_stmclite_probe(struct usb_serial *serial); |
| 93 | static int ftdi_8u2232c_probe(struct usb_serial *serial); | 92 | static int ftdi_8u2232c_probe(struct usb_serial *serial); |
| @@ -98,10 +97,6 @@ static struct ftdi_sio_quirk ftdi_jtag_quirk = { | |||
| 98 | .probe = ftdi_jtag_probe, | 97 | .probe = ftdi_jtag_probe, |
| 99 | }; | 98 | }; |
| 100 | 99 | ||
| 101 | static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { | ||
| 102 | .probe = ftdi_mtxorb_hack_setup, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static struct ftdi_sio_quirk ftdi_NDI_device_quirk = { | 100 | static struct ftdi_sio_quirk ftdi_NDI_device_quirk = { |
| 106 | .probe = ftdi_NDI_device_setup, | 101 | .probe = ftdi_NDI_device_setup, |
| 107 | }; | 102 | }; |
| @@ -151,6 +146,7 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 151 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | 146 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, |
| 152 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | 147 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, |
| 153 | { 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) }, | ||
| 154 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, | 150 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, |
| 155 | { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, | 151 | { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, |
| 156 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, | 152 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, |
| @@ -256,14 +252,12 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 256 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0124_PID) }, | 252 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0124_PID) }, |
| 257 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0125_PID) }, | 253 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0125_PID) }, |
| 258 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0126_PID) }, | 254 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0126_PID) }, |
| 259 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0127_PID), | 255 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0127_PID) }, |
| 260 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
| 261 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0128_PID) }, | 256 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0128_PID) }, |
| 262 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0129_PID) }, | 257 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0129_PID) }, |
| 263 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012A_PID) }, | 258 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012A_PID) }, |
| 264 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012B_PID) }, | 259 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012B_PID) }, |
| 265 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012C_PID), | 260 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012C_PID) }, |
| 266 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
| 267 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012D_PID) }, | 261 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012D_PID) }, |
| 268 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012E_PID) }, | 262 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012E_PID) }, |
| 269 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012F_PID) }, | 263 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012F_PID) }, |
| @@ -302,18 +296,12 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 302 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0150_PID) }, | 296 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0150_PID) }, |
| 303 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0151_PID) }, | 297 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0151_PID) }, |
| 304 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0152_PID) }, | 298 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0152_PID) }, |
| 305 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0153_PID), | 299 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0153_PID) }, |
| 306 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | 300 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0154_PID) }, |
| 307 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0154_PID), | 301 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0155_PID) }, |
| 308 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | 302 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0156_PID) }, |
| 309 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0155_PID), | 303 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0157_PID) }, |
| 310 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | 304 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0158_PID) }, |
| 311 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0156_PID), | ||
| 312 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
| 313 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0157_PID), | ||
| 314 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
| 315 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0158_PID), | ||
| 316 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
| 317 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0159_PID) }, | 305 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0159_PID) }, |
| 318 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015A_PID) }, | 306 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015A_PID) }, |
| 319 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015B_PID) }, | 307 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015B_PID) }, |
| @@ -673,6 +661,8 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 673 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, | 661 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, |
| 674 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, | 662 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, |
| 675 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, | 663 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, |
| 664 | { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, | ||
| 665 | { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, | ||
| 676 | { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, | 666 | { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, |
| 677 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, | 667 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, |
| 678 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, | 668 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
| @@ -945,6 +935,8 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 945 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, | 935 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, |
| 946 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, | 936 | { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, |
| 947 | { 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) }, | ||
| 948 | /* Infineon Devices */ | 940 | /* Infineon Devices */ |
| 949 | { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, | 941 | { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, |
| 950 | { } /* Terminating entry */ | 942 | { } /* Terminating entry */ |
| @@ -1559,45 +1551,40 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
| 1559 | } | 1551 | } |
| 1560 | 1552 | ||
| 1561 | 1553 | ||
| 1562 | /* Determine the maximum packet size for the device. This depends on the chip | 1554 | /* |
| 1563 | * type and the USB host capabilities. The value should be obtained from the | 1555 | * Determine the maximum packet size for the device. This depends on the chip |
| 1564 | * device descriptor as the chip will use the appropriate values for the host.*/ | 1556 | * type and the USB host capabilities. The value should be obtained from the |
| 1557 | * device descriptor as the chip will use the appropriate values for the host. | ||
| 1558 | */ | ||
| 1565 | static void ftdi_set_max_packet_size(struct usb_serial_port *port) | 1559 | static void ftdi_set_max_packet_size(struct usb_serial_port *port) |
| 1566 | { | 1560 | { |
| 1567 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1561 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
| 1568 | struct usb_serial *serial = port->serial; | 1562 | struct usb_interface *interface = port->serial->interface; |
| 1569 | struct usb_device *udev = serial->dev; | ||
| 1570 | |||
| 1571 | struct usb_interface *interface = serial->interface; | ||
| 1572 | struct usb_endpoint_descriptor *ep_desc; | 1563 | struct usb_endpoint_descriptor *ep_desc; |
| 1573 | |||
| 1574 | unsigned num_endpoints; | 1564 | unsigned num_endpoints; |
| 1575 | unsigned i; | 1565 | unsigned i; |
| 1576 | 1566 | ||
| 1577 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | 1567 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; |
| 1578 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | ||
| 1579 | |||
| 1580 | if (!num_endpoints) | 1568 | if (!num_endpoints) |
| 1581 | return; | 1569 | return; |
| 1582 | 1570 | ||
| 1583 | /* NOTE: some customers have programmed FT232R/FT245R devices | 1571 | /* |
| 1584 | * with an endpoint size of 0 - not good. In this case, we | 1572 | * NOTE: Some customers have programmed FT232R/FT245R devices |
| 1573 | * with an endpoint size of 0 - not good. In this case, we | ||
| 1585 | * want to override the endpoint descriptor setting and use a | 1574 | * want to override the endpoint descriptor setting and use a |
| 1586 | * value of 64 for wMaxPacketSize */ | 1575 | * value of 64 for wMaxPacketSize. |
| 1576 | */ | ||
| 1587 | for (i = 0; i < num_endpoints; i++) { | 1577 | for (i = 0; i < num_endpoints; i++) { |
| 1588 | dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1, | ||
| 1589 | interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize); | ||
| 1590 | ep_desc = &interface->cur_altsetting->endpoint[i].desc; | 1578 | ep_desc = &interface->cur_altsetting->endpoint[i].desc; |
| 1591 | if (ep_desc->wMaxPacketSize == 0) { | 1579 | if (!ep_desc->wMaxPacketSize) { |
| 1592 | ep_desc->wMaxPacketSize = cpu_to_le16(0x40); | 1580 | ep_desc->wMaxPacketSize = cpu_to_le16(0x40); |
| 1593 | dev_info(&udev->dev, "Overriding wMaxPacketSize on endpoint %d\n", i); | 1581 | dev_warn(&port->dev, "Overriding wMaxPacketSize on endpoint %d\n", |
| 1582 | usb_endpoint_num(ep_desc)); | ||
| 1594 | } | 1583 | } |
| 1595 | } | 1584 | } |
| 1596 | 1585 | ||
| 1597 | /* set max packet size based on descriptor */ | 1586 | /* Set max packet size based on last descriptor. */ |
| 1598 | priv->max_packet_size = usb_endpoint_maxp(ep_desc); | 1587 | priv->max_packet_size = usb_endpoint_maxp(ep_desc); |
| 1599 | |||
| 1600 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | ||
| 1601 | } | 1588 | } |
| 1602 | 1589 | ||
| 1603 | 1590 | ||
| @@ -1866,24 +1853,6 @@ static int ftdi_stmclite_probe(struct usb_serial *serial) | |||
| 1866 | return 0; | 1853 | return 0; |
| 1867 | } | 1854 | } |
| 1868 | 1855 | ||
| 1869 | /* | ||
| 1870 | * The Matrix Orbital VK204-25-USB has an invalid IN endpoint. | ||
| 1871 | * We have to correct it if we want to read from it. | ||
| 1872 | */ | ||
| 1873 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) | ||
| 1874 | { | ||
| 1875 | struct usb_host_endpoint *ep = serial->dev->ep_in[1]; | ||
| 1876 | struct usb_endpoint_descriptor *ep_desc = &ep->desc; | ||
| 1877 | |||
| 1878 | if (ep->enabled && ep_desc->wMaxPacketSize == 0) { | ||
| 1879 | ep_desc->wMaxPacketSize = cpu_to_le16(0x40); | ||
| 1880 | dev_info(&serial->dev->dev, | ||
| 1881 | "Fixing invalid wMaxPacketSize on read pipe\n"); | ||
| 1882 | } | ||
| 1883 | |||
| 1884 | return 0; | ||
| 1885 | } | ||
| 1886 | |||
| 1887 | static int ftdi_sio_port_remove(struct usb_serial_port *port) | 1856 | static int ftdi_sio_port_remove(struct usb_serial_port *port) |
| 1888 | { | 1857 | { |
| 1889 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1858 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index c4777bc6aee0..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 |
| @@ -140,12 +142,15 @@ | |||
| 140 | /* | 142 | /* |
| 141 | * Xsens Technologies BV products (http://www.xsens.com). | 143 | * Xsens Technologies BV products (http://www.xsens.com). |
| 142 | */ | 144 | */ |
| 143 | #define XSENS_CONVERTER_0_PID 0xD388 | 145 | #define XSENS_VID 0x2639 |
| 144 | #define XSENS_CONVERTER_1_PID 0xD389 | 146 | #define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ |
| 147 | #define XSENS_MTW_PID 0x0200 /* Xsens MTw */ | ||
| 148 | #define XSENS_CONVERTER_0_PID 0xD388 /* Xsens USB converter */ | ||
| 149 | #define XSENS_CONVERTER_1_PID 0xD389 /* Xsens Wireless Receiver */ | ||
| 145 | #define XSENS_CONVERTER_2_PID 0xD38A | 150 | #define XSENS_CONVERTER_2_PID 0xD38A |
| 146 | #define XSENS_CONVERTER_3_PID 0xD38B | 151 | #define XSENS_CONVERTER_3_PID 0xD38B /* Xsens USB-serial converter */ |
| 147 | #define XSENS_CONVERTER_4_PID 0xD38C | 152 | #define XSENS_CONVERTER_4_PID 0xD38C /* Xsens Wireless Receiver */ |
| 148 | #define XSENS_CONVERTER_5_PID 0xD38D | 153 | #define XSENS_CONVERTER_5_PID 0xD38D /* Xsens Awinda Station */ |
| 149 | #define XSENS_CONVERTER_6_PID 0xD38E | 154 | #define XSENS_CONVERTER_6_PID 0xD38E |
| 150 | #define XSENS_CONVERTER_7_PID 0xD38F | 155 | #define XSENS_CONVERTER_7_PID 0xD38F |
| 151 | 156 | ||
| @@ -1375,3 +1380,8 @@ | |||
| 1375 | #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 */ |
| 1376 | #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 */ |
| 1377 | #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/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index d7440b7557af..e020ad28a00c 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
| @@ -62,8 +62,6 @@ static void klsi_105_close(struct usb_serial_port *port); | |||
| 62 | static void klsi_105_set_termios(struct tty_struct *tty, | 62 | static void klsi_105_set_termios(struct tty_struct *tty, |
| 63 | struct usb_serial_port *port, struct ktermios *old); | 63 | struct usb_serial_port *port, struct ktermios *old); |
| 64 | static int klsi_105_tiocmget(struct tty_struct *tty); | 64 | static int klsi_105_tiocmget(struct tty_struct *tty); |
| 65 | static int klsi_105_tiocmset(struct tty_struct *tty, | ||
| 66 | unsigned int set, unsigned int clear); | ||
| 67 | static void klsi_105_process_read_urb(struct urb *urb); | 65 | static void klsi_105_process_read_urb(struct urb *urb); |
| 68 | static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, | 66 | static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, |
| 69 | void *dest, size_t size); | 67 | void *dest, size_t size); |
| @@ -93,7 +91,6 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
| 93 | .set_termios = klsi_105_set_termios, | 91 | .set_termios = klsi_105_set_termios, |
| 94 | /*.break_ctl = klsi_105_break_ctl,*/ | 92 | /*.break_ctl = klsi_105_break_ctl,*/ |
| 95 | .tiocmget = klsi_105_tiocmget, | 93 | .tiocmget = klsi_105_tiocmget, |
| 96 | .tiocmset = klsi_105_tiocmset, | ||
| 97 | .port_probe = klsi_105_port_probe, | 94 | .port_probe = klsi_105_port_probe, |
| 98 | .port_remove = klsi_105_port_remove, | 95 | .port_remove = klsi_105_port_remove, |
| 99 | .throttle = usb_serial_generic_throttle, | 96 | .throttle = usb_serial_generic_throttle, |
| @@ -602,33 +599,6 @@ static int klsi_105_tiocmget(struct tty_struct *tty) | |||
| 602 | return (int)line_state; | 599 | return (int)line_state; |
| 603 | } | 600 | } |
| 604 | 601 | ||
| 605 | static int klsi_105_tiocmset(struct tty_struct *tty, | ||
| 606 | unsigned int set, unsigned int clear) | ||
| 607 | { | ||
| 608 | int retval = -EINVAL; | ||
| 609 | |||
| 610 | /* if this ever gets implemented, it should be done something like this: | ||
| 611 | struct usb_serial *serial = port->serial; | ||
| 612 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
| 613 | unsigned long flags; | ||
| 614 | int control; | ||
| 615 | |||
| 616 | spin_lock_irqsave (&priv->lock, flags); | ||
| 617 | if (set & TIOCM_RTS) | ||
| 618 | priv->control_state |= TIOCM_RTS; | ||
| 619 | if (set & TIOCM_DTR) | ||
| 620 | priv->control_state |= TIOCM_DTR; | ||
| 621 | if (clear & TIOCM_RTS) | ||
| 622 | priv->control_state &= ~TIOCM_RTS; | ||
| 623 | if (clear & TIOCM_DTR) | ||
| 624 | priv->control_state &= ~TIOCM_DTR; | ||
| 625 | control = priv->control_state; | ||
| 626 | spin_unlock_irqrestore (&priv->lock, flags); | ||
| 627 | retval = mct_u232_set_modem_ctrl(serial, control); | ||
| 628 | */ | ||
| 629 | return retval; | ||
| 630 | } | ||
| 631 | |||
| 632 | module_usb_serial_driver(serial_drivers, id_table); | 602 | module_usb_serial_driver(serial_drivers, id_table); |
| 633 | 603 | ||
| 634 | MODULE_AUTHOR(DRIVER_AUTHOR); | 604 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 393be562d875..3d88eefdf1d1 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
| @@ -1181,10 +1181,7 @@ static void mos7840_close(struct usb_serial_port *port) | |||
| 1181 | /* Freeing Write URBs */ | 1181 | /* Freeing Write URBs */ |
| 1182 | for (j = 0; j < NUM_URBS; ++j) { | 1182 | for (j = 0; j < NUM_URBS; ++j) { |
| 1183 | if (mos7840_port->write_urb_pool[j]) { | 1183 | if (mos7840_port->write_urb_pool[j]) { |
| 1184 | if (mos7840_port->write_urb_pool[j]->transfer_buffer) | 1184 | kfree(mos7840_port->write_urb_pool[j]->transfer_buffer); |
| 1185 | kfree(mos7840_port->write_urb_pool[j]-> | ||
| 1186 | transfer_buffer); | ||
| 1187 | |||
| 1188 | usb_free_urb(mos7840_port->write_urb_pool[j]); | 1185 | usb_free_urb(mos7840_port->write_urb_pool[j]); |
| 1189 | } | 1186 | } |
| 1190 | } | 1187 | } |
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/Kconfig b/drivers/usb/storage/Kconfig index 13b5bfbaf951..715f299af6ea 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
| @@ -18,9 +18,7 @@ config USB_STORAGE | |||
| 18 | 18 | ||
| 19 | This option depends on 'SCSI' support being enabled, but you | 19 | This option depends on 'SCSI' support being enabled, but you |
| 20 | probably also need 'SCSI device support: SCSI disk support' | 20 | probably also need 'SCSI device support: SCSI disk support' |
| 21 | (BLK_DEV_SD) for most USB storage devices. Some devices also | 21 | (BLK_DEV_SD) for most USB storage devices. |
| 22 | will require 'Probe all LUNs on each SCSI device' | ||
| 23 | (SCSI_MULTI_LUN). | ||
| 24 | 22 | ||
| 25 | To compile this driver as a module, choose M here: the | 23 | To compile this driver as a module, choose M here: the |
| 26 | module will be called usb-storage. | 24 | module will be called usb-storage. |
| @@ -193,7 +191,7 @@ config USB_STORAGE_ENE_UB6250 | |||
| 193 | depends on USB_STORAGE | 191 | depends on USB_STORAGE |
| 194 | ---help--- | 192 | ---help--- |
| 195 | Say Y here if you wish to control a ENE SD/MS Card reader. | 193 | Say Y here if you wish to control a ENE SD/MS Card reader. |
| 196 | To use SM card, please build driver/staging/keucr/keucr.ko | 194 | Note that this driver does not support SM cards. |
| 197 | 195 | ||
| 198 | This option depends on 'SCSI' support being enabled, but you | 196 | This option depends on 'SCSI' support being enabled, but you |
| 199 | probably also need 'SCSI device support: SCSI disk support' | 197 | probably also need 'SCSI device support: SCSI disk support' |
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index ef6efb55dc31..56f782bef36b 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c | |||
| @@ -2344,8 +2344,8 @@ static int ene_ub6250_probe(struct usb_interface *intf, | |||
| 2344 | } | 2344 | } |
| 2345 | 2345 | ||
| 2346 | if (!(misc_reg03 & 0x01)) { | 2346 | if (!(misc_reg03 & 0x01)) { |
| 2347 | pr_info("ums_eneub6250: The driver only supports SD/MS card. " | 2347 | pr_info("ums_eneub6250: This driver only supports SD/MS cards. " |
| 2348 | "To use SM card, please build driver/staging/keucr\n"); | 2348 | "It does not support SM cards.\n"); |
| 2349 | } | 2349 | } |
| 2350 | 2350 | ||
| 2351 | return result; | 2351 | return result; |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 073a2c32ccc4..38a4504ce450 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
| @@ -1498,7 +1498,7 @@ static int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1498 | { | 1498 | { |
| 1499 | int ret; | 1499 | int ret; |
| 1500 | 1500 | ||
| 1501 | usb_stor_dbg(us, "LUN=%d\n", srb->device->lun); | 1501 | usb_stor_dbg(us, "LUN=%d\n", (u8)srb->device->lun); |
| 1502 | 1502 | ||
| 1503 | switch (srb->device->lun) { | 1503 | switch (srb->device->lun) { |
| 1504 | case 0: | 1504 | case 0: |
| @@ -1524,7 +1524,7 @@ static int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1524 | break; | 1524 | break; |
| 1525 | 1525 | ||
| 1526 | default: | 1526 | default: |
| 1527 | usb_stor_dbg(us, "Invalid LUN %d\n", srb->device->lun); | 1527 | usb_stor_dbg(us, "Invalid LUN %d\n", (u8)srb->device->lun); |
| 1528 | ret = USB_STOR_TRANSPORT_ERROR; | 1528 | ret = USB_STOR_TRANSPORT_ERROR; |
| 1529 | break; | 1529 | break; |
| 1530 | } | 1530 | } |
diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index bb05b984d5f6..503ac5c8d80f 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h | |||
| @@ -9,32 +9,15 @@ static int uas_is_interface(struct usb_host_interface *intf) | |||
| 9 | intf->desc.bInterfaceProtocol == USB_PR_UAS); | 9 | intf->desc.bInterfaceProtocol == USB_PR_UAS); |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | static int uas_isnt_supported(struct usb_device *udev) | ||
| 13 | { | ||
| 14 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
| 15 | |||
| 16 | dev_warn(&udev->dev, "The driver for the USB controller %s does not " | ||
| 17 | "support scatter-gather which is\n", | ||
| 18 | hcd->driver->description); | ||
| 19 | dev_warn(&udev->dev, "required by the UAS driver. Please try an" | ||
| 20 | "alternative USB controller if you wish to use UAS.\n"); | ||
| 21 | return -ENODEV; | ||
| 22 | } | ||
| 23 | |||
| 24 | static int uas_find_uas_alt_setting(struct usb_interface *intf) | 12 | static int uas_find_uas_alt_setting(struct usb_interface *intf) |
| 25 | { | 13 | { |
| 26 | int i; | 14 | int i; |
| 27 | struct usb_device *udev = interface_to_usbdev(intf); | ||
| 28 | int sg_supported = udev->bus->sg_tablesize != 0; | ||
| 29 | 15 | ||
| 30 | for (i = 0; i < intf->num_altsetting; i++) { | 16 | for (i = 0; i < intf->num_altsetting; i++) { |
| 31 | struct usb_host_interface *alt = &intf->altsetting[i]; | 17 | struct usb_host_interface *alt = &intf->altsetting[i]; |
| 32 | 18 | ||
| 33 | if (uas_is_interface(alt)) { | 19 | if (uas_is_interface(alt)) |
| 34 | if (!sg_supported) | ||
| 35 | return uas_isnt_supported(udev); | ||
| 36 | return alt->desc.bAlternateSetting; | 20 | return alt->desc.bAlternateSetting; |
| 37 | } | ||
| 38 | } | 21 | } |
| 39 | 22 | ||
| 40 | return -ENODEV; | 23 | return -ENODEV; |
| @@ -81,9 +64,6 @@ static int uas_use_uas_driver(struct usb_interface *intf, | |||
| 81 | if (flags & US_FL_IGNORE_UAS) | 64 | if (flags & US_FL_IGNORE_UAS) |
| 82 | return 0; | 65 | return 0; |
| 83 | 66 | ||
| 84 | if (udev->speed >= USB_SPEED_SUPER && !hcd->can_do_streams) | ||
| 85 | return 0; | ||
| 86 | |||
| 87 | alt = uas_find_uas_alt_setting(intf); | 67 | alt = uas_find_uas_alt_setting(intf); |
| 88 | if (alt < 0) | 68 | if (alt < 0) |
| 89 | return 0; | 69 | return 0; |
| @@ -92,5 +72,23 @@ static int uas_use_uas_driver(struct usb_interface *intf, | |||
| 92 | if (r < 0) | 72 | if (r < 0) |
| 93 | return 0; | 73 | return 0; |
| 94 | 74 | ||
| 75 | if (udev->bus->sg_tablesize == 0) { | ||
| 76 | dev_warn(&udev->dev, | ||
| 77 | "The driver for the USB controller %s does not support scatter-gather which is\n", | ||
| 78 | hcd->driver->description); | ||
| 79 | dev_warn(&udev->dev, | ||
| 80 | "required by the UAS driver. Please try an other USB controller if you wish to use UAS.\n"); | ||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | if (udev->speed >= USB_SPEED_SUPER && !hcd->can_do_streams) { | ||
| 85 | dev_warn(&udev->dev, | ||
| 86 | "USB controller %s does not support streams, which are required by the UAS driver.\n", | ||
| 87 | hcd_to_bus(hcd)->bus_name); | ||
| 88 | dev_warn(&udev->dev, | ||
| 89 | "Please try an other USB controller if you wish to use UAS.\n"); | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 95 | return 1; | 93 | return 1; |
| 96 | } | 94 | } |
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 511b22953167..3f42785f653c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
| @@ -1026,7 +1026,7 @@ static int uas_configure_endpoints(struct uas_dev_info *devinfo) | |||
| 1026 | usb_endpoint_num(&eps[3]->desc)); | 1026 | usb_endpoint_num(&eps[3]->desc)); |
| 1027 | 1027 | ||
| 1028 | if (udev->speed != USB_SPEED_SUPER) { | 1028 | if (udev->speed != USB_SPEED_SUPER) { |
| 1029 | devinfo->qdepth = 256; | 1029 | devinfo->qdepth = 32; |
| 1030 | devinfo->use_streams = 0; | 1030 | devinfo->use_streams = 0; |
| 1031 | } else { | 1031 | } else { |
| 1032 | devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1, | 1032 | devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1, |
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/storage/usb.c b/drivers/usb/storage/usb.c index f1c96261a501..cedb29252a92 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
| @@ -347,14 +347,16 @@ static int usb_stor_control_thread(void * __us) | |||
| 347 | */ | 347 | */ |
| 348 | else if (us->srb->device->id && | 348 | else if (us->srb->device->id && |
| 349 | !(us->fflags & US_FL_SCM_MULT_TARG)) { | 349 | !(us->fflags & US_FL_SCM_MULT_TARG)) { |
| 350 | usb_stor_dbg(us, "Bad target number (%d:%d)\n", | 350 | usb_stor_dbg(us, "Bad target number (%d:%llu)\n", |
| 351 | us->srb->device->id, us->srb->device->lun); | 351 | us->srb->device->id, |
| 352 | us->srb->device->lun); | ||
| 352 | us->srb->result = DID_BAD_TARGET << 16; | 353 | us->srb->result = DID_BAD_TARGET << 16; |
| 353 | } | 354 | } |
| 354 | 355 | ||
| 355 | else if (us->srb->device->lun > us->max_lun) { | 356 | else if (us->srb->device->lun > us->max_lun) { |
| 356 | usb_stor_dbg(us, "Bad LUN (%d:%d)\n", | 357 | usb_stor_dbg(us, "Bad LUN (%d:%llu)\n", |
| 357 | us->srb->device->id, us->srb->device->lun); | 358 | us->srb->device->id, |
| 359 | us->srb->device->lun); | ||
| 358 | us->srb->result = DID_BAD_TARGET << 16; | 360 | us->srb->result = DID_BAD_TARGET << 16; |
| 359 | } | 361 | } |
| 360 | 362 | ||
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, |
