diff options
| -rw-r--r-- | Documentation/DocBook/gadget.tmpl | 10 | ||||
| -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/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) | 0 | ||||
| -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) | 19 | ||||
| -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) | 0 | ||||
| -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) | 0 | ||||
| -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) | 0 | ||||
| -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 | 385 | ||||
| -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) | 2 | ||||
| -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) | 4 | ||||
| -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) | 0 | ||||
| -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) | 0 | ||||
| -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/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/phy/phy-am335x.c | 12 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-gpio-vbus-usb.c | 45 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-msm-usb.c | 12 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-tegra-usb.c | 2 | ||||
| -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-- | include/linux/usb/composite.h | 15 | ||||
| -rw-r--r-- | include/linux/usb/renesas_usbhs.h | 6 | ||||
| -rw-r--r-- | include/linux/usb/usb338x.h | 199 | ||||
| -rw-r--r-- | include/uapi/linux/usb/functionfs.h | 82 | ||||
| -rw-r--r-- | tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c | 39 | ||||
| -rw-r--r-- | tools/usb/ffs-aio-example/multibuff/host_app/test.c | 27 | ||||
| -rw-r--r-- | tools/usb/ffs-aio-example/simple/device_app/aio_simple.c | 39 | ||||
| -rw-r--r-- | tools/usb/ffs-aio-example/simple/host_app/test.c | 27 |
159 files changed, 7024 insertions, 4938 deletions
diff --git a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl index 2c425d70f7e2..641629221176 100644 --- a/Documentation/DocBook/gadget.tmpl +++ b/Documentation/DocBook/gadget.tmpl | |||
| @@ -556,11 +556,11 @@ been converted to this framework. | |||
| 556 | Near-term plans include converting all of them, except for "gadgetfs". | 556 | Near-term plans include converting all of them, except for "gadgetfs". |
| 557 | </para> | 557 | </para> |
| 558 | 558 | ||
| 559 | !Edrivers/usb/gadget/f_acm.c | 559 | !Edrivers/usb/gadget/function/f_acm.c |
| 560 | !Edrivers/usb/gadget/f_ecm.c | 560 | !Edrivers/usb/gadget/function/f_ecm.c |
| 561 | !Edrivers/usb/gadget/f_subset.c | 561 | !Edrivers/usb/gadget/function/f_subset.c |
| 562 | !Edrivers/usb/gadget/f_obex.c | 562 | !Edrivers/usb/gadget/function/f_obex.c |
| 563 | !Edrivers/usb/gadget/f_serial.c | 563 | !Edrivers/usb/gadget/function/f_serial.c |
| 564 | 564 | ||
| 565 | </sect1> | 565 | </sect1> |
| 566 | 566 | ||
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..ef4936ff626c 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 | u32 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/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..a186afeaa700 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 += -I$(PWD)/drivers/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..6d91f21b52a6 --- /dev/null +++ b/drivers/usb/gadget/function/Makefile | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | # | ||
| 2 | # USB peripheral controller drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | ccflags-y := -I$(PWD)/drivers/usb/gadget/ | ||
| 6 | ccflags-y += -I$(PWD)/drivers/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..f2b781773eed 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c | |||
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..d50adda913cf 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); |
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..71e896d4c5ae 100644 --- a/drivers/usb/gadget/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c | |||
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..a11aad5635df --- /dev/null +++ b/drivers/usb/gadget/legacy/Makefile | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | # | ||
| 2 | # USB gadget drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | ccflags-y := -I$(PWD)/drivers/usb/gadget/ | ||
| 6 | ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ | ||
| 7 | ccflags-y += -I$(PWD)/drivers/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..986fc511a2ed 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c | |||
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..2e4ce7704908 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/legacy/inode.c | |||
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..5151f947a4f5 --- /dev/null +++ b/drivers/usb/gadget/udc/Kconfig | |||
| @@ -0,0 +1,385 @@ | |||
| 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 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 | # | ||
| 357 | # LAST -- dummy/emulated controller | ||
| 358 | # | ||
| 359 | |||
| 360 | config USB_DUMMY_HCD | ||
| 361 | tristate "Dummy HCD (DEVELOPMENT)" | ||
| 362 | depends on USB=y || (USB=m && USB_GADGET=m) | ||
| 363 | help | ||
| 364 | This host controller driver emulates USB, looping all data transfer | ||
| 365 | requests back to a USB "gadget driver" in the same host. The host | ||
| 366 | side is the master; the gadget side is the slave. Gadget drivers | ||
| 367 | can be high, full, or low speed; and they have access to endpoints | ||
| 368 | like those from NET2280, PXA2xx, or SA1100 hardware. | ||
| 369 | |||
| 370 | This may help in some stages of creating a driver to embed in a | ||
| 371 | Linux device, since it lets you debug several parts of the gadget | ||
| 372 | driver without its hardware or drivers being involved. | ||
| 373 | |||
| 374 | Since such a gadget side driver needs to interoperate with a host | ||
| 375 | side Linux-USB device driver, this may help to debug both sides | ||
| 376 | of a USB protocol stack. | ||
| 377 | |||
| 378 | Say "y" to link the driver statically, or "m" to build a | ||
| 379 | dynamically linked module called "dummy_hcd" and force all | ||
| 380 | gadget drivers to also be dynamically linked. | ||
| 381 | |||
| 382 | # NOTE: Please keep dummy_hcd LAST so that "real hardware" appears | ||
| 383 | # first and will be selected by default. | ||
| 384 | |||
| 385 | 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..906e65f0e4fa 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
| @@ -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..d40255f784df 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; |
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 040fb169b162..040fb169b162 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c | |||
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..eb8c3bedb57a 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c | |||
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..46008421c1ec 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 (!reg) |
| 1882 | dev_err(&pdev->dev, "platform_get_resource error.\n"); | 1872 | return -ENODEV; |
| 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/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/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..ea9e705555df 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c | |||
| @@ -253,11 +253,13 @@ 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), |
| 262 | GFP_KERNEL); | ||
| 261 | if (!gpio_vbus->phy.otg) { | 263 | if (!gpio_vbus->phy.otg) { |
| 262 | kfree(gpio_vbus); | 264 | kfree(gpio_vbus); |
| 263 | return -ENOMEM; | 265 | return -ENOMEM; |
| @@ -274,11 +276,11 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
| 274 | gpio_vbus->phy.otg->phy = &gpio_vbus->phy; | 276 | gpio_vbus->phy.otg->phy = &gpio_vbus->phy; |
| 275 | gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; | 277 | gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; |
| 276 | 278 | ||
| 277 | err = gpio_request(gpio, "vbus_detect"); | 279 | err = devm_gpio_request(&pdev->dev, gpio, "vbus_detect"); |
| 278 | if (err) { | 280 | if (err) { |
| 279 | dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", | 281 | dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", |
| 280 | gpio, err); | 282 | gpio, err); |
| 281 | goto err_gpio; | 283 | return err; |
| 282 | } | 284 | } |
| 283 | gpio_direction_input(gpio); | 285 | gpio_direction_input(gpio); |
| 284 | 286 | ||
| @@ -296,27 +298,27 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
| 296 | /* if data line pullup is in use, initialize it to "not pulling up" */ | 298 | /* if data line pullup is in use, initialize it to "not pulling up" */ |
| 297 | gpio = pdata->gpio_pullup; | 299 | gpio = pdata->gpio_pullup; |
| 298 | if (gpio_is_valid(gpio)) { | 300 | if (gpio_is_valid(gpio)) { |
| 299 | err = gpio_request(gpio, "udc_pullup"); | 301 | err = devm_gpio_request(&pdev->dev, gpio, "udc_pullup"); |
| 300 | if (err) { | 302 | if (err) { |
| 301 | dev_err(&pdev->dev, | 303 | dev_err(&pdev->dev, |
| 302 | "can't request pullup gpio %d, err: %d\n", | 304 | "can't request pullup gpio %d, err: %d\n", |
| 303 | gpio, err); | 305 | gpio, err); |
| 304 | gpio_free(pdata->gpio_vbus); | 306 | return err; |
| 305 | goto err_gpio; | ||
| 306 | } | 307 | } |
| 307 | gpio_direction_output(gpio, pdata->gpio_pullup_inverted); | 308 | gpio_direction_output(gpio, pdata->gpio_pullup_inverted); |
| 308 | } | 309 | } |
| 309 | 310 | ||
| 310 | err = request_irq(irq, gpio_vbus_irq, irqflags, "vbus_detect", pdev); | 311 | err = devm_request_irq(&pdev->dev, irq, gpio_vbus_irq, irqflags, |
| 312 | "vbus_detect", pdev); | ||
| 311 | if (err) { | 313 | if (err) { |
| 312 | dev_err(&pdev->dev, "can't request irq %i, err: %d\n", | 314 | dev_err(&pdev->dev, "can't request irq %i, err: %d\n", |
| 313 | irq, err); | 315 | irq, err); |
| 314 | goto err_irq; | 316 | return err; |
| 315 | } | 317 | } |
| 316 | 318 | ||
| 317 | INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); | 319 | INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); |
| 318 | 320 | ||
| 319 | gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); | 321 | gpio_vbus->vbus_draw = devm_regulator_get(&pdev->dev, "vbus_draw"); |
| 320 | if (IS_ERR(gpio_vbus->vbus_draw)) { | 322 | if (IS_ERR(gpio_vbus->vbus_draw)) { |
| 321 | dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", | 323 | dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", |
| 322 | PTR_ERR(gpio_vbus->vbus_draw)); | 324 | PTR_ERR(gpio_vbus->vbus_draw)); |
| @@ -328,44 +330,23 @@ static int gpio_vbus_probe(struct platform_device *pdev) | |||
| 328 | if (err) { | 330 | if (err) { |
| 329 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", | 331 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", |
| 330 | err); | 332 | err); |
| 331 | goto err_otg; | 333 | return err; |
| 332 | } | 334 | } |
| 333 | 335 | ||
| 334 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 336 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
| 335 | 337 | ||
| 336 | return 0; | 338 | 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 | } | 339 | } |
| 349 | 340 | ||
| 350 | static int gpio_vbus_remove(struct platform_device *pdev) | 341 | static int gpio_vbus_remove(struct platform_device *pdev) |
| 351 | { | 342 | { |
| 352 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | 343 | 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 | 344 | ||
| 356 | device_init_wakeup(&pdev->dev, 0); | 345 | device_init_wakeup(&pdev->dev, 0); |
| 357 | cancel_delayed_work_sync(&gpio_vbus->work); | 346 | cancel_delayed_work_sync(&gpio_vbus->work); |
| 358 | regulator_put(gpio_vbus->vbus_draw); | ||
| 359 | 347 | ||
| 360 | usb_remove_phy(&gpio_vbus->phy); | 348 | usb_remove_phy(&gpio_vbus->phy); |
| 361 | 349 | ||
| 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; | 350 | return 0; |
| 370 | } | 351 | } |
| 371 | 352 | ||
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index c929370cdaa6..e4108eec5ef4 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"); |
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 50dc69e1666f..13b4fa287da8 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c | |||
| @@ -962,7 +962,7 @@ static const struct tegra_phy_soc_config tegra30_soc_config = { | |||
| 962 | .requires_extra_tuning_parameters = true, | 962 | .requires_extra_tuning_parameters = true, |
| 963 | }; | 963 | }; |
| 964 | 964 | ||
| 965 | static struct of_device_id tegra_usb_phy_id_table[] = { | 965 | static const struct of_device_id tegra_usb_phy_id_table[] = { |
| 966 | { .compatible = "nvidia,tegra30-usb-phy", .data = &tegra30_soc_config }, | 966 | { .compatible = "nvidia,tegra30-usb-phy", .data = &tegra30_soc_config }, |
| 967 | { .compatible = "nvidia,tegra20-usb-phy", .data = &tegra20_soc_config }, | 967 | { .compatible = "nvidia,tegra20-usb-phy", .data = &tegra20_soc_config }, |
| 968 | { }, | 968 | { }, |
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/include/linux/usb/composite.h b/include/linux/usb/composite.h index 7373203140e7..c330f5ef42cf 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h | |||
| @@ -386,6 +386,21 @@ struct usb_composite_driver { | |||
| 386 | 386 | ||
| 387 | extern int usb_composite_probe(struct usb_composite_driver *driver); | 387 | extern int usb_composite_probe(struct usb_composite_driver *driver); |
| 388 | extern void usb_composite_unregister(struct usb_composite_driver *driver); | 388 | extern void usb_composite_unregister(struct usb_composite_driver *driver); |
| 389 | |||
| 390 | /** | ||
| 391 | * module_usb_composite_driver() - Helper macro for registering a USB gadget | ||
| 392 | * composite driver | ||
| 393 | * @__usb_composite_driver: usb_composite_driver struct | ||
| 394 | * | ||
| 395 | * Helper macro for USB gadget composite drivers which do not do anything | ||
| 396 | * special in module init/exit. This eliminates a lot of boilerplate. Each | ||
| 397 | * module may only use this macro once, and calling it replaces module_init() | ||
| 398 | * and module_exit() | ||
| 399 | */ | ||
| 400 | #define module_usb_composite_driver(__usb_composite_driver) \ | ||
| 401 | module_driver(__usb_composite_driver, usb_composite_probe, \ | ||
| 402 | usb_composite_unregister) | ||
| 403 | |||
| 389 | extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); | 404 | extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); |
| 390 | extern int composite_dev_prepare(struct usb_composite_driver *composite, | 405 | extern int composite_dev_prepare(struct usb_composite_driver *composite, |
| 391 | struct usb_composite_dev *cdev); | 406 | struct usb_composite_dev *cdev); |
diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index e452ba6ec6bd..d5952bb66752 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h | |||
| @@ -153,6 +153,9 @@ struct renesas_usbhs_driver_param { | |||
| 153 | */ | 153 | */ |
| 154 | int pio_dma_border; /* default is 64byte */ | 154 | int pio_dma_border; /* default is 64byte */ |
| 155 | 155 | ||
| 156 | u32 type; | ||
| 157 | u32 enable_gpio; | ||
| 158 | |||
| 156 | /* | 159 | /* |
| 157 | * option: | 160 | * option: |
| 158 | */ | 161 | */ |
| @@ -160,6 +163,9 @@ struct renesas_usbhs_driver_param { | |||
| 160 | u32 has_sudmac:1; /* for SUDMAC */ | 163 | u32 has_sudmac:1; /* for SUDMAC */ |
| 161 | }; | 164 | }; |
| 162 | 165 | ||
| 166 | #define USBHS_TYPE_R8A7790 1 | ||
| 167 | #define USBHS_TYPE_R8A7791 2 | ||
| 168 | |||
| 163 | /* | 169 | /* |
| 164 | * option: | 170 | * option: |
| 165 | * | 171 | * |
diff --git a/include/linux/usb/usb338x.h b/include/linux/usb/usb338x.h new file mode 100644 index 000000000000..f92eb635b9d3 --- /dev/null +++ b/include/linux/usb/usb338x.h | |||
| @@ -0,0 +1,199 @@ | |||
| 1 | /* | ||
| 2 | * USB 338x super/high/full speed USB device controller. | ||
| 3 | * Unlike many such controllers, this one talks PCI. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) | ||
| 6 | * Copyright (C) 2003 David Brownell | ||
| 7 | * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __LINUX_USB_USB338X_H | ||
| 22 | #define __LINUX_USB_USB338X_H | ||
| 23 | |||
| 24 | #include <linux/usb/net2280.h> | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Extra defined bits for net2280 registers | ||
| 28 | */ | ||
| 29 | #define SCRATCH 0x0b | ||
| 30 | |||
| 31 | #define DEFECT7374_FSM_FIELD 28 | ||
| 32 | #define SUPER_SPEED 8 | ||
| 33 | #define DMA_REQUEST_OUTSTANDING 5 | ||
| 34 | #define DMA_PAUSE_DONE_INTERRUPT 26 | ||
| 35 | #define SET_ISOCHRONOUS_DELAY 24 | ||
| 36 | #define SET_SEL 22 | ||
| 37 | #define SUPER_SPEED_MODE 8 | ||
| 38 | |||
| 39 | /*ep_cfg*/ | ||
| 40 | #define MAX_BURST_SIZE 24 | ||
| 41 | #define EP_FIFO_BYTE_COUNT 16 | ||
| 42 | #define IN_ENDPOINT_ENABLE 14 | ||
| 43 | #define IN_ENDPOINT_TYPE 12 | ||
| 44 | #define OUT_ENDPOINT_ENABLE 10 | ||
| 45 | #define OUT_ENDPOINT_TYPE 8 | ||
| 46 | |||
| 47 | struct usb338x_usb_ext_regs { | ||
| 48 | u32 usbclass; | ||
| 49 | #define DEVICE_PROTOCOL 16 | ||
| 50 | #define DEVICE_SUB_CLASS 8 | ||
| 51 | #define DEVICE_CLASS 0 | ||
| 52 | u32 ss_sel; | ||
| 53 | #define U2_SYSTEM_EXIT_LATENCY 8 | ||
| 54 | #define U1_SYSTEM_EXIT_LATENCY 0 | ||
| 55 | u32 ss_del; | ||
| 56 | #define U2_DEVICE_EXIT_LATENCY 8 | ||
| 57 | #define U1_DEVICE_EXIT_LATENCY 0 | ||
| 58 | u32 usb2lpm; | ||
| 59 | #define USB_L1_LPM_HIRD 2 | ||
| 60 | #define USB_L1_LPM_REMOTE_WAKE 1 | ||
| 61 | #define USB_L1_LPM_SUPPORT 0 | ||
| 62 | u32 usb3belt; | ||
| 63 | #define BELT_MULTIPLIER 10 | ||
| 64 | #define BEST_EFFORT_LATENCY_TOLERANCE 0 | ||
| 65 | u32 usbctl2; | ||
| 66 | #define LTM_ENABLE 7 | ||
| 67 | #define U2_ENABLE 6 | ||
| 68 | #define U1_ENABLE 5 | ||
| 69 | #define FUNCTION_SUSPEND 4 | ||
| 70 | #define USB3_CORE_ENABLE 3 | ||
| 71 | #define USB2_CORE_ENABLE 2 | ||
| 72 | #define SERIAL_NUMBER_STRING_ENABLE 0 | ||
| 73 | u32 in_timeout; | ||
| 74 | #define GPEP3_TIMEOUT 19 | ||
| 75 | #define GPEP2_TIMEOUT 18 | ||
| 76 | #define GPEP1_TIMEOUT 17 | ||
| 77 | #define GPEP0_TIMEOUT 16 | ||
| 78 | #define GPEP3_TIMEOUT_VALUE 13 | ||
| 79 | #define GPEP3_TIMEOUT_ENABLE 12 | ||
| 80 | #define GPEP2_TIMEOUT_VALUE 9 | ||
| 81 | #define GPEP2_TIMEOUT_ENABLE 8 | ||
| 82 | #define GPEP1_TIMEOUT_VALUE 5 | ||
| 83 | #define GPEP1_TIMEOUT_ENABLE 4 | ||
| 84 | #define GPEP0_TIMEOUT_VALUE 1 | ||
| 85 | #define GPEP0_TIMEOUT_ENABLE 0 | ||
| 86 | u32 isodelay; | ||
| 87 | #define ISOCHRONOUS_DELAY 0 | ||
| 88 | } __packed; | ||
| 89 | |||
| 90 | struct usb338x_fifo_regs { | ||
| 91 | /* offset 0x0500, 0x0520, 0x0540, 0x0560, 0x0580 */ | ||
| 92 | u32 ep_fifo_size_base; | ||
| 93 | #define IN_FIFO_BASE_ADDRESS 22 | ||
| 94 | #define IN_FIFO_SIZE 16 | ||
| 95 | #define OUT_FIFO_BASE_ADDRESS 6 | ||
| 96 | #define OUT_FIFO_SIZE 0 | ||
| 97 | u32 ep_fifo_out_wrptr; | ||
| 98 | u32 ep_fifo_out_rdptr; | ||
| 99 | u32 ep_fifo_in_wrptr; | ||
| 100 | u32 ep_fifo_in_rdptr; | ||
| 101 | u32 unused[3]; | ||
| 102 | } __packed; | ||
| 103 | |||
| 104 | |||
| 105 | /* Link layer */ | ||
| 106 | struct usb338x_ll_regs { | ||
| 107 | /* offset 0x700 */ | ||
| 108 | u32 ll_ltssm_ctrl1; | ||
| 109 | u32 ll_ltssm_ctrl2; | ||
| 110 | u32 ll_ltssm_ctrl3; | ||
| 111 | u32 unused[2]; | ||
| 112 | u32 ll_general_ctrl0; | ||
| 113 | u32 ll_general_ctrl1; | ||
| 114 | #define PM_U3_AUTO_EXIT 29 | ||
| 115 | #define PM_U2_AUTO_EXIT 28 | ||
| 116 | #define PM_U1_AUTO_EXIT 27 | ||
| 117 | #define PM_FORCE_U2_ENTRY 26 | ||
| 118 | #define PM_FORCE_U1_ENTRY 25 | ||
| 119 | #define PM_LGO_COLLISION_SEND_LAU 24 | ||
| 120 | #define PM_DIR_LINK_REJECT 23 | ||
| 121 | #define PM_FORCE_LINK_ACCEPT 22 | ||
| 122 | #define PM_DIR_ENTRY_U3 20 | ||
| 123 | #define PM_DIR_ENTRY_U2 19 | ||
| 124 | #define PM_DIR_ENTRY_U1 18 | ||
| 125 | #define PM_U2_ENABLE 17 | ||
| 126 | #define PM_U1_ENABLE 16 | ||
| 127 | #define SKP_THRESHOLD_ADJUST_FMW 8 | ||
| 128 | #define RESEND_DPP_ON_LRTY_FMW 7 | ||
| 129 | #define DL_BIT_VALUE_FMW 6 | ||
| 130 | #define FORCE_DL_BIT 5 | ||
| 131 | u32 ll_general_ctrl2; | ||
| 132 | #define SELECT_INVERT_LANE_POLARITY 7 | ||
| 133 | #define FORCE_INVERT_LANE_POLARITY 6 | ||
| 134 | u32 ll_general_ctrl3; | ||
| 135 | u32 ll_general_ctrl4; | ||
| 136 | u32 ll_error_gen; | ||
| 137 | } __packed; | ||
| 138 | |||
| 139 | struct usb338x_ll_lfps_regs { | ||
| 140 | /* offset 0x748 */ | ||
| 141 | u32 ll_lfps_5; | ||
| 142 | #define TIMER_LFPS_6US 16 | ||
| 143 | u32 ll_lfps_6; | ||
| 144 | #define TIMER_LFPS_80US 0 | ||
| 145 | } __packed; | ||
| 146 | |||
| 147 | struct usb338x_ll_tsn_regs { | ||
| 148 | /* offset 0x77C */ | ||
| 149 | u32 ll_tsn_counters_2; | ||
| 150 | #define HOT_TX_NORESET_TS2 24 | ||
| 151 | u32 ll_tsn_counters_3; | ||
| 152 | #define HOT_RX_RESET_TS2 0 | ||
| 153 | } __packed; | ||
| 154 | |||
| 155 | struct usb338x_ll_chi_regs { | ||
| 156 | /* offset 0x79C */ | ||
| 157 | u32 ll_tsn_chicken_bit; | ||
| 158 | #define RECOVERY_IDLE_TO_RECOVER_FMW 3 | ||
| 159 | } __packed; | ||
| 160 | |||
| 161 | /* protocol layer */ | ||
| 162 | struct usb338x_pl_regs { | ||
| 163 | /* offset 0x800 */ | ||
| 164 | u32 pl_reg_1; | ||
| 165 | u32 pl_reg_2; | ||
| 166 | u32 pl_reg_3; | ||
| 167 | u32 pl_reg_4; | ||
| 168 | u32 pl_ep_ctrl; | ||
| 169 | /* Protocol Layer Endpoint Control*/ | ||
| 170 | #define PL_EP_CTRL 0x810 | ||
| 171 | #define ENDPOINT_SELECT 0 | ||
| 172 | /* [4:0] */ | ||
| 173 | #define EP_INITIALIZED 16 | ||
| 174 | #define SEQUENCE_NUMBER_RESET 17 | ||
| 175 | #define CLEAR_ACK_ERROR_CODE 20 | ||
| 176 | u32 pl_reg_6; | ||
| 177 | u32 pl_reg_7; | ||
| 178 | u32 pl_reg_8; | ||
| 179 | u32 pl_ep_status_1; | ||
| 180 | /* Protocol Layer Endpoint Status 1*/ | ||
| 181 | #define PL_EP_STATUS_1 0x820 | ||
| 182 | #define STATE 16 | ||
| 183 | #define ACK_GOOD_NORMAL 0x11 | ||
| 184 | #define ACK_GOOD_MORE_ACKS_TO_COME 0x16 | ||
| 185 | u32 pl_ep_status_2; | ||
| 186 | u32 pl_ep_status_3; | ||
| 187 | /* Protocol Layer Endpoint Status 3*/ | ||
| 188 | #define PL_EP_STATUS_3 0x828 | ||
| 189 | #define SEQUENCE_NUMBER 0 | ||
| 190 | u32 pl_ep_status_4; | ||
| 191 | /* Protocol Layer Endpoint Status 4*/ | ||
| 192 | #define PL_EP_STATUS_4 0x82c | ||
| 193 | u32 pl_ep_cfg_4; | ||
| 194 | /* Protocol Layer Endpoint Configuration 4*/ | ||
| 195 | #define PL_EP_CFG_4 0x830 | ||
| 196 | #define NON_CTRL_IN_TOLERATE_BAD_DIR 6 | ||
| 197 | } __packed; | ||
| 198 | |||
| 199 | #endif /* __LINUX_USB_USB338X_H */ | ||
diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index 24b68c59dcf8..0154b2859fd7 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h | |||
| @@ -18,10 +18,9 @@ enum functionfs_flags { | |||
| 18 | FUNCTIONFS_HAS_FS_DESC = 1, | 18 | FUNCTIONFS_HAS_FS_DESC = 1, |
| 19 | FUNCTIONFS_HAS_HS_DESC = 2, | 19 | FUNCTIONFS_HAS_HS_DESC = 2, |
| 20 | FUNCTIONFS_HAS_SS_DESC = 4, | 20 | FUNCTIONFS_HAS_SS_DESC = 4, |
| 21 | FUNCTIONFS_HAS_MS_OS_DESC = 8, | ||
| 21 | }; | 22 | }; |
| 22 | 23 | ||
| 23 | #ifndef __KERNEL__ | ||
| 24 | |||
| 25 | /* Descriptor of an non-audio endpoint */ | 24 | /* Descriptor of an non-audio endpoint */ |
| 26 | struct usb_endpoint_descriptor_no_audio { | 25 | struct usb_endpoint_descriptor_no_audio { |
| 27 | __u8 bLength; | 26 | __u8 bLength; |
| @@ -41,6 +40,37 @@ struct usb_functionfs_descs_head { | |||
| 41 | __le32 hs_count; | 40 | __le32 hs_count; |
| 42 | } __attribute__((packed, deprecated)); | 41 | } __attribute__((packed, deprecated)); |
| 43 | 42 | ||
| 43 | /* MS OS Descriptor header */ | ||
| 44 | struct usb_os_desc_header { | ||
| 45 | __u8 interface; | ||
| 46 | __le32 dwLength; | ||
| 47 | __le16 bcdVersion; | ||
| 48 | __le16 wIndex; | ||
| 49 | union { | ||
| 50 | struct { | ||
| 51 | __u8 bCount; | ||
| 52 | __u8 Reserved; | ||
| 53 | }; | ||
| 54 | __le16 wCount; | ||
| 55 | }; | ||
| 56 | } __attribute__((packed)); | ||
| 57 | |||
| 58 | struct usb_ext_compat_desc { | ||
| 59 | __u8 bFirstInterfaceNumber; | ||
| 60 | __u8 Reserved1; | ||
| 61 | __u8 CompatibleID[8]; | ||
| 62 | __u8 SubCompatibleID[8]; | ||
| 63 | __u8 Reserved2[6]; | ||
| 64 | }; | ||
| 65 | |||
| 66 | struct usb_ext_prop_desc { | ||
| 67 | __le32 dwSize; | ||
| 68 | __le32 dwPropertyDataType; | ||
| 69 | __le16 wPropertyNameLength; | ||
| 70 | } __attribute__((packed)); | ||
| 71 | |||
| 72 | #ifndef __KERNEL__ | ||
| 73 | |||
| 44 | /* | 74 | /* |
| 45 | * Descriptors format: | 75 | * Descriptors format: |
| 46 | * | 76 | * |
| @@ -52,9 +82,11 @@ struct usb_functionfs_descs_head { | |||
| 52 | * | | fs_count | LE32 | number of full-speed descriptors | | 82 | * | | fs_count | LE32 | number of full-speed descriptors | |
| 53 | * | | hs_count | LE32 | number of high-speed descriptors | | 83 | * | | hs_count | LE32 | number of high-speed descriptors | |
| 54 | * | | ss_count | LE32 | number of super-speed descriptors | | 84 | * | | ss_count | LE32 | number of super-speed descriptors | |
| 85 | * | | os_count | LE32 | number of MS OS descriptors | | ||
| 55 | * | | fs_descrs | Descriptor[] | list of full-speed descriptors | | 86 | * | | fs_descrs | Descriptor[] | list of full-speed descriptors | |
| 56 | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | | 87 | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | |
| 57 | * | | ss_descrs | Descriptor[] | list of super-speed descriptors | | 88 | * | | ss_descrs | Descriptor[] | list of super-speed descriptors | |
| 89 | * | | os_descrs | OSDesc[] | list of MS OS descriptors | | ||
| 58 | * | 90 | * |
| 59 | * Depending on which flags are set, various fields may be missing in the | 91 | * Depending on which flags are set, various fields may be missing in the |
| 60 | * structure. Any flags that are not recognised cause the whole block to be | 92 | * structure. Any flags that are not recognised cause the whole block to be |
| @@ -81,6 +113,52 @@ struct usb_functionfs_descs_head { | |||
| 81 | * | 0 | bLength | U8 | length of the descriptor | | 113 | * | 0 | bLength | U8 | length of the descriptor | |
| 82 | * | 1 | bDescriptorType | U8 | descriptor type | | 114 | * | 1 | bDescriptorType | U8 | descriptor type | |
| 83 | * | 2 | payload | | descriptor's payload | | 115 | * | 2 | payload | | descriptor's payload | |
| 116 | * | ||
| 117 | * OSDesc[] is an array of valid MS OS Feature Descriptors which have one of | ||
| 118 | * the following formats: | ||
| 119 | * | ||
| 120 | * | off | name | type | description | | ||
| 121 | * |-----+-----------------+------+--------------------------| | ||
| 122 | * | 0 | inteface | U8 | related interface number | | ||
| 123 | * | 1 | dwLength | U32 | length of the descriptor | | ||
| 124 | * | 5 | bcdVersion | U16 | currently supported: 1 | | ||
| 125 | * | 7 | wIndex | U16 | currently supported: 4 | | ||
| 126 | * | 9 | bCount | U8 | number of ext. compat. | | ||
| 127 | * | 10 | Reserved | U8 | 0 | | ||
| 128 | * | 11 | ExtCompat[] | | list of ext. compat. d. | | ||
| 129 | * | ||
| 130 | * | off | name | type | description | | ||
| 131 | * |-----+-----------------+------+--------------------------| | ||
| 132 | * | 0 | inteface | U8 | related interface number | | ||
| 133 | * | 1 | dwLength | U32 | length of the descriptor | | ||
| 134 | * | 5 | bcdVersion | U16 | currently supported: 1 | | ||
| 135 | * | 7 | wIndex | U16 | currently supported: 5 | | ||
| 136 | * | 9 | wCount | U16 | number of ext. compat. | | ||
| 137 | * | 11 | ExtProp[] | | list of ext. prop. d. | | ||
| 138 | * | ||
| 139 | * ExtCompat[] is an array of valid Extended Compatiblity descriptors | ||
| 140 | * which have the following format: | ||
| 141 | * | ||
| 142 | * | off | name | type | description | | ||
| 143 | * |-----+-----------------------+------+-------------------------------------| | ||
| 144 | * | 0 | bFirstInterfaceNumber | U8 | index of the interface or of the 1st| | ||
| 145 | * | | | | interface in an IAD group | | ||
| 146 | * | 1 | Reserved | U8 | 0 | | ||
| 147 | * | 2 | CompatibleID | U8[8]| compatible ID string | | ||
| 148 | * | 10 | SubCompatibleID | U8[8]| subcompatible ID string | | ||
| 149 | * | 18 | Reserved | U8[6]| 0 | | ||
| 150 | * | ||
| 151 | * ExtProp[] is an array of valid Extended Properties descriptors | ||
| 152 | * which have the following format: | ||
| 153 | * | ||
| 154 | * | off | name | type | description | | ||
| 155 | * |-----+-----------------------+------+-------------------------------------| | ||
| 156 | * | 0 | dwSize | U32 | length of the descriptor | | ||
| 157 | * | 4 | dwPropertyDataType | U32 | 1..7 | | ||
| 158 | * | 8 | wPropertyNameLength | U16 | bPropertyName length (NL) | | ||
| 159 | * | 10 | bPropertyName |U8[NL]| name of this property | | ||
| 160 | * |10+NL| dwPropertyDataLength | U32 | bPropertyData length (DL) | | ||
| 161 | * |14+NL| bProperty |U8[DL]| payload of this property | | ||
| 84 | */ | 162 | */ |
| 85 | 163 | ||
| 86 | struct usb_functionfs_strings_head { | 164 | struct usb_functionfs_strings_head { |
diff --git a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c index 87216a0c4a8b..af4b0508be77 100644 --- a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c +++ b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c | |||
| @@ -1,3 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This is free and unencumbered software released into the public domain. | ||
| 3 | * | ||
| 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or | ||
| 5 | * distribute this software, either in source code form or as a compiled | ||
| 6 | * binary, for any purpose, commercial or non-commercial, and by any | ||
| 7 | * means. | ||
| 8 | * | ||
| 9 | * In jurisdictions that recognize copyright laws, the author or authors | ||
| 10 | * of this software dedicate any and all copyright interest in the | ||
| 11 | * software to the public domain. We make this dedication for the benefit | ||
| 12 | * of the public at large and to the detriment of our heirs and | ||
| 13 | * successors. We intend this dedication to be an overt act of | ||
| 14 | * relinquishment in perpetuity of all present and future rights to this | ||
| 15 | * software under copyright law. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | * For more information, please refer to <http://unlicense.org/> | ||
| 26 | */ | ||
| 27 | |||
| 1 | #define _BSD_SOURCE /* for endian.h */ | 28 | #define _BSD_SOURCE /* for endian.h */ |
| 2 | 29 | ||
| 3 | #include <endian.h> | 30 | #include <endian.h> |
| @@ -27,7 +54,9 @@ | |||
| 27 | /******************** Descriptors and Strings *******************************/ | 54 | /******************** Descriptors and Strings *******************************/ |
| 28 | 55 | ||
| 29 | static const struct { | 56 | static const struct { |
| 30 | struct usb_functionfs_descs_head header; | 57 | struct usb_functionfs_descs_head_v2 header; |
| 58 | __le32 fs_count; | ||
| 59 | __le32 hs_count; | ||
| 31 | struct { | 60 | struct { |
| 32 | struct usb_interface_descriptor intf; | 61 | struct usb_interface_descriptor intf; |
| 33 | struct usb_endpoint_descriptor_no_audio bulk_sink; | 62 | struct usb_endpoint_descriptor_no_audio bulk_sink; |
| @@ -35,11 +64,12 @@ static const struct { | |||
| 35 | } __attribute__ ((__packed__)) fs_descs, hs_descs; | 64 | } __attribute__ ((__packed__)) fs_descs, hs_descs; |
| 36 | } __attribute__ ((__packed__)) descriptors = { | 65 | } __attribute__ ((__packed__)) descriptors = { |
| 37 | .header = { | 66 | .header = { |
| 38 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC), | 67 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), |
| 68 | .flags = htole32(FUNCTIONFS_HAS_FS_DESC | | ||
| 69 | FUNCTIONFS_HAS_HS_DESC), | ||
| 39 | .length = htole32(sizeof(descriptors)), | 70 | .length = htole32(sizeof(descriptors)), |
| 40 | .fs_count = 3, | ||
| 41 | .hs_count = 3, | ||
| 42 | }, | 71 | }, |
| 72 | .fs_count = htole32(3), | ||
| 43 | .fs_descs = { | 73 | .fs_descs = { |
| 44 | .intf = { | 74 | .intf = { |
| 45 | .bLength = sizeof(descriptors.fs_descs.intf), | 75 | .bLength = sizeof(descriptors.fs_descs.intf), |
| @@ -61,6 +91,7 @@ static const struct { | |||
| 61 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 91 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 62 | }, | 92 | }, |
| 63 | }, | 93 | }, |
| 94 | .hs_count = htole32(3), | ||
| 64 | .hs_descs = { | 95 | .hs_descs = { |
| 65 | .intf = { | 96 | .intf = { |
| 66 | .bLength = sizeof(descriptors.hs_descs.intf), | 97 | .bLength = sizeof(descriptors.hs_descs.intf), |
diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/test.c b/tools/usb/ffs-aio-example/multibuff/host_app/test.c index b0ad8747d03f..daa3abe6bebd 100644 --- a/tools/usb/ffs-aio-example/multibuff/host_app/test.c +++ b/tools/usb/ffs-aio-example/multibuff/host_app/test.c | |||
| @@ -1,3 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This is free and unencumbered software released into the public domain. | ||
| 3 | * | ||
| 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or | ||
| 5 | * distribute this software, either in source code form or as a compiled | ||
| 6 | * binary, for any purpose, commercial or non-commercial, and by any | ||
| 7 | * means. | ||
| 8 | * | ||
| 9 | * In jurisdictions that recognize copyright laws, the author or authors | ||
| 10 | * of this software dedicate any and all copyright interest in the | ||
| 11 | * software to the public domain. We make this dedication for the benefit | ||
| 12 | * of the public at large and to the detriment of our heirs and | ||
| 13 | * successors. We intend this dedication to be an overt act of | ||
| 14 | * relinquishment in perpetuity of all present and future rights to this | ||
| 15 | * software under copyright law. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | * For more information, please refer to <http://unlicense.org/> | ||
| 26 | */ | ||
| 27 | |||
| 1 | #include <libusb.h> | 28 | #include <libusb.h> |
| 2 | #include <stdio.h> | 29 | #include <stdio.h> |
| 3 | #include <string.h> | 30 | #include <string.h> |
diff --git a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c index f558664a3317..adc310a6d489 100644 --- a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c +++ b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c | |||
| @@ -1,3 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This is free and unencumbered software released into the public domain. | ||
| 3 | * | ||
| 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or | ||
| 5 | * distribute this software, either in source code form or as a compiled | ||
| 6 | * binary, for any purpose, commercial or non-commercial, and by any | ||
| 7 | * means. | ||
| 8 | * | ||
| 9 | * In jurisdictions that recognize copyright laws, the author or authors | ||
| 10 | * of this software dedicate any and all copyright interest in the | ||
| 11 | * software to the public domain. We make this dedication for the benefit | ||
| 12 | * of the public at large and to the detriment of our heirs and | ||
| 13 | * successors. We intend this dedication to be an overt act of | ||
| 14 | * relinquishment in perpetuity of all present and future rights to this | ||
| 15 | * software under copyright law. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | * For more information, please refer to <http://unlicense.org/> | ||
| 26 | */ | ||
| 27 | |||
| 1 | #define _BSD_SOURCE /* for endian.h */ | 28 | #define _BSD_SOURCE /* for endian.h */ |
| 2 | 29 | ||
| 3 | #include <endian.h> | 30 | #include <endian.h> |
| @@ -25,7 +52,9 @@ | |||
| 25 | /******************** Descriptors and Strings *******************************/ | 52 | /******************** Descriptors and Strings *******************************/ |
| 26 | 53 | ||
| 27 | static const struct { | 54 | static const struct { |
| 28 | struct usb_functionfs_descs_head header; | 55 | struct usb_functionfs_descs_head_v2 header; |
| 56 | __le32 fs_count; | ||
| 57 | __le32 hs_count; | ||
| 29 | struct { | 58 | struct { |
| 30 | struct usb_interface_descriptor intf; | 59 | struct usb_interface_descriptor intf; |
| 31 | struct usb_endpoint_descriptor_no_audio bulk_sink; | 60 | struct usb_endpoint_descriptor_no_audio bulk_sink; |
| @@ -33,11 +62,12 @@ static const struct { | |||
| 33 | } __attribute__ ((__packed__)) fs_descs, hs_descs; | 62 | } __attribute__ ((__packed__)) fs_descs, hs_descs; |
| 34 | } __attribute__ ((__packed__)) descriptors = { | 63 | } __attribute__ ((__packed__)) descriptors = { |
| 35 | .header = { | 64 | .header = { |
| 36 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC), | 65 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), |
| 66 | .flags = htole32(FUNCTIONFS_HAS_FS_DESC | | ||
| 67 | FUNCTIONFS_HAS_HS_DESC), | ||
| 37 | .length = htole32(sizeof(descriptors)), | 68 | .length = htole32(sizeof(descriptors)), |
| 38 | .fs_count = 3, | ||
| 39 | .hs_count = 3, | ||
| 40 | }, | 69 | }, |
| 70 | .fs_count = htole32(3), | ||
| 41 | .fs_descs = { | 71 | .fs_descs = { |
| 42 | .intf = { | 72 | .intf = { |
| 43 | .bLength = sizeof(descriptors.fs_descs.intf), | 73 | .bLength = sizeof(descriptors.fs_descs.intf), |
| @@ -59,6 +89,7 @@ static const struct { | |||
| 59 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 89 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 60 | }, | 90 | }, |
| 61 | }, | 91 | }, |
| 92 | .hs_count = htole32(3), | ||
| 62 | .hs_descs = { | 93 | .hs_descs = { |
| 63 | .intf = { | 94 | .intf = { |
| 64 | .bLength = sizeof(descriptors.hs_descs.intf), | 95 | .bLength = sizeof(descriptors.hs_descs.intf), |
diff --git a/tools/usb/ffs-aio-example/simple/host_app/test.c b/tools/usb/ffs-aio-example/simple/host_app/test.c index 64b6a57d8ca3..acd6332811f3 100644 --- a/tools/usb/ffs-aio-example/simple/host_app/test.c +++ b/tools/usb/ffs-aio-example/simple/host_app/test.c | |||
| @@ -1,3 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This is free and unencumbered software released into the public domain. | ||
| 3 | * | ||
| 4 | * Anyone is free to copy, modify, publish, use, compile, sell, or | ||
| 5 | * distribute this software, either in source code form or as a compiled | ||
| 6 | * binary, for any purpose, commercial or non-commercial, and by any | ||
| 7 | * means. | ||
| 8 | * | ||
| 9 | * In jurisdictions that recognize copyright laws, the author or authors | ||
| 10 | * of this software dedicate any and all copyright interest in the | ||
| 11 | * software to the public domain. We make this dedication for the benefit | ||
| 12 | * of the public at large and to the detriment of our heirs and | ||
| 13 | * successors. We intend this dedication to be an overt act of | ||
| 14 | * relinquishment in perpetuity of all present and future rights to this | ||
| 15 | * software under copyright law. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 23 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | * For more information, please refer to <http://unlicense.org/> | ||
| 26 | */ | ||
| 27 | |||
| 1 | #include <libusb.h> | 28 | #include <libusb.h> |
| 2 | #include <stdio.h> | 29 | #include <stdio.h> |
| 3 | #include <string.h> | 30 | #include <string.h> |
