* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (260 commits) usb: renesas_usbhs: fixup inconsistent return from usbhs_pkt_push() usb/isp1760: Allow to optionally trigger low-level chip reset via GPIOLIB. USB: gadget: midi: memory leak in f_midi_bind_config() USB: gadget: midi: fix range check in f_midi_out_open() QE/FHCI: fixed the CONTROL bug usb: renesas_usbhs: tidyup for smatch warnings USB: Fix USB Kconfig dependency problem on 85xx/QoirQ platforms EHCI: workaround for MosChip controller bug usb: gadget: file_storage: fix race on unloading USB: ftdi_sio.c: Use ftdi async_icount structure for TIOCMIWAIT, as in other drivers USB: ftdi_sio.c:Fill MSR fields of the ftdi async_icount structure USB: ftdi_sio.c: Fill LSR fields of the ftdi async_icount structure USB: ftdi_sio.c:Fill TX field of the ftdi async_icount structure USB: ftdi_sio.c: Fill the RX field of the ftdi async_icount structure USB: ftdi_sio.c: Basic icount infrastructure for ftdi_sio usb/isp1760: Let OF bindings depend on general CONFIG_OF instead of PPC_OF . USB: ftdi_sio: Support TI/Luminary Micro Stellaris BD-ICDI Board USB: Fix runtime wakeup on OHCI xHCI/USB: Make xHCI driver have a BOS descriptor. usb: gadget: add new usb gadget for ACM and mass storage ...
Unified · Split
| @@ -0,0 +1,46 @@ | |||
| 1 | What: /sys/bus/pci/drivers/ehci_hcd/.../companion | ||
| 2 | /sys/bus/usb/devices/usbN/../companion | ||
| 3 | Date: January 2007 | ||
| 4 | KernelVersion: 2.6.21 | ||
| 5 | Contact: Alan Stern <stern@rowland.harvard.edu> | ||
| 6 | Description: | ||
| 7 | PCI-based EHCI USB controllers (i.e., high-speed USB-2.0 | ||
| 8 | controllers) are often implemented along with a set of | ||
| 9 | "companion" full/low-speed USB-1.1 controllers. When a | ||
| 10 | high-speed device is plugged in, the connection is routed | ||
| 11 | to the EHCI controller; when a full- or low-speed device | ||
| 12 | is plugged in, the connection is routed to the companion | ||
| 13 | controller. | ||
| 14 | |||
| 15 | Sometimes you want to force a high-speed device to connect | ||
| 16 | at full speed, which can be accomplished by forcing the | ||
| 17 | connection to be routed to the companion controller. | ||
| 18 | That's what this file does. Writing a port number to the | ||
| 19 | file causes connections on that port to be routed to the | ||
| 20 | companion controller, and writing the negative of a port | ||
| 21 | number returns the port to normal operation. | ||
| 22 | |||
| 23 | For example: To force the high-speed device attached to | ||
| 24 | port 4 on bus 2 to run at full speed: | ||
| 25 | |||
| 26 | echo 4 >/sys/bus/usb/devices/usb2/../companion | ||
| 27 | |||
| 28 | To return the port to high-speed operation: | ||
| 29 | |||
| 30 | echo -4 >/sys/bus/usb/devices/usb2/../companion | ||
| 31 | |||
| 32 | Reading the file gives the list of ports currently forced | ||
| 33 | to the companion controller. | ||
| 34 | |||
| 35 | Note: Some EHCI controllers do not have companions; they | ||
| 36 | may contain an internal "transaction translator" or they | ||
| 37 | may be attached directly to a "rate-matching hub". This | ||
| 38 | mechanism will not work with such controllers. Also, it | ||
| 39 | cannot be used to force a port on a high-speed hub to | ||
| 40 | connect at full speed. | ||
| 41 | |||
| 42 | Note: When this file was first added, it appeared in a | ||
| 43 | different sysfs directory. The location given above is | ||
| 44 | correct for 2.6.35 (and probably several earlier kernel | ||
| 45 | versions as well). | ||
| 46 | |||
| @@ -142,3 +142,18 @@ Description: · 141 unmodified lines | |||
| 142 | such devices. | 142 | such devices. |
| 143 | Users: | 143 | Users: |
| 144 | usb_modeswitch | 144 | usb_modeswitch |
| 145 | |||
| 146 | What: /sys/bus/usb/devices/.../power/usb2_hardware_lpm | ||
| 147 | Date: September 2011 | ||
| 148 | Contact: Andiry Xu <andiry.xu@amd.com> | ||
| 149 | Description: | ||
| 150 | If CONFIG_USB_SUSPEND is set and a USB 2.0 lpm-capable device | ||
| 151 | is plugged in to a xHCI host which support link PM, it will | ||
| 152 | perform a LPM test; if the test is passed and host supports | ||
| 153 | USB2 hardware LPM (xHCI 1.0 feature), USB2 hardware LPM will | ||
| 154 | be enabled for the device and the USB device directory will | ||
| 155 | contain a file named power/usb2_hardware_lpm. The file holds | ||
| 156 | a string value (enable or disable) indicating whether or not | ||
| 157 | USB2 hardware LPM is enabled for the device. Developer can | ||
| 158 | write y/Y/1 or n/N/0 to the file to enable/disable the | ||
| 159 | feature. | ||
| @@ -0,0 +1,45 @@ | |||
| 1 | |||
| 2 | TODO | ||
| 3 | ~~~~~~ | ||
| 4 | Please pick something while reading :) | ||
| 5 | |||
| 6 | - Convert interrupt handler to per-ep-thread-irq | ||
| 7 | |||
| 8 | As it turns out some DWC3-commands ~1ms to complete. Currently we spin | ||
| 9 | until the command completes which is bad. | ||
| 10 | |||
| 11 | Implementation idea: | ||
| 12 | - dwc core implements a demultiplexing irq chip for interrupts per | ||
| 13 | endpoint. The interrupt numbers are allocated during probe and belong | ||
| 14 | to the device. If MSI provides per-endpoint interrupt this dummy | ||
| 15 | interrupt chip can be replaced with "real" interrupts. | ||
| 16 | - interrupts are requested / allocated on usb_ep_enable() and removed on | ||
| 17 | usb_ep_disable(). Worst case are 32 interrupts, the lower limit is two | ||
| 18 | for ep0/1. | ||
| 19 | - dwc3_send_gadget_ep_cmd() will sleep in wait_for_completion_timeout() | ||
| 20 | until the command completes. | ||
| 21 | - the interrupt handler is split into the following pieces: | ||
| 22 | - primary handler of the device | ||
| 23 | goes through every event and calls generic_handle_irq() for event | ||
| 24 | it. On return from generic_handle_irq() in acknowledges the event | ||
| 25 | counter so interrupt goes away (eventually). | ||
| 26 | |||
| 27 | - threaded handler of the device | ||
| 28 | none | ||
| 29 | |||
| 30 | - primary handler of the EP-interrupt | ||
| 31 | reads the event and tries to process it. Everything that requries | ||
| 32 | sleeping is handed over to the Thread. The event is saved in an | ||
| 33 | per-endpoint data-structure. | ||
| 34 | We probably have to pay attention not to process events once we | ||
| 35 | handed something to thread so we don't process event X prio Y | ||
| 36 | where X > Y. | ||
| 37 | |||
| 38 | - threaded handler of the EP-interrupt | ||
| 39 | handles the remaining EP work which might sleep such as waiting | ||
| 40 | for command completion. | ||
| 41 | |||
| 42 | Latency: | ||
| 43 | There should be no increase in latency since the interrupt-thread has a | ||
| 44 | high priority and will be run before an average task in user land | ||
| 45 | (except the user changed priorities). | ||
| @@ -487,3 +487,29 @@ succeed, it may still remain active and thus cause the system to · 486 unmodified lines | |||
| 487 | resume as soon as the system suspend is complete. Or the remote | 487 | resume as soon as the system suspend is complete. Or the remote |
| 488 | wakeup may fail and get lost. Which outcome occurs depends on timing | 488 | wakeup may fail and get lost. Which outcome occurs depends on timing |
| 489 | and on the hardware and firmware design. | 489 | and on the hardware and firmware design. |
| 490 | |||
| 491 | |||
| 492 | xHCI hardware link PM | ||
| 493 | --------------------- | ||
| 494 | |||
| 495 | xHCI host controller provides hardware link power management to usb2.0 | ||
| 496 | (xHCI 1.0 feature) and usb3.0 devices which support link PM. By | ||
| 497 | enabling hardware LPM, the host can automatically put the device into | ||
| 498 | lower power state(L1 for usb2.0 devices, or U1/U2 for usb3.0 devices), | ||
| 499 | which state device can enter and resume very quickly. | ||
| 500 | |||
| 501 | The user interface for controlling USB2 hardware LPM is located in the | ||
| 502 | power/ subdirectory of each USB device's sysfs directory, that is, in | ||
| 503 | /sys/bus/usb/devices/.../power/ where "..." is the device's ID. The | ||
| 504 | relevant attribute files is usb2_hardware_lpm. | ||
| 505 | |||
| 506 | power/usb2_hardware_lpm | ||
| 507 | |||
| 508 | When a USB2 device which support LPM is plugged to a | ||
| 509 | xHCI host root hub which support software LPM, the | ||
| 510 | host will run a software LPM test for it; if the device | ||
| 511 | enters L1 state and resume successfully and the host | ||
| 512 | supports USB2 hardware LPM, this file will show up and | ||
| 513 | driver will enable hardware LPM for the device. You | ||
| 514 | can write y/Y/1 or n/N/0 to the file to enable/disable | ||
| 515 | USB2 hardware LPM manually. This is for test purpose mainly. | ||
| @@ -2136,6 +2136,14 @@ M: Matthew Garrett <mjg59@srcf.ucam.org> · 2135 unmodified lines | |||
| 2136 | S: Maintained | 2136 | S: Maintained |
| 2137 | F: drivers/platform/x86/dell-wmi.c | 2137 | F: drivers/platform/x86/dell-wmi.c |
| 2138 | 2138 | ||
| 2139 | DESIGNWARE USB3 DRD IP DRIVER | ||
| 2140 | M: Felipe Balbi <balbi@ti.com> | ||
| 2141 | L: linux-usb@vger.kernel.org | ||
| 2142 | L: linux-omap@vger.kernel.org | ||
| 2143 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git | ||
| 2144 | S: Maintained | ||
| 2145 | F: drivers/usb/dwc3/ | ||
| 2146 | |||
| 2139 | DEVICE NUMBER REGISTRY | 2147 | DEVICE NUMBER REGISTRY |
| 2140 | M: Torben Mathiasen <device@lanana.org> | 2148 | M: Torben Mathiasen <device@lanana.org> |
| 2141 | W: http://lanana.org/docs/device-list/index.html | 2149 | W: http://lanana.org/docs/device-list/index.html |
| @@ -35,6 +35,13 @@ extern struct pxa_device_desc pxa168_device_fb; · 34 unmodified lines | |||
| 35 | extern struct pxa_device_desc pxa168_device_keypad; | 35 | extern struct pxa_device_desc pxa168_device_keypad; |
| 36 | extern struct pxa_device_desc pxa168_device_eth; | 36 | extern struct pxa_device_desc pxa168_device_eth; |
| 37 | 37 | ||
| 38 | struct pxa168_usb_pdata { | ||
| 39 | /* If NULL, default phy init routine for PXA168 would be called */ | ||
| 40 | int (*phy_init)(void __iomem *usb_phy_reg_base); | ||
| 41 | }; | ||
| 42 | /* pdata can be NULL */ | ||
| 43 | int __init pxa168_add_usb_host(struct pxa168_usb_pdata *pdata); | ||
| 44 | |||
| 38 | static inline int pxa168_add_uart(int id) | 45 | static inline int pxa168_add_uart(int id) |
| 39 | { | 46 | { |
| 40 | struct pxa_device_desc *d = NULL; | 47 | struct pxa_device_desc *d = NULL; |
| @@ -25,6 +25,9 @@ · 24 unmodified lines | |||
| 25 | #include <mach/dma.h> | 25 | #include <mach/dma.h> |
| 26 | #include <mach/devices.h> | 26 | #include <mach/devices.h> |
| 27 | #include <mach/mfp.h> | 27 | #include <mach/mfp.h> |
| 28 | #include <linux/platform_device.h> | ||
| 29 | #include <linux/dma-mapping.h> | ||
| 30 | #include <mach/pxa168.h> | ||
| 28 | 31 | ||
| 29 | #include "common.h" | 32 | #include "common.h" |
| 30 | #include "clock.h" | 33 | #include "clock.h" |
| @@ -83,6 +86,7 @@ static APBC_CLK(keypad, PXA168_KPC, 0, 32000); · 52 unmodified lines | |||
| 83 | static APMU_CLK(nand, NAND, 0x19b, 156000000); | 86 | static APMU_CLK(nand, NAND, 0x19b, 156000000); |
| 84 | static APMU_CLK(lcd, LCD, 0x7f, 312000000); | 87 | static APMU_CLK(lcd, LCD, 0x7f, 312000000); |
| 85 | static APMU_CLK(eth, ETH, 0x09, 0); | 88 | static APMU_CLK(eth, ETH, 0x09, 0); |
| 89 | static APMU_CLK(usb, USB, 0x12, 0); | ||
| 86 | 90 | ||
| 87 | /* device and clock bindings */ | 91 | /* device and clock bindings */ |
| 88 | static struct clk_lookup pxa168_clkregs[] = { | 92 | static struct clk_lookup pxa168_clkregs[] = { |
| @@ -104,6 +108,7 @@ static struct clk_lookup pxa168_clkregs[] = { · 15 unmodified lines | |||
| 104 | INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL), | 108 | INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL), |
| 105 | INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL), | 109 | INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL), |
| 106 | INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"), | 110 | INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"), |
| 111 | INIT_CLKREG(&clk_usb, "pxa168-ehci", "PXA168-USBCLK"), | ||
| 107 | }; | 112 | }; |
| 108 | 113 | ||
| 109 | static int __init pxa168_init(void) | 114 | static int __init pxa168_init(void) |
| @@ -169,3 +174,44 @@ PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61); · 59 unmodified lines | |||
| 169 | PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8); | 174 | PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8); |
| 170 | PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c); | 175 | PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c); |
| 171 | PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff); | 176 | PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff); |
| 177 | |||
| 178 | struct resource pxa168_usb_host_resources[] = { | ||
| 179 | /* USB Host conroller register base */ | ||
| 180 | [0] = { | ||
| 181 | .start = 0xd4209000, | ||
| 182 | .end = 0xd4209000 + 0x200, | ||
| 183 | .flags = IORESOURCE_MEM, | ||
| 184 | .name = "pxa168-usb-host", | ||
| 185 | }, | ||
| 186 | /* USB PHY register base */ | ||
| 187 | [1] = { | ||
| 188 | .start = 0xd4206000, | ||
| 189 | .end = 0xd4206000 + 0xff, | ||
| 190 | .flags = IORESOURCE_MEM, | ||
| 191 | .name = "pxa168-usb-phy", | ||
| 192 | }, | ||
| 193 | [2] = { | ||
| 194 | .start = IRQ_PXA168_USB2, | ||
| 195 | .end = IRQ_PXA168_USB2, | ||
| 196 | .flags = IORESOURCE_IRQ, | ||
| 197 | }, | ||
| 198 | }; | ||
| 199 | |||
| 200 | static u64 pxa168_usb_host_dmamask = DMA_BIT_MASK(32); | ||
| 201 | struct platform_device pxa168_device_usb_host = { | ||
| 202 | .name = "pxa168-ehci", | ||
| 203 | .id = -1, | ||
| 204 | .dev = { | ||
| 205 | .dma_mask = &pxa168_usb_host_dmamask, | ||
| 206 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 207 | }, | ||
| 208 | |||
| 209 | .num_resources = ARRAY_SIZE(pxa168_usb_host_resources), | ||
| 210 | .resource = pxa168_usb_host_resources, | ||
| 211 | }; | ||
| 212 | |||
| 213 | int __init pxa168_add_usb_host(struct pxa168_usb_pdata *pdata) | ||
| 214 | { | ||
| 215 | pxa168_device_usb_host.dev.platform_data = pdata; | ||
| 216 | return platform_device_register(&pxa168_device_usb_host); | ||
| 217 | } | ||
| @@ -242,14 +242,11 @@ obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o \ · 241 unmodified lines | |||
| 242 | obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \ | 242 | obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \ |
| 243 | hsmmc.o | 243 | hsmmc.o |
| 244 | obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ | 244 | obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ |
| 245 | hsmmc.o \ | 245 | hsmmc.o |
| 246 | omap_phy_internal.o | ||
| 247 | obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \ | 246 | obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \ |
| 248 | hsmmc.o \ | 247 | hsmmc.o |
| 249 | omap_phy_internal.o | ||
| 250 | 248 | ||
| 251 | obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o \ | 249 | obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o |
| 252 | omap_phy_internal.o \ | ||
| 253 | 250 | ||
| 254 | obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o | 251 | obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o |
| 255 | 252 | ||
| @@ -260,6 +257,8 @@ obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o · 4 unmodified lines | |||
| 260 | usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o | 257 | usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o |
| 261 | obj-y += $(usbfs-m) $(usbfs-y) | 258 | obj-y += $(usbfs-m) $(usbfs-y) |
| 262 | obj-y += usb-musb.o | 259 | obj-y += usb-musb.o |
| 260 | obj-y += omap_phy_internal.o | ||
| 261 | |||
| 263 | obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o | 262 | obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o |
| 264 | obj-y += usb-host.o | 263 | obj-y += usb-host.o |
| 265 | 264 | ||
| @@ -810,6 +810,7 @@ static struct usbhs_private usbhs1_private = { · 809 unmodified lines | |||
| 810 | }, | 810 | }, |
| 811 | .driver_param = { | 811 | .driver_param = { |
| 812 | .buswait_bwait = 4, | 812 | .buswait_bwait = 4, |
| 813 | .has_otg = 1, | ||
| 813 | .pipe_type = usbhs1_pipe_cfg, | 814 | .pipe_type = usbhs1_pipe_cfg, |
| 814 | .pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg), | 815 | .pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg), |
| 815 | .d0_tx_id = SHDMA_SLAVE_USB1_TX, | 816 | .d0_tx_id = SHDMA_SLAVE_USB1_TX, |
| @@ -12,6 +12,11 @@ menuconfig USB_SUPPORT · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | if USB_SUPPORT | 13 | if USB_SUPPORT |
| 14 | 14 | ||
| 15 | config USB_COMMON | ||
| 16 | tristate | ||
| 17 | default y | ||
| 18 | depends on USB || USB_GADGET | ||
| 19 | |||
| 15 | # Host-side USB depends on having a host controller | 20 | # Host-side USB depends on having a host controller |
| 16 | # NOTE: dummy_hcd is always an option, but it's ignored here ... | 21 | # NOTE: dummy_hcd is always an option, but it's ignored here ... |
| 17 | # NOTE: SL-811 option should be board-specific ... | 22 | # NOTE: SL-811 option should be board-specific ... |
| @@ -19,6 +24,7 @@ config USB_ARCH_HAS_HCD · 1 unmodified line | |||
| 19 | boolean | 24 | boolean |
| 20 | default y if USB_ARCH_HAS_OHCI | 25 | default y if USB_ARCH_HAS_OHCI |
| 21 | default y if USB_ARCH_HAS_EHCI | 26 | default y if USB_ARCH_HAS_EHCI |
| 27 | default y if USB_ARCH_HAS_XHCI | ||
| 22 | default y if PCMCIA && !M32R # sl811_cs | 28 | default y if PCMCIA && !M32R # sl811_cs |
| 23 | default y if ARM # SL-811 | 29 | default y if ARM # SL-811 |
| 24 | default y if BLACKFIN # SL-811 | 30 | default y if BLACKFIN # SL-811 |
| @@ -54,7 +60,7 @@ config USB_ARCH_HAS_OHCI · 29 unmodified lines | |||
| 54 | # some non-PCI hcds implement EHCI | 60 | # some non-PCI hcds implement EHCI |
| 55 | config USB_ARCH_HAS_EHCI | 61 | config USB_ARCH_HAS_EHCI |
| 56 | boolean | 62 | boolean |
| 57 | default y if PPC_83xx | 63 | default y if FSL_SOC |
| 58 | default y if PPC_MPC512x | 64 | default y if PPC_MPC512x |
| 59 | default y if SOC_AU1200 | 65 | default y if SOC_AU1200 |
| 60 | default y if ARCH_IXP4XX | 66 | default y if ARCH_IXP4XX |
| @@ -69,6 +75,12 @@ config USB_ARCH_HAS_EHCI · 8 unmodified lines | |||
| 69 | default y if ARCH_MSM | 75 | default y if ARCH_MSM |
| 70 | default y if MICROBLAZE | 76 | default y if MICROBLAZE |
| 71 | default y if SPARC_LEON | 77 | default y if SPARC_LEON |
| 78 | default y if ARCH_MMP | ||
| 79 | default PCI | ||
| 80 | |||
| 81 | # some non-PCI HCDs implement xHCI | ||
| 82 | config USB_ARCH_HAS_XHCI | ||
| 83 | boolean | ||
| 72 | default PCI | 84 | default PCI |
| 73 | 85 | ||
| 74 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. | 86 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. |
| @@ -110,6 +122,8 @@ config USB · 35 unmodified lines | |||
| 110 | 122 | ||
| 111 | source "drivers/usb/core/Kconfig" | 123 | source "drivers/usb/core/Kconfig" |
| 112 | 124 | ||
| 125 | source "drivers/usb/dwc3/Kconfig" | ||
| 126 | |||
| 113 | source "drivers/usb/mon/Kconfig" | 127 | source "drivers/usb/mon/Kconfig" |
| 114 | 128 | ||
| 115 | source "drivers/usb/wusbcore/Kconfig" | 129 | source "drivers/usb/wusbcore/Kconfig" |
| @@ -6,6 +6,8 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | obj-$(CONFIG_USB) += core/ | 7 | obj-$(CONFIG_USB) += core/ |
| 8 | 8 | ||
| 9 | obj-$(CONFIG_USB_DWC3) += dwc3/ | ||
| 10 | |||
| 9 | obj-$(CONFIG_USB_MON) += mon/ | 11 | obj-$(CONFIG_USB_MON) += mon/ |
| 10 | 12 | ||
| 11 | obj-$(CONFIG_PCI) += host/ | 13 | obj-$(CONFIG_PCI) += host/ |
| @@ -51,3 +53,5 @@ obj-$(CONFIG_USB_MUSB_HDRC) += musb/ · 39 unmodified lines | |||
| 51 | obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ | 53 | obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ |
| 52 | obj-$(CONFIG_USB_OTG_UTILS) += otg/ | 54 | obj-$(CONFIG_USB_OTG_UTILS) += otg/ |
| 53 | obj-$(CONFIG_USB_GADGET) += gadget/ | 55 | obj-$(CONFIG_USB_GADGET) += gadget/ |
| 56 | |||
| 57 | obj-$(CONFIG_USB_COMMON) += usb-common.o | ||
| @@ -1058,11 +1058,11 @@ made_compressed_probe: · 1057 unmodified lines | |||
| 1058 | goto alloc_fail; | 1058 | goto alloc_fail; |
| 1059 | } | 1059 | } |
| 1060 | 1060 | ||
| 1061 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); | 1061 | ctrlsize = usb_endpoint_maxp(epctrl); |
| 1062 | readsize = le16_to_cpu(epread->wMaxPacketSize) * | 1062 | readsize = usb_endpoint_maxp(epread) * |
| 1063 | (quirks == SINGLE_RX_URB ? 1 : 2); | 1063 | (quirks == SINGLE_RX_URB ? 1 : 2); |
| 1064 | acm->combined_interfaces = combined_interfaces; | 1064 | acm->combined_interfaces = combined_interfaces; |
| 1065 | acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize) * 20; | 1065 | acm->writesize = usb_endpoint_maxp(epwrite) * 20; |
| 1066 | acm->control = control_interface; | 1066 | acm->control = control_interface; |
| 1067 | acm->data = data_interface; | 1067 | acm->data = data_interface; |
| 1068 | acm->minor = minor; | 1068 | acm->minor = minor; |
| @@ -1534,6 +1534,9 @@ static const struct usb_device_id acm_ids[] = { · 465 unmodified lines | |||
| 1534 | { NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */ | 1534 | { NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */ |
| 1535 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ | 1535 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ |
| 1536 | 1536 | ||
| 1537 | /* Support for Owen devices */ | ||
| 1538 | { USB_DEVICE(0x03eb, 0x0030), }, /* Owen SI30 */ | ||
| 1539 | |||
| 1537 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ | 1540 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ |
| 1538 | 1541 | ||
| 1539 | /* Support Lego NXT using pbLua firmware */ | 1542 | /* Support Lego NXT using pbLua firmware */ |
| @@ -682,7 +682,7 @@ next_desc: · 681 unmodified lines | |||
| 682 | if (!ep || !usb_endpoint_is_int_in(ep)) | 682 | if (!ep || !usb_endpoint_is_int_in(ep)) |
| 683 | goto err; | 683 | goto err; |
| 684 | 684 | ||
| 685 | desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); | 685 | desc->wMaxPacketSize = usb_endpoint_maxp(ep); |
| 686 | desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; | 686 | desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; |
| 687 | 687 | ||
| 688 | desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); | 688 | desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); |
| @@ -186,8 +186,7 @@ static int usbtmc_ioctl_abort_bulk_in(struct usbtmc_device_data *data) · 185 unmodified lines | |||
| 186 | for (n = 0; n < current_setting->desc.bNumEndpoints; n++) | 186 | for (n = 0; n < current_setting->desc.bNumEndpoints; n++) |
| 187 | if (current_setting->endpoint[n].desc.bEndpointAddress == | 187 | if (current_setting->endpoint[n].desc.bEndpointAddress == |
| 188 | data->bulk_in) | 188 | data->bulk_in) |
| 189 | max_size = le16_to_cpu(current_setting->endpoint[n]. | 189 | max_size = usb_endpoint_maxp(¤t_setting->endpoint[n].desc); |
| 190 | desc.wMaxPacketSize); | ||
| 191 | 190 | ||
| 192 | if (max_size == 0) { | 191 | if (max_size == 0) { |
| 193 | dev_err(dev, "Couldn't get wMaxPacketSize\n"); | 192 | dev_err(dev, "Couldn't get wMaxPacketSize\n"); |
| @@ -636,7 +635,7 @@ static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) · 442 unmodified lines | |||
| 636 | for (n = 0; n < current_setting->desc.bNumEndpoints; n++) { | 635 | for (n = 0; n < current_setting->desc.bNumEndpoints; n++) { |
| 637 | desc = ¤t_setting->endpoint[n].desc; | 636 | desc = ¤t_setting->endpoint[n].desc; |
| 638 | if (desc->bEndpointAddress == data->bulk_in) | 637 | if (desc->bEndpointAddress == data->bulk_in) |
| 639 | max_size = le16_to_cpu(desc->wMaxPacketSize); | 638 | max_size = usb_endpoint_maxp(desc); |
| 640 | } | 639 | } |
| 641 | 640 | ||
| 642 | if (max_size == 0) { | 641 | if (max_size == 0) { |
| @@ -124,9 +124,9 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, · 123 unmodified lines | |||
| 124 | 124 | ||
| 125 | if (usb_endpoint_xfer_isoc(&ep->desc)) | 125 | if (usb_endpoint_xfer_isoc(&ep->desc)) |
| 126 | max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * | 126 | max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * |
| 127 | le16_to_cpu(ep->desc.wMaxPacketSize); | 127 | usb_endpoint_maxp(&ep->desc); |
| 128 | else if (usb_endpoint_xfer_int(&ep->desc)) | 128 | else if (usb_endpoint_xfer_int(&ep->desc)) |
| 129 | max_tx = le16_to_cpu(ep->desc.wMaxPacketSize) * | 129 | max_tx = usb_endpoint_maxp(&ep->desc) * |
| 130 | (desc->bMaxBurst + 1); | 130 | (desc->bMaxBurst + 1); |
| 131 | else | 131 | else |
| 132 | max_tx = 999999; | 132 | max_tx = 999999; |
| @@ -241,7 +241,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, · 108 unmodified lines | |||
| 241 | cfgno, inum, asnum, d->bEndpointAddress); | 241 | cfgno, inum, asnum, d->bEndpointAddress); |
| 242 | endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT; | 242 | endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT; |
| 243 | endpoint->desc.bInterval = 1; | 243 | endpoint->desc.bInterval = 1; |
| 244 | if (le16_to_cpu(endpoint->desc.wMaxPacketSize) > 8) | 244 | if (usb_endpoint_maxp(&endpoint->desc) > 8) |
| 245 | endpoint->desc.wMaxPacketSize = cpu_to_le16(8); | 245 | endpoint->desc.wMaxPacketSize = cpu_to_le16(8); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| @@ -254,7 +254,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, · 6 unmodified lines | |||
| 254 | && usb_endpoint_xfer_bulk(d)) { | 254 | && usb_endpoint_xfer_bulk(d)) { |
| 255 | unsigned maxp; | 255 | unsigned maxp; |
| 256 | 256 | ||
| 257 | maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize) & 0x07ff; | 257 | maxp = usb_endpoint_maxp(&endpoint->desc) & 0x07ff; |
| 258 | if (maxp != 512) | 258 | if (maxp != 512) |
| 259 | dev_warn(ddev, "config %d interface %d altsetting %d " | 259 | dev_warn(ddev, "config %d interface %d altsetting %d " |
| 260 | "bulk endpoint 0x%X has invalid maxpacket %d\n", | 260 | "bulk endpoint 0x%X has invalid maxpacket %d\n", |
| @@ -755,3 +755,106 @@ err2: · 494 unmodified lines | |||
| 755 | dev_err(ddev, "out of memory\n"); | 755 | dev_err(ddev, "out of memory\n"); |
| 756 | return result; | 756 | return result; |
| 757 | } | 757 | } |
| 758 | |||
| 759 | void usb_release_bos_descriptor(struct usb_device *dev) | ||
| 760 | { | ||
| 761 | if (dev->bos) { | ||
| 762 | kfree(dev->bos->desc); | ||
| 763 | kfree(dev->bos); | ||
| 764 | dev->bos = NULL; | ||
| 765 | } | ||
| 766 | } | ||
| 767 | |||
| 768 | /* Get BOS descriptor set */ | ||
| 769 | int usb_get_bos_descriptor(struct usb_device *dev) | ||
| 770 | { | ||
| 771 | struct device *ddev = &dev->dev; | ||
| 772 | struct usb_bos_descriptor *bos; | ||
| 773 | struct usb_dev_cap_header *cap; | ||
| 774 | unsigned char *buffer; | ||
| 775 | int length, total_len, num, i; | ||
| 776 | int ret; | ||
| 777 | |||
| 778 | bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_KERNEL); | ||
| 779 | if (!bos) | ||
| 780 | return -ENOMEM; | ||
| 781 | |||
| 782 | /* Get BOS descriptor */ | ||
| 783 | ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE); | ||
| 784 | if (ret < USB_DT_BOS_SIZE) { | ||
| 785 | dev_err(ddev, "unable to get BOS descriptor\n"); | ||
| 786 | if (ret >= 0) | ||
| 787 | ret = -ENOMSG; | ||
| 788 | kfree(bos); | ||
| 789 | return ret; | ||
| 790 | } | ||
| 791 | |||
| 792 | length = bos->bLength; | ||
| 793 | total_len = le16_to_cpu(bos->wTotalLength); | ||
| 794 | num = bos->bNumDeviceCaps; | ||
| 795 | kfree(bos); | ||
| 796 | if (total_len < length) | ||
| 797 | return -EINVAL; | ||
| 798 | |||
| 799 | dev->bos = kzalloc(sizeof(struct usb_host_bos), GFP_KERNEL); | ||
| 800 | if (!dev->bos) | ||
| 801 | return -ENOMEM; | ||
| 802 | |||
| 803 | /* Now let's get the whole BOS descriptor set */ | ||
| 804 | buffer = kzalloc(total_len, GFP_KERNEL); | ||
| 805 | if (!buffer) { | ||
| 806 | ret = -ENOMEM; | ||
| 807 | goto err; | ||
| 808 | } | ||
| 809 | dev->bos->desc = (struct usb_bos_descriptor *)buffer; | ||
| 810 | |||
| 811 | ret = usb_get_descriptor(dev, USB_DT_BOS, 0, buffer, total_len); | ||
| 812 | if (ret < total_len) { | ||
| 813 | dev_err(ddev, "unable to get BOS descriptor set\n"); | ||
| 814 | if (ret >= 0) | ||
| 815 | ret = -ENOMSG; | ||
| 816 | goto err; | ||
| 817 | } | ||
| 818 | total_len -= length; | ||
| 819 | |||
| 820 | for (i = 0; i < num; i++) { | ||
| 821 | buffer += length; | ||
| 822 | cap = (struct usb_dev_cap_header *)buffer; | ||
| 823 | length = cap->bLength; | ||
| 824 | |||
| 825 | if (total_len < length) | ||
| 826 | break; | ||
| 827 | total_len -= length; | ||
| 828 | |||
| 829 | if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { | ||
| 830 | dev_warn(ddev, "descriptor type invalid, skip\n"); | ||
| 831 | continue; | ||
| 832 | } | ||
| 833 | |||
| 834 | switch (cap->bDevCapabilityType) { | ||
| 835 | case USB_CAP_TYPE_WIRELESS_USB: | ||
| 836 | /* Wireless USB cap descriptor is handled by wusb */ | ||
| 837 | break; | ||
| 838 | case USB_CAP_TYPE_EXT: | ||
| 839 | dev->bos->ext_cap = | ||
| 840 | (struct usb_ext_cap_descriptor *)buffer; | ||
| 841 | break; | ||
| 842 | case USB_SS_CAP_TYPE: | ||
| 843 | dev->bos->ss_cap = | ||
| 844 | (struct usb_ss_cap_descriptor *)buffer; | ||
| 845 | break; | ||
| 846 | case CONTAINER_ID_TYPE: | ||
| 847 | dev->bos->ss_id = | ||
| 848 | (struct usb_ss_container_id_descriptor *)buffer; | ||
| 849 | break; | ||
| 850 | default: | ||
| 851 | break; | ||
| 852 | } | ||
| 853 | } | ||
| 854 | |||
| 855 | return 0; | ||
| 856 | |||
| 857 | err: | ||
| 858 | usb_release_bos_descriptor(dev); | ||
| 859 | return ret; | ||
| 860 | } | ||
| @@ -190,7 +190,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end, · 189 unmodified lines | |||
| 190 | dir = usb_endpoint_dir_in(desc) ? 'I' : 'O'; | 190 | dir = usb_endpoint_dir_in(desc) ? 'I' : 'O'; |
| 191 | 191 | ||
| 192 | if (speed == USB_SPEED_HIGH) { | 192 | if (speed == USB_SPEED_HIGH) { |
| 193 | switch (le16_to_cpu(desc->wMaxPacketSize) & (0x03 << 11)) { | 193 | switch (usb_endpoint_maxp(desc) & (0x03 << 11)) { |
| 194 | case 1 << 11: | 194 | case 1 << 11: |
| 195 | bandwidth = 2; break; | 195 | bandwidth = 2; break; |
| 196 | case 2 << 11: | 196 | case 2 << 11: |
| @@ -240,7 +240,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end, · 43 unmodified lines | |||
| 240 | 240 | ||
| 241 | start += sprintf(start, format_endpt, desc->bEndpointAddress, dir, | 241 | start += sprintf(start, format_endpt, desc->bEndpointAddress, dir, |
| 242 | desc->bmAttributes, type, | 242 | desc->bmAttributes, type, |
| 243 | (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) * | 243 | (usb_endpoint_maxp(desc) & 0x07ff) * |
| 244 | bandwidth, | 244 | bandwidth, |
| 245 | interval, unit); | 245 | interval, unit); |
| 246 | return start; | 246 | return start; |
| @@ -46,6 +46,7 @@ · 45 unmodified lines | |||
| 46 | #include <linux/cdev.h> | 46 | #include <linux/cdev.h> |
| 47 | #include <linux/notifier.h> | 47 | #include <linux/notifier.h> |
| 48 | #include <linux/security.h> | 48 | #include <linux/security.h> |
| 49 | #include <linux/user_namespace.h> | ||
| 49 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
| 50 | #include <asm/byteorder.h> | 51 | #include <asm/byteorder.h> |
| 51 | #include <linux/moduleparam.h> | 52 | #include <linux/moduleparam.h> |
| @@ -68,7 +69,7 @@ struct dev_state { · 16 unmodified lines | |||
| 68 | wait_queue_head_t wait; /* wake up if a request completed */ | 69 | wait_queue_head_t wait; /* wake up if a request completed */ |
| 69 | unsigned int discsignr; | 70 | unsigned int discsignr; |
| 70 | struct pid *disc_pid; | 71 | struct pid *disc_pid; |
| 71 | uid_t disc_uid, disc_euid; | 72 | const struct cred *cred; |
| 72 | void __user *disccontext; | 73 | void __user *disccontext; |
| 73 | unsigned long ifclaimed; | 74 | unsigned long ifclaimed; |
| 74 | u32 secid; | 75 | u32 secid; |
| @@ -79,7 +80,7 @@ struct async { · 4 unmodified lines | |||
| 79 | struct list_head asynclist; | 80 | struct list_head asynclist; |
| 80 | struct dev_state *ps; | 81 | struct dev_state *ps; |
| 81 | struct pid *pid; | 82 | struct pid *pid; |
| 82 | uid_t uid, euid; | 83 | const struct cred *cred; |
| 83 | unsigned int signr; | 84 | unsigned int signr; |
| 84 | unsigned int ifnum; | 85 | unsigned int ifnum; |
| 85 | void __user *userbuffer; | 86 | void __user *userbuffer; |
| @@ -248,6 +249,7 @@ static struct async *alloc_async(unsigned int numisoframes) · 162 unmodified lines | |||
| 248 | static void free_async(struct async *as) | 249 | static void free_async(struct async *as) |
| 249 | { | 250 | { |
| 250 | put_pid(as->pid); | 251 | put_pid(as->pid); |
| 252 | put_cred(as->cred); | ||
| 251 | kfree(as->urb->transfer_buffer); | 253 | kfree(as->urb->transfer_buffer); |
| 252 | kfree(as->urb->setup_packet); | 254 | kfree(as->urb->setup_packet); |
| 253 | usb_free_urb(as->urb); | 255 | usb_free_urb(as->urb); |
| @@ -393,9 +395,8 @@ static void async_completed(struct urb *urb) · 139 unmodified lines | |||
| 393 | struct dev_state *ps = as->ps; | 395 | struct dev_state *ps = as->ps; |
| 394 | struct siginfo sinfo; | 396 | struct siginfo sinfo; |
| 395 | struct pid *pid = NULL; | 397 | struct pid *pid = NULL; |
| 396 | uid_t uid = 0; | ||
| 397 | uid_t euid = 0; | ||
| 398 | u32 secid = 0; | 398 | u32 secid = 0; |
| 399 | const struct cred *cred = NULL; | ||
| 399 | int signr; | 400 | int signr; |
| 400 | 401 | ||
| 401 | spin_lock(&ps->lock); | 402 | spin_lock(&ps->lock); |
| @@ -407,9 +408,8 @@ static void async_completed(struct urb *urb) · 5 unmodified lines | |||
| 407 | sinfo.si_errno = as->status; | 408 | sinfo.si_errno = as->status; |
| 408 | sinfo.si_code = SI_ASYNCIO; | 409 | sinfo.si_code = SI_ASYNCIO; |
| 409 | sinfo.si_addr = as->userurb; | 410 | sinfo.si_addr = as->userurb; |
| 410 | pid = as->pid; | 411 | pid = get_pid(as->pid); |
| 411 | uid = as->uid; | 412 | cred = get_cred(as->cred); |
| 412 | euid = as->euid; | ||
| 413 | secid = as->secid; | 413 | secid = as->secid; |
| 414 | } | 414 | } |
| 415 | snoop(&urb->dev->dev, "urb complete\n"); | 415 | snoop(&urb->dev->dev, "urb complete\n"); |
| @@ -422,9 +422,11 @@ static void async_completed(struct urb *urb) · 6 unmodified lines | |||
| 422 | cancel_bulk_urbs(ps, as->bulk_addr); | 422 | cancel_bulk_urbs(ps, as->bulk_addr); |
| 423 | spin_unlock(&ps->lock); | 423 | spin_unlock(&ps->lock); |
| 424 | 424 | ||
| 425 | if (signr) | 425 | if (signr) { |
| 426 | kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid, | 426 | kill_pid_info_as_cred(sinfo.si_signo, &sinfo, pid, cred, secid); |
| 427 | euid, secid); | 427 | put_pid(pid); |
| 428 | put_cred(cred); | ||
| 429 | } | ||
| 428 | 430 | ||
| 429 | wake_up(&ps->wait); | 431 | wake_up(&ps->wait); |
| 430 | } | 432 | } |
| @@ -607,9 +609,10 @@ static int findintfep(struct usb_device *dev, unsigned int ep) · 176 unmodified lines | |||
| 607 | } | 609 | } |
| 608 | 610 | ||
| 609 | static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, | 611 | static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, |
| 610 | unsigned int index) | 612 | unsigned int request, unsigned int index) |
| 611 | { | 613 | { |
| 612 | int ret = 0; | 614 | int ret = 0; |
| 615 | struct usb_host_interface *alt_setting; | ||
| 613 | 616 | ||
| 614 | if (ps->dev->state != USB_STATE_UNAUTHENTICATED | 617 | if (ps->dev->state != USB_STATE_UNAUTHENTICATED |
| 615 | && ps->dev->state != USB_STATE_ADDRESS | 618 | && ps->dev->state != USB_STATE_ADDRESS |
| @@ -618,6 +621,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, · 2 unmodified lines | |||
| 618 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) | 621 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) |
| 619 | return 0; | 622 | return 0; |
| 620 | 623 | ||
| 624 | /* | ||
| 625 | * check for the special corner case 'get_device_id' in the printer | ||
| 626 | * class specification, where wIndex is (interface << 8 | altsetting) | ||
| 627 | * instead of just interface | ||
| 628 | */ | ||
| 629 | if (requesttype == 0xa1 && request == 0) { | ||
| 630 | alt_setting = usb_find_alt_setting(ps->dev->actconfig, | ||
| 631 | index >> 8, index & 0xff); | ||
| 632 | if (alt_setting | ||
| 633 | && alt_setting->desc.bInterfaceClass == USB_CLASS_PRINTER) | ||
| 634 | index >>= 8; | ||
| 635 | } | ||
| 636 | |||
| 621 | index &= 0xff; | 637 | index &= 0xff; |
| 622 | switch (requesttype & USB_RECIP_MASK) { | 638 | switch (requesttype & USB_RECIP_MASK) { |
| 623 | case USB_RECIP_ENDPOINT: | 639 | case USB_RECIP_ENDPOINT: |
| @@ -656,7 +672,6 @@ static int usbdev_open(struct inode *inode, struct file *file) · 32 unmodified lines | |||
| 656 | { | 672 | { |
| 657 | struct usb_device *dev = NULL; | 673 | struct usb_device *dev = NULL; |
| 658 | struct dev_state *ps; | 674 | struct dev_state *ps; |
| 659 | const struct cred *cred = current_cred(); | ||
| 660 | int ret; | 675 | int ret; |
| 661 | 676 | ||
| 662 | ret = -ENOMEM; | 677 | ret = -ENOMEM; |
| @@ -706,8 +721,7 @@ static int usbdev_open(struct inode *inode, struct file *file) · 43 unmodified lines | |||
| 706 | init_waitqueue_head(&ps->wait); | 721 | init_waitqueue_head(&ps->wait); |
| 707 | ps->discsignr = 0; | 722 | ps->discsignr = 0; |
| 708 | ps->disc_pid = get_pid(task_pid(current)); | 723 | ps->disc_pid = get_pid(task_pid(current)); |
| 709 | ps->disc_uid = cred->uid; | 724 | ps->cred = get_current_cred(); |
| 710 | ps->disc_euid = cred->euid; | ||
| 711 | ps->disccontext = NULL; | 725 | ps->disccontext = NULL; |
| 712 | ps->ifclaimed = 0; | 726 | ps->ifclaimed = 0; |
| 713 | security_task_getsecid(current, &ps->secid); | 727 | security_task_getsecid(current, &ps->secid); |
| @@ -749,6 +763,7 @@ static int usbdev_release(struct inode *inode, struct file *file) · 35 unmodified lines | |||
| 749 | usb_unlock_device(dev); | 763 | usb_unlock_device(dev); |
| 750 | usb_put_dev(dev); | 764 | usb_put_dev(dev); |
| 751 | put_pid(ps->disc_pid); | 765 | put_pid(ps->disc_pid); |
| 766 | put_cred(ps->cred); | ||
| 752 | 767 | ||
| 753 | as = async_getcompleted(ps); | 768 | as = async_getcompleted(ps); |
| 754 | while (as) { | 769 | while (as) { |
| @@ -770,7 +785,8 @@ static int proc_control(struct dev_state *ps, void __user *arg) · 15 unmodified lines | |||
| 770 | 785 | ||
| 771 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) | 786 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
| 772 | return -EFAULT; | 787 | return -EFAULT; |
| 773 | ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex); | 788 | ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.bRequest, |
| 789 | ctrl.wIndex); | ||
| 774 | if (ret) | 790 | if (ret) |
| 775 | return ret; | 791 | return ret; |
| 776 | wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */ | 792 | wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */ |
| @@ -1048,7 +1064,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, · 271 unmodified lines | |||
| 1048 | struct usb_host_endpoint *ep; | 1064 | struct usb_host_endpoint *ep; |
| 1049 | struct async *as; | 1065 | struct async *as; |
| 1050 | struct usb_ctrlrequest *dr = NULL; | 1066 | struct usb_ctrlrequest *dr = NULL; |
| 1051 | const struct cred *cred = current_cred(); | ||
| 1052 | unsigned int u, totlen, isofrmlen; | 1067 | unsigned int u, totlen, isofrmlen; |
| 1053 | int ret, ifnum = -1; | 1068 | int ret, ifnum = -1; |
| 1054 | int is_in; | 1069 | int is_in; |
| @@ -1100,7 +1115,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, · 45 unmodified lines | |||
| 1100 | kfree(dr); | 1115 | kfree(dr); |
| 1101 | return -EINVAL; | 1116 | return -EINVAL; |
| 1102 | } | 1117 | } |
| 1103 | ret = check_ctrlrecip(ps, dr->bRequestType, | 1118 | ret = check_ctrlrecip(ps, dr->bRequestType, dr->bRequest, |
| 1104 | le16_to_cpup(&dr->wIndex)); | 1119 | le16_to_cpup(&dr->wIndex)); |
| 1105 | if (ret) { | 1120 | if (ret) { |
| 1106 | kfree(dr); | 1121 | kfree(dr); |
| @@ -1262,8 +1277,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, · 155 unmodified lines | |||
| 1262 | as->signr = uurb->signr; | 1277 | as->signr = uurb->signr; |
| 1263 | as->ifnum = ifnum; | 1278 | as->ifnum = ifnum; |
| 1264 | as->pid = get_pid(task_pid(current)); | 1279 | as->pid = get_pid(task_pid(current)); |
| 1265 | as->uid = cred->uid; | 1280 | as->cred = get_current_cred(); |
| 1266 | as->euid = cred->euid; | ||
| 1267 | security_task_getsecid(current, &as->secid); | 1281 | security_task_getsecid(current, &as->secid); |
| 1268 | if (!is_in && uurb->buffer_length > 0) { | 1282 | if (!is_in && uurb->buffer_length > 0) { |
| 1269 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, | 1283 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, |
| @@ -1981,9 +1995,8 @@ static void usbdev_remove(struct usb_device *udev) · 711 unmodified lines | |||
| 1981 | sinfo.si_errno = EPIPE; | 1995 | sinfo.si_errno = EPIPE; |
| 1982 | sinfo.si_code = SI_ASYNCIO; | 1996 | sinfo.si_code = SI_ASYNCIO; |
| 1983 | sinfo.si_addr = ps->disccontext; | 1997 | sinfo.si_addr = ps->disccontext; |
| 1984 | kill_pid_info_as_uid(ps->discsignr, &sinfo, | 1998 | kill_pid_info_as_cred(ps->discsignr, &sinfo, |
| 1985 | ps->disc_pid, ps->disc_uid, | 1999 | ps->disc_pid, ps->cred, ps->secid); |
| 1986 | ps->disc_euid, ps->secid); | ||
| 1987 | } | 2000 | } |
| 1988 | } | 2001 | } |
| 1989 | } | 2002 | } |
| @@ -1583,7 +1583,7 @@ int usb_autopm_get_interface_async(struct usb_interface *intf) · 1582 unmodified lines | |||
| 1583 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", | 1583 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", |
| 1584 | __func__, atomic_read(&intf->dev.power.usage_count), | 1584 | __func__, atomic_read(&intf->dev.power.usage_count), |
| 1585 | status); | 1585 | status); |
| 1586 | if (status > 0) | 1586 | if (status > 0 || status == -EINPROGRESS) |
| 1587 | status = 0; | 1587 | status = 0; |
| 1588 | return status; | 1588 | return status; |
| 1589 | } | 1589 | } |
| @@ -1700,6 +1700,20 @@ int usb_runtime_idle(struct device *dev) · 110 unmodified lines | |||
| 1700 | return 0; | 1700 | return 0; |
| 1701 | } | 1701 | } |
| 1702 | 1702 | ||
| 1703 | int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) | ||
| 1704 | { | ||
| 1705 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
| 1706 | int ret = -EPERM; | ||
| 1707 | |||
| 1708 | if (hcd->driver->set_usb2_hw_lpm) { | ||
| 1709 | ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable); | ||
| 1710 | if (!ret) | ||
| 1711 | udev->usb2_hw_lpm_enabled = enable; | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | return ret; | ||
| 1715 | } | ||
| 1716 | |||
| 1703 | #endif /* CONFIG_USB_SUSPEND */ | 1717 | #endif /* CONFIG_USB_SUSPEND */ |
| 1704 | 1718 | ||
| 1705 | struct bus_type usb_bus_type = { | 1719 | struct bus_type usb_bus_type = { |
| @@ -56,7 +56,7 @@ static ssize_t show_ep_wMaxPacketSize(struct device *dev, · 55 unmodified lines | |||
| 56 | { | 56 | { |
| 57 | struct ep_device *ep = to_ep_device(dev); | 57 | struct ep_device *ep = to_ep_device(dev); |
| 58 | return sprintf(buf, "%04x\n", | 58 | return sprintf(buf, "%04x\n", |
| 59 | le16_to_cpu(ep->desc->wMaxPacketSize) & 0x07ff); | 59 | usb_endpoint_maxp(ep->desc) & 0x07ff); |
| 60 | } | 60 | } |
| 61 | static DEVICE_ATTR(wMaxPacketSize, S_IRUGO, show_ep_wMaxPacketSize, NULL); | 61 | static DEVICE_ATTR(wMaxPacketSize, S_IRUGO, show_ep_wMaxPacketSize, NULL); |
| 62 | 62 | ||
| @@ -242,7 +242,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 241 unmodified lines | |||
| 242 | 242 | ||
| 243 | pci_set_master(dev); | 243 | pci_set_master(dev); |
| 244 | 244 | ||
| 245 | retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); | 245 | retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED); |
| 246 | if (retval != 0) | 246 | if (retval != 0) |
| 247 | goto unmap_registers; | 247 | goto unmap_registers; |
| 248 | set_hs_companion(dev, hcd); | 248 | set_hs_companion(dev, hcd); |
| @@ -442,7 +442,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) · 441 unmodified lines | |||
| 442 | struct usb_ctrlrequest *cmd; | 442 | struct usb_ctrlrequest *cmd; |
| 443 | u16 typeReq, wValue, wIndex, wLength; | 443 | u16 typeReq, wValue, wIndex, wLength; |
| 444 | u8 *ubuf = urb->transfer_buffer; | 444 | u8 *ubuf = urb->transfer_buffer; |
| 445 | u8 tbuf [sizeof (struct usb_hub_descriptor)] | 445 | /* |
| 446 | * tbuf should be as big as the BOS descriptor and | ||
| 447 | * the USB hub descriptor. | ||
| 448 | */ | ||
| 449 | u8 tbuf[USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE] | ||
| 446 | __attribute__((aligned(4))); | 450 | __attribute__((aligned(4))); |
| 447 | const u8 *bufp = tbuf; | 451 | const u8 *bufp = tbuf; |
| 448 | unsigned len = 0; | 452 | unsigned len = 0; |
| @@ -562,6 +566,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) · 113 unmodified lines | |||
| 562 | else /* unsupported IDs --> "protocol stall" */ | 566 | else /* unsupported IDs --> "protocol stall" */ |
| 563 | goto error; | 567 | goto error; |
| 564 | break; | 568 | break; |
| 569 | case USB_DT_BOS << 8: | ||
| 570 | goto nongeneric; | ||
| 565 | default: | 571 | default: |
| 566 | goto error; | 572 | goto error; |
| 567 | } | 573 | } |
| @@ -596,6 +602,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) · 28 unmodified lines | |||
| 596 | /* CLASS REQUESTS (and errors) */ | 602 | /* CLASS REQUESTS (and errors) */ |
| 597 | 603 | ||
| 598 | default: | 604 | default: |
| 605 | nongeneric: | ||
| 599 | /* non-generic request */ | 606 | /* non-generic request */ |
| 600 | switch (typeReq) { | 607 | switch (typeReq) { |
| 601 | case GetHubStatus: | 608 | case GetHubStatus: |
| @@ -605,6 +612,9 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) · 3 unmodified lines | |||
| 605 | case GetHubDescriptor: | 612 | case GetHubDescriptor: |
| 606 | len = sizeof (struct usb_hub_descriptor); | 613 | len = sizeof (struct usb_hub_descriptor); |
| 607 | break; | 614 | break; |
| 615 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: | ||
| 616 | /* len is returned by hub_control */ | ||
| 617 | break; | ||
| 608 | } | 618 | } |
| 609 | status = hcd->driver->hub_control (hcd, | 619 | status = hcd->driver->hub_control (hcd, |
| 610 | typeReq, wValue, wIndex, | 620 | typeReq, wValue, wIndex, |
| @@ -615,7 +625,7 @@ error: · 4 unmodified lines | |||
| 615 | status = -EPIPE; | 625 | status = -EPIPE; |
| 616 | } | 626 | } |
| 617 | 627 | ||
| 618 | if (status) { | 628 | if (status < 0) { |
| 619 | len = 0; | 629 | len = 0; |
| 620 | if (status != -EPIPE) { | 630 | if (status != -EPIPE) { |
| 621 | dev_dbg (hcd->self.controller, | 631 | dev_dbg (hcd->self.controller, |
| @@ -624,6 +634,10 @@ error: · 2 unmodified lines | |||
| 624 | typeReq, wValue, wIndex, | 634 | typeReq, wValue, wIndex, |
| 625 | wLength, status); | 635 | wLength, status); |
| 626 | } | 636 | } |
| 637 | } else if (status > 0) { | ||
| 638 | /* hub_control may return the length of data copied. */ | ||
| 639 | len = status; | ||
| 640 | status = 0; | ||
| 627 | } | 641 | } |
| 628 | if (len) { | 642 | if (len) { |
| 629 | if (urb->transfer_buffer_length < len) | 643 | if (urb->transfer_buffer_length < len) |
| @@ -2429,7 +2443,7 @@ int usb_add_hcd(struct usb_hcd *hcd, · 1799 unmodified lines | |||
| 2429 | * but drivers can override it in reset() if needed, along with | 2443 | * but drivers can override it in reset() if needed, along with |
| 2430 | * recording the overall controller's system wakeup capability. | 2444 | * recording the overall controller's system wakeup capability. |
| 2431 | */ | 2445 | */ |
| 2432 | device_init_wakeup(&rhdev->dev, 1); | 2446 | device_set_wakeup_capable(&rhdev->dev, 1); |
| 2433 | 2447 | ||
| 2434 | /* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is | 2448 | /* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is |
| 2435 | * registered. But since the controller can die at any time, | 2449 | * registered. But since the controller can die at any time, |
| @@ -2478,6 +2492,13 @@ int usb_add_hcd(struct usb_hcd *hcd, · 42 unmodified lines | |||
| 2478 | } | 2492 | } |
| 2479 | if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) | 2493 | if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) |
| 2480 | usb_hcd_poll_rh_status(hcd); | 2494 | usb_hcd_poll_rh_status(hcd); |
| 2495 | |||
| 2496 | /* | ||
| 2497 | * Host controllers don't generate their own wakeup requests; | ||
| 2498 | * they only forward requests from the root hub. Therefore | ||
| 2499 | * controllers should always be enabled for remote wakeup. | ||
| 2500 | */ | ||
| 2501 | device_wakeup_enable(hcd->self.controller); | ||
| 2481 | return retval; | 2502 | return retval; |
| 2482 | 2503 | ||
| 2483 | error_create_attr_group: | 2504 | error_create_attr_group: |
| @@ -1636,11 +1636,6 @@ void usb_disconnect(struct usb_device **pdev) · 1635 unmodified lines | |||
| 1636 | int i; | 1636 | int i; |
| 1637 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | 1637 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); |
| 1638 | 1638 | ||
| 1639 | if (!udev) { | ||
| 1640 | pr_debug ("%s nodev\n", __func__); | ||
| 1641 | return; | ||
| 1642 | } | ||
| 1643 | |||
| 1644 | /* mark the device as inactive, so any further urb submissions for | 1639 | /* mark the device as inactive, so any further urb submissions for |
| 1645 | * this device (and any of its children) will fail immediately. | 1640 | * this device (and any of its children) will fail immediately. |
| 1646 | * this quiesces everything except pending urbs. | 1641 | * this quiesces everything except pending urbs. |
| @@ -2030,11 +2025,23 @@ static unsigned hub_is_wusb(struct usb_hub *hub) · 383 unmodified lines | |||
| 2030 | 2025 | ||
| 2031 | #define HUB_ROOT_RESET_TIME 50 /* times are in msec */ | 2026 | #define HUB_ROOT_RESET_TIME 50 /* times are in msec */ |
| 2032 | #define HUB_SHORT_RESET_TIME 10 | 2027 | #define HUB_SHORT_RESET_TIME 10 |
| 2028 | #define HUB_BH_RESET_TIME 50 | ||
| 2033 | #define HUB_LONG_RESET_TIME 200 | 2029 | #define HUB_LONG_RESET_TIME 200 |
| 2034 | #define HUB_RESET_TIMEOUT 500 | 2030 | #define HUB_RESET_TIMEOUT 500 |
| 2035 | 2031 | ||
| 2032 | static int hub_port_reset(struct usb_hub *hub, int port1, | ||
| 2033 | struct usb_device *udev, unsigned int delay, bool warm); | ||
| 2034 | |||
| 2035 | /* Is a USB 3.0 port in the Inactive state? */ | ||
| 2036 | static bool hub_port_inactive(struct usb_hub *hub, u16 portstatus) | ||
| 2037 | { | ||
| 2038 | return hub_is_superspeed(hub->hdev) && | ||
| 2039 | (portstatus & USB_PORT_STAT_LINK_STATE) == | ||
| 2040 | USB_SS_PORT_LS_SS_INACTIVE; | ||
| 2041 | } | ||
| 2042 | |||
| 2036 | static int hub_port_wait_reset(struct usb_hub *hub, int port1, | 2043 | static int hub_port_wait_reset(struct usb_hub *hub, int port1, |
| 2037 | struct usb_device *udev, unsigned int delay) | 2044 | struct usb_device *udev, unsigned int delay, bool warm) |
| 2038 | { | 2045 | { |
| 2039 | int delay_time, ret; | 2046 | int delay_time, ret; |
| 2040 | u16 portstatus; | 2047 | u16 portstatus; |
| @@ -2051,28 +2058,71 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, · 10 unmodified lines | |||
| 2051 | if (ret < 0) | 2058 | if (ret < 0) |
| 2052 | return ret; | 2059 | return ret; |
| 2053 | 2060 | ||
| 2054 | /* Device went away? */ | 2061 | /* |
| 2055 | if (!(portstatus & USB_PORT_STAT_CONNECTION)) | 2062 | * Some buggy devices require a warm reset to be issued even |
| 2056 | return -ENOTCONN; | 2063 | * when the port appears not to be connected. |
| 2057 | 2064 | */ | |
| 2058 | /* bomb out completely if the connection bounced */ | 2065 | if (!warm) { |
| 2059 | if ((portchange & USB_PORT_STAT_C_CONNECTION)) | 2066 | /* |
| 2060 | return -ENOTCONN; | 2067 | * Some buggy devices can cause an NEC host controller |
| 2061 | 2068 | * to transition to the "Error" state after a hot port | |
| 2062 | /* if we`ve finished resetting, then break out of the loop */ | 2069 | * reset. This will show up as the port state in |
| 2063 | if (!(portstatus & USB_PORT_STAT_RESET) && | 2070 | * "Inactive", and the port may also report a |
| 2064 | (portstatus & USB_PORT_STAT_ENABLE)) { | 2071 | * disconnect. Forcing a warm port reset seems to make |
| 2065 | if (hub_is_wusb(hub)) | 2072 | * the device work. |
| 2066 | udev->speed = USB_SPEED_WIRELESS; | 2073 | * |
| 2067 | else if (hub_is_superspeed(hub->hdev)) | 2074 | * See https://bugzilla.kernel.org/show_bug.cgi?id=41752 |
| 2068 | udev->speed = USB_SPEED_SUPER; | 2075 | */ |
| 2069 | else if (portstatus & USB_PORT_STAT_HIGH_SPEED) | 2076 | if (hub_port_inactive(hub, portstatus)) { |
| 2070 | udev->speed = USB_SPEED_HIGH; | 2077 | int ret; |
| 2071 | else if (portstatus & USB_PORT_STAT_LOW_SPEED) | 2078 | |
| 2072 | udev->speed = USB_SPEED_LOW; | 2079 | if ((portchange & USB_PORT_STAT_C_CONNECTION)) |
| 2073 | else | 2080 | clear_port_feature(hub->hdev, port1, |
| 2074 | udev->speed = USB_SPEED_FULL; | 2081 | USB_PORT_FEAT_C_CONNECTION); |
| 2075 | return 0; | 2082 | if (portchange & USB_PORT_STAT_C_LINK_STATE) |
| 2083 | clear_port_feature(hub->hdev, port1, | ||
| 2084 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
| 2085 | if (portchange & USB_PORT_STAT_C_RESET) | ||
| 2086 | clear_port_feature(hub->hdev, port1, | ||
| 2087 | USB_PORT_FEAT_C_RESET); | ||
| 2088 | dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n", | ||
| 2089 | port1); | ||
| 2090 | ret = hub_port_reset(hub, port1, | ||
| 2091 | udev, HUB_BH_RESET_TIME, | ||
| 2092 | true); | ||
| 2093 | if ((portchange & USB_PORT_STAT_C_CONNECTION)) | ||
| 2094 | clear_port_feature(hub->hdev, port1, | ||
| 2095 | USB_PORT_FEAT_C_CONNECTION); | ||
| 2096 | return ret; | ||
| 2097 | } | ||
| 2098 | /* Device went away? */ | ||
| 2099 | if (!(portstatus & USB_PORT_STAT_CONNECTION)) | ||
| 2100 | return -ENOTCONN; | ||
| 2101 | |||
| 2102 | /* bomb out completely if the connection bounced */ | ||
| 2103 | if ((portchange & USB_PORT_STAT_C_CONNECTION)) | ||
| 2104 | return -ENOTCONN; | ||
| 2105 | |||
| 2106 | /* if we`ve finished resetting, then break out of | ||
| 2107 | * the loop | ||
| 2108 | */ | ||
| 2109 | if (!(portstatus & USB_PORT_STAT_RESET) && | ||
| 2110 | (portstatus & USB_PORT_STAT_ENABLE)) { | ||
| 2111 | if (hub_is_wusb(hub)) | ||
| 2112 | udev->speed = USB_SPEED_WIRELESS; | ||
| 2113 | else if (hub_is_superspeed(hub->hdev)) | ||
| 2114 | udev->speed = USB_SPEED_SUPER; | ||
| 2115 | else if (portstatus & USB_PORT_STAT_HIGH_SPEED) | ||
| 2116 | udev->speed = USB_SPEED_HIGH; | ||
| 2117 | else if (portstatus & USB_PORT_STAT_LOW_SPEED) | ||
| 2118 | udev->speed = USB_SPEED_LOW; | ||
| 2119 | else | ||
| 2120 | udev->speed = USB_SPEED_FULL; | ||
| 2121 | return 0; | ||
| 2122 | } | ||
| 2123 | } else { | ||
| 2124 | if (portchange & USB_PORT_STAT_C_BH_RESET) | ||
| 2125 | return 0; | ||
| 2076 | } | 2126 | } |
| 2077 | 2127 | ||
| 2078 | /* switch to the long delay after two short delay failures */ | 2128 | /* switch to the long delay after two short delay failures */ |
| @@ -2080,35 +2130,84 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, · 1 unmodified line | |||
| 2080 | delay = HUB_LONG_RESET_TIME; | 2130 | delay = HUB_LONG_RESET_TIME; |
| 2081 | 2131 | ||
| 2082 | dev_dbg (hub->intfdev, | 2132 | dev_dbg (hub->intfdev, |
| 2083 | "port %d not reset yet, waiting %dms\n", | 2133 | "port %d not %sreset yet, waiting %dms\n", |
| 2084 | port1, delay); | 2134 | port1, warm ? "warm " : "", delay); |
| 2085 | } | 2135 | } |
| 2086 | 2136 | ||
| 2087 | return -EBUSY; | 2137 | return -EBUSY; |
| 2088 | } | 2138 | } |
| 2089 | 2139 | ||
| 2140 | static void hub_port_finish_reset(struct usb_hub *hub, int port1, | ||
| 2141 | struct usb_device *udev, int *status, bool warm) | ||
| 2142 | { | ||
| 2143 | switch (*status) { | ||
| 2144 | case 0: | ||
| 2145 | if (!warm) { | ||
| 2146 | struct usb_hcd *hcd; | ||
| 2147 | /* TRSTRCY = 10 ms; plus some extra */ | ||
| 2148 | msleep(10 + 40); | ||
| 2149 | update_devnum(udev, 0); | ||
| 2150 | hcd = bus_to_hcd(udev->bus); | ||
| 2151 | if (hcd->driver->reset_device) { | ||
| 2152 | *status = hcd->driver->reset_device(hcd, udev); | ||
| 2153 | if (*status < 0) { | ||
| 2154 | dev_err(&udev->dev, "Cannot reset " | ||
| 2155 | "HCD device state\n"); | ||
| 2156 | break; | ||
| 2157 | } | ||
| 2158 | } | ||
| 2159 | } | ||
| 2160 | /* FALL THROUGH */ | ||
| 2161 | case -ENOTCONN: | ||
| 2162 | case -ENODEV: | ||
| 2163 | clear_port_feature(hub->hdev, | ||
| 2164 | port1, USB_PORT_FEAT_C_RESET); | ||
| 2165 | /* FIXME need disconnect() for NOTATTACHED device */ | ||
| 2166 | if (warm) { | ||
| 2167 | clear_port_feature(hub->hdev, port1, | ||
| 2168 | USB_PORT_FEAT_C_BH_PORT_RESET); | ||
| 2169 | clear_port_feature(hub->hdev, port1, | ||
| 2170 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
| 2171 | } else { | ||
| 2172 | usb_set_device_state(udev, *status | ||
| 2173 | ? USB_STATE_NOTATTACHED | ||
| 2174 | : USB_STATE_DEFAULT); | ||
| 2175 | } | ||
| 2176 | break; | ||
| 2177 | } | ||
| 2178 | } | ||
| 2179 | |||
| 2180 | /* Handle port reset and port warm(BH) reset (for USB3 protocol ports) */ | ||
| 2090 | static int hub_port_reset(struct usb_hub *hub, int port1, | 2181 | static int hub_port_reset(struct usb_hub *hub, int port1, |
| 2091 | struct usb_device *udev, unsigned int delay) | 2182 | struct usb_device *udev, unsigned int delay, bool warm) |
| 2092 | { | 2183 | { |
| 2093 | int i, status; | 2184 | int i, status; |
| 2094 | struct usb_hcd *hcd; | ||
| 2095 | 2185 | ||
| 2096 | hcd = bus_to_hcd(udev->bus); | 2186 | if (!warm) { |
| 2097 | /* Block EHCI CF initialization during the port reset. | 2187 | /* Block EHCI CF initialization during the port reset. |
| 2098 | * Some companion controllers don't like it when they mix. | 2188 | * Some companion controllers don't like it when they mix. |
| 2099 | */ | 2189 | */ |
| 2100 | down_read(&ehci_cf_port_reset_rwsem); | 2190 | down_read(&ehci_cf_port_reset_rwsem); |
| 2191 | } else { | ||
| 2192 | if (!hub_is_superspeed(hub->hdev)) { | ||
| 2193 | dev_err(hub->intfdev, "only USB3 hub support " | ||
| 2194 | "warm reset\n"); | ||
| 2195 | return -EINVAL; | ||
| 2196 | } | ||
| 2197 | } | ||
| 2101 | 2198 | ||
| 2102 | /* Reset the port */ | 2199 | /* Reset the port */ |
| 2103 | for (i = 0; i < PORT_RESET_TRIES; i++) { | 2200 | for (i = 0; i < PORT_RESET_TRIES; i++) { |
| 2104 | status = set_port_feature(hub->hdev, | 2201 | status = set_port_feature(hub->hdev, port1, (warm ? |
| 2105 | port1, USB_PORT_FEAT_RESET); | 2202 | USB_PORT_FEAT_BH_PORT_RESET : |
| 2106 | if (status) | 2203 | USB_PORT_FEAT_RESET)); |
| 2204 | if (status) { | ||
| 2107 | dev_err(hub->intfdev, | 2205 | dev_err(hub->intfdev, |
| 2108 | "cannot reset port %d (err = %d)\n", | 2206 | "cannot %sreset port %d (err = %d)\n", |
| 2109 | port1, status); | 2207 | warm ? "warm " : "", port1, status); |
| 2110 | else { | 2208 | } else { |
| 2111 | status = hub_port_wait_reset(hub, port1, udev, delay); | 2209 | status = hub_port_wait_reset(hub, port1, udev, delay, |
| 2210 | warm); | ||
| 2112 | if (status && status != -ENOTCONN) | 2211 | if (status && status != -ENOTCONN) |
| 2113 | dev_dbg(hub->intfdev, | 2212 | dev_dbg(hub->intfdev, |
| 2114 | "port_wait_reset: err = %d\n", | 2213 | "port_wait_reset: err = %d\n", |
| @@ -2116,34 +2215,14 @@ static int hub_port_reset(struct usb_hub *hub, int port1, · 1 unmodified line | |||
| 2116 | } | 2215 | } |
| 2117 | 2216 | ||
| 2118 | /* return on disconnect or reset */ | 2217 | /* return on disconnect or reset */ |
| 2119 | switch (status) { | 2218 | if (status == 0 || status == -ENOTCONN || status == -ENODEV) { |
| 2120 | case 0: | 2219 | hub_port_finish_reset(hub, port1, udev, &status, warm); |
| 2121 | /* TRSTRCY = 10 ms; plus some extra */ | ||
| 2122 | msleep(10 + 40); | ||
| 2123 | update_devnum(udev, 0); | ||
| 2124 | if (hcd->driver->reset_device) { | ||
| 2125 | status = hcd->driver->reset_device(hcd, udev); | ||
| 2126 | if (status < 0) { | ||
| 2127 | dev_err(&udev->dev, "Cannot reset " | ||
| 2128 | "HCD device state\n"); | ||
| 2129 | break; | ||
| 2130 | } | ||
| 2131 | } | ||
| 2132 | /* FALL THROUGH */ | ||
| 2133 | case -ENOTCONN: | ||
| 2134 | case -ENODEV: | ||
| 2135 | clear_port_feature(hub->hdev, | ||
| 2136 | port1, USB_PORT_FEAT_C_RESET); | ||
| 2137 | /* FIXME need disconnect() for NOTATTACHED device */ | ||
| 2138 | usb_set_device_state(udev, status | ||
| 2139 | ? USB_STATE_NOTATTACHED | ||
| 2140 | : USB_STATE_DEFAULT); | ||
| 2141 | goto done; | 2220 | goto done; |
| 2142 | } | 2221 | } |
| 2143 | 2222 | ||
| 2144 | dev_dbg (hub->intfdev, | 2223 | dev_dbg (hub->intfdev, |
| 2145 | "port %d not enabled, trying reset again...\n", | 2224 | "port %d not enabled, trying %sreset again...\n", |
| 2146 | port1); | 2225 | port1, warm ? "warm " : ""); |
| 2147 | delay = HUB_LONG_RESET_TIME; | 2226 | delay = HUB_LONG_RESET_TIME; |
| 2148 | } | 2227 | } |
| 2149 | 2228 | ||
| @@ -2151,45 +2230,11 @@ static int hub_port_reset(struct usb_hub *hub, int port1, · 1 unmodified line | |||
| 2151 | "Cannot enable port %i. Maybe the USB cable is bad?\n", | 2230 | "Cannot enable port %i. Maybe the USB cable is bad?\n", |
| 2152 | port1); | 2231 | port1); |
| 2153 | 2232 | ||
| 2154 | done: | 2233 | done: |
| 2155 | up_read(&ehci_cf_port_reset_rwsem); | 2234 | if (!warm) |
| 2156 | return status; | 2235 | up_read(&ehci_cf_port_reset_rwsem); |
| 2157 | } | ||
| 2158 | |||
| 2159 | /* Warm reset a USB3 protocol port */ | ||
| 2160 | static int hub_port_warm_reset(struct usb_hub *hub, int port) | ||
| 2161 | { | ||
| 2162 | int ret; | ||
| 2163 | u16 portstatus, portchange; | ||
| 2164 | |||
| 2165 | if (!hub_is_superspeed(hub->hdev)) { | ||
| 2166 | dev_err(hub->intfdev, "only USB3 hub support warm reset\n"); | ||
| 2167 | return -EINVAL; | ||
| 2168 | } | ||
| 2169 | |||
| 2170 | /* Warm reset the port */ | ||
| 2171 | ret = set_port_feature(hub->hdev, | ||
| 2172 | port, USB_PORT_FEAT_BH_PORT_RESET); | ||
| 2173 | if (ret) { | ||
| 2174 | dev_err(hub->intfdev, "cannot warm reset port %d\n", port); | ||
| 2175 | return ret; | ||
| 2176 | } | ||
| 2177 | |||
| 2178 | msleep(20); | ||
| 2179 | ret = hub_port_status(hub, port, &portstatus, &portchange); | ||
| 2180 | |||
| 2181 | if (portchange & USB_PORT_STAT_C_RESET) | ||
| 2182 | clear_port_feature(hub->hdev, port, USB_PORT_FEAT_C_RESET); | ||
| 2183 | |||
| 2184 | if (portchange & USB_PORT_STAT_C_BH_RESET) | ||
| 2185 | clear_port_feature(hub->hdev, port, | ||
| 2186 | USB_PORT_FEAT_C_BH_PORT_RESET); | ||
| 2187 | |||
| 2188 | if (portchange & USB_PORT_STAT_C_LINK_STATE) | ||
| 2189 | clear_port_feature(hub->hdev, port, | ||
| 2190 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
| 2191 | 2236 | ||
| 2192 | return ret; | 2237 | return status; |
| 2193 | } | 2238 | } |
| 2194 | 2239 | ||
| 2195 | /* Check if a port is power on */ | 2240 | /* Check if a port is power on */ |
| @@ -2347,6 +2392,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) · 151 unmodified lines | |||
| 2347 | } | 2392 | } |
| 2348 | } | 2393 | } |
| 2349 | 2394 | ||
| 2395 | /* disable USB2 hardware LPM */ | ||
| 2396 | if (udev->usb2_hw_lpm_enabled == 1) | ||
| 2397 | usb_set_usb2_hardware_lpm(udev, 0); | ||
| 2398 | |||
| 2350 | /* see 7.1.7.6 */ | 2399 | /* see 7.1.7.6 */ |
| 2351 | if (hub_is_superspeed(hub->hdev)) | 2400 | if (hub_is_superspeed(hub->hdev)) |
| 2352 | status = set_port_feature(hub->hdev, | 2401 | status = set_port_feature(hub->hdev, |
| @@ -2558,7 +2607,12 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) · 205 unmodified lines | |||
| 2558 | if (status < 0) { | 2607 | if (status < 0) { |
| 2559 | dev_dbg(&udev->dev, "can't resume, status %d\n", status); | 2608 | dev_dbg(&udev->dev, "can't resume, status %d\n", status); |
| 2560 | hub_port_logical_disconnect(hub, port1); | 2609 | hub_port_logical_disconnect(hub, port1); |
| 2610 | } else { | ||
| 2611 | /* Try to enable USB2 hardware LPM */ | ||
| 2612 | if (udev->usb2_hw_lpm_capable == 1) | ||
| 2613 | usb_set_usb2_hardware_lpm(udev, 1); | ||
| 2561 | } | 2614 | } |
| 2615 | |||
| 2562 | return status; | 2616 | return status; |
| 2563 | } | 2617 | } |
| 2564 | 2618 | ||
| @@ -2798,7 +2852,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, · 233 unmodified lines | |||
| 2798 | int i, j, retval; | 2852 | int i, j, retval; |
| 2799 | unsigned delay = HUB_SHORT_RESET_TIME; | 2853 | unsigned delay = HUB_SHORT_RESET_TIME; |
| 2800 | enum usb_device_speed oldspeed = udev->speed; | 2854 | enum usb_device_speed oldspeed = udev->speed; |
| 2801 | char *speed, *type; | 2855 | const char *speed; |
| 2802 | int devnum = udev->devnum; | 2856 | int devnum = udev->devnum; |
| 2803 | 2857 | ||
| 2804 | /* root hub ports have a slightly longer reset period | 2858 | /* root hub ports have a slightly longer reset period |
| @@ -2819,7 +2873,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, · 14 unmodified lines | |||
| 2819 | 2873 | ||
| 2820 | /* Reset the device; full speed may morph to high speed */ | 2874 | /* Reset the device; full speed may morph to high speed */ |
| 2821 | /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ | 2875 | /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ |
| 2822 | retval = hub_port_reset(hub, port1, udev, delay); | 2876 | retval = hub_port_reset(hub, port1, udev, delay, false); |
| 2823 | if (retval < 0) /* error or disconnect */ | 2877 | if (retval < 0) /* error or disconnect */ |
| 2824 | goto fail; | 2878 | goto fail; |
| 2825 | /* success, speed is known */ | 2879 | /* success, speed is known */ |
| @@ -2858,25 +2912,16 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, · 32 unmodified lines | |||
| 2858 | default: | 2912 | default: |
| 2859 | goto fail; | 2913 | goto fail; |
| 2860 | } | 2914 | } |
| 2861 | 2915 | ||
| 2862 | type = ""; | 2916 | if (udev->speed == USB_SPEED_WIRELESS) |
| 2863 | switch (udev->speed) { | 2917 | speed = "variable speed Wireless"; |
| 2864 | case USB_SPEED_LOW: speed = "low"; break; | 2918 | else |
| 2865 | case USB_SPEED_FULL: speed = "full"; break; | 2919 | speed = usb_speed_string(udev->speed); |
| 2866 | case USB_SPEED_HIGH: speed = "high"; break; | 2920 | |
| 2867 | case USB_SPEED_SUPER: | ||
| 2868 | speed = "super"; | ||
| 2869 | break; | ||
| 2870 | case USB_SPEED_WIRELESS: | ||
| 2871 | speed = "variable"; | ||
| 2872 | type = "Wireless "; | ||
| 2873 | break; | ||
| 2874 | default: speed = "?"; break; | ||
| 2875 | } | ||
| 2876 | if (udev->speed != USB_SPEED_SUPER) | 2921 | if (udev->speed != USB_SPEED_SUPER) |
| 2877 | dev_info(&udev->dev, | 2922 | dev_info(&udev->dev, |
| 2878 | "%s %s speed %sUSB device number %d using %s\n", | 2923 | "%s %s USB device number %d using %s\n", |
| 2879 | (udev->config) ? "reset" : "new", speed, type, | 2924 | (udev->config) ? "reset" : "new", speed, |
| 2880 | devnum, udev->bus->controller->driver->name); | 2925 | devnum, udev->bus->controller->driver->name); |
| 2881 | 2926 | ||
| 2882 | /* Set up TT records, if needed */ | 2927 | /* Set up TT records, if needed */ |
| @@ -2949,7 +2994,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, · 66 unmodified lines | |||
| 2949 | buf->bMaxPacketSize0; | 2994 | buf->bMaxPacketSize0; |
| 2950 | kfree(buf); | 2995 | kfree(buf); |
| 2951 | 2996 | ||
| 2952 | retval = hub_port_reset(hub, port1, udev, delay); | 2997 | retval = hub_port_reset(hub, port1, udev, delay, false); |
| 2953 | if (retval < 0) /* error or disconnect */ | 2998 | if (retval < 0) /* error or disconnect */ |
| 2954 | goto fail; | 2999 | goto fail; |
| 2955 | if (oldspeed != udev->speed) { | 3000 | if (oldspeed != udev->speed) { |
| @@ -3023,7 +3068,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, · 67 unmodified lines | |||
| 3023 | i = 512; | 3068 | i = 512; |
| 3024 | else | 3069 | else |
| 3025 | i = udev->descriptor.bMaxPacketSize0; | 3070 | i = udev->descriptor.bMaxPacketSize0; |
| 3026 | if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) { | 3071 | if (usb_endpoint_maxp(&udev->ep0.desc) != i) { |
| 3027 | if (udev->speed == USB_SPEED_LOW || | 3072 | if (udev->speed == USB_SPEED_LOW || |
| 3028 | !(i == 8 || i == 16 || i == 32 || i == 64)) { | 3073 | !(i == 8 || i == 16 || i == 32 || i == 64)) { |
| 3029 | dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); | 3074 | dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); |
| @@ -3047,6 +3092,15 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, · 17 unmodified lines | |||
| 3047 | goto fail; | 3092 | goto fail; |
| 3048 | } | 3093 | } |
| 3049 | 3094 | ||
| 3095 | if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) { | ||
| 3096 | retval = usb_get_bos_descriptor(udev); | ||
| 3097 | if (!retval) { | ||
| 3098 | if (udev->bos->ext_cap && (USB_LPM_SUPPORT & | ||
| 3099 | le32_to_cpu(udev->bos->ext_cap->bmAttributes))) | ||
| 3100 | udev->lpm_capable = 1; | ||
| 3101 | } | ||
| 3102 | } | ||
| 3103 | |||
| 3050 | retval = 0; | 3104 | retval = 0; |
| 3051 | /* notify HCD that we have a device connected and addressed */ | 3105 | /* notify HCD that we have a device connected and addressed */ |
| 3052 | if (hcd->driver->update_device) | 3106 | if (hcd->driver->update_device) |
| @@ -3570,7 +3624,8 @@ static void hub_events(void) · 517 unmodified lines | |||
| 3570 | (portstatus & USB_PORT_STAT_LINK_STATE) | 3624 | (portstatus & USB_PORT_STAT_LINK_STATE) |
| 3571 | == USB_SS_PORT_LS_SS_INACTIVE) { | 3625 | == USB_SS_PORT_LS_SS_INACTIVE) { |
| 3572 | dev_dbg(hub_dev, "warm reset port %d\n", i); | 3626 | dev_dbg(hub_dev, "warm reset port %d\n", i); |
| 3573 | hub_port_warm_reset(hub, i); | 3627 | hub_port_reset(hub, i, NULL, |
| 3628 | HUB_BH_RESET_TIME, true); | ||
| 3574 | } | 3629 | } |
| 3575 | 3630 | ||
| 3576 | if (connect_change) | 3631 | if (connect_change) |
| @@ -435,7 +435,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, · 434 unmodified lines | |||
| 435 | 435 | ||
| 436 | len = sg->length; | 436 | len = sg->length; |
| 437 | if (length) { | 437 | if (length) { |
| 438 | len = min_t(unsigned, len, length); | 438 | len = min_t(size_t, len, length); |
| 439 | length -= len; | 439 | length -= len; |
| 440 | if (length == 0) | 440 | if (length == 0) |
| 441 | io->entries = i + 1; | 441 | io->entries = i + 1; |
| @@ -38,6 +38,27 @@ static const struct usb_device_id usb_quirk_list[] = { · 37 unmodified lines | |||
| 38 | /* Creative SB Audigy 2 NX */ | 38 | /* Creative SB Audigy 2 NX */ |
| 39 | { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, | 39 | { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 40 | 40 | ||
| 41 | /* Logitech Webcam C200 */ | ||
| 42 | { USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 43 | |||
| 44 | /* Logitech Webcam C250 */ | ||
| 45 | { USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 46 | |||
| 47 | /* Logitech Webcam C300 */ | ||
| 48 | { USB_DEVICE(0x046d, 0x0805), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 49 | |||
| 50 | /* Logitech Webcam B/C500 */ | ||
| 51 | { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 52 | |||
| 53 | /* Logitech Webcam Pro 9000 */ | ||
| 54 | { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 55 | |||
| 56 | /* Logitech Webcam C310 */ | ||
| 57 | { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 58 | |||
| 59 | /* Logitech Webcam C270 */ | ||
| 60 | { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 61 | |||
| 41 | /* Logitech Harmony 700-series */ | 62 | /* Logitech Harmony 700-series */ |
| 42 | { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, | 63 | { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 43 | 64 | ||
| @@ -69,6 +90,9 @@ static const struct usb_device_id usb_quirk_list[] = { · 25 unmodified lines | |||
| 69 | { USB_DEVICE(0x06a3, 0x0006), .driver_info = | 90 | { USB_DEVICE(0x06a3, 0x0006), .driver_info = |
| 70 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 91 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
| 71 | 92 | ||
| 93 | /* Guillemot Webcam Hercules Dualpix Exchange*/ | ||
| 94 | { USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 95 | |||
| 72 | /* M-Systems Flash Disk Pioneers */ | 96 | /* M-Systems Flash Disk Pioneers */ |
| 73 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 97 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 74 | 98 | ||
| @@ -412,6 +412,56 @@ set_level(struct device *dev, struct device_attribute *attr, · 411 unmodified lines | |||
| 412 | 412 | ||
| 413 | static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); | 413 | static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); |
| 414 | 414 | ||
| 415 | static ssize_t | ||
| 416 | show_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, | ||
| 417 | char *buf) | ||
| 418 | { | ||
| 419 | struct usb_device *udev = to_usb_device(dev); | ||
| 420 | const char *p; | ||
| 421 | |||
| 422 | if (udev->usb2_hw_lpm_enabled == 1) | ||
| 423 | p = "enabled"; | ||
| 424 | else | ||
| 425 | p = "disabled"; | ||
| 426 | |||
| 427 | return sprintf(buf, "%s\n", p); | ||
| 428 | } | ||
| 429 | |||
| 430 | static ssize_t | ||
| 431 | set_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, | ||
| 432 | const char *buf, size_t count) | ||
| 433 | { | ||
| 434 | struct usb_device *udev = to_usb_device(dev); | ||
| 435 | bool value; | ||
| 436 | int ret; | ||
| 437 | |||
| 438 | usb_lock_device(udev); | ||
| 439 | |||
| 440 | ret = strtobool(buf, &value); | ||
| 441 | |||
| 442 | if (!ret) | ||
| 443 | ret = usb_set_usb2_hardware_lpm(udev, value); | ||
| 444 | |||
| 445 | usb_unlock_device(udev); | ||
| 446 | |||
| 447 | if (!ret) | ||
| 448 | return count; | ||
| 449 | |||
| 450 | return ret; | ||
| 451 | } | ||
| 452 | |||
| 453 | static DEVICE_ATTR(usb2_hardware_lpm, S_IRUGO | S_IWUSR, show_usb2_hardware_lpm, | ||
| 454 | set_usb2_hardware_lpm); | ||
| 455 | |||
| 456 | static struct attribute *usb2_hardware_lpm_attr[] = { | ||
| 457 | &dev_attr_usb2_hardware_lpm.attr, | ||
| 458 | NULL, | ||
| 459 | }; | ||
| 460 | static struct attribute_group usb2_hardware_lpm_attr_group = { | ||
| 461 | .name = power_group_name, | ||
| 462 | .attrs = usb2_hardware_lpm_attr, | ||
| 463 | }; | ||
| 464 | |||
| 415 | static struct attribute *power_attrs[] = { | 465 | static struct attribute *power_attrs[] = { |
| 416 | &dev_attr_autosuspend.attr, | 466 | &dev_attr_autosuspend.attr, |
| 417 | &dev_attr_level.attr, | 467 | &dev_attr_level.attr, |
| @@ -428,13 +478,20 @@ static int add_power_attributes(struct device *dev) · 10 unmodified lines | |||
| 428 | { | 478 | { |
| 429 | int rc = 0; | 479 | int rc = 0; |
| 430 | 480 | ||
| 431 | if (is_usb_device(dev)) | 481 | if (is_usb_device(dev)) { |
| 482 | struct usb_device *udev = to_usb_device(dev); | ||
| 432 | rc = sysfs_merge_group(&dev->kobj, &power_attr_group); | 483 | rc = sysfs_merge_group(&dev->kobj, &power_attr_group); |
| 484 | if (udev->usb2_hw_lpm_capable == 1) | ||
| 485 | rc = sysfs_merge_group(&dev->kobj, | ||
| 486 | &usb2_hardware_lpm_attr_group); | ||
| 487 | } | ||
| 488 | |||
| 433 | return rc; | 489 | return rc; |
| 434 | } | 490 | } |
| 435 | 491 | ||
| 436 | static void remove_power_attributes(struct device *dev) | 492 | static void remove_power_attributes(struct device *dev) |
| 437 | { | 493 | { |
| 494 | sysfs_unmerge_group(&dev->kobj, &usb2_hardware_lpm_attr_group); | ||
| 438 | sysfs_unmerge_group(&dev->kobj, &power_attr_group); | 495 | sysfs_unmerge_group(&dev->kobj, &power_attr_group); |
| 439 | } | 496 | } |
| 440 | 497 | ||
| @@ -350,7 +350,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) · 349 unmodified lines | |||
| 350 | dev->state < USB_STATE_CONFIGURED) | 350 | dev->state < USB_STATE_CONFIGURED) |
| 351 | return -ENODEV; | 351 | return -ENODEV; |
| 352 | 352 | ||
| 353 | max = le16_to_cpu(ep->desc.wMaxPacketSize); | 353 | max = usb_endpoint_maxp(&ep->desc); |
| 354 | if (max <= 0) { | 354 | if (max <= 0) { |
| 355 | dev_dbg(&dev->dev, | 355 | dev_dbg(&dev->dev, |
| 356 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", | 356 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", |
| @@ -225,6 +225,7 @@ static void usb_release_dev(struct device *dev) · 224 unmodified lines | |||
| 225 | hcd = bus_to_hcd(udev->bus); | 225 | hcd = bus_to_hcd(udev->bus); |
| 226 | 226 | ||
| 227 | usb_destroy_configuration(udev); | 227 | usb_destroy_configuration(udev); |
| 228 | usb_release_bos_descriptor(udev); | ||
| 228 | usb_put_hcd(hcd); | 229 | usb_put_hcd(hcd); |
| 229 | kfree(udev->product); | 230 | kfree(udev->product); |
| 230 | kfree(udev->manufacturer); | 231 | kfree(udev->manufacturer); |
| @@ -28,6 +28,8 @@ extern int usb_remove_device(struct usb_device *udev); · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | extern int usb_get_device_descriptor(struct usb_device *dev, | 29 | extern int usb_get_device_descriptor(struct usb_device *dev, |
| 30 | unsigned int size); | 30 | unsigned int size); |
| 31 | extern int usb_get_bos_descriptor(struct usb_device *dev); | ||
| 32 | extern void usb_release_bos_descriptor(struct usb_device *dev); | ||
| 31 | extern char *usb_cache_string(struct usb_device *udev, int index); | 33 | extern char *usb_cache_string(struct usb_device *udev, int index); |
| 32 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 34 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
| 33 | extern int usb_choose_configuration(struct usb_device *udev); | 35 | extern int usb_choose_configuration(struct usb_device *udev); |
| @@ -80,6 +82,7 @@ extern int usb_remote_wakeup(struct usb_device *dev); · 46 unmodified lines | |||
| 80 | extern int usb_runtime_suspend(struct device *dev); | 82 | extern int usb_runtime_suspend(struct device *dev); |
| 81 | extern int usb_runtime_resume(struct device *dev); | 83 | extern int usb_runtime_resume(struct device *dev); |
| 82 | extern int usb_runtime_idle(struct device *dev); | 84 | extern int usb_runtime_idle(struct device *dev); |
| 85 | extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable); | ||
| 83 | 86 | ||
| 84 | #else | 87 | #else |
| 85 | 88 | ||
| @@ -94,6 +97,10 @@ static inline int usb_remote_wakeup(struct usb_device *udev) · 8 unmodified lines | |||
| 94 | return 0; | 97 | return 0; |
| 95 | } | 98 | } |
| 96 | 99 | ||
| 100 | static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) | ||
| 101 | { | ||
| 102 | return 0; | ||
| 103 | } | ||
| 97 | #endif | 104 | #endif |
| 98 | 105 | ||
| 99 | extern struct bus_type usb_bus_type; | 106 | extern struct bus_type usb_bus_type; |
| @@ -0,0 +1,25 @@ | |||
| 1 | config USB_DWC3 | ||
| 2 | tristate "DesignWare USB3 DRD Core Support" | ||
| 3 | depends on (USB || USB_GADGET) | ||
| 4 | select USB_OTG_UTILS | ||
| 5 | help | ||
| 6 | Say Y or M here if your system has a Dual Role SuperSpeed | ||
| 7 | USB controller based on the DesignWare USB3 IP Core. | ||
| 8 | |||
| 9 | If you choose to build this driver is a dynamically linked | ||
| 10 | module, the module will be called dwc3.ko. | ||
| 11 | |||
| 12 | if USB_DWC3 | ||
| 13 | |||
| 14 | config USB_DWC3_DEBUG | ||
| 15 | bool "Enable Debugging Messages" | ||
| 16 | help | ||
| 17 | Say Y here to enable debugging messages on DWC3 Driver. | ||
| 18 | |||
| 19 | config USB_DWC3_VERBOSE | ||
| 20 | bool "Enable Verbose Debugging Messages" | ||
| 21 | depends on USB_DWC3_DEBUG | ||
| 22 | help | ||
| 23 | Say Y here to enable verbose debugging messages on DWC3 Driver. | ||
| 24 | |||
| 25 | endif | ||
| @@ -0,0 +1,36 @@ | |||
| 1 | ccflags-$(CONFIG_USB_DWC3_DEBUG) := -DDEBUG | ||
| 2 | ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG | ||
| 3 | |||
| 4 | obj-$(CONFIG_USB_DWC3) += dwc3.o | ||
| 5 | |||
| 6 | dwc3-y := core.o | ||
| 7 | |||
| 8 | ifneq ($(CONFIG_USB_GADGET_DWC3),) | ||
| 9 | dwc3-y += gadget.o ep0.o | ||
| 10 | endif | ||
| 11 | |||
| 12 | ifneq ($(CONFIG_DEBUG_FS),) | ||
| 13 | dwc3-y += debugfs.o | ||
| 14 | endif | ||
| 15 | |||
| 16 | ## | ||
| 17 | # Platform-specific glue layers go here | ||
| 18 | # | ||
| 19 | # NOTICE: Make sure your glue layer doesn't depend on anything | ||
| 20 | # which is arch-specific and that it compiles on all situations. | ||
| 21 | # | ||
| 22 | # We want to keep this requirement in order to be able to compile | ||
| 23 | # the entire driver (with all its glue layers) on several architectures | ||
| 24 | # and make sure it compiles fine. This will also help with allmodconfig | ||
| 25 | # and allyesconfig builds. | ||
| 26 | # | ||
| 27 | # The only exception is the PCI glue layer, but that's only because | ||
| 28 | # PCI doesn't provide nops if CONFIG_PCI isn't enabled. | ||
| 29 | ## | ||
| 30 | |||
| 31 | obj-$(CONFIG_USB_DWC3) += dwc3-omap.o | ||
| 32 | |||
| 33 | ifneq ($(CONFIG_PCI),) | ||
| 34 | obj-$(CONFIG_USB_DWC3) += dwc3-pci.o | ||
| 35 | endif | ||
| 36 | |||
| @@ -0,0 +1,484 @@ | |||
| 1 | /** | ||
| 2 | * core.c - DesignWare USB3 DRD Controller Core file | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/module.h> | ||
| 40 | #include <linux/kernel.h> | ||
| 41 | #include <linux/slab.h> | ||
| 42 | #include <linux/spinlock.h> | ||
| 43 | #include <linux/platform_device.h> | ||
| 44 | #include <linux/pm_runtime.h> | ||
| 45 | #include <linux/interrupt.h> | ||
| 46 | #include <linux/ioport.h> | ||
| 47 | #include <linux/io.h> | ||
| 48 | #include <linux/list.h> | ||
| 49 | #include <linux/delay.h> | ||
| 50 | #include <linux/dma-mapping.h> | ||
| 51 | |||
| 52 | #include <linux/usb/ch9.h> | ||
| 53 | #include <linux/usb/gadget.h> | ||
| 54 | #include <linux/module.h> | ||
| 55 | |||
| 56 | #include "core.h" | ||
| 57 | #include "gadget.h" | ||
| 58 | #include "io.h" | ||
| 59 | |||
| 60 | #include "debug.h" | ||
| 61 | |||
| 62 | /** | ||
| 63 | * dwc3_core_soft_reset - Issues core soft reset and PHY reset | ||
| 64 | * @dwc: pointer to our context structure | ||
| 65 | */ | ||
| 66 | static void dwc3_core_soft_reset(struct dwc3 *dwc) | ||
| 67 | { | ||
| 68 | u32 reg; | ||
| 69 | |||
| 70 | /* Before Resetting PHY, put Core in Reset */ | ||
| 71 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | ||
| 72 | reg |= DWC3_GCTL_CORESOFTRESET; | ||
| 73 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | ||
| 74 | |||
| 75 | /* Assert USB3 PHY reset */ | ||
| 76 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); | ||
| 77 | reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST; | ||
| 78 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); | ||
| 79 | |||
| 80 | /* Assert USB2 PHY reset */ | ||
| 81 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | ||
| 82 | reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; | ||
| 83 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | ||
| 84 | |||
| 85 | mdelay(100); | ||
| 86 | |||
| 87 | /* Clear USB3 PHY reset */ | ||
| 88 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); | ||
| 89 | reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; | ||
| 90 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); | ||
| 91 | |||
| 92 | /* Clear USB2 PHY reset */ | ||
| 93 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | ||
| 94 | reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; | ||
| 95 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | ||
| 96 | |||
| 97 | /* After PHYs are stable we can take Core out of reset state */ | ||
| 98 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | ||
| 99 | reg &= ~DWC3_GCTL_CORESOFTRESET; | ||
| 100 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | ||
| 101 | } | ||
| 102 | |||
| 103 | /** | ||
| 104 | * dwc3_free_one_event_buffer - Frees one event buffer | ||
| 105 | * @dwc: Pointer to our controller context structure | ||
| 106 | * @evt: Pointer to event buffer to be freed | ||
| 107 | */ | ||
| 108 | static void dwc3_free_one_event_buffer(struct dwc3 *dwc, | ||
| 109 | struct dwc3_event_buffer *evt) | ||
| 110 | { | ||
| 111 | dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma); | ||
| 112 | kfree(evt); | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * dwc3_alloc_one_event_buffer - Allocated one event buffer structure | ||
| 117 | * @dwc: Pointer to our controller context structure | ||
| 118 | * @length: size of the event buffer | ||
| 119 | * | ||
| 120 | * Returns a pointer to the allocated event buffer structure on succes | ||
| 121 | * otherwise ERR_PTR(errno). | ||
| 122 | */ | ||
| 123 | static struct dwc3_event_buffer *__devinit | ||
| 124 | dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) | ||
| 125 | { | ||
| 126 | struct dwc3_event_buffer *evt; | ||
| 127 | |||
| 128 | evt = kzalloc(sizeof(*evt), GFP_KERNEL); | ||
| 129 | if (!evt) | ||
| 130 | return ERR_PTR(-ENOMEM); | ||
| 131 | |||
| 132 | evt->dwc = dwc; | ||
| 133 | evt->length = length; | ||
| 134 | evt->buf = dma_alloc_coherent(dwc->dev, length, | ||
| 135 | &evt->dma, GFP_KERNEL); | ||
| 136 | if (!evt->buf) { | ||
| 137 | kfree(evt); | ||
| 138 | return ERR_PTR(-ENOMEM); | ||
| 139 | } | ||
| 140 | |||
| 141 | return evt; | ||
| 142 | } | ||
| 143 | |||
| 144 | /** | ||
| 145 | * dwc3_free_event_buffers - frees all allocated event buffers | ||
| 146 | * @dwc: Pointer to our controller context structure | ||
| 147 | */ | ||
| 148 | static void dwc3_free_event_buffers(struct dwc3 *dwc) | ||
| 149 | { | ||
| 150 | struct dwc3_event_buffer *evt; | ||
| 151 | int i; | ||
| 152 | |||
| 153 | for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) { | ||
| 154 | evt = dwc->ev_buffs[i]; | ||
| 155 | if (evt) { | ||
| 156 | dwc3_free_one_event_buffer(dwc, evt); | ||
| 157 | dwc->ev_buffs[i] = NULL; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | /** | ||
| 163 | * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length | ||
| 164 | * @dwc: Pointer to out controller context structure | ||
| 165 | * @num: number of event buffers to allocate | ||
| 166 | * @length: size of event buffer | ||
| 167 | * | ||
| 168 | * Returns 0 on success otherwise negative errno. In error the case, dwc | ||
| 169 | * may contain some buffers allocated but not all which were requested. | ||
| 170 | */ | ||
| 171 | static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned num, | ||
| 172 | unsigned length) | ||
| 173 | { | ||
| 174 | int i; | ||
| 175 | |||
| 176 | for (i = 0; i < num; i++) { | ||
| 177 | struct dwc3_event_buffer *evt; | ||
| 178 | |||
| 179 | evt = dwc3_alloc_one_event_buffer(dwc, length); | ||
| 180 | if (IS_ERR(evt)) { | ||
| 181 | dev_err(dwc->dev, "can't allocate event buffer\n"); | ||
| 182 | return PTR_ERR(evt); | ||
| 183 | } | ||
| 184 | dwc->ev_buffs[i] = evt; | ||
| 185 | } | ||
| 186 | |||
| 187 | return 0; | ||
| 188 | } | ||
| 189 | |||
| 190 | /** | ||
| 191 | * dwc3_event_buffers_setup - setup our allocated event buffers | ||
| 192 | * @dwc: Pointer to out controller context structure | ||
| 193 | * | ||
| 194 | * Returns 0 on success otherwise negative errno. | ||
| 195 | */ | ||
| 196 | static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc) | ||
| 197 | { | ||
| 198 | struct dwc3_event_buffer *evt; | ||
| 199 | int n; | ||
| 200 | |||
| 201 | for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) { | ||
| 202 | evt = dwc->ev_buffs[n]; | ||
| 203 | dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n", | ||
| 204 | evt->buf, (unsigned long long) evt->dma, | ||
| 205 | evt->length); | ||
| 206 | |||
| 207 | dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), | ||
| 208 | lower_32_bits(evt->dma)); | ||
| 209 | dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), | ||
| 210 | upper_32_bits(evt->dma)); | ||
| 211 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), | ||
| 212 | evt->length & 0xffff); | ||
| 213 | dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0); | ||
| 214 | } | ||
| 215 | |||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | static void dwc3_event_buffers_cleanup(struct dwc3 *dwc) | ||
| 220 | { | ||
| 221 | struct dwc3_event_buffer *evt; | ||
| 222 | int n; | ||
| 223 | |||
| 224 | for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) { | ||
| 225 | evt = dwc->ev_buffs[n]; | ||
| 226 | dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0); | ||
| 227 | dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0); | ||
| 228 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0); | ||
| 229 | dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0); | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc) | ||
| 234 | { | ||
| 235 | struct dwc3_hwparams *parms = &dwc->hwparams; | ||
| 236 | |||
| 237 | parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0); | ||
| 238 | parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1); | ||
| 239 | parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2); | ||
| 240 | parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3); | ||
| 241 | parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4); | ||
| 242 | parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5); | ||
| 243 | parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6); | ||
| 244 | parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7); | ||
| 245 | parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); | ||
| 246 | } | ||
| 247 | |||
| 248 | /** | ||
| 249 | * dwc3_core_init - Low-level initialization of DWC3 Core | ||
| 250 | * @dwc: Pointer to our controller context structure | ||
| 251 | * | ||
| 252 | * Returns 0 on success otherwise negative errno. | ||
| 253 | */ | ||
| 254 | static int __devinit dwc3_core_init(struct dwc3 *dwc) | ||
| 255 | { | ||
| 256 | unsigned long timeout; | ||
| 257 | u32 reg; | ||
| 258 | int ret; | ||
| 259 | |||
| 260 | reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); | ||
| 261 | /* This should read as U3 followed by revision number */ | ||
| 262 | if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) { | ||
| 263 | dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); | ||
| 264 | ret = -ENODEV; | ||
| 265 | goto err0; | ||
| 266 | } | ||
| 267 | dwc->revision = reg & DWC3_GSNPSREV_MASK; | ||
| 268 | |||
| 269 | dwc3_core_soft_reset(dwc); | ||
| 270 | |||
| 271 | /* issue device SoftReset too */ | ||
| 272 | timeout = jiffies + msecs_to_jiffies(500); | ||
| 273 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); | ||
| 274 | do { | ||
| 275 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
| 276 | if (!(reg & DWC3_DCTL_CSFTRST)) | ||
| 277 | break; | ||
| 278 | |||
| 279 | if (time_after(jiffies, timeout)) { | ||
| 280 | dev_err(dwc->dev, "Reset Timed Out\n"); | ||
| 281 | ret = -ETIMEDOUT; | ||
| 282 | goto err0; | ||
| 283 | } | ||
| 284 | |||
| 285 | cpu_relax(); | ||
| 286 | } while (true); | ||
| 287 | |||
| 288 | ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_NUM, | ||
| 289 | DWC3_EVENT_BUFFERS_SIZE); | ||
| 290 | if (ret) { | ||
| 291 | dev_err(dwc->dev, "failed to allocate event buffers\n"); | ||
| 292 | ret = -ENOMEM; | ||
| 293 | goto err1; | ||
| 294 | } | ||
| 295 | |||
| 296 | ret = dwc3_event_buffers_setup(dwc); | ||
| 297 | if (ret) { | ||
| 298 | dev_err(dwc->dev, "failed to setup event buffers\n"); | ||
| 299 | goto err1; | ||
| 300 | } | ||
| 301 | |||
| 302 | dwc3_cache_hwparams(dwc); | ||
| 303 | |||
| 304 | return 0; | ||
| 305 | |||
| 306 | err1: | ||
| 307 | dwc3_free_event_buffers(dwc); | ||
| 308 | |||
| 309 | err0: | ||
| 310 | return ret; | ||
| 311 | } | ||
| 312 | |||
| 313 | static void dwc3_core_exit(struct dwc3 *dwc) | ||
| 314 | { | ||
| 315 | dwc3_event_buffers_cleanup(dwc); | ||
| 316 | dwc3_free_event_buffers(dwc); | ||
| 317 | } | ||
| 318 | |||
| 319 | #define DWC3_ALIGN_MASK (16 - 1) | ||
| 320 | |||
| 321 | static int __devinit dwc3_probe(struct platform_device *pdev) | ||
| 322 | { | ||
| 323 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
| 324 | struct resource *res; | ||
| 325 | struct dwc3 *dwc; | ||
| 326 | void __iomem *regs; | ||
| 327 | unsigned int features = id->driver_data; | ||
| 328 | int ret = -ENOMEM; | ||
| 329 | int irq; | ||
| 330 | void *mem; | ||
| 331 | |||
| 332 | mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); | ||
| 333 | if (!mem) { | ||
| 334 | dev_err(&pdev->dev, "not enough memory\n"); | ||
| 335 | goto err0; | ||
| 336 | } | ||
| 337 | dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); | ||
| 338 | dwc->mem = mem; | ||
| 339 | |||
| 340 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 341 | if (!res) { | ||
| 342 | dev_err(&pdev->dev, "missing resource\n"); | ||
| 343 | goto err1; | ||
| 344 | } | ||
| 345 | |||
| 346 | res = request_mem_region(res->start, resource_size(res), | ||
| 347 | dev_name(&pdev->dev)); | ||
| 348 | if (!res) { | ||
| 349 | dev_err(&pdev->dev, "can't request mem region\n"); | ||
| 350 | goto err1; | ||
| 351 | } | ||
| 352 | |||
| 353 | regs = ioremap(res->start, resource_size(res)); | ||
| 354 | if (!regs) { | ||
| 355 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
| 356 | goto err2; | ||
| 357 | } | ||
| 358 | |||
| 359 | irq = platform_get_irq(pdev, 0); | ||
| 360 | if (irq < 0) { | ||
| 361 | dev_err(&pdev->dev, "missing IRQ\n"); | ||
| 362 | goto err3; | ||
| 363 | } | ||
| 364 | |||
| 365 | spin_lock_init(&dwc->lock); | ||
| 366 | platform_set_drvdata(pdev, dwc); | ||
| 367 | |||
| 368 | dwc->regs = regs; | ||
| 369 | dwc->regs_size = resource_size(res); | ||
| 370 | dwc->dev = &pdev->dev; | ||
| 371 | dwc->irq = irq; | ||
| 372 | |||
| 373 | pm_runtime_enable(&pdev->dev); | ||
| 374 | pm_runtime_get_sync(&pdev->dev); | ||
| 375 | pm_runtime_forbid(&pdev->dev); | ||
| 376 | |||
| 377 | ret = dwc3_core_init(dwc); | ||
| 378 | if (ret) { | ||
| 379 | dev_err(&pdev->dev, "failed to initialize core\n"); | ||
| 380 | goto err3; | ||
| 381 | } | ||
| 382 | |||
| 383 | if (features & DWC3_HAS_PERIPHERAL) { | ||
| 384 | ret = dwc3_gadget_init(dwc); | ||
| 385 | if (ret) { | ||
| 386 | dev_err(&pdev->dev, "failed to initialized gadget\n"); | ||
| 387 | goto err4; | ||
| 388 | } | ||
| 389 | } | ||
| 390 | |||
| 391 | ret = dwc3_debugfs_init(dwc); | ||
| 392 | if (ret) { | ||
| 393 | dev_err(&pdev->dev, "failed to initialize debugfs\n"); | ||
| 394 | goto err5; | ||
| 395 | } | ||
| 396 | |||
| 397 | pm_runtime_allow(&pdev->dev); | ||
| 398 | |||
| 399 | return 0; | ||
| 400 | |||
| 401 | err5: | ||
| 402 | if (features & DWC3_HAS_PERIPHERAL) | ||
| 403 | dwc3_gadget_exit(dwc); | ||
| 404 | |||
| 405 | err4: | ||
| 406 | dwc3_core_exit(dwc); | ||
| 407 | |||
| 408 | err3: | ||
| 409 | iounmap(regs); | ||
| 410 | |||
| 411 | err2: | ||
| 412 | release_mem_region(res->start, resource_size(res)); | ||
| 413 | |||
| 414 | err1: | ||
| 415 | kfree(dwc->mem); | ||
| 416 | |||
| 417 | err0: | ||
| 418 | return ret; | ||
| 419 | } | ||
| 420 | |||
| 421 | static int __devexit dwc3_remove(struct platform_device *pdev) | ||
| 422 | { | ||
| 423 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
| 424 | struct dwc3 *dwc = platform_get_drvdata(pdev); | ||
| 425 | struct resource *res; | ||
| 426 | unsigned int features = id->driver_data; | ||
| 427 | |||
| 428 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 429 | |||
| 430 | pm_runtime_put(&pdev->dev); | ||
| 431 | pm_runtime_disable(&pdev->dev); | ||
| 432 | |||
| 433 | dwc3_debugfs_exit(dwc); | ||
| 434 | |||
| 435 | if (features & DWC3_HAS_PERIPHERAL) | ||
| 436 | dwc3_gadget_exit(dwc); | ||
| 437 | |||
| 438 | dwc3_core_exit(dwc); | ||
| 439 | release_mem_region(res->start, resource_size(res)); | ||
| 440 | iounmap(dwc->regs); | ||
| 441 | kfree(dwc->mem); | ||
| 442 | |||
| 443 | return 0; | ||
| 444 | } | ||
| 445 | |||
| 446 | static const struct platform_device_id dwc3_id_table[] __devinitconst = { | ||
| 447 | { | ||
| 448 | .name = "dwc3-omap", | ||
| 449 | .driver_data = (DWC3_HAS_PERIPHERAL | ||
| 450 | | DWC3_HAS_XHCI | ||
| 451 | | DWC3_HAS_OTG), | ||
| 452 | }, | ||
| 453 | { | ||
| 454 | .name = "dwc3-pci", | ||
| 455 | .driver_data = DWC3_HAS_PERIPHERAL, | ||
| 456 | }, | ||
| 457 | { }, /* Terminating Entry */ | ||
| 458 | }; | ||
| 459 | MODULE_DEVICE_TABLE(platform, dwc3_id_table); | ||
| 460 | |||
| 461 | static struct platform_driver dwc3_driver = { | ||
| 462 | .probe = dwc3_probe, | ||
| 463 | .remove = __devexit_p(dwc3_remove), | ||
| 464 | .driver = { | ||
| 465 | .name = "dwc3", | ||
| 466 | }, | ||
| 467 | .id_table = dwc3_id_table, | ||
| 468 | }; | ||
| 469 | |||
| 470 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | ||
| 471 | MODULE_LICENSE("Dual BSD/GPL"); | ||
| 472 | MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver"); | ||
| 473 | |||
| 474 | static int __devinit dwc3_init(void) | ||
| 475 | { | ||
| 476 | return platform_driver_register(&dwc3_driver); | ||
| 477 | } | ||
| 478 | module_init(dwc3_init); | ||
| 479 | |||
| 480 | static void __exit dwc3_exit(void) | ||
| 481 | { | ||
| 482 | platform_driver_unregister(&dwc3_driver); | ||
| 483 | } | ||
| 484 | module_exit(dwc3_exit); | ||
| @@ -0,0 +1,768 @@ | |||
| 1 | /** | ||
| 2 | * core.h - DesignWare USB3 DRD Core Header | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #ifndef __DRIVERS_USB_DWC3_CORE_H | ||
| 40 | #define __DRIVERS_USB_DWC3_CORE_H | ||
| 41 | |||
| 42 | #include <linux/device.h> | ||
| 43 | #include <linux/spinlock.h> | ||
| 44 | #include <linux/list.h> | ||
| 45 | #include <linux/dma-mapping.h> | ||
| 46 | #include <linux/mm.h> | ||
| 47 | #include <linux/debugfs.h> | ||
| 48 | |||
| 49 | #include <linux/usb/ch9.h> | ||
| 50 | #include <linux/usb/gadget.h> | ||
| 51 | |||
| 52 | /* Global constants */ | ||
| 53 | #define DWC3_ENDPOINTS_NUM 32 | ||
| 54 | |||
| 55 | #define DWC3_EVENT_BUFFERS_NUM 2 | ||
| 56 | #define DWC3_EVENT_BUFFERS_SIZE PAGE_SIZE | ||
| 57 | #define DWC3_EVENT_TYPE_MASK 0xfe | ||
| 58 | |||
| 59 | #define DWC3_EVENT_TYPE_DEV 0 | ||
| 60 | #define DWC3_EVENT_TYPE_CARKIT 3 | ||
| 61 | #define DWC3_EVENT_TYPE_I2C 4 | ||
| 62 | |||
| 63 | #define DWC3_DEVICE_EVENT_DISCONNECT 0 | ||
| 64 | #define DWC3_DEVICE_EVENT_RESET 1 | ||
| 65 | #define DWC3_DEVICE_EVENT_CONNECT_DONE 2 | ||
| 66 | #define DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE 3 | ||
| 67 | #define DWC3_DEVICE_EVENT_WAKEUP 4 | ||
| 68 | #define DWC3_DEVICE_EVENT_EOPF 6 | ||
| 69 | #define DWC3_DEVICE_EVENT_SOF 7 | ||
| 70 | #define DWC3_DEVICE_EVENT_ERRATIC_ERROR 9 | ||
| 71 | #define DWC3_DEVICE_EVENT_CMD_CMPL 10 | ||
| 72 | #define DWC3_DEVICE_EVENT_OVERFLOW 11 | ||
| 73 | |||
| 74 | #define DWC3_GEVNTCOUNT_MASK 0xfffc | ||
| 75 | #define DWC3_GSNPSID_MASK 0xffff0000 | ||
| 76 | #define DWC3_GSNPSREV_MASK 0xffff | ||
| 77 | |||
| 78 | /* Global Registers */ | ||
| 79 | #define DWC3_GSBUSCFG0 0xc100 | ||
| 80 | #define DWC3_GSBUSCFG1 0xc104 | ||
| 81 | #define DWC3_GTXTHRCFG 0xc108 | ||
| 82 | #define DWC3_GRXTHRCFG 0xc10c | ||
| 83 | #define DWC3_GCTL 0xc110 | ||
| 84 | #define DWC3_GEVTEN 0xc114 | ||
| 85 | #define DWC3_GSTS 0xc118 | ||
| 86 | #define DWC3_GSNPSID 0xc120 | ||
| 87 | #define DWC3_GGPIO 0xc124 | ||
| 88 | #define DWC3_GUID 0xc128 | ||
| 89 | #define DWC3_GUCTL 0xc12c | ||
| 90 | #define DWC3_GBUSERRADDR0 0xc130 | ||
| 91 | #define DWC3_GBUSERRADDR1 0xc134 | ||
| 92 | #define DWC3_GPRTBIMAP0 0xc138 | ||
| 93 | #define DWC3_GPRTBIMAP1 0xc13c | ||
| 94 | #define DWC3_GHWPARAMS0 0xc140 | ||
| 95 | #define DWC3_GHWPARAMS1 0xc144 | ||
| 96 | #define DWC3_GHWPARAMS2 0xc148 | ||
| 97 | #define DWC3_GHWPARAMS3 0xc14c | ||
| 98 | #define DWC3_GHWPARAMS4 0xc150 | ||
| 99 | #define DWC3_GHWPARAMS5 0xc154 | ||
| 100 | #define DWC3_GHWPARAMS6 0xc158 | ||
| 101 | #define DWC3_GHWPARAMS7 0xc15c | ||
| 102 | #define DWC3_GDBGFIFOSPACE 0xc160 | ||
| 103 | #define DWC3_GDBGLTSSM 0xc164 | ||
| 104 | #define DWC3_GPRTBIMAP_HS0 0xc180 | ||
| 105 | #define DWC3_GPRTBIMAP_HS1 0xc184 | ||
| 106 | #define DWC3_GPRTBIMAP_FS0 0xc188 | ||
| 107 | #define DWC3_GPRTBIMAP_FS1 0xc18c | ||
| 108 | |||
| 109 | #define DWC3_GUSB2PHYCFG(n) (0xc200 + (n * 0x04)) | ||
| 110 | #define DWC3_GUSB2I2CCTL(n) (0xc240 + (n * 0x04)) | ||
| 111 | |||
| 112 | #define DWC3_GUSB2PHYACC(n) (0xc280 + (n * 0x04)) | ||
| 113 | |||
| 114 | #define DWC3_GUSB3PIPECTL(n) (0xc2c0 + (n * 0x04)) | ||
| 115 | |||
| 116 | #define DWC3_GTXFIFOSIZ(n) (0xc300 + (n * 0x04)) | ||
| 117 | #define DWC3_GRXFIFOSIZ(n) (0xc380 + (n * 0x04)) | ||
| 118 | |||
| 119 | #define DWC3_GEVNTADRLO(n) (0xc400 + (n * 0x10)) | ||
| 120 | #define DWC3_GEVNTADRHI(n) (0xc404 + (n * 0x10)) | ||
| 121 | #define DWC3_GEVNTSIZ(n) (0xc408 + (n * 0x10)) | ||
| 122 | #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) | ||
| 123 | |||
| 124 | #define DWC3_GHWPARAMS8 0xc600 | ||
| 125 | |||
| 126 | /* Device Registers */ | ||
| 127 | #define DWC3_DCFG 0xc700 | ||
| 128 | #define DWC3_DCTL 0xc704 | ||
| 129 | #define DWC3_DEVTEN 0xc708 | ||
| 130 | #define DWC3_DSTS 0xc70c | ||
| 131 | #define DWC3_DGCMDPAR 0xc710 | ||
| 132 | #define DWC3_DGCMD 0xc714 | ||
| 133 | #define DWC3_DALEPENA 0xc720 | ||
| 134 | #define DWC3_DEPCMDPAR2(n) (0xc800 + (n * 0x10)) | ||
| 135 | #define DWC3_DEPCMDPAR1(n) (0xc804 + (n * 0x10)) | ||
| 136 | #define DWC3_DEPCMDPAR0(n) (0xc808 + (n * 0x10)) | ||
| 137 | #define DWC3_DEPCMD(n) (0xc80c + (n * 0x10)) | ||
| 138 | |||
| 139 | /* OTG Registers */ | ||
| 140 | #define DWC3_OCFG 0xcc00 | ||
| 141 | #define DWC3_OCTL 0xcc04 | ||
| 142 | #define DWC3_OEVTEN 0xcc08 | ||
| 143 | #define DWC3_OSTS 0xcc0C | ||
| 144 | |||
| 145 | /* Bit fields */ | ||
| 146 | |||
| 147 | /* Global Configuration Register */ | ||
| 148 | #define DWC3_GCTL_PWRDNSCALE(n) (n << 19) | ||
| 149 | #define DWC3_GCTL_U2RSTECN (1 << 16) | ||
| 150 | #define DWC3_GCTL_RAMCLKSEL(x) ((x & DWC3_GCTL_CLK_MASK) << 6) | ||
| 151 | #define DWC3_GCTL_CLK_BUS (0) | ||
| 152 | #define DWC3_GCTL_CLK_PIPE (1) | ||
| 153 | #define DWC3_GCTL_CLK_PIPEHALF (2) | ||
| 154 | #define DWC3_GCTL_CLK_MASK (3) | ||
| 155 | |||
| 156 | #define DWC3_GCTL_PRTCAPDIR(n) (n << 12) | ||
| 157 | #define DWC3_GCTL_PRTCAP_HOST 1 | ||
| 158 | #define DWC3_GCTL_PRTCAP_DEVICE 2 | ||
| 159 | #define DWC3_GCTL_PRTCAP_OTG 3 | ||
| 160 | |||
| 161 | #define DWC3_GCTL_CORESOFTRESET (1 << 11) | ||
| 162 | #define DWC3_GCTL_SCALEDOWN(n) (n << 4) | ||
| 163 | #define DWC3_GCTL_DISSCRAMBLE (1 << 3) | ||
| 164 | #define DWC3_GCTL_DSBLCLKGTNG (1 << 0) | ||
| 165 | |||
| 166 | /* Global USB2 PHY Configuration Register */ | ||
| 167 | #define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31) | ||
| 168 | #define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6) | ||
| 169 | |||
| 170 | /* Global USB3 PIPE Control Register */ | ||
| 171 | #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) | ||
| 172 | #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) | ||
| 173 | |||
| 174 | /* Global HWPARAMS1 Register */ | ||
| 175 | #define DWC3_GHWPARAMS1_EN_PWROPT(n) ((n & (3 << 24)) >> 24) | ||
| 176 | #define DWC3_GHWPARAMS1_EN_PWROPT_NO 0 | ||
| 177 | #define DWC3_GHWPARAMS1_EN_PWROPT_CLK 1 | ||
| 178 | |||
| 179 | /* Device Configuration Register */ | ||
| 180 | #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3) | ||
| 181 | #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) | ||
| 182 | |||
| 183 | #define DWC3_DCFG_SPEED_MASK (7 << 0) | ||
| 184 | #define DWC3_DCFG_SUPERSPEED (4 << 0) | ||
| 185 | #define DWC3_DCFG_HIGHSPEED (0 << 0) | ||
| 186 | #define DWC3_DCFG_FULLSPEED2 (1 << 0) | ||
| 187 | #define DWC3_DCFG_LOWSPEED (2 << 0) | ||
| 188 | #define DWC3_DCFG_FULLSPEED1 (3 << 0) | ||
| 189 | |||
| 190 | /* Device Control Register */ | ||
| 191 | #define DWC3_DCTL_RUN_STOP (1 << 31) | ||
| 192 | #define DWC3_DCTL_CSFTRST (1 << 30) | ||
| 193 | #define DWC3_DCTL_LSFTRST (1 << 29) | ||
| 194 | |||
| 195 | #define DWC3_DCTL_HIRD_THRES_MASK (0x1f << 24) | ||
| 196 | #define DWC3_DCTL_HIRD_THRES(n) (((n) & DWC3_DCTL_HIRD_THRES_MASK) >> 24) | ||
| 197 | |||
| 198 | #define DWC3_DCTL_APPL1RES (1 << 23) | ||
| 199 | |||
| 200 | #define DWC3_DCTL_INITU2ENA (1 << 12) | ||
| 201 | #define DWC3_DCTL_ACCEPTU2ENA (1 << 11) | ||
| 202 | #define DWC3_DCTL_INITU1ENA (1 << 10) | ||
| 203 | #define DWC3_DCTL_ACCEPTU1ENA (1 << 9) | ||
| 204 | #define DWC3_DCTL_TSTCTRL_MASK (0xf << 1) | ||
| 205 | |||
| 206 | #define DWC3_DCTL_ULSTCHNGREQ_MASK (0x0f << 5) | ||
| 207 | #define DWC3_DCTL_ULSTCHNGREQ(n) (((n) << 5) & DWC3_DCTL_ULSTCHNGREQ_MASK) | ||
| 208 | |||
| 209 | #define DWC3_DCTL_ULSTCHNG_NO_ACTION (DWC3_DCTL_ULSTCHNGREQ(0)) | ||
| 210 | #define DWC3_DCTL_ULSTCHNG_SS_DISABLED (DWC3_DCTL_ULSTCHNGREQ(4)) | ||
| 211 | #define DWC3_DCTL_ULSTCHNG_RX_DETECT (DWC3_DCTL_ULSTCHNGREQ(5)) | ||
| 212 | #define DWC3_DCTL_ULSTCHNG_SS_INACTIVE (DWC3_DCTL_ULSTCHNGREQ(6)) | ||
| 213 | #define DWC3_DCTL_ULSTCHNG_RECOVERY (DWC3_DCTL_ULSTCHNGREQ(8)) | ||
| 214 | #define DWC3_DCTL_ULSTCHNG_COMPLIANCE (DWC3_DCTL_ULSTCHNGREQ(10)) | ||
| 215 | #define DWC3_DCTL_ULSTCHNG_LOOPBACK (DWC3_DCTL_ULSTCHNGREQ(11)) | ||
| 216 | |||
| 217 | /* Device Event Enable Register */ | ||
| 218 | #define DWC3_DEVTEN_VNDRDEVTSTRCVEDEN (1 << 12) | ||
| 219 | #define DWC3_DEVTEN_EVNTOVERFLOWEN (1 << 11) | ||
| 220 | #define DWC3_DEVTEN_CMDCMPLTEN (1 << 10) | ||
| 221 | #define DWC3_DEVTEN_ERRTICERREN (1 << 9) | ||
| 222 | #define DWC3_DEVTEN_SOFEN (1 << 7) | ||
| 223 | #define DWC3_DEVTEN_EOPFEN (1 << 6) | ||
| 224 | #define DWC3_DEVTEN_WKUPEVTEN (1 << 4) | ||
| 225 | #define DWC3_DEVTEN_ULSTCNGEN (1 << 3) | ||
| 226 | #define DWC3_DEVTEN_CONNECTDONEEN (1 << 2) | ||
| 227 | #define DWC3_DEVTEN_USBRSTEN (1 << 1) | ||
| 228 | #define DWC3_DEVTEN_DISCONNEVTEN (1 << 0) | ||
| 229 | |||
| 230 | /* Device Status Register */ | ||
| 231 | #define DWC3_DSTS_PWRUPREQ (1 << 24) | ||
| 232 | #define DWC3_DSTS_COREIDLE (1 << 23) | ||
| 233 | #define DWC3_DSTS_DEVCTRLHLT (1 << 22) | ||
| 234 | |||
| 235 | #define DWC3_DSTS_USBLNKST_MASK (0x0f << 18) | ||
| 236 | #define DWC3_DSTS_USBLNKST(n) (((n) & DWC3_DSTS_USBLNKST_MASK) >> 18) | ||
| 237 | |||
| 238 | #define DWC3_DSTS_RXFIFOEMPTY (1 << 17) | ||
| 239 | |||
| 240 | #define DWC3_DSTS_SOFFN_MASK (0x3ff << 3) | ||
| 241 | #define DWC3_DSTS_SOFFN(n) (((n) & DWC3_DSTS_SOFFN_MASK) >> 3) | ||
| 242 | |||
| 243 | #define DWC3_DSTS_CONNECTSPD (7 << 0) | ||
| 244 | |||
| 245 | #define DWC3_DSTS_SUPERSPEED (4 << 0) | ||
| 246 | #define DWC3_DSTS_HIGHSPEED (0 << 0) | ||
| 247 | #define DWC3_DSTS_FULLSPEED2 (1 << 0) | ||
| 248 | #define DWC3_DSTS_LOWSPEED (2 << 0) | ||
| 249 | #define DWC3_DSTS_FULLSPEED1 (3 << 0) | ||
| 250 | |||
| 251 | /* Device Generic Command Register */ | ||
| 252 | #define DWC3_DGCMD_SET_LMP 0x01 | ||
| 253 | #define DWC3_DGCMD_SET_PERIODIC_PAR 0x02 | ||
| 254 | #define DWC3_DGCMD_XMIT_FUNCTION 0x03 | ||
| 255 | #define DWC3_DGCMD_SELECTED_FIFO_FLUSH 0x09 | ||
| 256 | #define DWC3_DGCMD_ALL_FIFO_FLUSH 0x0a | ||
| 257 | #define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c | ||
| 258 | #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10 | ||
| 259 | |||
| 260 | /* Device Endpoint Command Register */ | ||
| 261 | #define DWC3_DEPCMD_PARAM_SHIFT 16 | ||
| 262 | #define DWC3_DEPCMD_PARAM(x) (x << DWC3_DEPCMD_PARAM_SHIFT) | ||
| 263 | #define DWC3_DEPCMD_GET_RSC_IDX(x) ((x >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f) | ||
| 264 | #define DWC3_DEPCMD_STATUS_MASK (0x0f << 12) | ||
| 265 | #define DWC3_DEPCMD_STATUS(x) ((x & DWC3_DEPCMD_STATUS_MASK) >> 12) | ||
| 266 | #define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11) | ||
| 267 | #define DWC3_DEPCMD_CMDACT (1 << 10) | ||
| 268 | #define DWC3_DEPCMD_CMDIOC (1 << 8) | ||
| 269 | |||
| 270 | #define DWC3_DEPCMD_DEPSTARTCFG (0x09 << 0) | ||
| 271 | #define DWC3_DEPCMD_ENDTRANSFER (0x08 << 0) | ||
| 272 | #define DWC3_DEPCMD_UPDATETRANSFER (0x07 << 0) | ||
| 273 | #define DWC3_DEPCMD_STARTTRANSFER (0x06 << 0) | ||
| 274 | #define DWC3_DEPCMD_CLEARSTALL (0x05 << 0) | ||
| 275 | #define DWC3_DEPCMD_SETSTALL (0x04 << 0) | ||
| 276 | #define DWC3_DEPCMD_GETSEQNUMBER (0x03 << 0) | ||
| 277 | #define DWC3_DEPCMD_SETTRANSFRESOURCE (0x02 << 0) | ||
| 278 | #define DWC3_DEPCMD_SETEPCONFIG (0x01 << 0) | ||
| 279 | |||
| 280 | /* The EP number goes 0..31 so ep0 is always out and ep1 is always in */ | ||
| 281 | #define DWC3_DALEPENA_EP(n) (1 << n) | ||
| 282 | |||
| 283 | #define DWC3_DEPCMD_TYPE_CONTROL 0 | ||
| 284 | #define DWC3_DEPCMD_TYPE_ISOC 1 | ||
| 285 | #define DWC3_DEPCMD_TYPE_BULK 2 | ||
| 286 | #define DWC3_DEPCMD_TYPE_INTR 3 | ||
| 287 | |||
| 288 | /* Structures */ | ||
| 289 | |||
| 290 | struct dwc3_trb_hw; | ||
| 291 | |||
| 292 | /** | ||
| 293 | * struct dwc3_event_buffer - Software event buffer representation | ||
| 294 | * @list: a list of event buffers | ||
| 295 | * @buf: _THE_ buffer | ||
| 296 | * @length: size of this buffer | ||
| 297 | * @dma: dma_addr_t | ||
| 298 | * @dwc: pointer to DWC controller | ||
| 299 | */ | ||
| 300 | struct dwc3_event_buffer { | ||
| 301 | void *buf; | ||
| 302 | unsigned length; | ||
| 303 | unsigned int lpos; | ||
| 304 | |||
| 305 | dma_addr_t dma; | ||
| 306 | |||
| 307 | struct dwc3 *dwc; | ||
| 308 | }; | ||
| 309 | |||
| 310 | #define DWC3_EP_FLAG_STALLED (1 << 0) | ||
| 311 | #define DWC3_EP_FLAG_WEDGED (1 << 1) | ||
| 312 | |||
| 313 | #define DWC3_EP_DIRECTION_TX true | ||
| 314 | #define DWC3_EP_DIRECTION_RX false | ||
| 315 | |||
| 316 | #define DWC3_TRB_NUM 32 | ||
| 317 | #define DWC3_TRB_MASK (DWC3_TRB_NUM - 1) | ||
| 318 | |||
| 319 | /** | ||
| 320 | * struct dwc3_ep - device side endpoint representation | ||
| 321 | * @endpoint: usb endpoint | ||
| 322 | * @request_list: list of requests for this endpoint | ||
| 323 | * @req_queued: list of requests on this ep which have TRBs setup | ||
| 324 | * @trb_pool: array of transaction buffers | ||
| 325 | * @trb_pool_dma: dma address of @trb_pool | ||
| 326 | * @free_slot: next slot which is going to be used | ||
| 327 | * @busy_slot: first slot which is owned by HW | ||
| 328 | * @desc: usb_endpoint_descriptor pointer | ||
| 329 | * @dwc: pointer to DWC controller | ||
| 330 | * @flags: endpoint flags (wedged, stalled, ...) | ||
| 331 | * @current_trb: index of current used trb | ||
| 332 | * @number: endpoint number (1 - 15) | ||
| 333 | * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK | ||
| 334 | * @res_trans_idx: Resource transfer index | ||
| 335 | * @interval: the intervall on which the ISOC transfer is started | ||
| 336 | * @name: a human readable name e.g. ep1out-bulk | ||
| 337 | * @direction: true for TX, false for RX | ||
| 338 | * @stream_capable: true when streams are enabled | ||
| 339 | */ | ||
| 340 | struct dwc3_ep { | ||
| 341 | struct usb_ep endpoint; | ||
| 342 | struct list_head request_list; | ||
| 343 | struct list_head req_queued; | ||
| 344 | |||
| 345 | struct dwc3_trb_hw *trb_pool; | ||
| 346 | dma_addr_t trb_pool_dma; | ||
| 347 | u32 free_slot; | ||
| 348 | u32 busy_slot; | ||
| 349 | const struct usb_endpoint_descriptor *desc; | ||
| 350 | struct dwc3 *dwc; | ||
| 351 | |||
| 352 | unsigned flags; | ||
| 353 | #define DWC3_EP_ENABLED (1 << 0) | ||
| 354 | #define DWC3_EP_STALL (1 << 1) | ||
| 355 | #define DWC3_EP_WEDGE (1 << 2) | ||
| 356 | #define DWC3_EP_BUSY (1 << 4) | ||
| 357 | #define DWC3_EP_PENDING_REQUEST (1 << 5) | ||
| 358 | |||
| 359 | /* This last one is specific to EP0 */ | ||
| 360 | #define DWC3_EP0_DIR_IN (1 << 31) | ||
| 361 | |||
| 362 | unsigned current_trb; | ||
| 363 | |||
| 364 | u8 number; | ||
| 365 | u8 type; | ||
| 366 | u8 res_trans_idx; | ||
| 367 | u32 interval; | ||
| 368 | |||
| 369 | char name[20]; | ||
| 370 | |||
| 371 | unsigned direction:1; | ||
| 372 | unsigned stream_capable:1; | ||
| 373 | }; | ||
| 374 | |||
| 375 | enum dwc3_phy { | ||
| 376 | DWC3_PHY_UNKNOWN = 0, | ||
| 377 | DWC3_PHY_USB3, | ||
| 378 | DWC3_PHY_USB2, | ||
| 379 | }; | ||
| 380 | |||
| 381 | enum dwc3_ep0_next { | ||
| 382 | DWC3_EP0_UNKNOWN = 0, | ||
| 383 | DWC3_EP0_COMPLETE, | ||
| 384 | DWC3_EP0_NRDY_SETUP, | ||
| 385 | DWC3_EP0_NRDY_DATA, | ||
| 386 | DWC3_EP0_NRDY_STATUS, | ||
| 387 | }; | ||
| 388 | |||
| 389 | enum dwc3_ep0_state { | ||
| 390 | EP0_UNCONNECTED = 0, | ||
| 391 | EP0_SETUP_PHASE, | ||
| 392 | EP0_DATA_PHASE, | ||
| 393 | EP0_STATUS_PHASE, | ||
| 394 | }; | ||
| 395 | |||
| 396 | enum dwc3_link_state { | ||
| 397 | /* In SuperSpeed */ | ||
| 398 | DWC3_LINK_STATE_U0 = 0x00, /* in HS, means ON */ | ||
| 399 | DWC3_LINK_STATE_U1 = 0x01, | ||
| 400 | DWC3_LINK_STATE_U2 = 0x02, /* in HS, means SLEEP */ | ||
| 401 | DWC3_LINK_STATE_U3 = 0x03, /* in HS, means SUSPEND */ | ||
| 402 | DWC3_LINK_STATE_SS_DIS = 0x04, | ||
| 403 | DWC3_LINK_STATE_RX_DET = 0x05, /* in HS, means Early Suspend */ | ||
| 404 | DWC3_LINK_STATE_SS_INACT = 0x06, | ||
| 405 | DWC3_LINK_STATE_POLL = 0x07, | ||
| 406 | DWC3_LINK_STATE_RECOV = 0x08, | ||
| 407 | DWC3_LINK_STATE_HRESET = 0x09, | ||
| 408 | DWC3_LINK_STATE_CMPLY = 0x0a, | ||
| 409 | DWC3_LINK_STATE_LPBK = 0x0b, | ||
| 410 | DWC3_LINK_STATE_MASK = 0x0f, | ||
| 411 | }; | ||
| 412 | |||
| 413 | enum dwc3_device_state { | ||
| 414 | DWC3_DEFAULT_STATE, | ||
| 415 | DWC3_ADDRESS_STATE, | ||
| 416 | DWC3_CONFIGURED_STATE, | ||
| 417 | }; | ||
| 418 | |||
| 419 | /** | ||
| 420 | * struct dwc3_trb - transfer request block | ||
| 421 | * @bpl: lower 32bit of the buffer | ||
| 422 | * @bph: higher 32bit of the buffer | ||
| 423 | * @length: buffer size (up to 16mb - 1) | ||
| 424 | * @pcm1: packet count m1 | ||
| 425 | * @trbsts: trb status | ||
| 426 | * 0 = ok | ||
| 427 | * 1 = missed isoc | ||
| 428 | * 2 = setup pending | ||
| 429 | * @hwo: hardware owner of descriptor | ||
| 430 | * @lst: last trb | ||
| 431 | * @chn: chain buffers | ||
| 432 | * @csp: continue on short packets (only supported on isoc eps) | ||
| 433 | * @trbctl: trb control | ||
| 434 | * 1 = normal | ||
| 435 | * 2 = control-setup | ||
| 436 | * 3 = control-status-2 | ||
| 437 | * 4 = control-status-3 | ||
| 438 | * 5 = control-data (first trb of data stage) | ||
| 439 | * 6 = isochronous-first (first trb of service interval) | ||
| 440 | * 7 = isochronous | ||
| 441 | * 8 = link trb | ||
| 442 | * others = reserved | ||
| 443 | * @isp_imi: interrupt on short packet / interrupt on missed isoc | ||
| 444 | * @ioc: interrupt on complete | ||
| 445 | * @sid_sofn: Stream ID / SOF Number | ||
| 446 | */ | ||
| 447 | struct dwc3_trb { | ||
| 448 | u64 bplh; | ||
| 449 | |||
| 450 | union { | ||
| 451 | struct { | ||
| 452 | u32 length:24; | ||
| 453 | u32 pcm1:2; | ||
| 454 | u32 reserved27_26:2; | ||
| 455 | u32 trbsts:4; | ||
| 456 | #define DWC3_TRB_STS_OKAY 0 | ||
| 457 | #define DWC3_TRB_STS_MISSED_ISOC 1 | ||
| 458 | #define DWC3_TRB_STS_SETUP_PENDING 2 | ||
| 459 | }; | ||
| 460 | u32 len_pcm; | ||
| 461 | }; | ||
| 462 | |||
| 463 | union { | ||
| 464 | struct { | ||
| 465 | u32 hwo:1; | ||
| 466 | u32 lst:1; | ||
| 467 | u32 chn:1; | ||
| 468 | u32 csp:1; | ||
| 469 | u32 trbctl:6; | ||
| 470 | u32 isp_imi:1; | ||
| 471 | u32 ioc:1; | ||
| 472 | u32 reserved13_12:2; | ||
| 473 | u32 sid_sofn:16; | ||
| 474 | u32 reserved31_30:2; | ||
| 475 | }; | ||
| 476 | u32 control; | ||
| 477 | }; | ||
| 478 | } __packed; | ||
| 479 | |||
| 480 | /** | ||
| 481 | * struct dwc3_trb_hw - transfer request block (hw format) | ||
| 482 | * @bpl: DW0-3 | ||
| 483 | * @bph: DW4-7 | ||
| 484 | * @size: DW8-B | ||
| 485 | * @trl: DWC-F | ||
| 486 | */ | ||
| 487 | struct dwc3_trb_hw { | ||
| 488 | __le32 bpl; | ||
| 489 | __le32 bph; | ||
| 490 | __le32 size; | ||
| 491 | __le32 ctrl; | ||
| 492 | } __packed; | ||
| 493 | |||
| 494 | static inline void dwc3_trb_to_hw(struct dwc3_trb *nat, struct dwc3_trb_hw *hw) | ||
| 495 | { | ||
| 496 | hw->bpl = cpu_to_le32(lower_32_bits(nat->bplh)); | ||
| 497 | hw->bph = cpu_to_le32(upper_32_bits(nat->bplh)); | ||
| 498 | hw->size = cpu_to_le32p(&nat->len_pcm); | ||
| 499 | /* HWO is written last */ | ||
| 500 | hw->ctrl = cpu_to_le32p(&nat->control); | ||
| 501 | } | ||
| 502 | |||
| 503 | static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat) | ||
| 504 | { | ||
| 505 | u64 bplh; | ||
| 506 | |||
| 507 | bplh = le32_to_cpup(&hw->bpl); | ||
| 508 | bplh |= (u64) le32_to_cpup(&hw->bph) << 32; | ||
| 509 | nat->bplh = bplh; | ||
| 510 | |||
| 511 | nat->len_pcm = le32_to_cpup(&hw->size); | ||
| 512 | nat->control = le32_to_cpup(&hw->ctrl); | ||
| 513 | } | ||
| 514 | |||
| 515 | /** | ||
| 516 | * dwc3_hwparams - copy of HWPARAMS registers | ||
| 517 | * @hwparams0 - GHWPARAMS0 | ||
| 518 | * @hwparams1 - GHWPARAMS1 | ||
| 519 | * @hwparams2 - GHWPARAMS2 | ||
| 520 | * @hwparams3 - GHWPARAMS3 | ||
| 521 | * @hwparams4 - GHWPARAMS4 | ||
| 522 | * @hwparams5 - GHWPARAMS5 | ||
| 523 | * @hwparams6 - GHWPARAMS6 | ||
| 524 | * @hwparams7 - GHWPARAMS7 | ||
| 525 | * @hwparams8 - GHWPARAMS8 | ||
| 526 | */ | ||
| 527 | struct dwc3_hwparams { | ||
| 528 | u32 hwparams0; | ||
| 529 | u32 hwparams1; | ||
| 530 | u32 hwparams2; | ||
| 531 | u32 hwparams3; | ||
| 532 | u32 hwparams4; | ||
| 533 | u32 hwparams5; | ||
| 534 | u32 hwparams6; | ||
| 535 | u32 hwparams7; | ||
| 536 | u32 hwparams8; | ||
| 537 | }; | ||
| 538 | |||
| 539 | /** | ||
| 540 | * struct dwc3 - representation of our controller | ||
| 541 | * @ctrl_req: usb control request which is used for ep0 | ||
| 542 | * @ep0_trb: trb which is used for the ctrl_req | ||
| 543 | * @ep0_bounce: bounce buffer for ep0 | ||
| 544 | * @setup_buf: used while precessing STD USB requests | ||
| 545 | * @ctrl_req_addr: dma address of ctrl_req | ||
| 546 | * @ep0_trb: dma address of ep0_trb | ||
| 547 | * @ep0_usb_req: dummy req used while handling STD USB requests | ||
| 548 | * @setup_buf_addr: dma address of setup_buf | ||
| 549 | * @ep0_bounce_addr: dma address of ep0_bounce | ||
| 550 | * @lock: for synchronizing | ||
| 551 | * @dev: pointer to our struct device | ||
| 552 | * @event_buffer_list: a list of event buffers | ||
| 553 | * @gadget: device side representation of the peripheral controller | ||
| 554 | * @gadget_driver: pointer to the gadget driver | ||
| 555 | * @regs: base address for our registers | ||
| 556 | * @regs_size: address space size | ||
| 557 | * @irq: IRQ number | ||
| 558 | * @revision: revision register contents | ||
| 559 | * @is_selfpowered: true when we are selfpowered | ||
| 560 | * @three_stage_setup: set if we perform a three phase setup | ||
| 561 | * @ep0_status_pending: ep0 status response without a req is pending | ||
| 562 | * @ep0_bounced: true when we used bounce buffer | ||
| 563 | * @ep0_expect_in: true when we expect a DATA IN transfer | ||
| 564 | * @start_config_issued: true when StartConfig command has been issued | ||
| 565 | * @ep0_next_event: hold the next expected event | ||
| 566 | * @ep0state: state of endpoint zero | ||
| 567 | * @link_state: link state | ||
| 568 | * @speed: device speed (super, high, full, low) | ||
| 569 | * @mem: points to start of memory which is used for this struct. | ||
| 570 | * @hwparams: copy of hwparams registers | ||
| 571 | * @root: debugfs root folder pointer | ||
| 572 | */ | ||
| 573 | struct dwc3 { | ||
| 574 | struct usb_ctrlrequest *ctrl_req; | ||
| 575 | struct dwc3_trb_hw *ep0_trb; | ||
| 576 | void *ep0_bounce; | ||
| 577 | u8 *setup_buf; | ||
| 578 | dma_addr_t ctrl_req_addr; | ||
| 579 | dma_addr_t ep0_trb_addr; | ||
| 580 | dma_addr_t setup_buf_addr; | ||
| 581 | dma_addr_t ep0_bounce_addr; | ||
| 582 | struct usb_request ep0_usb_req; | ||
| 583 | /* device lock */ | ||
| 584 | spinlock_t lock; | ||
| 585 | struct device *dev; | ||
| 586 | |||
| 587 | struct dwc3_event_buffer *ev_buffs[DWC3_EVENT_BUFFERS_NUM]; | ||
| 588 | struct dwc3_ep *eps[DWC3_ENDPOINTS_NUM]; | ||
| 589 | |||
| 590 | struct usb_gadget gadget; | ||
| 591 | struct usb_gadget_driver *gadget_driver; | ||
| 592 | |||
| 593 | void __iomem *regs; | ||
| 594 | size_t regs_size; | ||
| 595 | |||
| 596 | int irq; | ||
| 597 | |||
| 598 | u32 revision; | ||
| 599 | |||
| 600 | #define DWC3_REVISION_173A 0x5533173a | ||
| 601 | #define DWC3_REVISION_175A 0x5533175a | ||
| 602 | #define DWC3_REVISION_180A 0x5533180a | ||
| 603 | #define DWC3_REVISION_183A 0x5533183a | ||
| 604 | #define DWC3_REVISION_185A 0x5533185a | ||
| 605 | #define DWC3_REVISION_188A 0x5533188a | ||
| 606 | #define DWC3_REVISION_190A 0x5533190a | ||
| 607 | |||
| 608 | unsigned is_selfpowered:1; | ||
| 609 | unsigned three_stage_setup:1; | ||
| 610 | unsigned ep0_status_pending:1; | ||
| 611 | unsigned ep0_bounced:1; | ||
| 612 | unsigned ep0_expect_in:1; | ||
| 613 | unsigned start_config_issued:1; | ||
| 614 | |||
| 615 | enum dwc3_ep0_next ep0_next_event; | ||
| 616 | enum dwc3_ep0_state ep0state; | ||
| 617 | enum dwc3_link_state link_state; | ||
| 618 | enum dwc3_device_state dev_state; | ||
| 619 | |||
| 620 | u8 speed; | ||
| 621 | void *mem; | ||
| 622 | |||
| 623 | struct dwc3_hwparams hwparams; | ||
| 624 | struct dentry *root; | ||
| 625 | }; | ||
| 626 | |||
| 627 | /* -------------------------------------------------------------------------- */ | ||
| 628 | |||
| 629 | #define DWC3_TRBSTS_OK 0 | ||
| 630 | #define DWC3_TRBSTS_MISSED_ISOC 1 | ||
| 631 | #define DWC3_TRBSTS_SETUP_PENDING 2 | ||
| 632 | |||
| 633 | #define DWC3_TRBCTL_NORMAL 1 | ||
| 634 | #define DWC3_TRBCTL_CONTROL_SETUP 2 | ||
| 635 | #define DWC3_TRBCTL_CONTROL_STATUS2 3 | ||
| 636 | #define DWC3_TRBCTL_CONTROL_STATUS3 4 | ||
| 637 | #define DWC3_TRBCTL_CONTROL_DATA 5 | ||
| 638 | #define DWC3_TRBCTL_ISOCHRONOUS_FIRST 6 | ||
| 639 | #define DWC3_TRBCTL_ISOCHRONOUS 7 | ||
| 640 | #define DWC3_TRBCTL_LINK_TRB 8 | ||
| 641 | |||
| 642 | /* -------------------------------------------------------------------------- */ | ||
| 643 | |||
| 644 | struct dwc3_event_type { | ||
| 645 | u32 is_devspec:1; | ||
| 646 | u32 type:6; | ||
| 647 | u32 reserved8_31:25; | ||
| 648 | } __packed; | ||
| 649 | |||
| 650 | #define DWC3_DEPEVT_XFERCOMPLETE 0x01 | ||
| 651 | #define DWC3_DEPEVT_XFERINPROGRESS 0x02 | ||
| 652 | #define DWC3_DEPEVT_XFERNOTREADY 0x03 | ||
| 653 | #define DWC3_DEPEVT_RXTXFIFOEVT 0x04 | ||
| 654 | #define DWC3_DEPEVT_STREAMEVT 0x06 | ||
| 655 | #define DWC3_DEPEVT_EPCMDCMPLT 0x07 | ||
| 656 | |||
| 657 | /** | ||
| 658 | * struct dwc3_event_depvt - Device Endpoint Events | ||
| 659 | * @one_bit: indicates this is an endpoint event (not used) | ||
| 660 | * @endpoint_number: number of the endpoint | ||
| 661 | * @endpoint_event: The event we have: | ||
| 662 | * 0x00 - Reserved | ||
| 663 | * 0x01 - XferComplete | ||
| 664 | * 0x02 - XferInProgress | ||
| 665 | * 0x03 - XferNotReady | ||
| 666 | * 0x04 - RxTxFifoEvt (IN->Underrun, OUT->Overrun) | ||
| 667 | * 0x05 - Reserved | ||
| 668 | * 0x06 - StreamEvt | ||
| 669 | * 0x07 - EPCmdCmplt | ||
| 670 | * @reserved11_10: Reserved, don't use. | ||
| 671 | * @status: Indicates the status of the event. Refer to databook for | ||
| 672 | * more information. | ||
| 673 | * @parameters: Parameters of the current event. Refer to databook for | ||
| 674 | * more information. | ||
| 675 | */ | ||
| 676 | struct dwc3_event_depevt { | ||
| 677 | u32 one_bit:1; | ||
| 678 | u32 endpoint_number:5; | ||
| 679 | u32 endpoint_event:4; | ||
| 680 | u32 reserved11_10:2; | ||
| 681 | u32 status:4; | ||
| 682 | #define DEPEVT_STATUS_BUSERR (1 << 0) | ||
| 683 | #define DEPEVT_STATUS_SHORT (1 << 1) | ||
| 684 | #define DEPEVT_STATUS_IOC (1 << 2) | ||
| 685 | #define DEPEVT_STATUS_LST (1 << 3) | ||
| 686 | |||
| 687 | /* Stream event only */ | ||
| 688 | #define DEPEVT_STREAMEVT_FOUND 1 | ||
| 689 | #define DEPEVT_STREAMEVT_NOTFOUND 2 | ||
| 690 | |||
| 691 | /* Control-only Status */ | ||
| 692 | #define DEPEVT_STATUS_CONTROL_SETUP 0 | ||
| 693 | #define DEPEVT_STATUS_CONTROL_DATA 1 | ||
| 694 | #define DEPEVT_STATUS_CONTROL_STATUS 2 | ||
| 695 | |||
| 696 | u32 parameters:16; | ||
| 697 | } __packed; | ||
| 698 | |||
| 699 | /** | ||
| 700 | * struct dwc3_event_devt - Device Events | ||
| 701 | * @one_bit: indicates this is a non-endpoint event (not used) | ||
| 702 | * @device_event: indicates it's a device event. Should read as 0x00 | ||
| 703 | * @type: indicates the type of device event. | ||
| 704 | * 0 - DisconnEvt | ||
| 705 | * 1 - USBRst | ||
| 706 | * 2 - ConnectDone | ||
| 707 | * 3 - ULStChng | ||
| 708 | * 4 - WkUpEvt | ||
| 709 | * 5 - Reserved | ||
| 710 | * 6 - EOPF | ||
| 711 | * 7 - SOF | ||
| 712 | * 8 - Reserved | ||
| 713 | * 9 - ErrticErr | ||
| 714 | * 10 - CmdCmplt | ||
| 715 | * 11 - EvntOverflow | ||
| 716 | * 12 - VndrDevTstRcved | ||
| 717 | * @reserved15_12: Reserved, not used | ||
| 718 | * @event_info: Information about this event | ||
| 719 | * @reserved31_24: Reserved, not used | ||
| 720 | */ | ||
| 721 | struct dwc3_event_devt { | ||
| 722 | u32 one_bit:1; | ||
| 723 | u32 device_event:7; | ||
| 724 | u32 type:4; | ||
| 725 | u32 reserved15_12:4; | ||
| 726 | u32 event_info:8; | ||
| 727 | u32 reserved31_24:8; | ||
| 728 | } __packed; | ||
| 729 | |||
| 730 | /** | ||
| 731 | * struct dwc3_event_gevt - Other Core Events | ||
| 732 | * @one_bit: indicates this is a non-endpoint event (not used) | ||
| 733 | * @device_event: indicates it's (0x03) Carkit or (0x04) I2C event. | ||
| 734 | * @phy_port_number: self-explanatory | ||
| 735 | * @reserved31_12: Reserved, not used. | ||
| 736 | */ | ||
| 737 | struct dwc3_event_gevt { | ||
| 738 | u32 one_bit:1; | ||
| 739 | u32 device_event:7; | ||
| 740 | u32 phy_port_number:4; | ||
| 741 | u32 reserved31_12:20; | ||
| 742 | } __packed; | ||
| 743 | |||
| 744 | /** | ||
| 745 | * union dwc3_event - representation of Event Buffer contents | ||
| 746 | * @raw: raw 32-bit event | ||
| 747 | * @type: the type of the event | ||
| 748 | * @depevt: Device Endpoint Event | ||
| 749 | * @devt: Device Event | ||
| 750 | * @gevt: Global Event | ||
| 751 | */ | ||
| 752 | union dwc3_event { | ||
| 753 | u32 raw; | ||
| 754 | struct dwc3_event_type type; | ||
| 755 | struct dwc3_event_depevt depevt; | ||
| 756 | struct dwc3_event_devt devt; | ||
| 757 | struct dwc3_event_gevt gevt; | ||
| 758 | }; | ||
| 759 | |||
| 760 | /* | ||
| 761 | * DWC3 Features to be used as Driver Data | ||
| 762 | */ | ||
| 763 | |||
| 764 | #define DWC3_HAS_PERIPHERAL BIT(0) | ||
| 765 | #define DWC3_HAS_XHCI BIT(1) | ||
| 766 | #define DWC3_HAS_OTG BIT(3) | ||
| 767 | |||
| 768 | #endif /* __DRIVERS_USB_DWC3_CORE_H */ | ||
| @@ -0,0 +1,50 @@ | |||
| 1 | /** | ||
| 2 | * debug.h - DesignWare USB3 DRD Controller Debug Header | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include "core.h" | ||
| 40 | |||
| 41 | #ifdef CONFIG_DEBUG_FS | ||
| 42 | extern int dwc3_debugfs_init(struct dwc3 *); | ||
| 43 | extern void dwc3_debugfs_exit(struct dwc3 *); | ||
| 44 | #else | ||
| 45 | static inline int dwc3_debugfs_init(struct dwc3 *d) | ||
| 46 | { return 0; } | ||
| 47 | static inline void dwc3_debugfs_exit(struct dwc3 *d) | ||
| 48 | { } | ||
| 49 | #endif | ||
| 50 | |||
| @@ -0,0 +1,441 @@ | |||
| 1 | /** | ||
| 2 | * debugfs.c - DesignWare USB3 DRD Controller DebugFS file | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/kernel.h> | ||
| 40 | #include <linux/slab.h> | ||
| 41 | #include <linux/ptrace.h> | ||
| 42 | #include <linux/types.h> | ||
| 43 | #include <linux/spinlock.h> | ||
| 44 | #include <linux/debugfs.h> | ||
| 45 | #include <linux/seq_file.h> | ||
| 46 | #include <linux/delay.h> | ||
| 47 | |||
| 48 | #include <asm/uaccess.h> | ||
| 49 | |||
| 50 | #include "core.h" | ||
| 51 | #include "gadget.h" | ||
| 52 | #include "io.h" | ||
| 53 | |||
| 54 | struct dwc3_register { | ||
| 55 | const char *name; | ||
| 56 | u32 offset; | ||
| 57 | }; | ||
| 58 | |||
| 59 | #define dump_register(nm) \ | ||
| 60 | { \ | ||
| 61 | .name = __stringify(nm), \ | ||
| 62 | .offset = DWC3_ ##nm, \ | ||
| 63 | } | ||
| 64 | |||
| 65 | static const struct dwc3_register dwc3_regs[] = { | ||
| 66 | dump_register(GSBUSCFG0), | ||
| 67 | dump_register(GSBUSCFG1), | ||
| 68 | dump_register(GTXTHRCFG), | ||
| 69 | dump_register(GRXTHRCFG), | ||
| 70 | dump_register(GCTL), | ||
| 71 | dump_register(GEVTEN), | ||
| 72 | dump_register(GSTS), | ||
| 73 | dump_register(GSNPSID), | ||
| 74 | dump_register(GGPIO), | ||
| 75 | dump_register(GUID), | ||
| 76 | dump_register(GUCTL), | ||
| 77 | dump_register(GBUSERRADDR0), | ||
| 78 | dump_register(GBUSERRADDR1), | ||
| 79 | dump_register(GPRTBIMAP0), | ||
| 80 | dump_register(GPRTBIMAP1), | ||
| 81 | dump_register(GHWPARAMS0), | ||
| 82 | dump_register(GHWPARAMS1), | ||
| 83 | dump_register(GHWPARAMS2), | ||
| 84 | dump_register(GHWPARAMS3), | ||
| 85 | dump_register(GHWPARAMS4), | ||
| 86 | dump_register(GHWPARAMS5), | ||
| 87 | dump_register(GHWPARAMS6), | ||
| 88 | dump_register(GHWPARAMS7), | ||
| 89 | dump_register(GDBGFIFOSPACE), | ||
| 90 | dump_register(GDBGLTSSM), | ||
| 91 | dump_register(GPRTBIMAP_HS0), | ||
| 92 | dump_register(GPRTBIMAP_HS1), | ||
| 93 | dump_register(GPRTBIMAP_FS0), | ||
| 94 | dump_register(GPRTBIMAP_FS1), | ||
| 95 | |||
| 96 | dump_register(GUSB2PHYCFG(0)), | ||
| 97 | dump_register(GUSB2PHYCFG(1)), | ||
| 98 | dump_register(GUSB2PHYCFG(2)), | ||
| 99 | dump_register(GUSB2PHYCFG(3)), | ||
| 100 | dump_register(GUSB2PHYCFG(4)), | ||
| 101 | dump_register(GUSB2PHYCFG(5)), | ||
| 102 | dump_register(GUSB2PHYCFG(6)), | ||
| 103 | dump_register(GUSB2PHYCFG(7)), | ||
| 104 | dump_register(GUSB2PHYCFG(8)), | ||
| 105 | dump_register(GUSB2PHYCFG(9)), | ||
| 106 | dump_register(GUSB2PHYCFG(10)), | ||
| 107 | dump_register(GUSB2PHYCFG(11)), | ||
| 108 | dump_register(GUSB2PHYCFG(12)), | ||
| 109 | dump_register(GUSB2PHYCFG(13)), | ||
| 110 | dump_register(GUSB2PHYCFG(14)), | ||
| 111 | dump_register(GUSB2PHYCFG(15)), | ||
| 112 | |||
| 113 | dump_register(GUSB2I2CCTL(0)), | ||
| 114 | dump_register(GUSB2I2CCTL(1)), | ||
| 115 | dump_register(GUSB2I2CCTL(2)), | ||
| 116 | dump_register(GUSB2I2CCTL(3)), | ||
| 117 | dump_register(GUSB2I2CCTL(4)), | ||
| 118 | dump_register(GUSB2I2CCTL(5)), | ||
| 119 | dump_register(GUSB2I2CCTL(6)), | ||
| 120 | dump_register(GUSB2I2CCTL(7)), | ||
| 121 | dump_register(GUSB2I2CCTL(8)), | ||
| 122 | dump_register(GUSB2I2CCTL(9)), | ||
| 123 | dump_register(GUSB2I2CCTL(10)), | ||
| 124 | dump_register(GUSB2I2CCTL(11)), | ||
| 125 | dump_register(GUSB2I2CCTL(12)), | ||
| 126 | dump_register(GUSB2I2CCTL(13)), | ||
| 127 | dump_register(GUSB2I2CCTL(14)), | ||
| 128 | dump_register(GUSB2I2CCTL(15)), | ||
| 129 | |||
| 130 | dump_register(GUSB2PHYACC(0)), | ||
| 131 | dump_register(GUSB2PHYACC(1)), | ||
| 132 | dump_register(GUSB2PHYACC(2)), | ||
| 133 | dump_register(GUSB2PHYACC(3)), | ||
| 134 | dump_register(GUSB2PHYACC(4)), | ||
| 135 | dump_register(GUSB2PHYACC(5)), | ||
| 136 | dump_register(GUSB2PHYACC(6)), | ||
| 137 | dump_register(GUSB2PHYACC(7)), | ||
| 138 | dump_register(GUSB2PHYACC(8)), | ||
| 139 | dump_register(GUSB2PHYACC(9)), | ||
| 140 | dump_register(GUSB2PHYACC(10)), | ||
| 141 | dump_register(GUSB2PHYACC(11)), | ||
| 142 | dump_register(GUSB2PHYACC(12)), | ||
| 143 | dump_register(GUSB2PHYACC(13)), | ||
| 144 | dump_register(GUSB2PHYACC(14)), | ||
| 145 | dump_register(GUSB2PHYACC(15)), | ||
| 146 | |||
| 147 | dump_register(GUSB3PIPECTL(0)), | ||
| 148 | dump_register(GUSB3PIPECTL(1)), | ||
| 149 | dump_register(GUSB3PIPECTL(2)), | ||
| 150 | dump_register(GUSB3PIPECTL(3)), | ||
| 151 | dump_register(GUSB3PIPECTL(4)), | ||
| 152 | dump_register(GUSB3PIPECTL(5)), | ||
| 153 | dump_register(GUSB3PIPECTL(6)), | ||
| 154 | dump_register(GUSB3PIPECTL(7)), | ||
| 155 | dump_register(GUSB3PIPECTL(8)), | ||
| 156 | dump_register(GUSB3PIPECTL(9)), | ||
| 157 | dump_register(GUSB3PIPECTL(10)), | ||
| 158 | dump_register(GUSB3PIPECTL(11)), | ||
| 159 | dump_register(GUSB3PIPECTL(12)), | ||
| 160 | dump_register(GUSB3PIPECTL(13)), | ||
| 161 | dump_register(GUSB3PIPECTL(14)), | ||
| 162 | dump_register(GUSB3PIPECTL(15)), | ||
| 163 | |||
| 164 | dump_register(GTXFIFOSIZ(0)), | ||
| 165 | dump_register(GTXFIFOSIZ(1)), | ||
| 166 | dump_register(GTXFIFOSIZ(2)), | ||
| 167 | dump_register(GTXFIFOSIZ(3)), | ||
| 168 | dump_register(GTXFIFOSIZ(4)), | ||
| 169 | dump_register(GTXFIFOSIZ(5)), | ||
| 170 | dump_register(GTXFIFOSIZ(6)), | ||
| 171 | dump_register(GTXFIFOSIZ(7)), | ||
| 172 | dump_register(GTXFIFOSIZ(8)), | ||
| 173 | dump_register(GTXFIFOSIZ(9)), | ||
| 174 | dump_register(GTXFIFOSIZ(10)), | ||
| 175 | dump_register(GTXFIFOSIZ(11)), | ||
| 176 | dump_register(GTXFIFOSIZ(12)), | ||
| 177 | dump_register(GTXFIFOSIZ(13)), | ||
| 178 | dump_register(GTXFIFOSIZ(14)), | ||
| 179 | dump_register(GTXFIFOSIZ(15)), | ||
| 180 | dump_register(GTXFIFOSIZ(16)), | ||
| 181 | dump_register(GTXFIFOSIZ(17)), | ||
| 182 | dump_register(GTXFIFOSIZ(18)), | ||
| 183 | dump_register(GTXFIFOSIZ(19)), | ||
| 184 | dump_register(GTXFIFOSIZ(20)), | ||
| 185 | dump_register(GTXFIFOSIZ(21)), | ||
| 186 | dump_register(GTXFIFOSIZ(22)), | ||
| 187 | dump_register(GTXFIFOSIZ(23)), | ||
| 188 | dump_register(GTXFIFOSIZ(24)), | ||
| 189 | dump_register(GTXFIFOSIZ(25)), | ||
| 190 | dump_register(GTXFIFOSIZ(26)), | ||
| 191 | dump_register(GTXFIFOSIZ(27)), | ||
| 192 | dump_register(GTXFIFOSIZ(28)), | ||
| 193 | dump_register(GTXFIFOSIZ(29)), | ||
| 194 | dump_register(GTXFIFOSIZ(30)), | ||
| 195 | dump_register(GTXFIFOSIZ(31)), | ||
| 196 | |||
| 197 | dump_register(GRXFIFOSIZ(0)), | ||
| 198 | dump_register(GRXFIFOSIZ(1)), | ||
| 199 | dump_register(GRXFIFOSIZ(2)), | ||
| 200 | dump_register(GRXFIFOSIZ(3)), | ||
| 201 | dump_register(GRXFIFOSIZ(4)), | ||
| 202 | dump_register(GRXFIFOSIZ(5)), | ||
| 203 | dump_register(GRXFIFOSIZ(6)), | ||
| 204 | dump_register(GRXFIFOSIZ(7)), | ||
| 205 | dump_register(GRXFIFOSIZ(8)), | ||
| 206 | dump_register(GRXFIFOSIZ(9)), | ||
| 207 | dump_register(GRXFIFOSIZ(10)), | ||
| 208 | dump_register(GRXFIFOSIZ(11)), | ||
| 209 | dump_register(GRXFIFOSIZ(12)), | ||
| 210 | dump_register(GRXFIFOSIZ(13)), | ||
| 211 | dump_register(GRXFIFOSIZ(14)), | ||
| 212 | dump_register(GRXFIFOSIZ(15)), | ||
| 213 | dump_register(GRXFIFOSIZ(16)), | ||
| 214 | dump_register(GRXFIFOSIZ(17)), | ||
| 215 | dump_register(GRXFIFOSIZ(18)), | ||
| 216 | dump_register(GRXFIFOSIZ(19)), | ||
| 217 | dump_register(GRXFIFOSIZ(20)), | ||
| 218 | dump_register(GRXFIFOSIZ(21)), | ||
| 219 | dump_register(GRXFIFOSIZ(22)), | ||
| 220 | dump_register(GRXFIFOSIZ(23)), | ||
| 221 | dump_register(GRXFIFOSIZ(24)), | ||
| 222 | dump_register(GRXFIFOSIZ(25)), | ||
| 223 | dump_register(GRXFIFOSIZ(26)), | ||
| 224 | dump_register(GRXFIFOSIZ(27)), | ||
| 225 | dump_register(GRXFIFOSIZ(28)), | ||
| 226 | dump_register(GRXFIFOSIZ(29)), | ||
| 227 | dump_register(GRXFIFOSIZ(30)), | ||
| 228 | dump_register(GRXFIFOSIZ(31)), | ||
| 229 | |||
| 230 | dump_register(GEVNTADRLO(0)), | ||
| 231 | dump_register(GEVNTADRHI(0)), | ||
| 232 | dump_register(GEVNTSIZ(0)), | ||
| 233 | dump_register(GEVNTCOUNT(0)), | ||
| 234 | |||
| 235 | dump_register(GHWPARAMS8), | ||
| 236 | dump_register(DCFG), | ||
| 237 | dump_register(DCTL), | ||
| 238 | dump_register(DEVTEN), | ||
| 239 | dump_register(DSTS), | ||
| 240 | dump_register(DGCMDPAR), | ||
| 241 | dump_register(DGCMD), | ||
| 242 | dump_register(DALEPENA), | ||
| 243 | |||
| 244 | dump_register(DEPCMDPAR2(0)), | ||
| 245 | dump_register(DEPCMDPAR2(1)), | ||
| 246 | dump_register(DEPCMDPAR2(2)), | ||
| 247 | dump_register(DEPCMDPAR2(3)), | ||
| 248 | dump_register(DEPCMDPAR2(4)), | ||
| 249 | dump_register(DEPCMDPAR2(5)), | ||
| 250 | dump_register(DEPCMDPAR2(6)), | ||
| 251 | dump_register(DEPCMDPAR2(7)), | ||
| 252 | dump_register(DEPCMDPAR2(8)), | ||
| 253 | dump_register(DEPCMDPAR2(9)), | ||
| 254 | dump_register(DEPCMDPAR2(10)), | ||
| 255 | dump_register(DEPCMDPAR2(11)), | ||
| 256 | dump_register(DEPCMDPAR2(12)), | ||
| 257 | dump_register(DEPCMDPAR2(13)), | ||
| 258 | dump_register(DEPCMDPAR2(14)), | ||
| 259 | dump_register(DEPCMDPAR2(15)), | ||
| 260 | dump_register(DEPCMDPAR2(16)), | ||
| 261 | dump_register(DEPCMDPAR2(17)), | ||
| 262 | dump_register(DEPCMDPAR2(18)), | ||
| 263 | dump_register(DEPCMDPAR2(19)), | ||
| 264 | dump_register(DEPCMDPAR2(20)), | ||
| 265 | dump_register(DEPCMDPAR2(21)), | ||
| 266 | dump_register(DEPCMDPAR2(22)), | ||
| 267 | dump_register(DEPCMDPAR2(23)), | ||
| 268 | dump_register(DEPCMDPAR2(24)), | ||
| 269 | dump_register(DEPCMDPAR2(25)), | ||
| 270 | dump_register(DEPCMDPAR2(26)), | ||
| 271 | dump_register(DEPCMDPAR2(27)), | ||
| 272 | dump_register(DEPCMDPAR2(28)), | ||
| 273 | dump_register(DEPCMDPAR2(29)), | ||
| 274 | dump_register(DEPCMDPAR2(30)), | ||
| 275 | dump_register(DEPCMDPAR2(31)), | ||
| 276 | |||
| 277 | dump_register(DEPCMDPAR1(0)), | ||
| 278 | dump_register(DEPCMDPAR1(1)), | ||
| 279 | dump_register(DEPCMDPAR1(2)), | ||
| 280 | dump_register(DEPCMDPAR1(3)), | ||
| 281 | dump_register(DEPCMDPAR1(4)), | ||
| 282 | dump_register(DEPCMDPAR1(5)), | ||
| 283 | dump_register(DEPCMDPAR1(6)), | ||
| 284 | dump_register(DEPCMDPAR1(7)), | ||
| 285 | dump_register(DEPCMDPAR1(8)), | ||
| 286 | dump_register(DEPCMDPAR1(9)), | ||
| 287 | dump_register(DEPCMDPAR1(10)), | ||
| 288 | dump_register(DEPCMDPAR1(11)), | ||
| 289 | dump_register(DEPCMDPAR1(12)), | ||
| 290 | dump_register(DEPCMDPAR1(13)), | ||
| 291 | dump_register(DEPCMDPAR1(14)), | ||
| 292 | dump_register(DEPCMDPAR1(15)), | ||
| 293 | dump_register(DEPCMDPAR1(16)), | ||
| 294 | dump_register(DEPCMDPAR1(17)), | ||
| 295 | dump_register(DEPCMDPAR1(18)), | ||
| 296 | dump_register(DEPCMDPAR1(19)), | ||
| 297 | dump_register(DEPCMDPAR1(20)), | ||
| 298 | dump_register(DEPCMDPAR1(21)), | ||
| 299 | dump_register(DEPCMDPAR1(22)), | ||
| 300 | dump_register(DEPCMDPAR1(23)), | ||
| 301 | dump_register(DEPCMDPAR1(24)), | ||
| 302 | dump_register(DEPCMDPAR1(25)), | ||
| 303 | dump_register(DEPCMDPAR1(26)), | ||
| 304 | dump_register(DEPCMDPAR1(27)), | ||
| 305 | dump_register(DEPCMDPAR1(28)), | ||
| 306 | dump_register(DEPCMDPAR1(29)), | ||
| 307 | dump_register(DEPCMDPAR1(30)), | ||
| 308 | dump_register(DEPCMDPAR1(31)), | ||
| 309 | |||
| 310 | dump_register(DEPCMDPAR0(0)), | ||
| 311 | dump_register(DEPCMDPAR0(1)), | ||
| 312 | dump_register(DEPCMDPAR0(2)), | ||
| 313 | dump_register(DEPCMDPAR0(3)), | ||
| 314 | dump_register(DEPCMDPAR0(4)), | ||
| 315 | dump_register(DEPCMDPAR0(5)), | ||
| 316 | dump_register(DEPCMDPAR0(6)), | ||
| 317 | dump_register(DEPCMDPAR0(7)), | ||
| 318 | dump_register(DEPCMDPAR0(8)), | ||
| 319 | dump_register(DEPCMDPAR0(9)), | ||
| 320 | dump_register(DEPCMDPAR0(10)), | ||
| 321 | dump_register(DEPCMDPAR0(11)), | ||
| 322 | dump_register(DEPCMDPAR0(12)), | ||
| 323 | dump_register(DEPCMDPAR0(13)), | ||
| 324 | dump_register(DEPCMDPAR0(14)), | ||
| 325 | dump_register(DEPCMDPAR0(15)), | ||
| 326 | dump_register(DEPCMDPAR0(16)), | ||
| 327 | dump_register(DEPCMDPAR0(17)), | ||
| 328 | dump_register(DEPCMDPAR0(18)), | ||
| 329 | dump_register(DEPCMDPAR0(19)), | ||
| 330 | dump_register(DEPCMDPAR0(20)), | ||
| 331 | dump_register(DEPCMDPAR0(21)), | ||
| 332 | dump_register(DEPCMDPAR0(22)), | ||
| 333 | dump_register(DEPCMDPAR0(23)), | ||
| 334 | dump_register(DEPCMDPAR0(24)), | ||
| 335 | dump_register(DEPCMDPAR0(25)), | ||
| 336 | dump_register(DEPCMDPAR0(26)), | ||
| 337 | dump_register(DEPCMDPAR0(27)), | ||
| 338 | dump_register(DEPCMDPAR0(28)), | ||
| 339 | dump_register(DEPCMDPAR0(29)), | ||
| 340 | dump_register(DEPCMDPAR0(30)), | ||
| 341 | dump_register(DEPCMDPAR0(31)), | ||
| 342 | |||
| 343 | dump_register(DEPCMD(0)), | ||
| 344 | dump_register(DEPCMD(1)), | ||
| 345 | dump_register(DEPCMD(2)), | ||
| 346 | dump_register(DEPCMD(3)), | ||
| 347 | dump_register(DEPCMD(4)), | ||
| 348 | dump_register(DEPCMD(5)), | ||
| 349 | dump_register(DEPCMD(6)), | ||
| 350 | dump_register(DEPCMD(7)), | ||
| 351 | dump_register(DEPCMD(8)), | ||
| 352 | dump_register(DEPCMD(9)), | ||
| 353 | dump_register(DEPCMD(10)), | ||
| 354 | dump_register(DEPCMD(11)), | ||
| 355 | dump_register(DEPCMD(12)), | ||
| 356 | dump_register(DEPCMD(13)), | ||
| 357 | dump_register(DEPCMD(14)), | ||
| 358 | dump_register(DEPCMD(15)), | ||
| 359 | dump_register(DEPCMD(16)), | ||
| 360 | dump_register(DEPCMD(17)), | ||
| 361 | dump_register(DEPCMD(18)), | ||
| 362 | dump_register(DEPCMD(19)), | ||
| 363 | dump_register(DEPCMD(20)), | ||
| 364 | dump_register(DEPCMD(21)), | ||
| 365 | dump_register(DEPCMD(22)), | ||
| 366 | dump_register(DEPCMD(23)), | ||
| 367 | dump_register(DEPCMD(24)), | ||
| 368 | dump_register(DEPCMD(25)), | ||
| 369 | dump_register(DEPCMD(26)), | ||
| 370 | dump_register(DEPCMD(27)), | ||
| 371 | dump_register(DEPCMD(28)), | ||
| 372 | dump_register(DEPCMD(29)), | ||
| 373 | dump_register(DEPCMD(30)), | ||
| 374 | dump_register(DEPCMD(31)), | ||
| 375 | |||
| 376 | dump_register(OCFG), | ||
| 377 | dump_register(OCTL), | ||
| 378 | dump_register(OEVTEN), | ||
| 379 | dump_register(OSTS), | ||
| 380 | }; | ||
| 381 | |||
| 382 | static int dwc3_regdump_show(struct seq_file *s, void *unused) | ||
| 383 | { | ||
| 384 | struct dwc3 *dwc = s->private; | ||
| 385 | int i; | ||
| 386 | |||
| 387 | seq_printf(s, "DesignWare USB3 Core Register Dump\n"); | ||
| 388 | |||
| 389 | for (i = 0; i < ARRAY_SIZE(dwc3_regs); i++) { | ||
| 390 | seq_printf(s, "%-20s : %08x\n", dwc3_regs[i].name, | ||
| 391 | dwc3_readl(dwc->regs, dwc3_regs[i].offset)); | ||
| 392 | } | ||
| 393 | |||
| 394 | return 0; | ||
| 395 | } | ||
| 396 | |||
| 397 | static int dwc3_regdump_open(struct inode *inode, struct file *file) | ||
| 398 | { | ||
| 399 | return single_open(file, dwc3_regdump_show, inode->i_private); | ||
| 400 | } | ||
| 401 | |||
| 402 | static const struct file_operations dwc3_regdump_fops = { | ||
| 403 | .open = dwc3_regdump_open, | ||
| 404 | .read = seq_read, | ||
| 405 | .release = single_release, | ||
| 406 | }; | ||
| 407 | |||
| 408 | int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | ||
| 409 | { | ||
| 410 | struct dentry *root; | ||
| 411 | struct dentry *file; | ||
| 412 | int ret; | ||
| 413 | |||
| 414 | root = debugfs_create_dir(dev_name(dwc->dev), NULL); | ||
| 415 | if (IS_ERR(root)){ | ||
| 416 | ret = PTR_ERR(root); | ||
| 417 | goto err0; | ||
| 418 | } | ||
| 419 | |||
| 420 | dwc->root = root; | ||
| 421 | |||
| 422 | file = debugfs_create_file("regdump", S_IRUGO, root, dwc, | ||
| 423 | &dwc3_regdump_fops); | ||
| 424 | if (IS_ERR(file)) { | ||
| 425 | ret = PTR_ERR(file); | ||
| 426 | goto err1; | ||
| 427 | } | ||
| 428 | return 0; | ||
| 429 | |||
| 430 | err1: | ||
| 431 | debugfs_remove_recursive(root); | ||
| 432 | |||
| 433 | err0: | ||
| 434 | return ret; | ||
| 435 | } | ||
| 436 | |||
| 437 | void __devexit dwc3_debugfs_exit(struct dwc3 *dwc) | ||
| 438 | { | ||
| 439 | debugfs_remove_recursive(dwc->root); | ||
| 440 | dwc->root = NULL; | ||
| 441 | } | ||
| @@ -0,0 +1,401 @@ | |||
| 1 | /** | ||
| 2 | * dwc3-omap.c - OMAP Specific Glue layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/module.h> | ||
| 40 | #include <linux/kernel.h> | ||
| 41 | #include <linux/slab.h> | ||
| 42 | #include <linux/interrupt.h> | ||
| 43 | #include <linux/spinlock.h> | ||
| 44 | #include <linux/platform_device.h> | ||
| 45 | #include <linux/platform_data/dwc3-omap.h> | ||
| 46 | #include <linux/dma-mapping.h> | ||
| 47 | #include <linux/ioport.h> | ||
| 48 | #include <linux/io.h> | ||
| 49 | #include <linux/module.h> | ||
| 50 | |||
| 51 | #include "io.h" | ||
| 52 | |||
| 53 | /* | ||
| 54 | * All these registers belong to OMAP's Wrapper around the | ||
| 55 | * DesignWare USB3 Core. | ||
| 56 | */ | ||
| 57 | |||
| 58 | #define USBOTGSS_REVISION 0x0000 | ||
| 59 | #define USBOTGSS_SYSCONFIG 0x0010 | ||
| 60 | #define USBOTGSS_IRQ_EOI 0x0020 | ||
| 61 | #define USBOTGSS_IRQSTATUS_RAW_0 0x0024 | ||
| 62 | #define USBOTGSS_IRQSTATUS_0 0x0028 | ||
| 63 | #define USBOTGSS_IRQENABLE_SET_0 0x002c | ||
| 64 | #define USBOTGSS_IRQENABLE_CLR_0 0x0030 | ||
| 65 | #define USBOTGSS_IRQSTATUS_RAW_1 0x0034 | ||
| 66 | #define USBOTGSS_IRQSTATUS_1 0x0038 | ||
| 67 | #define USBOTGSS_IRQENABLE_SET_1 0x003c | ||
| 68 | #define USBOTGSS_IRQENABLE_CLR_1 0x0040 | ||
| 69 | #define USBOTGSS_UTMI_OTG_CTRL 0x0080 | ||
| 70 | #define USBOTGSS_UTMI_OTG_STATUS 0x0084 | ||
| 71 | #define USBOTGSS_MMRAM_OFFSET 0x0100 | ||
| 72 | #define USBOTGSS_FLADJ 0x0104 | ||
| 73 | #define USBOTGSS_DEBUG_CFG 0x0108 | ||
| 74 | #define USBOTGSS_DEBUG_DATA 0x010c | ||
| 75 | |||
| 76 | /* SYSCONFIG REGISTER */ | ||
| 77 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) | ||
| 78 | #define USBOTGSS_SYSCONFIG_STANDBYMODE(x) ((x) << 4) | ||
| 79 | |||
| 80 | #define USBOTGSS_STANDBYMODE_FORCE_STANDBY 0 | ||
| 81 | #define USBOTGSS_STANDBYMODE_NO_STANDBY 1 | ||
| 82 | #define USBOTGSS_STANDBYMODE_SMART_STANDBY 2 | ||
| 83 | #define USBOTGSS_STANDBYMODE_SMART_WAKEUP 3 | ||
| 84 | |||
| 85 | #define USBOTGSS_STANDBYMODE_MASK (0x03 << 4) | ||
| 86 | |||
| 87 | #define USBOTGSS_SYSCONFIG_IDLEMODE(x) ((x) << 2) | ||
| 88 | |||
| 89 | #define USBOTGSS_IDLEMODE_FORCE_IDLE 0 | ||
| 90 | #define USBOTGSS_IDLEMODE_NO_IDLE 1 | ||
| 91 | #define USBOTGSS_IDLEMODE_SMART_IDLE 2 | ||
| 92 | #define USBOTGSS_IDLEMODE_SMART_WAKEUP 3 | ||
| 93 | |||
| 94 | #define USBOTGSS_IDLEMODE_MASK (0x03 << 2) | ||
| 95 | |||
| 96 | /* IRQ_EOI REGISTER */ | ||
| 97 | #define USBOTGSS_IRQ_EOI_LINE_NUMBER (1 << 0) | ||
| 98 | |||
| 99 | /* IRQS0 BITS */ | ||
| 100 | #define USBOTGSS_IRQO_COREIRQ_ST (1 << 0) | ||
| 101 | |||
| 102 | /* IRQ1 BITS */ | ||
| 103 | #define USBOTGSS_IRQ1_DMADISABLECLR (1 << 17) | ||
| 104 | #define USBOTGSS_IRQ1_OEVT (1 << 16) | ||
| 105 | #define USBOTGSS_IRQ1_DRVVBUS_RISE (1 << 13) | ||
| 106 | #define USBOTGSS_IRQ1_CHRGVBUS_RISE (1 << 12) | ||
| 107 | #define USBOTGSS_IRQ1_DISCHRGVBUS_RISE (1 << 11) | ||
| 108 | #define USBOTGSS_IRQ1_IDPULLUP_RISE (1 << 8) | ||
| 109 | #define USBOTGSS_IRQ1_DRVVBUS_FALL (1 << 5) | ||
| 110 | #define USBOTGSS_IRQ1_CHRGVBUS_FALL (1 << 4) | ||
| 111 | #define USBOTGSS_IRQ1_DISCHRGVBUS_FALL (1 << 3) | ||
| 112 | #define USBOTGSS_IRQ1_IDPULLUP_FALL (1 << 0) | ||
| 113 | |||
| 114 | /* UTMI_OTG_CTRL REGISTER */ | ||
| 115 | #define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS (1 << 5) | ||
| 116 | #define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS (1 << 4) | ||
| 117 | #define USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS (1 << 3) | ||
| 118 | #define USBOTGSS_UTMI_OTG_CTRL_IDPULLUP (1 << 0) | ||
| 119 | |||
| 120 | /* UTMI_OTG_STATUS REGISTER */ | ||
| 121 | #define USBOTGSS_UTMI_OTG_STATUS_SW_MODE (1 << 31) | ||
| 122 | #define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT (1 << 9) | ||
| 123 | #define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE (1 << 8) | ||
| 124 | #define USBOTGSS_UTMI_OTG_STATUS_IDDIG (1 << 4) | ||
| 125 | #define USBOTGSS_UTMI_OTG_STATUS_SESSEND (1 << 3) | ||
| 126 | #define USBOTGSS_UTMI_OTG_STATUS_SESSVALID (1 << 2) | ||
| 127 | #define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID (1 << 1) | ||
| 128 | |||
| 129 | struct dwc3_omap { | ||
| 130 | /* device lock */ | ||
| 131 | spinlock_t lock; | ||
| 132 | |||
| 133 | struct platform_device *dwc3; | ||
| 134 | struct device *dev; | ||
| 135 | |||
| 136 | int irq; | ||
| 137 | void __iomem *base; | ||
| 138 | |||
| 139 | void *context; | ||
| 140 | u32 resource_size; | ||
| 141 | |||
| 142 | u32 dma_status:1; | ||
| 143 | }; | ||
| 144 | |||
| 145 | static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) | ||
| 146 | { | ||
| 147 | struct dwc3_omap *omap = _omap; | ||
| 148 | u32 reg; | ||
| 149 | |||
| 150 | spin_lock(&omap->lock); | ||
| 151 | |||
| 152 | reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_1); | ||
| 153 | |||
| 154 | if (reg & USBOTGSS_IRQ1_DMADISABLECLR) { | ||
| 155 | dev_dbg(omap->dev, "DMA Disable was Cleared\n"); | ||
| 156 | omap->dma_status = false; | ||
| 157 | } | ||
| 158 | |||
| 159 | if (reg & USBOTGSS_IRQ1_OEVT) | ||
| 160 | dev_dbg(omap->dev, "OTG Event\n"); | ||
| 161 | |||
| 162 | if (reg & USBOTGSS_IRQ1_DRVVBUS_RISE) | ||
| 163 | dev_dbg(omap->dev, "DRVVBUS Rise\n"); | ||
| 164 | |||
| 165 | if (reg & USBOTGSS_IRQ1_CHRGVBUS_RISE) | ||
| 166 | dev_dbg(omap->dev, "CHRGVBUS Rise\n"); | ||
| 167 | |||
| 168 | if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_RISE) | ||
| 169 | dev_dbg(omap->dev, "DISCHRGVBUS Rise\n"); | ||
| 170 | |||
| 171 | if (reg & USBOTGSS_IRQ1_IDPULLUP_RISE) | ||
| 172 | dev_dbg(omap->dev, "IDPULLUP Rise\n"); | ||
| 173 | |||
| 174 | if (reg & USBOTGSS_IRQ1_DRVVBUS_FALL) | ||
| 175 | dev_dbg(omap->dev, "DRVVBUS Fall\n"); | ||
| 176 | |||
| 177 | if (reg & USBOTGSS_IRQ1_CHRGVBUS_FALL) | ||
| 178 | dev_dbg(omap->dev, "CHRGVBUS Fall\n"); | ||
| 179 | |||
| 180 | if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_FALL) | ||
| 181 | dev_dbg(omap->dev, "DISCHRGVBUS Fall\n"); | ||
| 182 | |||
| 183 | if (reg & USBOTGSS_IRQ1_IDPULLUP_FALL) | ||
| 184 | dev_dbg(omap->dev, "IDPULLUP Fall\n"); | ||
| 185 | |||
| 186 | dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_1, reg); | ||
| 187 | |||
| 188 | reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_0); | ||
| 189 | dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_0, reg); | ||
| 190 | |||
| 191 | spin_unlock(&omap->lock); | ||
| 192 | |||
| 193 | return IRQ_HANDLED; | ||
| 194 | } | ||
| 195 | |||
| 196 | static int __devinit dwc3_omap_probe(struct platform_device *pdev) | ||
| 197 | { | ||
| 198 | struct dwc3_omap_data *pdata = pdev->dev.platform_data; | ||
| 199 | struct platform_device *dwc3; | ||
| 200 | struct dwc3_omap *omap; | ||
| 201 | struct resource *res; | ||
| 202 | |||
| 203 | int ret = -ENOMEM; | ||
| 204 | int irq; | ||
| 205 | |||
| 206 | u32 reg; | ||
| 207 | |||
| 208 | void __iomem *base; | ||
| 209 | void *context; | ||
| 210 | |||
| 211 | omap = kzalloc(sizeof(*omap), GFP_KERNEL); | ||
| 212 | if (!omap) { | ||
| 213 | dev_err(&pdev->dev, "not enough memory\n"); | ||
| 214 | goto err0; | ||
| 215 | } | ||
| 216 | |||
| 217 | platform_set_drvdata(pdev, omap); | ||
| 218 | |||
| 219 | irq = platform_get_irq(pdev, 1); | ||
| 220 | if (irq < 0) { | ||
| 221 | dev_err(&pdev->dev, "missing IRQ resource\n"); | ||
| 222 | ret = -EINVAL; | ||
| 223 | goto err1; | ||
| 224 | } | ||
| 225 | |||
| 226 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 227 | if (!res) { | ||
| 228 | dev_err(&pdev->dev, "missing memory base resource\n"); | ||
| 229 | ret = -EINVAL; | ||
| 230 | goto err1; | ||
| 231 | } | ||
| 232 | |||
| 233 | base = ioremap_nocache(res->start, resource_size(res)); | ||
| 234 | if (!base) { | ||
| 235 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
| 236 | goto err1; | ||
| 237 | } | ||
| 238 | |||
| 239 | dwc3 = platform_device_alloc("dwc3-omap", -1); | ||
| 240 | if (!dwc3) { | ||
| 241 | dev_err(&pdev->dev, "couldn't allocate dwc3 device\n"); | ||
| 242 | goto err2; | ||
| 243 | } | ||
| 244 | |||
| 245 | context = kzalloc(resource_size(res), GFP_KERNEL); | ||
| 246 | if (!context) { | ||
| 247 | dev_err(&pdev->dev, "couldn't allocate dwc3 context memory\n"); | ||
| 248 | goto err3; | ||
| 249 | } | ||
| 250 | |||
| 251 | spin_lock_init(&omap->lock); | ||
| 252 | dma_set_coherent_mask(&dwc3->dev, pdev->dev.coherent_dma_mask); | ||
| 253 | |||
| 254 | dwc3->dev.parent = &pdev->dev; | ||
| 255 | dwc3->dev.dma_mask = pdev->dev.dma_mask; | ||
| 256 | dwc3->dev.dma_parms = pdev->dev.dma_parms; | ||
| 257 | omap->resource_size = resource_size(res); | ||
| 258 | omap->context = context; | ||
| 259 | omap->dev = &pdev->dev; | ||
| 260 | omap->irq = irq; | ||
| 261 | omap->base = base; | ||
| 262 | omap->dwc3 = dwc3; | ||
| 263 | |||
| 264 | reg = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); | ||
| 265 | |||
| 266 | if (!pdata) { | ||
| 267 | dev_dbg(&pdev->dev, "missing platform data\n"); | ||
| 268 | } else { | ||
| 269 | switch (pdata->utmi_mode) { | ||
| 270 | case DWC3_OMAP_UTMI_MODE_SW: | ||
| 271 | reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 272 | break; | ||
| 273 | case DWC3_OMAP_UTMI_MODE_HW: | ||
| 274 | reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
| 275 | break; | ||
| 276 | default: | ||
| 277 | dev_dbg(&pdev->dev, "UNKNOWN utmi mode %d\n", | ||
| 278 | pdata->utmi_mode); | ||
| 279 | } | ||
| 280 | } | ||
| 281 | |||
| 282 | dwc3_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg); | ||
| 283 | |||
| 284 | /* check the DMA Status */ | ||
| 285 | reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG); | ||
| 286 | omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE); | ||
| 287 | |||
| 288 | /* Set No-Idle and No-Standby */ | ||
| 289 | reg &= ~(USBOTGSS_STANDBYMODE_MASK | ||
| 290 | | USBOTGSS_IDLEMODE_MASK); | ||
| 291 | |||
| 292 | reg |= (USBOTGSS_SYSCONFIG_STANDBYMODE(USBOTGSS_STANDBYMODE_NO_STANDBY) | ||
| 293 | | USBOTGSS_SYSCONFIG_IDLEMODE(USBOTGSS_IDLEMODE_NO_IDLE)); | ||
| 294 | |||
| 295 | dwc3_writel(omap->base, USBOTGSS_SYSCONFIG, reg); | ||
| 296 | |||
| 297 | ret = request_irq(omap->irq, dwc3_omap_interrupt, 0, | ||
| 298 | "dwc3-omap", omap); | ||
| 299 | if (ret) { | ||
| 300 | dev_err(&pdev->dev, "failed to request IRQ #%d --> %d\n", | ||
| 301 | omap->irq, ret); | ||
| 302 | goto err4; | ||
| 303 | } | ||
| 304 | |||
| 305 | /* enable all IRQs */ | ||
| 306 | reg = USBOTGSS_IRQO_COREIRQ_ST; | ||
| 307 | dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg); | ||
| 308 | |||
| 309 | reg = (USBOTGSS_IRQ1_OEVT | | ||
| 310 | USBOTGSS_IRQ1_DRVVBUS_RISE | | ||
| 311 | USBOTGSS_IRQ1_CHRGVBUS_RISE | | ||
| 312 | USBOTGSS_IRQ1_DISCHRGVBUS_RISE | | ||
| 313 | USBOTGSS_IRQ1_IDPULLUP_RISE | | ||
| 314 | USBOTGSS_IRQ1_DRVVBUS_FALL | | ||
| 315 | USBOTGSS_IRQ1_CHRGVBUS_FALL | | ||
| 316 | USBOTGSS_IRQ1_DISCHRGVBUS_FALL | | ||
| 317 | USBOTGSS_IRQ1_IDPULLUP_FALL); | ||
| 318 | |||
| 319 | dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg); | ||
| 320 | |||
| 321 | ret = platform_device_add_resources(dwc3, pdev->resource, | ||
| 322 | pdev->num_resources); | ||
| 323 | if (ret) { | ||
| 324 | dev_err(&pdev->dev, "couldn't add resources to dwc3 device\n"); | ||
| 325 | goto err5; | ||
| 326 | } | ||
| 327 | |||
| 328 | ret = platform_device_add(dwc3); | ||
| 329 | if (ret) { | ||
| 330 | dev_err(&pdev->dev, "failed to register dwc3 device\n"); | ||
| 331 | goto err5; | ||
| 332 | } | ||
| 333 | |||
| 334 | return 0; | ||
| 335 | |||
| 336 | err5: | ||
| 337 | free_irq(omap->irq, omap); | ||
| 338 | |||
| 339 | err4: | ||
| 340 | kfree(omap->context); | ||
| 341 | |||
| 342 | err3: | ||
| 343 | platform_device_put(dwc3); | ||
| 344 | |||
| 345 | err2: | ||
| 346 | iounmap(base); | ||
| 347 | |||
| 348 | err1: | ||
| 349 | kfree(omap); | ||
| 350 | |||
| 351 | err0: | ||
| 352 | return ret; | ||
| 353 | } | ||
| 354 | |||
| 355 | static int __devexit dwc3_omap_remove(struct platform_device *pdev) | ||
| 356 | { | ||
| 357 | struct dwc3_omap *omap = platform_get_drvdata(pdev); | ||
| 358 | |||
| 359 | platform_device_unregister(omap->dwc3); | ||
| 360 | |||
| 361 | free_irq(omap->irq, omap); | ||
| 362 | iounmap(omap->base); | ||
| 363 | |||
| 364 | kfree(omap->context); | ||
| 365 | kfree(omap); | ||
| 366 | |||
| 367 | return 0; | ||
| 368 | } | ||
| 369 | |||
| 370 | static const struct of_device_id of_dwc3_matach[] = { | ||
| 371 | { | ||
| 372 | "ti,dwc3", | ||
| 373 | }, | ||
| 374 | { }, | ||
| 375 | }; | ||
| 376 | MODULE_DEVICE_TABLE(of, of_dwc3_matach); | ||
| 377 | |||
| 378 | static struct platform_driver dwc3_omap_driver = { | ||
| 379 | .probe = dwc3_omap_probe, | ||
| 380 | .remove = __devexit_p(dwc3_omap_remove), | ||
| 381 | .driver = { | ||
| 382 | .name = "omap-dwc3", | ||
| 383 | .of_match_table = of_dwc3_matach, | ||
| 384 | }, | ||
| 385 | }; | ||
| 386 | |||
| 387 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | ||
| 388 | MODULE_LICENSE("Dual BSD/GPL"); | ||
| 389 | MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer"); | ||
| 390 | |||
| 391 | static int __devinit dwc3_omap_init(void) | ||
| 392 | { | ||
| 393 | return platform_driver_register(&dwc3_omap_driver); | ||
| 394 | } | ||
| 395 | module_init(dwc3_omap_init); | ||
| 396 | |||
| 397 | static void __exit dwc3_omap_exit(void) | ||
| 398 | { | ||
| 399 | platform_driver_unregister(&dwc3_omap_driver); | ||
| 400 | } | ||
| 401 | module_exit(dwc3_omap_exit); | ||
| @@ -0,0 +1,219 @@ | |||
| 1 | /** | ||
| 2 | * dwc3-pci.c - PCI Specific glue layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/kernel.h> | ||
| 40 | #include <linux/module.h> | ||
| 41 | #include <linux/slab.h> | ||
| 42 | #include <linux/pci.h> | ||
| 43 | #include <linux/platform_device.h> | ||
| 44 | |||
| 45 | /* FIXME define these in <linux/pci_ids.h> */ | ||
| 46 | #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 | ||
| 47 | #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd | ||
| 48 | |||
| 49 | #define DWC3_PCI_DEVS_POSSIBLE 32 | ||
| 50 | |||
| 51 | struct dwc3_pci { | ||
| 52 | struct device *dev; | ||
| 53 | struct platform_device *dwc3; | ||
| 54 | }; | ||
| 55 | |||
| 56 | static DECLARE_BITMAP(dwc3_pci_devs, DWC3_PCI_DEVS_POSSIBLE); | ||
| 57 | |||
| 58 | static int dwc3_pci_get_device_id(struct dwc3_pci *glue) | ||
| 59 | { | ||
| 60 | int id; | ||
| 61 | |||
| 62 | again: | ||
| 63 | id = find_first_zero_bit(dwc3_pci_devs, DWC3_PCI_DEVS_POSSIBLE); | ||
| 64 | if (id < DWC3_PCI_DEVS_POSSIBLE) { | ||
| 65 | int old; | ||
| 66 | |||
| 67 | old = test_and_set_bit(id, dwc3_pci_devs); | ||
| 68 | if (old) | ||
| 69 | goto again; | ||
| 70 | } else { | ||
| 71 | dev_err(glue->dev, "no space for new device\n"); | ||
| 72 | id = -ENOMEM; | ||
| 73 | } | ||
| 74 | |||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | static void dwc3_pci_put_device_id(struct dwc3_pci *glue, int id) | ||
| 79 | { | ||
| 80 | int ret; | ||
| 81 | |||
| 82 | if (id < 0) | ||
| 83 | return; | ||
| 84 | |||
| 85 | ret = test_bit(id, dwc3_pci_devs); | ||
| 86 | WARN(!ret, "Device: %s\nID %d not in use\n", | ||
| 87 | dev_driver_string(glue->dev), id); | ||
| 88 | clear_bit(id, dwc3_pci_devs); | ||
| 89 | } | ||
| 90 | |||
| 91 | static int __devinit dwc3_pci_probe(struct pci_dev *pci, | ||
| 92 | const struct pci_device_id *id) | ||
| 93 | { | ||
| 94 | struct resource res[2]; | ||
| 95 | struct platform_device *dwc3; | ||
| 96 | struct dwc3_pci *glue; | ||
| 97 | int ret = -ENOMEM; | ||
| 98 | int devid; | ||
| 99 | |||
| 100 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
| 101 | if (!glue) { | ||
| 102 | dev_err(&pci->dev, "not enough memory\n"); | ||
| 103 | goto err0; | ||
| 104 | } | ||
| 105 | |||
| 106 | glue->dev = &pci->dev; | ||
| 107 | |||
| 108 | ret = pci_enable_device(pci); | ||
| 109 | if (ret) { | ||
| 110 | dev_err(&pci->dev, "failed to enable pci device\n"); | ||
| 111 | goto err1; | ||
| 112 | } | ||
| 113 | |||
| 114 | pci_set_power_state(pci, PCI_D0); | ||
| 115 | pci_set_master(pci); | ||
| 116 | |||
| 117 | devid = dwc3_pci_get_device_id(glue); | ||
| 118 | if (devid < 0) | ||
| 119 | goto err2; | ||
| 120 | |||
| 121 | dwc3 = platform_device_alloc("dwc3-pci", devid); | ||
| 122 | if (!dwc3) { | ||
| 123 | dev_err(&pci->dev, "couldn't allocate dwc3 device\n"); | ||
| 124 | goto err3; | ||
| 125 | } | ||
| 126 | |||
| 127 | memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); | ||
| 128 | |||
| 129 | res[0].start = pci_resource_start(pci, 0); | ||
| 130 | res[0].end = pci_resource_end(pci, 0); | ||
| 131 | res[0].name = "dwc_usb3"; | ||
| 132 | res[0].flags = IORESOURCE_MEM; | ||
| 133 | |||
| 134 | res[1].start = pci->irq; | ||
| 135 | res[1].name = "dwc_usb3"; | ||
| 136 | res[1].flags = IORESOURCE_IRQ; | ||
| 137 | |||
| 138 | ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); | ||
| 139 | if (ret) { | ||
| 140 | dev_err(&pci->dev, "couldn't add resources to dwc3 device\n"); | ||
| 141 | goto err4; | ||
| 142 | } | ||
| 143 | |||
| 144 | pci_set_drvdata(pci, glue); | ||
| 145 | |||
| 146 | dma_set_coherent_mask(&dwc3->dev, pci->dev.coherent_dma_mask); | ||
| 147 | |||
| 148 | dwc3->dev.dma_mask = pci->dev.dma_mask; | ||
| 149 | dwc3->dev.dma_parms = pci->dev.dma_parms; | ||
| 150 | dwc3->dev.parent = &pci->dev; | ||
| 151 | glue->dwc3 = dwc3; | ||
| 152 | |||
| 153 | ret = platform_device_add(dwc3); | ||
| 154 | if (ret) { | ||
| 155 | dev_err(&pci->dev, "failed to register dwc3 device\n"); | ||
| 156 | goto err4; | ||
| 157 | } | ||
| 158 | |||
| 159 | return 0; | ||
| 160 | |||
| 161 | err4: | ||
| 162 | pci_set_drvdata(pci, NULL); | ||
| 163 | platform_device_put(dwc3); | ||
| 164 | |||
| 165 | err3: | ||
| 166 | dwc3_pci_put_device_id(glue, devid); | ||
| 167 | |||
| 168 | err2: | ||
| 169 | pci_disable_device(pci); | ||
| 170 | |||
| 171 | err1: | ||
| 172 | kfree(pci); | ||
| 173 | |||
| 174 | err0: | ||
| 175 | return ret; | ||
| 176 | } | ||
| 177 | |||
| 178 | static void __devexit dwc3_pci_remove(struct pci_dev *pci) | ||
| 179 | { | ||
| 180 | struct dwc3_pci *glue = pci_get_drvdata(pci); | ||
| 181 | |||
| 182 | dwc3_pci_put_device_id(glue, glue->dwc3->id); | ||
| 183 | platform_device_unregister(glue->dwc3); | ||
| 184 | pci_set_drvdata(pci, NULL); | ||
| 185 | pci_disable_device(pci); | ||
| 186 | kfree(glue); | ||
| 187 | } | ||
| 188 | |||
| 189 | static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = { | ||
| 190 | { | ||
| 191 | PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, | ||
| 192 | PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), | ||
| 193 | }, | ||
| 194 | { } /* Terminating Entry */ | ||
| 195 | }; | ||
| 196 | MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); | ||
| 197 | |||
| 198 | static struct pci_driver dwc3_pci_driver = { | ||
| 199 | .name = "pci-dwc3", | ||
| 200 | .id_table = dwc3_pci_id_table, | ||
| 201 | .probe = dwc3_pci_probe, | ||
| 202 | .remove = __devexit_p(dwc3_pci_remove), | ||
| 203 | }; | ||
| 204 | |||
| 205 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | ||
| 206 | MODULE_LICENSE("Dual BSD/GPL"); | ||
| 207 | MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer"); | ||
| 208 | |||
| 209 | static int __devinit dwc3_pci_init(void) | ||
| 210 | { | ||
| 211 | return pci_register_driver(&dwc3_pci_driver); | ||
| 212 | } | ||
| 213 | module_init(dwc3_pci_init); | ||
| 214 | |||
| 215 | static void __exit dwc3_pci_exit(void) | ||
| 216 | { | ||
| 217 | pci_unregister_driver(&dwc3_pci_driver); | ||
| 218 | } | ||
| 219 | module_exit(dwc3_pci_exit); | ||
| @@ -0,0 +1,804 @@ | |||
| 1 | /** | ||
| 2 | * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/kernel.h> | ||
| 40 | #include <linux/slab.h> | ||
| 41 | #include <linux/spinlock.h> | ||
| 42 | #include <linux/platform_device.h> | ||
| 43 | #include <linux/pm_runtime.h> | ||
| 44 | #include <linux/interrupt.h> | ||
| 45 | #include <linux/io.h> | ||
| 46 | #include <linux/list.h> | ||
| 47 | #include <linux/dma-mapping.h> | ||
| 48 | |||
| 49 | #include <linux/usb/ch9.h> | ||
| 50 | #include <linux/usb/gadget.h> | ||
| 51 | |||
| 52 | #include "core.h" | ||
| 53 | #include "gadget.h" | ||
| 54 | #include "io.h" | ||
| 55 | |||
| 56 | static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, | ||
| 57 | const struct dwc3_event_depevt *event); | ||
| 58 | |||
| 59 | static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) | ||
| 60 | { | ||
| 61 | switch (state) { | ||
| 62 | case EP0_UNCONNECTED: | ||
| 63 | return "Unconnected"; | ||
| 64 | case EP0_SETUP_PHASE: | ||
| 65 | return "Setup Phase"; | ||
| 66 | case EP0_DATA_PHASE: | ||
| 67 | return "Data Phase"; | ||
| 68 | case EP0_STATUS_PHASE: | ||
| 69 | return "Status Phase"; | ||
| 70 | default: | ||
| 71 | return "UNKNOWN"; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | ||
| 76 | u32 len, u32 type) | ||
| 77 | { | ||
| 78 | struct dwc3_gadget_ep_cmd_params params; | ||
| 79 | struct dwc3_trb_hw *trb_hw; | ||
| 80 | struct dwc3_trb trb; | ||
| 81 | struct dwc3_ep *dep; | ||
| 82 | |||
| 83 | int ret; | ||
| 84 | |||
| 85 | dep = dwc->eps[epnum]; | ||
| 86 | if (dep->flags & DWC3_EP_BUSY) { | ||
| 87 | dev_vdbg(dwc->dev, "%s: still busy\n", dep->name); | ||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | |||
| 91 | trb_hw = dwc->ep0_trb; | ||
| 92 | memset(&trb, 0, sizeof(trb)); | ||
| 93 | |||
| 94 | trb.trbctl = type; | ||
| 95 | trb.bplh = buf_dma; | ||
| 96 | trb.length = len; | ||
| 97 | |||
| 98 | trb.hwo = 1; | ||
| 99 | trb.lst = 1; | ||
| 100 | trb.ioc = 1; | ||
| 101 | trb.isp_imi = 1; | ||
| 102 | |||
| 103 | dwc3_trb_to_hw(&trb, trb_hw); | ||
| 104 | |||
| 105 | memset(¶ms, 0, sizeof(params)); | ||
| 106 | params.param0 = upper_32_bits(dwc->ep0_trb_addr); | ||
| 107 | params.param1 = lower_32_bits(dwc->ep0_trb_addr); | ||
| 108 | |||
| 109 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | ||
| 110 | DWC3_DEPCMD_STARTTRANSFER, ¶ms); | ||
| 111 | if (ret < 0) { | ||
| 112 | dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); | ||
| 113 | return ret; | ||
| 114 | } | ||
| 115 | |||
| 116 | dep->flags |= DWC3_EP_BUSY; | ||
| 117 | dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, | ||
| 118 | dep->number); | ||
| 119 | |||
| 120 | dwc->ep0_next_event = DWC3_EP0_COMPLETE; | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, | ||
| 126 | struct dwc3_request *req) | ||
| 127 | { | ||
| 128 | int ret = 0; | ||
| 129 | |||
| 130 | req->request.actual = 0; | ||
| 131 | req->request.status = -EINPROGRESS; | ||
| 132 | req->epnum = dep->number; | ||
| 133 | |||
| 134 | list_add_tail(&req->list, &dep->request_list); | ||
| 135 | |||
| 136 | /* | ||
| 137 | * Gadget driver might not be quick enough to queue a request | ||
| 138 | * before we get a Transfer Not Ready event on this endpoint. | ||
| 139 | * | ||
| 140 | * In that case, we will set DWC3_EP_PENDING_REQUEST. When that | ||
| 141 | * flag is set, it's telling us that as soon as Gadget queues the | ||
| 142 | * required request, we should kick the transfer here because the | ||
| 143 | * IRQ we were waiting for is long gone. | ||
| 144 | */ | ||
| 145 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | ||
| 146 | struct dwc3 *dwc = dep->dwc; | ||
| 147 | unsigned direction; | ||
| 148 | u32 type; | ||
| 149 | |||
| 150 | direction = !!(dep->flags & DWC3_EP0_DIR_IN); | ||
| 151 | |||
| 152 | if (dwc->ep0state == EP0_STATUS_PHASE) { | ||
| 153 | type = dwc->three_stage_setup | ||
| 154 | ? DWC3_TRBCTL_CONTROL_STATUS3 | ||
| 155 | : DWC3_TRBCTL_CONTROL_STATUS2; | ||
| 156 | } else if (dwc->ep0state == EP0_DATA_PHASE) { | ||
| 157 | type = DWC3_TRBCTL_CONTROL_DATA; | ||
| 158 | } else { | ||
| 159 | /* should never happen */ | ||
| 160 | WARN_ON(1); | ||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | ret = dwc3_ep0_start_trans(dwc, direction, | ||
| 165 | req->request.dma, req->request.length, type); | ||
| 166 | dep->flags &= ~(DWC3_EP_PENDING_REQUEST | | ||
| 167 | DWC3_EP0_DIR_IN); | ||
| 168 | } | ||
| 169 | |||
| 170 | return ret; | ||
| 171 | } | ||
| 172 | |||
| 173 | int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, | ||
| 174 | gfp_t gfp_flags) | ||
| 175 | { | ||
| 176 | struct dwc3_request *req = to_dwc3_request(request); | ||
| 177 | struct dwc3_ep *dep = to_dwc3_ep(ep); | ||
| 178 | struct dwc3 *dwc = dep->dwc; | ||
| 179 | |||
| 180 | unsigned long flags; | ||
| 181 | |||
| 182 | int ret; | ||
| 183 | |||
| 184 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 185 | if (!dep->desc) { | ||
| 186 | dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", | ||
| 187 | request, dep->name); | ||
| 188 | ret = -ESHUTDOWN; | ||
| 189 | goto out; | ||
| 190 | } | ||
| 191 | |||
| 192 | /* we share one TRB for ep0/1 */ | ||
| 193 | if (!list_empty(&dwc->eps[0]->request_list) || | ||
| 194 | !list_empty(&dwc->eps[1]->request_list) || | ||
| 195 | dwc->ep0_status_pending) { | ||
| 196 | ret = -EBUSY; | ||
| 197 | goto out; | ||
| 198 | } | ||
| 199 | |||
| 200 | dev_vdbg(dwc->dev, "queueing request %p to %s length %d, state '%s'\n", | ||
| 201 | request, dep->name, request->length, | ||
| 202 | dwc3_ep0_state_string(dwc->ep0state)); | ||
| 203 | |||
| 204 | ret = __dwc3_gadget_ep0_queue(dep, req); | ||
| 205 | |||
| 206 | out: | ||
| 207 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 208 | |||
| 209 | return ret; | ||
| 210 | } | ||
| 211 | |||
| 212 | static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) | ||
| 213 | { | ||
| 214 | struct dwc3_ep *dep = dwc->eps[0]; | ||
| 215 | |||
| 216 | /* stall is always issued on EP0 */ | ||
| 217 | __dwc3_gadget_ep_set_halt(dwc->eps[0], 1); | ||
| 218 | dwc->eps[0]->flags = DWC3_EP_ENABLED; | ||
| 219 | |||
| 220 | if (!list_empty(&dep->request_list)) { | ||
| 221 | struct dwc3_request *req; | ||
| 222 | |||
| 223 | req = next_request(&dep->request_list); | ||
| 224 | dwc3_gadget_giveback(dep, req, -ECONNRESET); | ||
| 225 | } | ||
| 226 | |||
| 227 | dwc->ep0state = EP0_SETUP_PHASE; | ||
| 228 | dwc3_ep0_out_start(dwc); | ||
| 229 | } | ||
| 230 | |||
| 231 | void dwc3_ep0_out_start(struct dwc3 *dwc) | ||
| 232 | { | ||
| 233 | int ret; | ||
| 234 | |||
| 235 | ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8, | ||
| 236 | DWC3_TRBCTL_CONTROL_SETUP); | ||
| 237 | WARN_ON(ret < 0); | ||
| 238 | } | ||
| 239 | |||
| 240 | static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) | ||
| 241 | { | ||
| 242 | struct dwc3_ep *dep; | ||
| 243 | u32 windex = le16_to_cpu(wIndex_le); | ||
| 244 | u32 epnum; | ||
| 245 | |||
| 246 | epnum = (windex & USB_ENDPOINT_NUMBER_MASK) << 1; | ||
| 247 | if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) | ||
| 248 | epnum |= 1; | ||
| 249 | |||
| 250 | dep = dwc->eps[epnum]; | ||
| 251 | if (dep->flags & DWC3_EP_ENABLED) | ||
| 252 | return dep; | ||
| 253 | |||
| 254 | return NULL; | ||
| 255 | } | ||
| 256 | |||
| 257 | static void dwc3_ep0_send_status_response(struct dwc3 *dwc) | ||
| 258 | { | ||
| 259 | dwc3_ep0_start_trans(dwc, 1, dwc->setup_buf_addr, | ||
| 260 | dwc->ep0_usb_req.length, | ||
| 261 | DWC3_TRBCTL_CONTROL_DATA); | ||
| 262 | } | ||
| 263 | |||
| 264 | /* | ||
| 265 | * ch 9.4.5 | ||
| 266 | */ | ||
| 267 | static int dwc3_ep0_handle_status(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | ||
| 268 | { | ||
| 269 | struct dwc3_ep *dep; | ||
| 270 | u32 recip; | ||
| 271 | u16 usb_status = 0; | ||
| 272 | __le16 *response_pkt; | ||
| 273 | |||
| 274 | recip = ctrl->bRequestType & USB_RECIP_MASK; | ||
| 275 | switch (recip) { | ||
| 276 | case USB_RECIP_DEVICE: | ||
| 277 | /* | ||
| 278 | * We are self-powered. U1/U2/LTM will be set later | ||
| 279 | * once we handle this states. RemoteWakeup is 0 on SS | ||
| 280 | */ | ||
| 281 | usb_status |= dwc->is_selfpowered << USB_DEVICE_SELF_POWERED; | ||
| 282 | break; | ||
| 283 | |||
| 284 | case USB_RECIP_INTERFACE: | ||
| 285 | /* | ||
| 286 | * Function Remote Wake Capable D0 | ||
| 287 | * Function Remote Wakeup D1 | ||
| 288 | */ | ||
| 289 | break; | ||
| 290 | |||
| 291 | case USB_RECIP_ENDPOINT: | ||
| 292 | dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); | ||
| 293 | if (!dep) | ||
| 294 | return -EINVAL; | ||
| 295 | |||
| 296 | if (dep->flags & DWC3_EP_STALL) | ||
| 297 | usb_status = 1 << USB_ENDPOINT_HALT; | ||
| 298 | break; | ||
| 299 | default: | ||
| 300 | return -EINVAL; | ||
| 301 | }; | ||
| 302 | |||
| 303 | response_pkt = (__le16 *) dwc->setup_buf; | ||
| 304 | *response_pkt = cpu_to_le16(usb_status); | ||
| 305 | dwc->ep0_usb_req.length = sizeof(*response_pkt); | ||
| 306 | dwc->ep0_status_pending = 1; | ||
| 307 | |||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | static int dwc3_ep0_handle_feature(struct dwc3 *dwc, | ||
| 312 | struct usb_ctrlrequest *ctrl, int set) | ||
| 313 | { | ||
| 314 | struct dwc3_ep *dep; | ||
| 315 | u32 recip; | ||
| 316 | u32 wValue; | ||
| 317 | u32 wIndex; | ||
| 318 | u32 reg; | ||
| 319 | int ret; | ||
| 320 | u32 mode; | ||
| 321 | |||
| 322 | wValue = le16_to_cpu(ctrl->wValue); | ||
| 323 | wIndex = le16_to_cpu(ctrl->wIndex); | ||
| 324 | recip = ctrl->bRequestType & USB_RECIP_MASK; | ||
| 325 | switch (recip) { | ||
| 326 | case USB_RECIP_DEVICE: | ||
| 327 | |||
| 328 | /* | ||
| 329 | * 9.4.1 says only only for SS, in AddressState only for | ||
| 330 | * default control pipe | ||
| 331 | */ | ||
| 332 | switch (wValue) { | ||
| 333 | case USB_DEVICE_U1_ENABLE: | ||
| 334 | case USB_DEVICE_U2_ENABLE: | ||
| 335 | case USB_DEVICE_LTM_ENABLE: | ||
| 336 | if (dwc->dev_state != DWC3_CONFIGURED_STATE) | ||
| 337 | return -EINVAL; | ||
| 338 | if (dwc->speed != DWC3_DSTS_SUPERSPEED) | ||
| 339 | return -EINVAL; | ||
| 340 | } | ||
| 341 | |||
| 342 | /* XXX add U[12] & LTM */ | ||
| 343 | switch (wValue) { | ||
| 344 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 345 | break; | ||
| 346 | case USB_DEVICE_U1_ENABLE: | ||
| 347 | break; | ||
| 348 | case USB_DEVICE_U2_ENABLE: | ||
| 349 | break; | ||
| 350 | case USB_DEVICE_LTM_ENABLE: | ||
| 351 | break; | ||
| 352 | |||
| 353 | case USB_DEVICE_TEST_MODE: | ||
| 354 | if ((wIndex & 0xff) != 0) | ||
| 355 | return -EINVAL; | ||
| 356 | if (!set) | ||
| 357 | return -EINVAL; | ||
| 358 | |||
| 359 | mode = wIndex >> 8; | ||
| 360 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
| 361 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; | ||
| 362 | |||
| 363 | switch (mode) { | ||
| 364 | case TEST_J: | ||
| 365 | case TEST_K: | ||
| 366 | case TEST_SE0_NAK: | ||
| 367 | case TEST_PACKET: | ||
| 368 | case TEST_FORCE_EN: | ||
| 369 | reg |= mode << 1; | ||
| 370 | break; | ||
| 371 | default: | ||
| 372 | return -EINVAL; | ||
| 373 | } | ||
| 374 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
| 375 | break; | ||
| 376 | default: | ||
| 377 | return -EINVAL; | ||
| 378 | } | ||
| 379 | break; | ||
| 380 | |||
| 381 | case USB_RECIP_INTERFACE: | ||
| 382 | switch (wValue) { | ||
| 383 | case USB_INTRF_FUNC_SUSPEND: | ||
| 384 | if (wIndex & USB_INTRF_FUNC_SUSPEND_LP) | ||
| 385 | /* XXX enable Low power suspend */ | ||
| 386 | ; | ||
| 387 | if (wIndex & USB_INTRF_FUNC_SUSPEND_RW) | ||
| 388 | /* XXX enable remote wakeup */ | ||
| 389 | ; | ||
| 390 | break; | ||
| 391 | default: | ||
| 392 | return -EINVAL; | ||
| 393 | } | ||
| 394 | break; | ||
| 395 | |||
| 396 | case USB_RECIP_ENDPOINT: | ||
| 397 | switch (wValue) { | ||
| 398 | case USB_ENDPOINT_HALT: | ||
| 399 | |||
| 400 | dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); | ||
| 401 | if (!dep) | ||
| 402 | return -EINVAL; | ||
| 403 | ret = __dwc3_gadget_ep_set_halt(dep, set); | ||
| 404 | if (ret) | ||
| 405 | return -EINVAL; | ||
| 406 | break; | ||
| 407 | default: | ||
| 408 | return -EINVAL; | ||
| 409 | } | ||
| 410 | break; | ||
| 411 | |||
| 412 | default: | ||
| 413 | return -EINVAL; | ||
| 414 | }; | ||
| 415 | |||
| 416 | return 0; | ||
| 417 | } | ||
| 418 | |||
| 419 | static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | ||
| 420 | { | ||
| 421 | u32 addr; | ||
| 422 | u32 reg; | ||
| 423 | |||
| 424 | addr = le16_to_cpu(ctrl->wValue); | ||
| 425 | if (addr > 127) | ||
| 426 | return -EINVAL; | ||
| 427 | |||
| 428 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); | ||
| 429 | reg &= ~(DWC3_DCFG_DEVADDR_MASK); | ||
| 430 | reg |= DWC3_DCFG_DEVADDR(addr); | ||
| 431 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | ||
| 432 | |||
| 433 | if (addr) | ||
| 434 | dwc->dev_state = DWC3_ADDRESS_STATE; | ||
| 435 | else | ||
| 436 | dwc->dev_state = DWC3_DEFAULT_STATE; | ||
| 437 | |||
| 438 | return 0; | ||
| 439 | } | ||
| 440 | |||
| 441 | static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | ||
| 442 | { | ||
| 443 | int ret; | ||
| 444 | |||
| 445 | spin_unlock(&dwc->lock); | ||
| 446 | ret = dwc->gadget_driver->setup(&dwc->gadget, ctrl); | ||
| 447 | spin_lock(&dwc->lock); | ||
| 448 | return ret; | ||
| 449 | } | ||
| 450 | |||
| 451 | static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | ||
| 452 | { | ||
| 453 | u32 cfg; | ||
| 454 | int ret; | ||
| 455 | |||
| 456 | dwc->start_config_issued = false; | ||
| 457 | cfg = le16_to_cpu(ctrl->wValue); | ||
| 458 | |||
| 459 | switch (dwc->dev_state) { | ||
| 460 | case DWC3_DEFAULT_STATE: | ||
| 461 | return -EINVAL; | ||
| 462 | break; | ||
| 463 | |||
| 464 | case DWC3_ADDRESS_STATE: | ||
| 465 | ret = dwc3_ep0_delegate_req(dwc, ctrl); | ||
| 466 | /* if the cfg matches and the cfg is non zero */ | ||
| 467 | if (!ret && cfg) | ||
| 468 | dwc->dev_state = DWC3_CONFIGURED_STATE; | ||
| 469 | break; | ||
| 470 | |||
| 471 | case DWC3_CONFIGURED_STATE: | ||
| 472 | ret = dwc3_ep0_delegate_req(dwc, ctrl); | ||
| 473 | if (!cfg) | ||
| 474 | dwc->dev_state = DWC3_ADDRESS_STATE; | ||
| 475 | break; | ||
| 476 | } | ||
| 477 | return 0; | ||
| 478 | } | ||
| 479 | |||
| 480 | static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | ||
| 481 | { | ||
| 482 | int ret; | ||
| 483 | |||
| 484 | switch (ctrl->bRequest) { | ||
| 485 | case USB_REQ_GET_STATUS: | ||
| 486 | dev_vdbg(dwc->dev, "USB_REQ_GET_STATUS\n"); | ||
| 487 | ret = dwc3_ep0_handle_status(dwc, ctrl); | ||
| 488 | break; | ||
| 489 | case USB_REQ_CLEAR_FEATURE: | ||
| 490 | dev_vdbg(dwc->dev, "USB_REQ_CLEAR_FEATURE\n"); | ||
| 491 | ret = dwc3_ep0_handle_feature(dwc, ctrl, 0); | ||
| 492 | break; | ||
| 493 | case USB_REQ_SET_FEATURE: | ||
| 494 | dev_vdbg(dwc->dev, "USB_REQ_SET_FEATURE\n"); | ||
| 495 | ret = dwc3_ep0_handle_feature(dwc, ctrl, 1); | ||
| 496 | break; | ||
| 497 | case USB_REQ_SET_ADDRESS: | ||
| 498 | dev_vdbg(dwc->dev, "USB_REQ_SET_ADDRESS\n"); | ||
| 499 | ret = dwc3_ep0_set_address(dwc, ctrl); | ||
| 500 | break; | ||
| 501 | case USB_REQ_SET_CONFIGURATION: | ||
| 502 | dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n"); | ||
| 503 | ret = dwc3_ep0_set_config(dwc, ctrl); | ||
| 504 | break; | ||
| 505 | default: | ||
| 506 | dev_vdbg(dwc->dev, "Forwarding to gadget driver\n"); | ||
| 507 | ret = dwc3_ep0_delegate_req(dwc, ctrl); | ||
| 508 | break; | ||
| 509 | }; | ||
| 510 | |||
| 511 | return ret; | ||
| 512 | } | ||
| 513 | |||
| 514 | static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, | ||
| 515 | const struct dwc3_event_depevt *event) | ||
| 516 | { | ||
| 517 | struct usb_ctrlrequest *ctrl = dwc->ctrl_req; | ||
| 518 | int ret; | ||
| 519 | u32 len; | ||
| 520 | |||
| 521 | if (!dwc->gadget_driver) | ||
| 522 | goto err; | ||
| 523 | |||
| 524 | len = le16_to_cpu(ctrl->wLength); | ||
| 525 | if (!len) { | ||
| 526 | dwc->three_stage_setup = false; | ||
| 527 | dwc->ep0_expect_in = false; | ||
| 528 | dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS; | ||
| 529 | } else { | ||
| 530 | dwc->three_stage_setup = true; | ||
| 531 | dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN); | ||
| 532 | dwc->ep0_next_event = DWC3_EP0_NRDY_DATA; | ||
| 533 | } | ||
| 534 | |||
| 535 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) | ||
| 536 | ret = dwc3_ep0_std_request(dwc, ctrl); | ||
| 537 | else | ||
| 538 | ret = dwc3_ep0_delegate_req(dwc, ctrl); | ||
| 539 | |||
| 540 | if (ret >= 0) | ||
| 541 | return; | ||
| 542 | |||
| 543 | err: | ||
| 544 | dwc3_ep0_stall_and_restart(dwc); | ||
| 545 | } | ||
| 546 | |||
| 547 | static void dwc3_ep0_complete_data(struct dwc3 *dwc, | ||
| 548 | const struct dwc3_event_depevt *event) | ||
| 549 | { | ||
| 550 | struct dwc3_request *r = NULL; | ||
| 551 | struct usb_request *ur; | ||
| 552 | struct dwc3_trb trb; | ||
| 553 | struct dwc3_ep *dep; | ||
| 554 | u32 transferred; | ||
| 555 | u8 epnum; | ||
| 556 | |||
| 557 | epnum = event->endpoint_number; | ||
| 558 | dep = dwc->eps[epnum]; | ||
| 559 | |||
| 560 | dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS; | ||
| 561 | |||
| 562 | if (!dwc->ep0_status_pending) { | ||
| 563 | r = next_request(&dwc->eps[0]->request_list); | ||
| 564 | ur = &r->request; | ||
| 565 | } else { | ||
| 566 | ur = &dwc->ep0_usb_req; | ||
| 567 | dwc->ep0_status_pending = 0; | ||
| 568 | } | ||
| 569 | |||
| 570 | dwc3_trb_to_nat(dwc->ep0_trb, &trb); | ||
| 571 | |||
| 572 | if (dwc->ep0_bounced) { | ||
| 573 | struct dwc3_ep *ep0 = dwc->eps[0]; | ||
| 574 | |||
| 575 | transferred = min_t(u32, ur->length, | ||
| 576 | ep0->endpoint.maxpacket - trb.length); | ||
| 577 | memcpy(ur->buf, dwc->ep0_bounce, transferred); | ||
| 578 | dwc->ep0_bounced = false; | ||
| 579 | } else { | ||
| 580 | transferred = ur->length - trb.length; | ||
| 581 | ur->actual += transferred; | ||
| 582 | } | ||
| 583 | |||
| 584 | if ((epnum & 1) && ur->actual < ur->length) { | ||
| 585 | /* for some reason we did not get everything out */ | ||
| 586 | |||
| 587 | dwc3_ep0_stall_and_restart(dwc); | ||
| 588 | } else { | ||
| 589 | /* | ||
| 590 | * handle the case where we have to send a zero packet. This | ||
| 591 | * seems to be case when req.length > maxpacket. Could it be? | ||
| 592 | */ | ||
| 593 | if (r) | ||
| 594 | dwc3_gadget_giveback(dep, r, 0); | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | static void dwc3_ep0_complete_req(struct dwc3 *dwc, | ||
| 599 | const struct dwc3_event_depevt *event) | ||
| 600 | { | ||
| 601 | struct dwc3_request *r; | ||
| 602 | struct dwc3_ep *dep; | ||
| 603 | |||
| 604 | dep = dwc->eps[0]; | ||
| 605 | |||
| 606 | if (!list_empty(&dep->request_list)) { | ||
| 607 | r = next_request(&dep->request_list); | ||
| 608 | |||
| 609 | dwc3_gadget_giveback(dep, r, 0); | ||
| 610 | } | ||
| 611 | |||
| 612 | dwc->ep0state = EP0_SETUP_PHASE; | ||
| 613 | dwc3_ep0_out_start(dwc); | ||
| 614 | } | ||
| 615 | |||
| 616 | static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, | ||
| 617 | const struct dwc3_event_depevt *event) | ||
| 618 | { | ||
| 619 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; | ||
| 620 | |||
| 621 | dep->flags &= ~DWC3_EP_BUSY; | ||
| 622 | |||
| 623 | switch (dwc->ep0state) { | ||
| 624 | case EP0_SETUP_PHASE: | ||
| 625 | dev_vdbg(dwc->dev, "Inspecting Setup Bytes\n"); | ||
| 626 | dwc3_ep0_inspect_setup(dwc, event); | ||
| 627 | break; | ||
| 628 | |||
| 629 | case EP0_DATA_PHASE: | ||
| 630 | dev_vdbg(dwc->dev, "Data Phase\n"); | ||
| 631 | dwc3_ep0_complete_data(dwc, event); | ||
| 632 | break; | ||
| 633 | |||
| 634 | case EP0_STATUS_PHASE: | ||
| 635 | dev_vdbg(dwc->dev, "Status Phase\n"); | ||
| 636 | dwc3_ep0_complete_req(dwc, event); | ||
| 637 | break; | ||
| 638 | default: | ||
| 639 | WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state); | ||
| 640 | } | ||
| 641 | } | ||
| 642 | |||
| 643 | static void dwc3_ep0_do_control_setup(struct dwc3 *dwc, | ||
| 644 | const struct dwc3_event_depevt *event) | ||
| 645 | { | ||
| 646 | dwc->ep0state = EP0_SETUP_PHASE; | ||
| 647 | dwc3_ep0_out_start(dwc); | ||
| 648 | } | ||
| 649 | |||
| 650 | static void dwc3_ep0_do_control_data(struct dwc3 *dwc, | ||
| 651 | const struct dwc3_event_depevt *event) | ||
| 652 | { | ||
| 653 | struct dwc3_ep *dep; | ||
| 654 | struct dwc3_request *req; | ||
| 655 | int ret; | ||
| 656 | |||
| 657 | dep = dwc->eps[0]; | ||
| 658 | dwc->ep0state = EP0_DATA_PHASE; | ||
| 659 | |||
| 660 | if (dwc->ep0_status_pending) { | ||
| 661 | dwc3_ep0_send_status_response(dwc); | ||
| 662 | return; | ||
| 663 | } | ||
| 664 | |||
| 665 | if (list_empty(&dep->request_list)) { | ||
| 666 | dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n"); | ||
| 667 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
| 668 | |||
| 669 | if (event->endpoint_number) | ||
| 670 | dep->flags |= DWC3_EP0_DIR_IN; | ||
| 671 | return; | ||
| 672 | } | ||
| 673 | |||
| 674 | req = next_request(&dep->request_list); | ||
| 675 | req->direction = !!event->endpoint_number; | ||
| 676 | |||
| 677 | dwc->ep0state = EP0_DATA_PHASE; | ||
| 678 | if (req->request.length == 0) { | ||
| 679 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | ||
| 680 | dwc->ctrl_req_addr, 0, | ||
| 681 | DWC3_TRBCTL_CONTROL_DATA); | ||
| 682 | } else if ((req->request.length % dep->endpoint.maxpacket) | ||
| 683 | && (event->endpoint_number == 0)) { | ||
| 684 | dwc3_map_buffer_to_dma(req); | ||
| 685 | |||
| 686 | WARN_ON(req->request.length > dep->endpoint.maxpacket); | ||
| 687 | |||
| 688 | dwc->ep0_bounced = true; | ||
| 689 | |||
| 690 | /* | ||
| 691 | * REVISIT in case request length is bigger than EP0 | ||
| 692 | * wMaxPacketSize, we will need two chained TRBs to handle | ||
| 693 | * the transfer. | ||
| 694 | */ | ||
| 695 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | ||
| 696 | dwc->ep0_bounce_addr, dep->endpoint.maxpacket, | ||
| 697 | DWC3_TRBCTL_CONTROL_DATA); | ||
| 698 | } else { | ||
| 699 | dwc3_map_buffer_to_dma(req); | ||
| 700 | |||
| 701 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | ||
| 702 | req->request.dma, req->request.length, | ||
| 703 | DWC3_TRBCTL_CONTROL_DATA); | ||
| 704 | } | ||
| 705 | |||
| 706 | WARN_ON(ret < 0); | ||
| 707 | } | ||
| 708 | |||
| 709 | static void dwc3_ep0_do_control_status(struct dwc3 *dwc, | ||
| 710 | const struct dwc3_event_depevt *event) | ||
| 711 | { | ||
| 712 | u32 type; | ||
| 713 | int ret; | ||
| 714 | |||
| 715 | dwc->ep0state = EP0_STATUS_PHASE; | ||
| 716 | |||
| 717 | type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 | ||
| 718 | : DWC3_TRBCTL_CONTROL_STATUS2; | ||
| 719 | |||
| 720 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | ||
| 721 | dwc->ctrl_req_addr, 0, type); | ||
| 722 | |||
| 723 | WARN_ON(ret < 0); | ||
| 724 | } | ||
| 725 | |||
| 726 | static void dwc3_ep0_xfernotready(struct dwc3 *dwc, | ||
| 727 | const struct dwc3_event_depevt *event) | ||
| 728 | { | ||
| 729 | switch (event->status) { | ||
| 730 | case DEPEVT_STATUS_CONTROL_SETUP: | ||
| 731 | dev_vdbg(dwc->dev, "Control Setup\n"); | ||
| 732 | dwc3_ep0_do_control_setup(dwc, event); | ||
| 733 | break; | ||
| 734 | |||
| 735 | case DEPEVT_STATUS_CONTROL_DATA: | ||
| 736 | dev_vdbg(dwc->dev, "Control Data\n"); | ||
| 737 | |||
| 738 | if (dwc->ep0_next_event != DWC3_EP0_NRDY_DATA) { | ||
| 739 | dev_vdbg(dwc->dev, "Expected %d got %d\n", | ||
| 740 | dwc->ep0_next_event, | ||
| 741 | DWC3_EP0_NRDY_DATA); | ||
| 742 | |||
| 743 | dwc3_ep0_stall_and_restart(dwc); | ||
| 744 | return; | ||
| 745 | } | ||
| 746 | |||
| 747 | /* | ||
| 748 | * One of the possible error cases is when Host _does_ | ||
| 749 | * request for Data Phase, but it does so on the wrong | ||
| 750 | * direction. | ||
| 751 | * | ||
| 752 | * Here, we already know ep0_next_event is DATA (see above), | ||
| 753 | * so we only need to check for direction. | ||
| 754 | */ | ||
| 755 | if (dwc->ep0_expect_in != event->endpoint_number) { | ||
| 756 | dev_vdbg(dwc->dev, "Wrong direction for Data phase\n"); | ||
| 757 | dwc3_ep0_stall_and_restart(dwc); | ||
| 758 | return; | ||
| 759 | } | ||
| 760 | |||
| 761 | dwc3_ep0_do_control_data(dwc, event); | ||
| 762 | break; | ||
| 763 | |||
| 764 | case DEPEVT_STATUS_CONTROL_STATUS: | ||
| 765 | dev_vdbg(dwc->dev, "Control Status\n"); | ||
| 766 | |||
| 767 | if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) { | ||
| 768 | dev_vdbg(dwc->dev, "Expected %d got %d\n", | ||
| 769 | dwc->ep0_next_event, | ||
| 770 | DWC3_EP0_NRDY_STATUS); | ||
| 771 | |||
| 772 | dwc3_ep0_stall_and_restart(dwc); | ||
| 773 | return; | ||
| 774 | } | ||
| 775 | dwc3_ep0_do_control_status(dwc, event); | ||
| 776 | } | ||
| 777 | } | ||
| 778 | |||
| 779 | void dwc3_ep0_interrupt(struct dwc3 *dwc, | ||
| 780 | const const struct dwc3_event_depevt *event) | ||
| 781 | { | ||
| 782 | u8 epnum = event->endpoint_number; | ||
| 783 | |||
| 784 | dev_dbg(dwc->dev, "%s while ep%d%s in state '%s'\n", | ||
| 785 | dwc3_ep_event_string(event->endpoint_event), | ||
| 786 | epnum >> 1, (epnum & 1) ? "in" : "out", | ||
| 787 | dwc3_ep0_state_string(dwc->ep0state)); | ||
| 788 | |||
| 789 | switch (event->endpoint_event) { | ||
| 790 | case DWC3_DEPEVT_XFERCOMPLETE: | ||
| 791 | dwc3_ep0_xfer_complete(dwc, event); | ||
| 792 | break; | ||
| 793 | |||
| 794 | case DWC3_DEPEVT_XFERNOTREADY: | ||
| 795 | dwc3_ep0_xfernotready(dwc, event); | ||
| 796 | break; | ||
| 797 | |||
| 798 | case DWC3_DEPEVT_XFERINPROGRESS: | ||
| 799 | case DWC3_DEPEVT_RXTXFIFOEVT: | ||
| 800 | case DWC3_DEPEVT_STREAMEVT: | ||
| 801 | case DWC3_DEPEVT_EPCMDCMPLT: | ||
| 802 | break; | ||
| 803 | } | ||
| 804 | } | ||
| @@ -0,0 +1,2104 @@ | |||
| 1 | /** | ||
| 2 | * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/kernel.h> | ||
| 40 | #include <linux/delay.h> | ||
| 41 | #include <linux/slab.h> | ||
| 42 | #include <linux/spinlock.h> | ||
| 43 | #include <linux/platform_device.h> | ||
| 44 | #include <linux/pm_runtime.h> | ||
| 45 | #include <linux/interrupt.h> | ||
| 46 | #include <linux/io.h> | ||
| 47 | #include <linux/list.h> | ||
| 48 | #include <linux/dma-mapping.h> | ||
| 49 | |||
| 50 | #include <linux/usb/ch9.h> | ||
| 51 | #include <linux/usb/gadget.h> | ||
| 52 | |||
| 53 | #include "core.h" | ||
| 54 | #include "gadget.h" | ||
| 55 | #include "io.h" | ||
| 56 | |||
| 57 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
| 58 | |||
| 59 | void dwc3_map_buffer_to_dma(struct dwc3_request *req) | ||
| 60 | { | ||
| 61 | struct dwc3 *dwc = req->dep->dwc; | ||
| 62 | |||
| 63 | if (req->request.length == 0) { | ||
| 64 | /* req->request.dma = dwc->setup_buf_addr; */ | ||
| 65 | return; | ||
| 66 | } | ||
| 67 | |||
| 68 | if (req->request.dma == DMA_ADDR_INVALID) { | ||
| 69 | req->request.dma = dma_map_single(dwc->dev, req->request.buf, | ||
| 70 | req->request.length, req->direction | ||
| 71 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 72 | req->mapped = true; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | void dwc3_unmap_buffer_from_dma(struct dwc3_request *req) | ||
| 77 | { | ||
| 78 | struct dwc3 *dwc = req->dep->dwc; | ||
| 79 | |||
| 80 | if (req->request.length == 0) { | ||
| 81 | req->request.dma = DMA_ADDR_INVALID; | ||
| 82 | return; | ||
| 83 | } | ||
| 84 | |||
| 85 | if (req->mapped) { | ||
| 86 | dma_unmap_single(dwc->dev, req->request.dma, | ||
| 87 | req->request.length, req->direction | ||
| 88 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 89 | req->mapped = 0; | ||
| 90 | req->request.dma = DMA_ADDR_INVALID; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | ||
| 95 | int status) | ||
| 96 | { | ||
| 97 | struct dwc3 *dwc = dep->dwc; | ||
| 98 | |||
| 99 | if (req->queued) { | ||
| 100 | dep->busy_slot++; | ||
| 101 | /* | ||
| 102 | * Skip LINK TRB. We can't use req->trb and check for | ||
| 103 | * DWC3_TRBCTL_LINK_TRB because it points the TRB we just | ||
| 104 | * completed (not the LINK TRB). | ||
| 105 | */ | ||
| 106 | if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && | ||
| 107 | usb_endpoint_xfer_isoc(dep->desc)) | ||
| 108 | dep->busy_slot++; | ||
| 109 | } | ||
| 110 | list_del(&req->list); | ||
| 111 | |||
| 112 | if (req->request.status == -EINPROGRESS) | ||
| 113 | req->request.status = status; | ||
| 114 | |||
| 115 | dwc3_unmap_buffer_from_dma(req); | ||
| 116 | |||
| 117 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", | ||
| 118 | req, dep->name, req->request.actual, | ||
| 119 | req->request.length, status); | ||
| 120 | |||
| 121 | spin_unlock(&dwc->lock); | ||
| 122 | req->request.complete(&req->dep->endpoint, &req->request); | ||
| 123 | spin_lock(&dwc->lock); | ||
| 124 | } | ||
| 125 | |||
| 126 | static const char *dwc3_gadget_ep_cmd_string(u8 cmd) | ||
| 127 | { | ||
| 128 | switch (cmd) { | ||
| 129 | case DWC3_DEPCMD_DEPSTARTCFG: | ||
| 130 | return "Start New Configuration"; | ||
| 131 | case DWC3_DEPCMD_ENDTRANSFER: | ||
| 132 | return "End Transfer"; | ||
| 133 | case DWC3_DEPCMD_UPDATETRANSFER: | ||
| 134 | return "Update Transfer"; | ||
| 135 | case DWC3_DEPCMD_STARTTRANSFER: | ||
| 136 | return "Start Transfer"; | ||
| 137 | case DWC3_DEPCMD_CLEARSTALL: | ||
| 138 | return "Clear Stall"; | ||
| 139 | case DWC3_DEPCMD_SETSTALL: | ||
| 140 | return "Set Stall"; | ||
| 141 | case DWC3_DEPCMD_GETSEQNUMBER: | ||
| 142 | return "Get Data Sequence Number"; | ||
| 143 | case DWC3_DEPCMD_SETTRANSFRESOURCE: | ||
| 144 | return "Set Endpoint Transfer Resource"; | ||
| 145 | case DWC3_DEPCMD_SETEPCONFIG: | ||
| 146 | return "Set Endpoint Configuration"; | ||
| 147 | default: | ||
| 148 | return "UNKNOWN command"; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | ||
| 153 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params) | ||
| 154 | { | ||
| 155 | struct dwc3_ep *dep = dwc->eps[ep]; | ||
| 156 | u32 timeout = 500; | ||
| 157 | u32 reg; | ||
| 158 | |||
| 159 | dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n", | ||
| 160 | dep->name, | ||
| 161 | dwc3_gadget_ep_cmd_string(cmd), params->param0, | ||
| 162 | params->param1, params->param2); | ||
| 163 | |||
| 164 | dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); | ||
| 165 | dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1); | ||
| 166 | dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2); | ||
| 167 | |||
| 168 | dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT); | ||
| 169 | do { | ||
| 170 | reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep)); | ||
| 171 | if (!(reg & DWC3_DEPCMD_CMDACT)) { | ||
| 172 | dev_vdbg(dwc->dev, "Command Complete --> %d\n", | ||
| 173 | DWC3_DEPCMD_STATUS(reg)); | ||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | /* | ||
| 178 | * We can't sleep here, because it is also called from | ||
| 179 | * interrupt context. | ||
| 180 | */ | ||
| 181 | timeout--; | ||
| 182 | if (!timeout) | ||
| 183 | return -ETIMEDOUT; | ||
| 184 | |||
| 185 | udelay(1); | ||
| 186 | } while (1); | ||
| 187 | } | ||
| 188 | |||
| 189 | static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep, | ||
| 190 | struct dwc3_trb_hw *trb) | ||
| 191 | { | ||
| 192 | u32 offset = (char *) trb - (char *) dep->trb_pool; | ||
| 193 | |||
| 194 | return dep->trb_pool_dma + offset; | ||
| 195 | } | ||
| 196 | |||
| 197 | static int dwc3_alloc_trb_pool(struct dwc3_ep *dep) | ||
| 198 | { | ||
| 199 | struct dwc3 *dwc = dep->dwc; | ||
| 200 | |||
| 201 | if (dep->trb_pool) | ||
| 202 | return 0; | ||
| 203 | |||
| 204 | if (dep->number == 0 || dep->number == 1) | ||
| 205 | return 0; | ||
| 206 | |||
| 207 | dep->trb_pool = dma_alloc_coherent(dwc->dev, | ||
| 208 | sizeof(struct dwc3_trb) * DWC3_TRB_NUM, | ||
| 209 | &dep->trb_pool_dma, GFP_KERNEL); | ||
| 210 | if (!dep->trb_pool) { | ||
| 211 | dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n", | ||
| 212 | dep->name); | ||
| 213 | return -ENOMEM; | ||
| 214 | } | ||
| 215 | |||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | static void dwc3_free_trb_pool(struct dwc3_ep *dep) | ||
| 220 | { | ||
| 221 | struct dwc3 *dwc = dep->dwc; | ||
| 222 | |||
| 223 | dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM, | ||
| 224 | dep->trb_pool, dep->trb_pool_dma); | ||
| 225 | |||
| 226 | dep->trb_pool = NULL; | ||
| 227 | dep->trb_pool_dma = 0; | ||
| 228 | } | ||
| 229 | |||
| 230 | static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep) | ||
| 231 | { | ||
| 232 | struct dwc3_gadget_ep_cmd_params params; | ||
| 233 | u32 cmd; | ||
| 234 | |||
| 235 | memset(¶ms, 0x00, sizeof(params)); | ||
| 236 | |||
| 237 | if (dep->number != 1) { | ||
| 238 | cmd = DWC3_DEPCMD_DEPSTARTCFG; | ||
| 239 | /* XferRscIdx == 0 for ep0 and 2 for the remaining */ | ||
| 240 | if (dep->number > 1) { | ||
| 241 | if (dwc->start_config_issued) | ||
| 242 | return 0; | ||
| 243 | dwc->start_config_issued = true; | ||
| 244 | cmd |= DWC3_DEPCMD_PARAM(2); | ||
| 245 | } | ||
| 246 | |||
| 247 | return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, ¶ms); | ||
| 248 | } | ||
| 249 | |||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 253 | static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, | ||
| 254 | const struct usb_endpoint_descriptor *desc) | ||
| 255 | { | ||
| 256 | struct dwc3_gadget_ep_cmd_params params; | ||
| 257 | |||
| 258 | memset(¶ms, 0x00, sizeof(params)); | ||
| 259 | |||
| 260 | params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc)) | ||
| 261 | | DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc)) | ||
| 262 | | DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst); | ||
| 263 | |||
| 264 | params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN | ||
| 265 | | DWC3_DEPCFG_XFER_NOT_READY_EN; | ||
| 266 | |||
| 267 | if (usb_endpoint_xfer_bulk(desc) && dep->endpoint.max_streams) { | ||
| 268 | params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE | ||
| 269 | | DWC3_DEPCFG_STREAM_EVENT_EN; | ||
| 270 | dep->stream_capable = true; | ||
| 271 | } | ||
| 272 | |||
| 273 | if (usb_endpoint_xfer_isoc(desc)) | ||
| 274 | params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN; | ||
| 275 | |||
| 276 | /* | ||
| 277 | * We are doing 1:1 mapping for endpoints, meaning | ||
| 278 | * Physical Endpoints 2 maps to Logical Endpoint 2 and | ||
| 279 | * so on. We consider the direction bit as part of the physical | ||
| 280 | * endpoint number. So USB endpoint 0x81 is 0x03. | ||
| 281 | */ | ||
| 282 | params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number); | ||
| 283 | |||
| 284 | /* | ||
| 285 | * We must use the lower 16 TX FIFOs even though | ||
| 286 | * HW might have more | ||
| 287 | */ | ||
| 288 | if (dep->direction) | ||
| 289 | params.param0 |= DWC3_DEPCFG_FIFO_NUMBER(dep->number >> 1); | ||
| 290 | |||
| 291 | if (desc->bInterval) { | ||
| 292 | params.param1 |= DWC3_DEPCFG_BINTERVAL_M1(desc->bInterval - 1); | ||
| 293 | dep->interval = 1 << (desc->bInterval - 1); | ||
| 294 | } | ||
| 295 | |||
| 296 | return dwc3_send_gadget_ep_cmd(dwc, dep->number, | ||
| 297 | DWC3_DEPCMD_SETEPCONFIG, ¶ms); | ||
| 298 | } | ||
| 299 | |||
| 300 | static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep) | ||
| 301 | { | ||
| 302 | struct dwc3_gadget_ep_cmd_params params; | ||
| 303 | |||
| 304 | memset(¶ms, 0x00, sizeof(params)); | ||
| 305 | |||
| 306 | params.param0 = DWC3_DEPXFERCFG_NUM_XFER_RES(1); | ||
| 307 | |||
| 308 | return dwc3_send_gadget_ep_cmd(dwc, dep->number, | ||
| 309 | DWC3_DEPCMD_SETTRANSFRESOURCE, ¶ms); | ||
| 310 | } | ||
| 311 | |||
| 312 | /** | ||
| 313 | * __dwc3_gadget_ep_enable - Initializes a HW endpoint | ||
| 314 | * @dep: endpoint to be initialized | ||
| 315 | * @desc: USB Endpoint Descriptor | ||
| 316 | * | ||
| 317 | * Caller should take care of locking | ||
| 318 | */ | ||
| 319 | static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, | ||
| 320 | const struct usb_endpoint_descriptor *desc) | ||
| 321 | { | ||
| 322 | struct dwc3 *dwc = dep->dwc; | ||
| 323 | u32 reg; | ||
| 324 | int ret = -ENOMEM; | ||
| 325 | |||
| 326 | if (!(dep->flags & DWC3_EP_ENABLED)) { | ||
| 327 | ret = dwc3_gadget_start_config(dwc, dep); | ||
| 328 | if (ret) | ||
| 329 | return ret; | ||
| 330 | } | ||
| 331 | |||
| 332 | ret = dwc3_gadget_set_ep_config(dwc, dep, desc); | ||
| 333 | if (ret) | ||
| 334 | return ret; | ||
| 335 | |||
| 336 | if (!(dep->flags & DWC3_EP_ENABLED)) { | ||
| 337 | struct dwc3_trb_hw *trb_st_hw; | ||
| 338 | struct dwc3_trb_hw *trb_link_hw; | ||
| 339 | struct dwc3_trb trb_link; | ||
| 340 | |||
| 341 | ret = dwc3_gadget_set_xfer_resource(dwc, dep); | ||
| 342 | if (ret) | ||
| 343 | return ret; | ||
| 344 | |||
| 345 | dep->desc = desc; | ||
| 346 | dep->type = usb_endpoint_type(desc); | ||
| 347 | dep->flags |= DWC3_EP_ENABLED; | ||
| 348 | |||
| 349 | reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); | ||
| 350 | reg |= DWC3_DALEPENA_EP(dep->number); | ||
| 351 | dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); | ||
| 352 | |||
| 353 | if (!usb_endpoint_xfer_isoc(desc)) | ||
| 354 | return 0; | ||
| 355 | |||
| 356 | memset(&trb_link, 0, sizeof(trb_link)); | ||
| 357 | |||
| 358 | /* Link TRB for ISOC. The HWO but is never reset */ | ||
| 359 | trb_st_hw = &dep->trb_pool[0]; | ||
| 360 | |||
| 361 | trb_link.bplh = dwc3_trb_dma_offset(dep, trb_st_hw); | ||
| 362 | trb_link.trbctl = DWC3_TRBCTL_LINK_TRB; | ||
| 363 | trb_link.hwo = true; | ||
| 364 | |||
| 365 | trb_link_hw = &dep->trb_pool[DWC3_TRB_NUM - 1]; | ||
| 366 | dwc3_trb_to_hw(&trb_link, trb_link_hw); | ||
| 367 | } | ||
| 368 | |||
| 369 | return 0; | ||
| 370 | } | ||
| 371 | |||
| 372 | static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum); | ||
| 373 | static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) | ||
| 374 | { | ||
| 375 | struct dwc3_request *req; | ||
| 376 | |||
| 377 | if (!list_empty(&dep->req_queued)) | ||
| 378 | dwc3_stop_active_transfer(dwc, dep->number); | ||
| 379 | |||
| 380 | while (!list_empty(&dep->request_list)) { | ||
| 381 | req = next_request(&dep->request_list); | ||
| 382 | |||
| 383 | dwc3_gadget_giveback(dep, req, -ESHUTDOWN); | ||
| 384 | } | ||
| 385 | } | ||
| 386 | |||
| 387 | /** | ||
| 388 | * __dwc3_gadget_ep_disable - Disables a HW endpoint | ||
| 389 | * @dep: the endpoint to disable | ||
| 390 | * | ||
| 391 | * This function also removes requests which are currently processed ny the | ||
| 392 | * hardware and those which are not yet scheduled. | ||
| 393 | * Caller should take care of locking. | ||
| 394 | */ | ||
| 395 | static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) | ||
| 396 | { | ||
| 397 | struct dwc3 *dwc = dep->dwc; | ||
| 398 | u32 reg; | ||
| 399 | |||
| 400 | dwc3_remove_requests(dwc, dep); | ||
| 401 | |||
| 402 | reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); | ||
| 403 | reg &= ~DWC3_DALEPENA_EP(dep->number); | ||
| 404 | dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); | ||
| 405 | |||
| 406 | dep->stream_capable = false; | ||
| 407 | dep->desc = NULL; | ||
| 408 | dep->type = 0; | ||
| 409 | dep->flags = 0; | ||
| 410 | |||
| 411 | return 0; | ||
| 412 | } | ||
| 413 | |||
| 414 | /* -------------------------------------------------------------------------- */ | ||
| 415 | |||
| 416 | static int dwc3_gadget_ep0_enable(struct usb_ep *ep, | ||
| 417 | const struct usb_endpoint_descriptor *desc) | ||
| 418 | { | ||
| 419 | return -EINVAL; | ||
| 420 | } | ||
| 421 | |||
| 422 | static int dwc3_gadget_ep0_disable(struct usb_ep *ep) | ||
| 423 | { | ||
| 424 | return -EINVAL; | ||
| 425 | } | ||
| 426 | |||
| 427 | /* -------------------------------------------------------------------------- */ | ||
| 428 | |||
| 429 | static int dwc3_gadget_ep_enable(struct usb_ep *ep, | ||
| 430 | const struct usb_endpoint_descriptor *desc) | ||
| 431 | { | ||
| 432 | struct dwc3_ep *dep; | ||
| 433 | struct dwc3 *dwc; | ||
| 434 | unsigned long flags; | ||
| 435 | int ret; | ||
| 436 | |||
| 437 | if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { | ||
| 438 | pr_debug("dwc3: invalid parameters\n"); | ||
| 439 | return -EINVAL; | ||
| 440 | } | ||
| 441 | |||
| 442 | if (!desc->wMaxPacketSize) { | ||
| 443 | pr_debug("dwc3: missing wMaxPacketSize\n"); | ||
| 444 | return -EINVAL; | ||
| 445 | } | ||
| 446 | |||
| 447 | dep = to_dwc3_ep(ep); | ||
| 448 | dwc = dep->dwc; | ||
| 449 | |||
| 450 | switch (usb_endpoint_type(desc)) { | ||
| 451 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 452 | strncat(dep->name, "-control", sizeof(dep->name)); | ||
| 453 | break; | ||
| 454 | case USB_ENDPOINT_XFER_ISOC: | ||
| 455 | strncat(dep->name, "-isoc", sizeof(dep->name)); | ||
| 456 | break; | ||
| 457 | case USB_ENDPOINT_XFER_BULK: | ||
| 458 | strncat(dep->name, "-bulk", sizeof(dep->name)); | ||
| 459 | break; | ||
| 460 | case USB_ENDPOINT_XFER_INT: | ||
| 461 | strncat(dep->name, "-int", sizeof(dep->name)); | ||
| 462 | break; | ||
| 463 | default: | ||
| 464 | dev_err(dwc->dev, "invalid endpoint transfer type\n"); | ||
| 465 | } | ||
| 466 | |||
| 467 | if (dep->flags & DWC3_EP_ENABLED) { | ||
| 468 | dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n", | ||
| 469 | dep->name); | ||
| 470 | return 0; | ||
| 471 | } | ||
| 472 | |||
| 473 | dev_vdbg(dwc->dev, "Enabling %s\n", dep->name); | ||
| 474 | |||
| 475 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 476 | ret = __dwc3_gadget_ep_enable(dep, desc); | ||
| 477 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 478 | |||
| 479 | return ret; | ||
| 480 | } | ||
| 481 | |||
| 482 | static int dwc3_gadget_ep_disable(struct usb_ep *ep) | ||
| 483 | { | ||
| 484 | struct dwc3_ep *dep; | ||
| 485 | struct dwc3 *dwc; | ||
| 486 | unsigned long flags; | ||
| 487 | int ret; | ||
| 488 | |||
| 489 | if (!ep) { | ||
| 490 | pr_debug("dwc3: invalid parameters\n"); | ||
| 491 | return -EINVAL; | ||
| 492 | } | ||
| 493 | |||
| 494 | dep = to_dwc3_ep(ep); | ||
| 495 | dwc = dep->dwc; | ||
| 496 | |||
| 497 | if (!(dep->flags & DWC3_EP_ENABLED)) { | ||
| 498 | dev_WARN_ONCE(dwc->dev, true, "%s is already disabled\n", | ||
| 499 | dep->name); | ||
| 500 | return 0; | ||
| 501 | } | ||
| 502 | |||
| 503 | snprintf(dep->name, sizeof(dep->name), "ep%d%s", | ||
| 504 | dep->number >> 1, | ||
| 505 | (dep->number & 1) ? "in" : "out"); | ||
| 506 | |||
| 507 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 508 | ret = __dwc3_gadget_ep_disable(dep); | ||
| 509 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 510 | |||
| 511 | return ret; | ||
| 512 | } | ||
| 513 | |||
| 514 | static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep, | ||
| 515 | gfp_t gfp_flags) | ||
| 516 | { | ||
| 517 | struct dwc3_request *req; | ||
| 518 | struct dwc3_ep *dep = to_dwc3_ep(ep); | ||
| 519 | struct dwc3 *dwc = dep->dwc; | ||
| 520 | |||
| 521 | req = kzalloc(sizeof(*req), gfp_flags); | ||
| 522 | if (!req) { | ||
| 523 | dev_err(dwc->dev, "not enough memory\n"); | ||
| 524 | return NULL; | ||
| 525 | } | ||
| 526 | |||
| 527 | req->epnum = dep->number; | ||
| 528 | req->dep = dep; | ||
| 529 | req->request.dma = DMA_ADDR_INVALID; | ||
| 530 | |||
| 531 | return &req->request; | ||
| 532 | } | ||
| 533 | |||
| 534 | static void dwc3_gadget_ep_free_request(struct usb_ep *ep, | ||
| 535 | struct usb_request *request) | ||
| 536 | { | ||
| 537 | struct dwc3_request *req = to_dwc3_request(request); | ||
| 538 | |||
| 539 | kfree(req); | ||
| 540 | } | ||
| 541 | |||
| 542 | /* | ||
| 543 | * dwc3_prepare_trbs - setup TRBs from requests | ||
| 544 | * @dep: endpoint for which requests are being prepared | ||
| 545 | * @starting: true if the endpoint is idle and no requests are queued. | ||
| 546 | * | ||
| 547 | * The functions goes through the requests list and setups TRBs for the | ||
| 548 | * transfers. The functions returns once there are not more TRBs available or | ||
| 549 | * it run out of requests. | ||
| 550 | */ | ||
| 551 | static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep, | ||
| 552 | bool starting) | ||
| 553 | { | ||
| 554 | struct dwc3_request *req, *n, *ret = NULL; | ||
| 555 | struct dwc3_trb_hw *trb_hw; | ||
| 556 | struct dwc3_trb trb; | ||
| 557 | u32 trbs_left; | ||
| 558 | |||
| 559 | BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); | ||
| 560 | |||
| 561 | /* the first request must not be queued */ | ||
| 562 | trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK; | ||
| 563 | /* | ||
| 564 | * if busy & slot are equal than it is either full or empty. If we are | ||
| 565 | * starting to proceed requests then we are empty. Otherwise we ar | ||
| 566 | * full and don't do anything | ||
| 567 | */ | ||
| 568 | if (!trbs_left) { | ||
| 569 | if (!starting) | ||
| 570 | return NULL; | ||
| 571 | trbs_left = DWC3_TRB_NUM; | ||
| 572 | /* | ||
| 573 | * In case we start from scratch, we queue the ISOC requests | ||
| 574 | * starting from slot 1. This is done because we use ring | ||
| 575 | * buffer and have no LST bit to stop us. Instead, we place | ||
| 576 | * IOC bit TRB_NUM/4. We try to avoid to having an interrupt | ||
| 577 | * after the first request so we start at slot 1 and have | ||
| 578 | * 7 requests proceed before we hit the first IOC. | ||
| 579 | * Other transfer types don't use the ring buffer and are | ||
| 580 | * processed from the first TRB until the last one. Since we | ||
| 581 | * don't wrap around we have to start at the beginning. | ||
| 582 | */ | ||
| 583 | if (usb_endpoint_xfer_isoc(dep->desc)) { | ||
| 584 | dep->busy_slot = 1; | ||
| 585 | dep->free_slot = 1; | ||
| 586 | } else { | ||
| 587 | dep->busy_slot = 0; | ||
| 588 | dep->free_slot = 0; | ||
| 589 | } | ||
| 590 | } | ||
| 591 | |||
| 592 | /* The last TRB is a link TRB, not used for xfer */ | ||
| 593 | if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc)) | ||
| 594 | return NULL; | ||
| 595 | |||
| 596 | list_for_each_entry_safe(req, n, &dep->request_list, list) { | ||
| 597 | unsigned int last_one = 0; | ||
| 598 | unsigned int cur_slot; | ||
| 599 | |||
| 600 | trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; | ||
| 601 | cur_slot = dep->free_slot; | ||
| 602 | dep->free_slot++; | ||
| 603 | |||
| 604 | /* Skip the LINK-TRB on ISOC */ | ||
| 605 | if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && | ||
| 606 | usb_endpoint_xfer_isoc(dep->desc)) | ||
| 607 | continue; | ||
| 608 | |||
| 609 | dwc3_gadget_move_request_queued(req); | ||
| 610 | memset(&trb, 0, sizeof(trb)); | ||
| 611 | trbs_left--; | ||
| 612 | |||
| 613 | /* Is our TRB pool empty? */ | ||
| 614 | if (!trbs_left) | ||
| 615 | last_one = 1; | ||
| 616 | /* Is this the last request? */ | ||
| 617 | if (list_empty(&dep->request_list)) | ||
| 618 | last_one = 1; | ||
| 619 | |||
| 620 | /* | ||
| 621 | * FIXME we shouldn't need to set LST bit always but we are | ||
| 622 | * facing some weird problem with the Hardware where it doesn't | ||
| 623 | * complete even though it has been previously started. | ||
| 624 | * | ||
| 625 | * While we're debugging the problem, as a workaround to | ||
| 626 | * multiple TRBs handling, use only one TRB at a time. | ||
| 627 | */ | ||
| 628 | last_one = 1; | ||
| 629 | |||
| 630 | req->trb = trb_hw; | ||
| 631 | if (!ret) | ||
| 632 | ret = req; | ||
| 633 | |||
| 634 | trb.bplh = req->request.dma; | ||
| 635 | |||
| 636 | if (usb_endpoint_xfer_isoc(dep->desc)) { | ||
| 637 | trb.isp_imi = true; | ||
| 638 | trb.csp = true; | ||
| 639 | } else { | ||
| 640 | trb.lst = last_one; | ||
| 641 | } | ||
| 642 | |||
| 643 | if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable) | ||
| 644 | trb.sid_sofn = req->request.stream_id; | ||
| 645 | |||
| 646 | switch (usb_endpoint_type(dep->desc)) { | ||
| 647 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 648 | trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; | ||
| 649 | break; | ||
| 650 | |||
| 651 | case USB_ENDPOINT_XFER_ISOC: | ||
| 652 | trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; | ||
| 653 | |||
| 654 | /* IOC every DWC3_TRB_NUM / 4 so we can refill */ | ||
| 655 | if (!(cur_slot % (DWC3_TRB_NUM / 4))) | ||
| 656 | trb.ioc = last_one; | ||
| 657 | break; | ||
| 658 | |||
| 659 | case USB_ENDPOINT_XFER_BULK: | ||
| 660 | case USB_ENDPOINT_XFER_INT: | ||
| 661 | trb.trbctl = DWC3_TRBCTL_NORMAL; | ||
| 662 | break; | ||
| 663 | default: | ||
| 664 | /* | ||
| 665 | * This is only possible with faulty memory because we | ||
| 666 | * checked it already :) | ||
| 667 | */ | ||
| 668 | BUG(); | ||
| 669 | } | ||
| 670 | |||
| 671 | trb.length = req->request.length; | ||
| 672 | trb.hwo = true; | ||
| 673 | |||
| 674 | dwc3_trb_to_hw(&trb, trb_hw); | ||
| 675 | req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw); | ||
| 676 | |||
| 677 | if (last_one) | ||
| 678 | break; | ||
| 679 | } | ||
| 680 | |||
| 681 | return ret; | ||
| 682 | } | ||
| 683 | |||
| 684 | static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | ||
| 685 | int start_new) | ||
| 686 | { | ||
| 687 | struct dwc3_gadget_ep_cmd_params params; | ||
| 688 | struct dwc3_request *req; | ||
| 689 | struct dwc3 *dwc = dep->dwc; | ||
| 690 | int ret; | ||
| 691 | u32 cmd; | ||
| 692 | |||
| 693 | if (start_new && (dep->flags & DWC3_EP_BUSY)) { | ||
| 694 | dev_vdbg(dwc->dev, "%s: endpoint busy\n", dep->name); | ||
| 695 | return -EBUSY; | ||
| 696 | } | ||
| 697 | dep->flags &= ~DWC3_EP_PENDING_REQUEST; | ||
| 698 | |||
| 699 | /* | ||
| 700 | * If we are getting here after a short-out-packet we don't enqueue any | ||
| 701 | * new requests as we try to set the IOC bit only on the last request. | ||
| 702 | */ | ||
| 703 | if (start_new) { | ||
| 704 | if (list_empty(&dep->req_queued)) | ||
| 705 | dwc3_prepare_trbs(dep, start_new); | ||
| 706 | |||
| 707 | /* req points to the first request which will be sent */ | ||
| 708 | req = next_request(&dep->req_queued); | ||
| 709 | } else { | ||
| 710 | /* | ||
| 711 | * req points to the first request where HWO changed | ||
| 712 | * from 0 to 1 | ||
| 713 | */ | ||
| 714 | req = dwc3_prepare_trbs(dep, start_new); | ||
| 715 | } | ||
| 716 | if (!req) { | ||
| 717 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
| 718 | return 0; | ||
| 719 | } | ||
| 720 | |||
| 721 | memset(¶ms, 0, sizeof(params)); | ||
| 722 | params.param0 = upper_32_bits(req->trb_dma); | ||
| 723 | params.param1 = lower_32_bits(req->trb_dma); | ||
| 724 | |||
| 725 | if (start_new) | ||
| 726 | cmd = DWC3_DEPCMD_STARTTRANSFER; | ||
| 727 | else | ||
| 728 | cmd = DWC3_DEPCMD_UPDATETRANSFER; | ||
| 729 | |||
| 730 | cmd |= DWC3_DEPCMD_PARAM(cmd_param); | ||
| 731 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); | ||
| 732 | if (ret < 0) { | ||
| 733 | dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); | ||
| 734 | |||
| 735 | /* | ||
| 736 | * FIXME we need to iterate over the list of requests | ||
| 737 | * here and stop, unmap, free and del each of the linked | ||
| 738 | * requests instead of we do now. | ||
| 739 | */ | ||
| 740 | dwc3_unmap_buffer_from_dma(req); | ||
| 741 | list_del(&req->list); | ||
| 742 | return ret; | ||
| 743 | } | ||
| 744 | |||
| 745 | dep->flags |= DWC3_EP_BUSY; | ||
| 746 | dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, | ||
| 747 | dep->number); | ||
| 748 | if (!dep->res_trans_idx) | ||
| 749 | printk_once(KERN_ERR "%s() res_trans_idx is invalid\n", __func__); | ||
| 750 | return 0; | ||
| 751 | } | ||
| 752 | |||
| 753 | static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | ||
| 754 | { | ||
| 755 | req->request.actual = 0; | ||
| 756 | req->request.status = -EINPROGRESS; | ||
| 757 | req->direction = dep->direction; | ||
| 758 | req->epnum = dep->number; | ||
| 759 | |||
| 760 | /* | ||
| 761 | * We only add to our list of requests now and | ||
| 762 | * start consuming the list once we get XferNotReady | ||
| 763 | * IRQ. | ||
| 764 | * | ||
| 765 | * That way, we avoid doing anything that we don't need | ||
| 766 | * to do now and defer it until the point we receive a | ||
| 767 | * particular token from the Host side. | ||
| 768 | * | ||
| 769 | * This will also avoid Host cancelling URBs due to too | ||
| 770 | * many NACKs. | ||
| 771 | */ | ||
| 772 | dwc3_map_buffer_to_dma(req); | ||
| 773 | list_add_tail(&req->list, &dep->request_list); | ||
| 774 | |||
| 775 | /* | ||
| 776 | * There is one special case: XferNotReady with | ||
| 777 | * empty list of requests. We need to kick the | ||
| 778 | * transfer here in that situation, otherwise | ||
| 779 | * we will be NAKing forever. | ||
| 780 | * | ||
| 781 | * If we get XferNotReady before gadget driver | ||
| 782 | * has a chance to queue a request, we will ACK | ||
| 783 | * the IRQ but won't be able to receive the data | ||
| 784 | * until the next request is queued. The following | ||
| 785 | * code is handling exactly that. | ||
| 786 | */ | ||
| 787 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | ||
| 788 | int ret; | ||
| 789 | int start_trans; | ||
| 790 | |||
| 791 | start_trans = 1; | ||
| 792 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && | ||
| 793 | dep->flags & DWC3_EP_BUSY) | ||
| 794 | start_trans = 0; | ||
| 795 | |||
| 796 | ret = __dwc3_gadget_kick_transfer(dep, 0, start_trans); | ||
| 797 | if (ret && ret != -EBUSY) { | ||
| 798 | struct dwc3 *dwc = dep->dwc; | ||
| 799 | |||
| 800 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | ||
| 801 | dep->name); | ||
| 802 | } | ||
| 803 | }; | ||
| 804 | |||
| 805 | return 0; | ||
| 806 | } | ||
| 807 | |||
| 808 | static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, | ||
| 809 | gfp_t gfp_flags) | ||
| 810 | { | ||
| 811 | struct dwc3_request *req = to_dwc3_request(request); | ||
| 812 | struct dwc3_ep *dep = to_dwc3_ep(ep); | ||
| 813 | struct dwc3 *dwc = dep->dwc; | ||
| 814 | |||
| 815 | unsigned long flags; | ||
| 816 | |||
| 817 | int ret; | ||
| 818 | |||
| 819 | if (!dep->desc) { | ||
| 820 | dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", | ||
| 821 | request, ep->name); | ||
| 822 | return -ESHUTDOWN; | ||
| 823 | } | ||
| 824 | |||
| 825 | dev_vdbg(dwc->dev, "queing request %p to %s length %d\n", | ||
| 826 | request, ep->name, request->length); | ||
| 827 | |||
| 828 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 829 | ret = __dwc3_gadget_ep_queue(dep, req); | ||
| 830 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 831 | |||
| 832 | return ret; | ||
| 833 | } | ||
| 834 | |||
| 835 | static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, | ||
| 836 | struct usb_request *request) | ||
| 837 | { | ||
| 838 | struct dwc3_request *req = to_dwc3_request(request); | ||
| 839 | struct dwc3_request *r = NULL; | ||
| 840 | |||
| 841 | struct dwc3_ep *dep = to_dwc3_ep(ep); | ||
| 842 | struct dwc3 *dwc = dep->dwc; | ||
| 843 | |||
| 844 | unsigned long flags; | ||
| 845 | int ret = 0; | ||
| 846 | |||
| 847 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 848 | |||
| 849 | list_for_each_entry(r, &dep->request_list, list) { | ||
| 850 | if (r == req) | ||
| 851 | break; | ||
| 852 | } | ||
| 853 | |||
| 854 | if (r != req) { | ||
| 855 | list_for_each_entry(r, &dep->req_queued, list) { | ||
| 856 | if (r == req) | ||
| 857 | break; | ||
| 858 | } | ||
| 859 | if (r == req) { | ||
| 860 | /* wait until it is processed */ | ||
| 861 | dwc3_stop_active_transfer(dwc, dep->number); | ||
| 862 | goto out0; | ||
| 863 | } | ||
| 864 | dev_err(dwc->dev, "request %p was not queued to %s\n", | ||
| 865 | request, ep->name); | ||
| 866 | ret = -EINVAL; | ||
| 867 | goto out0; | ||
| 868 | } | ||
| 869 | |||
| 870 | /* giveback the request */ | ||
| 871 | dwc3_gadget_giveback(dep, req, -ECONNRESET); | ||
| 872 | |||
| 873 | out0: | ||
| 874 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 875 | |||
| 876 | return ret; | ||
| 877 | } | ||
| 878 | |||
| 879 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) | ||
| 880 | { | ||
| 881 | struct dwc3_gadget_ep_cmd_params params; | ||
| 882 | struct dwc3 *dwc = dep->dwc; | ||
| 883 | int ret; | ||
| 884 | |||
| 885 | memset(¶ms, 0x00, sizeof(params)); | ||
| 886 | |||
| 887 | if (value) { | ||
| 888 | if (dep->number == 0 || dep->number == 1) { | ||
| 889 | /* | ||
| 890 | * Whenever EP0 is stalled, we will restart | ||
| 891 | * the state machine, thus moving back to | ||
| 892 | * Setup Phase | ||
| 893 | */ | ||
| 894 | dwc->ep0state = EP0_SETUP_PHASE; | ||
| 895 | } | ||
| 896 | |||
| 897 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | ||
| 898 | DWC3_DEPCMD_SETSTALL, ¶ms); | ||
| 899 | if (ret) | ||
| 900 | dev_err(dwc->dev, "failed to %s STALL on %s\n", | ||
| 901 | value ? "set" : "clear", | ||
| 902 | dep->name); | ||
| 903 | else | ||
| 904 | dep->flags |= DWC3_EP_STALL; | ||
| 905 | } else { | ||
| 906 | if (dep->flags & DWC3_EP_WEDGE) | ||
| 907 | return 0; | ||
| 908 | |||
| 909 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | ||
| 910 | DWC3_DEPCMD_CLEARSTALL, ¶ms); | ||
| 911 | if (ret) | ||
| 912 | dev_err(dwc->dev, "failed to %s STALL on %s\n", | ||
| 913 | value ? "set" : "clear", | ||
| 914 | dep->name); | ||
| 915 | else | ||
| 916 | dep->flags &= ~DWC3_EP_STALL; | ||
| 917 | } | ||
| 918 | |||
| 919 | return ret; | ||
| 920 | } | ||
| 921 | |||
| 922 | static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value) | ||
| 923 | { | ||
| 924 | struct dwc3_ep *dep = to_dwc3_ep(ep); | ||
| 925 | struct dwc3 *dwc = dep->dwc; | ||
| 926 | |||
| 927 | unsigned long flags; | ||
| 928 | |||
| 929 | int ret; | ||
| 930 | |||
| 931 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 932 | |||
| 933 | if (usb_endpoint_xfer_isoc(dep->desc)) { | ||
| 934 | dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name); | ||
| 935 | ret = -EINVAL; | ||
| 936 | goto out; | ||
| 937 | } | ||
| 938 | |||
| 939 | ret = __dwc3_gadget_ep_set_halt(dep, value); | ||
| 940 | out: | ||
| 941 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 942 | |||
| 943 | return ret; | ||
| 944 | } | ||
| 945 | |||
| 946 | static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep) | ||
| 947 | { | ||
| 948 | struct dwc3_ep *dep = to_dwc3_ep(ep); | ||
| 949 | |||
| 950 | dep->flags |= DWC3_EP_WEDGE; | ||
| 951 | |||
| 952 | return dwc3_gadget_ep_set_halt(ep, 1); | ||
| 953 | } | ||
| 954 | |||
| 955 | /* -------------------------------------------------------------------------- */ | ||
| 956 | |||
| 957 | static struct usb_endpoint_descriptor dwc3_gadget_ep0_desc = { | ||
| 958 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 959 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 960 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
| 961 | }; | ||
| 962 | |||
| 963 | static const struct usb_ep_ops dwc3_gadget_ep0_ops = { | ||
| 964 | .enable = dwc3_gadget_ep0_enable, | ||
| 965 | .disable = dwc3_gadget_ep0_disable, | ||
| 966 | .alloc_request = dwc3_gadget_ep_alloc_request, | ||
| 967 | .free_request = dwc3_gadget_ep_free_request, | ||
| 968 | .queue = dwc3_gadget_ep0_queue, | ||
| 969 | .dequeue = dwc3_gadget_ep_dequeue, | ||
| 970 | .set_halt = dwc3_gadget_ep_set_halt, | ||
| 971 | .set_wedge = dwc3_gadget_ep_set_wedge, | ||
| 972 | }; | ||
| 973 | |||
| 974 | static const struct usb_ep_ops dwc3_gadget_ep_ops = { | ||
| 975 | .enable = dwc3_gadget_ep_enable, | ||
| 976 | .disable = dwc3_gadget_ep_disable, | ||
| 977 | .alloc_request = dwc3_gadget_ep_alloc_request, | ||
| 978 | .free_request = dwc3_gadget_ep_free_request, | ||
| 979 | .queue = dwc3_gadget_ep_queue, | ||
| 980 | .dequeue = dwc3_gadget_ep_dequeue, | ||
| 981 | .set_halt = dwc3_gadget_ep_set_halt, | ||
| 982 | .set_wedge = dwc3_gadget_ep_set_wedge, | ||
| 983 | }; | ||
| 984 | |||
| 985 | /* -------------------------------------------------------------------------- */ | ||
| 986 | |||
| 987 | static int dwc3_gadget_get_frame(struct usb_gadget *g) | ||
| 988 | { | ||
| 989 | struct dwc3 *dwc = gadget_to_dwc(g); | ||
| 990 | u32 reg; | ||
| 991 | |||
| 992 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | ||
| 993 | return DWC3_DSTS_SOFFN(reg); | ||
| 994 | } | ||
| 995 | |||
| 996 | static int dwc3_gadget_wakeup(struct usb_gadget *g) | ||
| 997 | { | ||
| 998 | struct dwc3 *dwc = gadget_to_dwc(g); | ||
| 999 | |||
| 1000 | unsigned long timeout; | ||
| 1001 | unsigned long flags; | ||
| 1002 | |||
| 1003 | u32 reg; | ||
| 1004 | |||
| 1005 | int ret = 0; | ||
| 1006 | |||
| 1007 | u8 link_state; | ||
| 1008 | u8 speed; | ||
| 1009 | |||
| 1010 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 1011 | |||
| 1012 | /* | ||
| 1013 | * According to the Databook Remote wakeup request should | ||
| 1014 | * be issued only when the device is in early suspend state. | ||
| 1015 | * | ||
| 1016 | * We can check that via USB Link State bits in DSTS register. | ||
| 1017 | */ | ||
| 1018 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | ||
| 1019 | |||
| 1020 | speed = reg & DWC3_DSTS_CONNECTSPD; | ||
| 1021 | if (speed == DWC3_DSTS_SUPERSPEED) { | ||
| 1022 | dev_dbg(dwc->dev, "no wakeup on SuperSpeed\n"); | ||
| 1023 | ret = -EINVAL; | ||
| 1024 | goto out; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | link_state = DWC3_DSTS_USBLNKST(reg); | ||
| 1028 | |||
| 1029 | switch (link_state) { | ||
| 1030 | case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */ | ||
| 1031 | case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */ | ||
| 1032 | break; | ||
| 1033 | default: | ||
| 1034 | dev_dbg(dwc->dev, "can't wakeup from link state %d\n", | ||
| 1035 | link_state); | ||
| 1036 | ret = -EINVAL; | ||
| 1037 | goto out; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
| 1041 | |||
| 1042 | /* | ||
| 1043 | * Switch link state to Recovery. In HS/FS/LS this means | ||
| 1044 | * RemoteWakeup Request | ||
| 1045 | */ | ||
| 1046 | reg |= DWC3_DCTL_ULSTCHNG_RECOVERY; | ||
| 1047 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
| 1048 | |||
| 1049 | /* wait for at least 2000us */ | ||
| 1050 | usleep_range(2000, 2500); | ||
| 1051 | |||
| 1052 | /* write zeroes to Link Change Request */ | ||
| 1053 | reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; | ||
| 1054 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
| 1055 | |||
| 1056 | /* pool until Link State change to ON */ | ||
| 1057 | timeout = jiffies + msecs_to_jiffies(100); | ||
| 1058 | |||
| 1059 | while (!(time_after(jiffies, timeout))) { | ||
| 1060 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | ||
| 1061 | |||
| 1062 | /* in HS, means ON */ | ||
| 1063 | if (DWC3_DSTS_USBLNKST(reg) == DWC3_LINK_STATE_U0) | ||
| 1064 | break; | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) { | ||
| 1068 | dev_err(dwc->dev, "failed to send remote wakeup\n"); | ||
| 1069 | ret = -EINVAL; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | out: | ||
| 1073 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 1074 | |||
| 1075 | return ret; | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static int dwc3_gadget_set_selfpowered(struct usb_gadget *g, | ||
| 1079 | int is_selfpowered) | ||
| 1080 | { | ||
| 1081 | struct dwc3 *dwc = gadget_to_dwc(g); | ||
| 1082 | |||
| 1083 | dwc->is_selfpowered = !!is_selfpowered; | ||
| 1084 | |||
| 1085 | return 0; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) | ||
| 1089 | { | ||
| 1090 | u32 reg; | ||
| 1091 | u32 timeout = 500; | ||
| 1092 | |||
| 1093 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
| 1094 | if (is_on) | ||
| 1095 | reg |= DWC3_DCTL_RUN_STOP; | ||
| 1096 | else | ||
| 1097 | reg &= ~DWC3_DCTL_RUN_STOP; | ||
| 1098 | |||
| 1099 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
| 1100 | |||
| 1101 | do { | ||
| 1102 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | ||
| 1103 | if (is_on) { | ||
| 1104 | if (!(reg & DWC3_DSTS_DEVCTRLHLT)) | ||
| 1105 | break; | ||
| 1106 | } else { | ||
| 1107 | if (reg & DWC3_DSTS_DEVCTRLHLT) | ||
| 1108 | break; | ||
| 1109 | } | ||
| 1110 | timeout--; | ||
| 1111 | if (!timeout) | ||
| 1112 | break; | ||
| 1113 | udelay(1); | ||
| 1114 | } while (1); | ||
| 1115 | |||
| 1116 | dev_vdbg(dwc->dev, "gadget %s data soft-%s\n", | ||
| 1117 | dwc->gadget_driver | ||
| 1118 | ? dwc->gadget_driver->function : "no-function", | ||
| 1119 | is_on ? "connect" : "disconnect"); | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) | ||
| 1123 | { | ||
| 1124 | struct dwc3 *dwc = gadget_to_dwc(g); | ||
| 1125 | unsigned long flags; | ||
| 1126 | |||
| 1127 | is_on = !!is_on; | ||
| 1128 | |||
| 1129 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 1130 | dwc3_gadget_run_stop(dwc, is_on); | ||
| 1131 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 1132 | |||
| 1133 | return 0; | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | static int dwc3_gadget_start(struct usb_gadget *g, | ||
| 1137 | struct usb_gadget_driver *driver) | ||
| 1138 | { | ||
| 1139 | struct dwc3 *dwc = gadget_to_dwc(g); | ||
| 1140 | struct dwc3_ep *dep; | ||
| 1141 | unsigned long flags; | ||
| 1142 | int ret = 0; | ||
| 1143 | u32 reg; | ||
| 1144 | |||
| 1145 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 1146 | |||
| 1147 | if (dwc->gadget_driver) { | ||
| 1148 | dev_err(dwc->dev, "%s is already bound to %s\n", | ||
| 1149 | dwc->gadget.name, | ||
| 1150 | dwc->gadget_driver->driver.name); | ||
| 1151 | ret = -EBUSY; | ||
| 1152 | goto err0; | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | dwc->gadget_driver = driver; | ||
| 1156 | dwc->gadget.dev.driver = &driver->driver; | ||
| 1157 | |||
| 1158 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | ||
| 1159 | |||
| 1160 | reg &= ~DWC3_GCTL_SCALEDOWN(3); | ||
| 1161 | reg &= ~DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG); | ||
| 1162 | reg &= ~DWC3_GCTL_DISSCRAMBLE; | ||
| 1163 | reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE); | ||
| 1164 | |||
| 1165 | switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams0)) { | ||
| 1166 | case DWC3_GHWPARAMS1_EN_PWROPT_CLK: | ||
| 1167 | reg &= ~DWC3_GCTL_DSBLCLKGTNG; | ||
| 1168 | break; | ||
| 1169 | default: | ||
| 1170 | dev_dbg(dwc->dev, "No power optimization available\n"); | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | /* | ||
| 1174 | * WORKAROUND: DWC3 revisions <1.90a have a bug | ||
| 1175 | * when The device fails to connect at SuperSpeed | ||
| 1176 | * and falls back to high-speed mode which causes | ||
| 1177 | * the device to enter in a Connect/Disconnect loop | ||
| 1178 | */ | ||
| 1179 | if (dwc->revision < DWC3_REVISION_190A) | ||
| 1180 | reg |= DWC3_GCTL_U2RSTECN; | ||
| 1181 | |||
| 1182 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | ||
| 1183 | |||
| 1184 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); | ||
| 1185 | reg &= ~(DWC3_DCFG_SPEED_MASK); | ||
| 1186 | reg |= DWC3_DCFG_SUPERSPEED; | ||
| 1187 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | ||
| 1188 | |||
| 1189 | dwc->start_config_issued = false; | ||
| 1190 | |||
| 1191 | /* Start with SuperSpeed Default */ | ||
| 1192 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); | ||
| 1193 | |||
| 1194 | dep = dwc->eps[0]; | ||
| 1195 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc); | ||
| 1196 | if (ret) { | ||
| 1197 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | ||
| 1198 | goto err0; | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | dep = dwc->eps[1]; | ||
| 1202 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc); | ||
| 1203 | if (ret) { | ||
| 1204 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | ||
| 1205 | goto err1; | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | /* begin to receive SETUP packets */ | ||
| 1209 | dwc->ep0state = EP0_SETUP_PHASE; | ||
| 1210 | dwc3_ep0_out_start(dwc); | ||
| 1211 | |||
| 1212 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 1213 | |||
| 1214 | return 0; | ||
| 1215 | |||
| 1216 | err1: | ||
| 1217 | __dwc3_gadget_ep_disable(dwc->eps[0]); | ||
| 1218 | |||
| 1219 | err0: | ||
| 1220 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 1221 | |||
| 1222 | return ret; | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | static int dwc3_gadget_stop(struct usb_gadget *g, | ||
| 1226 | struct usb_gadget_driver *driver) | ||
| 1227 | { | ||
| 1228 | struct dwc3 *dwc = gadget_to_dwc(g); | ||
| 1229 | unsigned long flags; | ||
| 1230 | |||
| 1231 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 1232 | |||
| 1233 | __dwc3_gadget_ep_disable(dwc->eps[0]); | ||
| 1234 | __dwc3_gadget_ep_disable(dwc->eps[1]); | ||
| 1235 | |||
| 1236 | dwc->gadget_driver = NULL; | ||
| 1237 | dwc->gadget.dev.driver = NULL; | ||
| 1238 | |||
| 1239 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 1240 | |||
| 1241 | return 0; | ||
| 1242 | } | ||
| 1243 | static const struct usb_gadget_ops dwc3_gadget_ops = { | ||
| 1244 | .get_frame = dwc3_gadget_get_frame, | ||
| 1245 | .wakeup = dwc3_gadget_wakeup, | ||
| 1246 | .set_selfpowered = dwc3_gadget_set_selfpowered, | ||
| 1247 | .pullup = dwc3_gadget_pullup, | ||
| 1248 | .udc_start = dwc3_gadget_start, | ||
| 1249 | .udc_stop = dwc3_gadget_stop, | ||
| 1250 | }; | ||
| 1251 | |||
| 1252 | /* -------------------------------------------------------------------------- */ | ||
| 1253 | |||
| 1254 | static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc) | ||
| 1255 | { | ||
| 1256 | struct dwc3_ep *dep; | ||
| 1257 | u8 epnum; | ||
| 1258 | |||
| 1259 | INIT_LIST_HEAD(&dwc->gadget.ep_list); | ||
| 1260 | |||
| 1261 | for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | ||
| 1262 | dep = kzalloc(sizeof(*dep), GFP_KERNEL); | ||
| 1263 | if (!dep) { | ||
| 1264 | dev_err(dwc->dev, "can't allocate endpoint %d\n", | ||
| 1265 | epnum); | ||
| 1266 | return -ENOMEM; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | dep->dwc = dwc; | ||
| 1270 | dep->number = epnum; | ||
| 1271 | dwc->eps[epnum] = dep; | ||
| 1272 | |||
| 1273 | snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1, | ||
| 1274 | (epnum & 1) ? "in" : "out"); | ||
| 1275 | dep->endpoint.name = dep->name; | ||
| 1276 | dep->direction = (epnum & 1); | ||
| 1277 | |||
| 1278 | if (epnum == 0 || epnum == 1) { | ||
| 1279 | dep->endpoint.maxpacket = 512; | ||
| 1280 | dep->endpoint.ops = &dwc3_gadget_ep0_ops; | ||
| 1281 | if (!epnum) | ||
| 1282 | dwc->gadget.ep0 = &dep->endpoint; | ||
| 1283 | } else { | ||
| 1284 | int ret; | ||
| 1285 | |||
| 1286 | dep->endpoint.maxpacket = 1024; | ||
| 1287 | dep->endpoint.ops = &dwc3_gadget_ep_ops; | ||
| 1288 | list_add_tail(&dep->endpoint.ep_list, | ||
| 1289 | &dwc->gadget.ep_list); | ||
| 1290 | |||
| 1291 | ret = dwc3_alloc_trb_pool(dep); | ||
| 1292 | if (ret) { | ||
| 1293 | dev_err(dwc->dev, "%s: failed to allocate TRB pool\n", dep->name); | ||
| 1294 | return ret; | ||
| 1295 | } | ||
| 1296 | } | ||
| 1297 | INIT_LIST_HEAD(&dep->request_list); | ||
| 1298 | INIT_LIST_HEAD(&dep->req_queued); | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | return 0; | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) | ||
| 1305 | { | ||
| 1306 | struct dwc3_ep *dep; | ||
| 1307 | u8 epnum; | ||
| 1308 | |||
| 1309 | for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | ||
| 1310 | dep = dwc->eps[epnum]; | ||
| 1311 | dwc3_free_trb_pool(dep); | ||
| 1312 | |||
| 1313 | if (epnum != 0 && epnum != 1) | ||
| 1314 | list_del(&dep->endpoint.ep_list); | ||
| 1315 | |||
| 1316 | kfree(dep); | ||
| 1317 | } | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | static void dwc3_gadget_release(struct device *dev) | ||
| 1321 | { | ||
| 1322 | dev_dbg(dev, "%s\n", __func__); | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | /* -------------------------------------------------------------------------- */ | ||
| 1326 | static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | ||
| 1327 | const struct dwc3_event_depevt *event, int status) | ||
| 1328 | { | ||
| 1329 | struct dwc3_request *req; | ||
| 1330 | struct dwc3_trb trb; | ||
| 1331 | unsigned int count; | ||
| 1332 | unsigned int s_pkt = 0; | ||
| 1333 | |||
| 1334 | do { | ||
| 1335 | req = next_request(&dep->req_queued); | ||
| 1336 | if (!req) | ||
| 1337 | break; | ||
| 1338 | |||
| 1339 | dwc3_trb_to_nat(req->trb, &trb); | ||
| 1340 | |||
| 1341 | if (trb.hwo && status != -ESHUTDOWN) | ||
| 1342 | /* | ||
| 1343 | * We continue despite the error. There is not much we | ||
| 1344 | * can do. If we don't clean in up we loop for ever. If | ||
| 1345 | * we skip the TRB than it gets overwritten reused after | ||
| 1346 | * a while since we use them in a ring buffer. a BUG() | ||
| 1347 | * would help. Lets hope that if this occures, someone | ||
| 1348 | * fixes the root cause instead of looking away :) | ||
| 1349 | */ | ||
| 1350 | dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", | ||
| 1351 | dep->name, req->trb); | ||
| 1352 | count = trb.length; | ||
| 1353 | |||
| 1354 | if (dep->direction) { | ||
| 1355 | if (count) { | ||
| 1356 | dev_err(dwc->dev, "incomplete IN transfer %s\n", | ||
| 1357 | dep->name); | ||
| 1358 | status = -ECONNRESET; | ||
| 1359 | } | ||
| 1360 | } else { | ||
| 1361 | if (count && (event->status & DEPEVT_STATUS_SHORT)) | ||
| 1362 | s_pkt = 1; | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | /* | ||
| 1366 | * We assume here we will always receive the entire data block | ||
| 1367 | * which we should receive. Meaning, if we program RX to | ||
| 1368 | * receive 4K but we receive only 2K, we assume that's all we | ||
| 1369 | * should receive and we simply bounce the request back to the | ||
| 1370 | * gadget driver for further processing. | ||
| 1371 | */ | ||
| 1372 | req->request.actual += req->request.length - count; | ||
| 1373 | dwc3_gadget_giveback(dep, req, status); | ||
| 1374 | if (s_pkt) | ||
| 1375 | break; | ||
| 1376 | if ((event->status & DEPEVT_STATUS_LST) && trb.lst) | ||
| 1377 | break; | ||
| 1378 | if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc) | ||
| 1379 | break; | ||
| 1380 | } while (1); | ||
| 1381 | |||
| 1382 | if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc) | ||
| 1383 | return 0; | ||
| 1384 | return 1; | ||
| 1385 | } | ||
| 1386 | |||
| 1387 | static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, | ||
| 1388 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event, | ||
| 1389 | int start_new) | ||
| 1390 | { | ||
| 1391 | unsigned status = 0; | ||
| 1392 | int clean_busy; | ||
| 1393 | |||
| 1394 | if (event->status & DEPEVT_STATUS_BUSERR) | ||
| 1395 | status = -ECONNRESET; | ||
| 1396 | |||
| 1397 | clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status); | ||
| 1398 | if (clean_busy) { | ||
| 1399 | dep->flags &= ~DWC3_EP_BUSY; | ||
| 1400 | dep->res_trans_idx = 0; | ||
| 1401 | } | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | static void dwc3_gadget_start_isoc(struct dwc3 *dwc, | ||
| 1405 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event) | ||
| 1406 | { | ||
| 1407 | u32 uf; | ||
| 1408 | |||
| 1409 | if (list_empty(&dep->request_list)) { | ||
| 1410 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | ||
| 1411 | dep->name); | ||
| 1412 | return; | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | if (event->parameters) { | ||
| 1416 | u32 mask; | ||
| 1417 | |||
| 1418 | mask = ~(dep->interval - 1); | ||
| 1419 | uf = event->parameters & mask; | ||
| 1420 | /* 4 micro frames in the future */ | ||
| 1421 | uf += dep->interval * 4; | ||
| 1422 | } else { | ||
| 1423 | uf = 0; | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | __dwc3_gadget_kick_transfer(dep, uf, 1); | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep, | ||
| 1430 | const struct dwc3_event_depevt *event) | ||
| 1431 | { | ||
| 1432 | struct dwc3 *dwc = dep->dwc; | ||
| 1433 | struct dwc3_event_depevt mod_ev = *event; | ||
| 1434 | |||
| 1435 | /* | ||
| 1436 | * We were asked to remove one requests. It is possible that this | ||
| 1437 | * request and a few other were started together and have the same | ||
| 1438 | * transfer index. Since we stopped the complete endpoint we don't | ||
| 1439 | * know how many requests were already completed (and not yet) | ||
| 1440 | * reported and how could be done (later). We purge them all until | ||
| 1441 | * the end of the list. | ||
| 1442 | */ | ||
| 1443 | mod_ev.status = DEPEVT_STATUS_LST; | ||
| 1444 | dwc3_cleanup_done_reqs(dwc, dep, &mod_ev, -ESHUTDOWN); | ||
| 1445 | dep->flags &= ~DWC3_EP_BUSY; | ||
| 1446 | /* pending requets are ignored and are queued on XferNotReady */ | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | static void dwc3_ep_cmd_compl(struct dwc3_ep *dep, | ||
| 1450 | const struct dwc3_event_depevt *event) | ||
| 1451 | { | ||
| 1452 | u32 param = event->parameters; | ||
| 1453 | u32 cmd_type = (param >> 8) & ((1 << 5) - 1); | ||
| 1454 | |||
| 1455 | switch (cmd_type) { | ||
| 1456 | case DWC3_DEPCMD_ENDTRANSFER: | ||
| 1457 | dwc3_process_ep_cmd_complete(dep, event); | ||
| 1458 | break; | ||
| 1459 | case DWC3_DEPCMD_STARTTRANSFER: | ||
| 1460 | dep->res_trans_idx = param & 0x7f; | ||
| 1461 | break; | ||
| 1462 | default: | ||
| 1463 | printk(KERN_ERR "%s() unknown /unexpected type: %d\n", | ||
| 1464 | __func__, cmd_type); | ||
| 1465 | break; | ||
| 1466 | }; | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | ||
| 1470 | const struct dwc3_event_depevt *event) | ||
| 1471 | { | ||
| 1472 | struct dwc3_ep *dep; | ||
| 1473 | u8 epnum = event->endpoint_number; | ||
| 1474 | |||
| 1475 | dep = dwc->eps[epnum]; | ||
| 1476 | |||
| 1477 | dev_vdbg(dwc->dev, "%s: %s\n", dep->name, | ||
| 1478 | dwc3_ep_event_string(event->endpoint_event)); | ||
| 1479 | |||
| 1480 | if (epnum == 0 || epnum == 1) { | ||
| 1481 | dwc3_ep0_interrupt(dwc, event); | ||
| 1482 | return; | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | switch (event->endpoint_event) { | ||
| 1486 | case DWC3_DEPEVT_XFERCOMPLETE: | ||
| 1487 | if (usb_endpoint_xfer_isoc(dep->desc)) { | ||
| 1488 | dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n", | ||
| 1489 | dep->name); | ||
| 1490 | return; | ||
| 1491 | } | ||
| 1492 | |||
| 1493 | dwc3_endpoint_transfer_complete(dwc, dep, event, 1); | ||
| 1494 | break; | ||
| 1495 | case DWC3_DEPEVT_XFERINPROGRESS: | ||
| 1496 | if (!usb_endpoint_xfer_isoc(dep->desc)) { | ||
| 1497 | dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n", | ||
| 1498 | dep->name); | ||
| 1499 | return; | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | dwc3_endpoint_transfer_complete(dwc, dep, event, 0); | ||
| 1503 | break; | ||
| 1504 | case DWC3_DEPEVT_XFERNOTREADY: | ||
| 1505 | if (usb_endpoint_xfer_isoc(dep->desc)) { | ||
| 1506 | dwc3_gadget_start_isoc(dwc, dep, event); | ||
| 1507 | } else { | ||
| 1508 | int ret; | ||
| 1509 | |||
| 1510 | dev_vdbg(dwc->dev, "%s: reason %s\n", | ||
| 1511 | dep->name, event->status | ||
| 1512 | ? "Transfer Active" | ||
| 1513 | : "Transfer Not Active"); | ||
| 1514 | |||
| 1515 | ret = __dwc3_gadget_kick_transfer(dep, 0, 1); | ||
| 1516 | if (!ret || ret == -EBUSY) | ||
| 1517 | return; | ||
| 1518 | |||
| 1519 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | ||
| 1520 | dep->name); | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | break; | ||
| 1524 | case DWC3_DEPEVT_STREAMEVT: | ||
| 1525 | if (!usb_endpoint_xfer_bulk(dep->desc)) { | ||
| 1526 | dev_err(dwc->dev, "Stream event for non-Bulk %s\n", | ||
| 1527 | dep->name); | ||
| 1528 | return; | ||
| 1529 | } | ||
| 1530 | |||
| 1531 | switch (event->status) { | ||
| 1532 | case DEPEVT_STREAMEVT_FOUND: | ||
| 1533 | dev_vdbg(dwc->dev, "Stream %d found and started\n", | ||
| 1534 | event->parameters); | ||
| 1535 | |||
| 1536 | break; | ||
| 1537 | case DEPEVT_STREAMEVT_NOTFOUND: | ||
| 1538 | /* FALLTHROUGH */ | ||
| 1539 | default: | ||
| 1540 | dev_dbg(dwc->dev, "Couldn't find suitable stream\n"); | ||
| 1541 | } | ||
| 1542 | break; | ||
| 1543 | case DWC3_DEPEVT_RXTXFIFOEVT: | ||
| 1544 | dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); | ||
| 1545 | break; | ||
| 1546 | case DWC3_DEPEVT_EPCMDCMPLT: | ||
| 1547 | dwc3_ep_cmd_compl(dep, event); | ||
| 1548 | break; | ||
| 1549 | } | ||
| 1550 | } | ||
| 1551 | |||
| 1552 | static void dwc3_disconnect_gadget(struct dwc3 *dwc) | ||
| 1553 | { | ||
| 1554 | if (dwc->gadget_driver && dwc->gadget_driver->disconnect) { | ||
| 1555 | spin_unlock(&dwc->lock); | ||
| 1556 | dwc->gadget_driver->disconnect(&dwc->gadget); | ||
| 1557 | spin_lock(&dwc->lock); | ||
| 1558 | } | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) | ||
| 1562 | { | ||
| 1563 | struct dwc3_ep *dep; | ||
| 1564 | struct dwc3_gadget_ep_cmd_params params; | ||
| 1565 | u32 cmd; | ||
| 1566 | int ret; | ||
| 1567 | |||
| 1568 | dep = dwc->eps[epnum]; | ||
| 1569 | |||
| 1570 | WARN_ON(!dep->res_trans_idx); | ||
| 1571 | if (dep->res_trans_idx) { | ||
| 1572 | cmd = DWC3_DEPCMD_ENDTRANSFER; | ||
| 1573 | cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC; | ||
| 1574 | cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx); | ||
| 1575 | memset(¶ms, 0, sizeof(params)); | ||
| 1576 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); | ||
| 1577 | WARN_ON_ONCE(ret); | ||
| 1578 | dep->res_trans_idx = 0; | ||
| 1579 | } | ||
| 1580 | } | ||
| 1581 | |||
| 1582 | static void dwc3_stop_active_transfers(struct dwc3 *dwc) | ||
| 1583 | { | ||
| 1584 | u32 epnum; | ||
| 1585 | |||
| 1586 | for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | ||
| 1587 | struct dwc3_ep *dep; | ||
| 1588 | |||
| 1589 | dep = dwc->eps[epnum]; | ||
| 1590 | if (!(dep->flags & DWC3_EP_ENABLED)) | ||
| 1591 | continue; | ||
| 1592 | |||
| 1593 | dwc3_remove_requests(dwc, dep); | ||
| 1594 | } | ||
| 1595 | } | ||
| 1596 | |||
| 1597 | static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) | ||
| 1598 | { | ||
| 1599 | u32 epnum; | ||
| 1600 | |||
| 1601 | for (epnum = 1; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | ||
| 1602 | struct dwc3_ep *dep; | ||
| 1603 | struct dwc3_gadget_ep_cmd_params params; | ||
| 1604 | int ret; | ||
| 1605 | |||
| 1606 | dep = dwc->eps[epnum]; | ||
| 1607 | |||
| 1608 | if (!(dep->flags & DWC3_EP_STALL)) | ||
| 1609 | continue; | ||
| 1610 | |||
| 1611 | dep->flags &= ~DWC3_EP_STALL; | ||
| 1612 | |||
| 1613 | memset(¶ms, 0, sizeof(params)); | ||
| 1614 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | ||
| 1615 | DWC3_DEPCMD_CLEARSTALL, ¶ms); | ||
| 1616 | WARN_ON_ONCE(ret); | ||
| 1617 | } | ||
| 1618 | } | ||
| 1619 | |||
| 1620 | static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) | ||
| 1621 | { | ||
| 1622 | dev_vdbg(dwc->dev, "%s\n", __func__); | ||
| 1623 | #if 0 | ||
| 1624 | XXX | ||
| 1625 | U1/U2 is powersave optimization. Skip it for now. Anyway we need to | ||
| 1626 | enable it before we can disable it. | ||
| 1627 | |||
| 1628 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
| 1629 | reg &= ~DWC3_DCTL_INITU1ENA; | ||
| 1630 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
| 1631 | |||
| 1632 | reg &= ~DWC3_DCTL_INITU2ENA; | ||
| 1633 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
| 1634 | #endif | ||
| 1635 | |||
| 1636 | dwc3_stop_active_transfers(dwc); | ||
| 1637 | dwc3_disconnect_gadget(dwc); | ||
| 1638 | dwc->start_config_issued = false; | ||
| 1639 | |||
| 1640 | dwc->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on) | ||
| 1644 | { | ||
| 1645 | u32 reg; | ||
| 1646 | |||
| 1647 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); | ||
| 1648 | |||
| 1649 | if (on) | ||
| 1650 | reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; | ||
| 1651 | else | ||
| 1652 | reg |= DWC3_GUSB3PIPECTL_SUSPHY; | ||
| 1653 | |||
| 1654 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | static void dwc3_gadget_usb2_phy_power(struct dwc3 *dwc, int on) | ||
| 1658 | { | ||
| 1659 | u32 reg; | ||
| 1660 | |||
| 1661 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | ||
| 1662 | |||
| 1663 | if (on) | ||
| 1664 | reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; | ||
| 1665 | else | ||
| 1666 | reg |= DWC3_GUSB2PHYCFG_SUSPHY; | ||
| 1667 | |||
| 1668 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | ||
| 1669 | } | ||
| 1670 | |||
| 1671 | static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) | ||
| 1672 | { | ||
| 1673 | u32 reg; | ||
| 1674 | |||
| 1675 | dev_vdbg(dwc->dev, "%s\n", __func__); | ||
| 1676 | |||
| 1677 | /* Enable PHYs */ | ||
| 1678 | dwc3_gadget_usb2_phy_power(dwc, true); | ||
| 1679 | dwc3_gadget_usb3_phy_power(dwc, true); | ||
| 1680 | |||
| 1681 | if (dwc->gadget.speed != USB_SPEED_UNKNOWN) | ||
| 1682 | dwc3_disconnect_gadget(dwc); | ||
| 1683 | |||
| 1684 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
| 1685 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; | ||
| 1686 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
| 1687 | |||
| 1688 | dwc3_stop_active_transfers(dwc); | ||
| 1689 | dwc3_clear_stall_all_ep(dwc); | ||
| 1690 | dwc->start_config_issued = false; | ||
| 1691 | |||
| 1692 | /* Reset device address to zero */ | ||
| 1693 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); | ||
| 1694 | reg &= ~(DWC3_DCFG_DEVADDR_MASK); | ||
| 1695 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | static void dwc3_update_ram_clk_sel(struct dwc3 *dwc, u32 speed) | ||
| 1699 | { | ||
| 1700 | u32 reg; | ||
| 1701 | u32 usb30_clock = DWC3_GCTL_CLK_BUS; | ||
| 1702 | |||
| 1703 | /* | ||
| 1704 | * We change the clock only at SS but I dunno why I would want to do | ||
| 1705 | * this. Maybe it becomes part of the power saving plan. | ||
| 1706 | */ | ||
| 1707 | |||
| 1708 | if (speed != DWC3_DSTS_SUPERSPEED) | ||
| 1709 | return; | ||
| 1710 | |||
| 1711 | /* | ||
| 1712 | * RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed | ||
| 1713 | * each time on Connect Done. | ||
| 1714 | */ | ||
| 1715 | if (!usb30_clock) | ||
| 1716 | return; | ||
| 1717 | |||
| 1718 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | ||
| 1719 | reg |= DWC3_GCTL_RAMCLKSEL(usb30_clock); | ||
| 1720 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | ||
| 1721 | } | ||
| 1722 | |||
| 1723 | static void dwc3_gadget_disable_phy(struct dwc3 *dwc, u8 speed) | ||
| 1724 | { | ||
| 1725 | switch (speed) { | ||
| 1726 | case USB_SPEED_SUPER: | ||
| 1727 | dwc3_gadget_usb2_phy_power(dwc, false); | ||
| 1728 | break; | ||
| 1729 | case USB_SPEED_HIGH: | ||
| 1730 | case USB_SPEED_FULL: | ||
| 1731 | case USB_SPEED_LOW: | ||
| 1732 | dwc3_gadget_usb3_phy_power(dwc, false); | ||
| 1733 | break; | ||
| 1734 | } | ||
| 1735 | } | ||
| 1736 | |||
| 1737 | static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) | ||
| 1738 | { | ||
| 1739 | struct dwc3_gadget_ep_cmd_params params; | ||
| 1740 | struct dwc3_ep *dep; | ||
| 1741 | int ret; | ||
| 1742 | u32 reg; | ||
| 1743 | u8 speed; | ||
| 1744 | |||
| 1745 | dev_vdbg(dwc->dev, "%s\n", __func__); | ||
| 1746 | |||
| 1747 | memset(¶ms, 0x00, sizeof(params)); | ||
| 1748 | |||
| 1749 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | ||
| 1750 | speed = reg & DWC3_DSTS_CONNECTSPD; | ||
| 1751 | dwc->speed = speed; | ||
| 1752 | |||
| 1753 | dwc3_update_ram_clk_sel(dwc, speed); | ||
| 1754 | |||
| 1755 | switch (speed) { | ||
| 1756 | case DWC3_DCFG_SUPERSPEED: | ||
| 1757 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); | ||
| 1758 | dwc->gadget.ep0->maxpacket = 512; | ||
| 1759 | dwc->gadget.speed = USB_SPEED_SUPER; | ||
| 1760 | break; | ||
| 1761 | case DWC3_DCFG_HIGHSPEED: | ||
| 1762 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); | ||
| 1763 | dwc->gadget.ep0->maxpacket = 64; | ||
| 1764 | dwc->gadget.speed = USB_SPEED_HIGH; | ||
| 1765 | break; | ||
| 1766 | case DWC3_DCFG_FULLSPEED2: | ||
| 1767 | case DWC3_DCFG_FULLSPEED1: | ||
| 1768 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); | ||
| 1769 | dwc->gadget.ep0->maxpacket = 64; | ||
| 1770 | dwc->gadget.speed = USB_SPEED_FULL; | ||
| 1771 | break; | ||
| 1772 | case DWC3_DCFG_LOWSPEED: | ||
| 1773 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8); | ||
| 1774 | dwc->gadget.ep0->maxpacket = 8; | ||
| 1775 | dwc->gadget.speed = USB_SPEED_LOW; | ||
| 1776 | break; | ||
| 1777 | } | ||
| 1778 | |||
| 1779 | /* Disable unneded PHY */ | ||
| 1780 | dwc3_gadget_disable_phy(dwc, dwc->gadget.speed); | ||
| 1781 | |||
| 1782 | dep = dwc->eps[0]; | ||
| 1783 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc); | ||
| 1784 | if (ret) { | ||
| 1785 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | ||
| 1786 | return; | ||
| 1787 | } | ||
| 1788 | |||
| 1789 | dep = dwc->eps[1]; | ||
| 1790 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc); | ||
| 1791 | if (ret) { | ||
| 1792 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | ||
| 1793 | return; | ||
| 1794 | } | ||
| 1795 | |||
| 1796 | /* | ||
| 1797 | * Configure PHY via GUSB3PIPECTLn if required. | ||
| 1798 | * | ||
| 1799 | * Update GTXFIFOSIZn | ||
| 1800 | * | ||
| 1801 | * In both cases reset values should be sufficient. | ||
| 1802 | */ | ||
| 1803 | } | ||
| 1804 | |||
| 1805 | static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) | ||
| 1806 | { | ||
| 1807 | dev_vdbg(dwc->dev, "%s\n", __func__); | ||
| 1808 | |||
| 1809 | /* | ||
| 1810 | * TODO take core out of low power mode when that's | ||
| 1811 | * implemented. | ||
| 1812 | */ | ||
| 1813 | |||
| 1814 | dwc->gadget_driver->resume(&dwc->gadget); | ||
| 1815 | } | ||
| 1816 | |||
| 1817 | static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, | ||
| 1818 | unsigned int evtinfo) | ||
| 1819 | { | ||
| 1820 | /* The fith bit says SuperSpeed yes or no. */ | ||
| 1821 | dwc->link_state = evtinfo & DWC3_LINK_STATE_MASK; | ||
| 1822 | |||
| 1823 | dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state); | ||
| 1824 | } | ||
| 1825 | |||
| 1826 | static void dwc3_gadget_interrupt(struct dwc3 *dwc, | ||
| 1827 | const struct dwc3_event_devt *event) | ||
| 1828 | { | ||
| 1829 | switch (event->type) { | ||
| 1830 | case DWC3_DEVICE_EVENT_DISCONNECT: | ||
| 1831 | dwc3_gadget_disconnect_interrupt(dwc); | ||
| 1832 | break; | ||
| 1833 | case DWC3_DEVICE_EVENT_RESET: | ||
| 1834 | dwc3_gadget_reset_interrupt(dwc); | ||
| 1835 | break; | ||
| 1836 | case DWC3_DEVICE_EVENT_CONNECT_DONE: | ||
| 1837 | dwc3_gadget_conndone_interrupt(dwc); | ||
| 1838 | break; | ||
| 1839 | case DWC3_DEVICE_EVENT_WAKEUP: | ||
| 1840 | dwc3_gadget_wakeup_interrupt(dwc); | ||
| 1841 | break; | ||
| 1842 | case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: | ||
| 1843 | dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); | ||
| 1844 | break; | ||
| 1845 | case DWC3_DEVICE_EVENT_EOPF: | ||
| 1846 | dev_vdbg(dwc->dev, "End of Periodic Frame\n"); | ||
| 1847 | break; | ||
| 1848 | case DWC3_DEVICE_EVENT_SOF: | ||
| 1849 | dev_vdbg(dwc->dev, "Start of Periodic Frame\n"); | ||
| 1850 | break; | ||
| 1851 | case DWC3_DEVICE_EVENT_ERRATIC_ERROR: | ||
| 1852 | dev_vdbg(dwc->dev, "Erratic Error\n"); | ||
| 1853 | break; | ||
| 1854 | case DWC3_DEVICE_EVENT_CMD_CMPL: | ||
| 1855 | dev_vdbg(dwc->dev, "Command Complete\n"); | ||
| 1856 | break; | ||
| 1857 | case DWC3_DEVICE_EVENT_OVERFLOW: | ||
| 1858 | dev_vdbg(dwc->dev, "Overflow\n"); | ||
| 1859 | break; | ||
| 1860 | default: | ||
| 1861 | dev_dbg(dwc->dev, "UNKNOWN IRQ %d\n", event->type); | ||
| 1862 | } | ||
| 1863 | } | ||
| 1864 | |||
| 1865 | static void dwc3_process_event_entry(struct dwc3 *dwc, | ||
| 1866 | const union dwc3_event *event) | ||
| 1867 | { | ||
| 1868 | /* Endpoint IRQ, handle it and return early */ | ||
| 1869 | if (event->type.is_devspec == 0) { | ||
| 1870 | /* depevt */ | ||
| 1871 | return dwc3_endpoint_interrupt(dwc, &event->depevt); | ||
| 1872 | } | ||
| 1873 | |||
| 1874 | switch (event->type.type) { | ||
| 1875 | case DWC3_EVENT_TYPE_DEV: | ||
| 1876 | dwc3_gadget_interrupt(dwc, &event->devt); | ||
| 1877 | break; | ||
| 1878 | /* REVISIT what to do with Carkit and I2C events ? */ | ||
| 1879 | default: | ||
| 1880 | dev_err(dwc->dev, "UNKNOWN IRQ type %d\n", event->raw); | ||
| 1881 | } | ||
| 1882 | } | ||
| 1883 | |||
| 1884 | static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) | ||
| 1885 | { | ||
| 1886 | struct dwc3_event_buffer *evt; | ||
| 1887 | int left; | ||
| 1888 | u32 count; | ||
| 1889 | |||
| 1890 | count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf)); | ||
| 1891 | count &= DWC3_GEVNTCOUNT_MASK; | ||
| 1892 | if (!count) | ||
| 1893 | return IRQ_NONE; | ||
| 1894 | |||
| 1895 | evt = dwc->ev_buffs[buf]; | ||
| 1896 | left = count; | ||
| 1897 | |||
| 1898 | while (left > 0) { | ||
| 1899 | union dwc3_event event; | ||
| 1900 | |||
| 1901 | memcpy(&event.raw, (evt->buf + evt->lpos), sizeof(event.raw)); | ||
| 1902 | dwc3_process_event_entry(dwc, &event); | ||
| 1903 | /* | ||
| 1904 | * XXX we wrap around correctly to the next entry as almost all | ||
| 1905 | * entries are 4 bytes in size. There is one entry which has 12 | ||
| 1906 | * bytes which is a regular entry followed by 8 bytes data. ATM | ||
| 1907 | * I don't know how things are organized if were get next to the | ||
| 1908 | * a boundary so I worry about that once we try to handle that. | ||
| 1909 | */ | ||
| 1910 | evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE; | ||
| 1911 | left -= 4; | ||
| 1912 | |||
| 1913 | dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4); | ||
| 1914 | } | ||
| 1915 | |||
| 1916 | return IRQ_HANDLED; | ||
| 1917 | } | ||
| 1918 | |||
| 1919 | static irqreturn_t dwc3_interrupt(int irq, void *_dwc) | ||
| 1920 | { | ||
| 1921 | struct dwc3 *dwc = _dwc; | ||
| 1922 | int i; | ||
| 1923 | irqreturn_t ret = IRQ_NONE; | ||
| 1924 | |||
| 1925 | spin_lock(&dwc->lock); | ||
| 1926 | |||
| 1927 | for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) { | ||
| 1928 | irqreturn_t status; | ||
| 1929 | |||
| 1930 | status = dwc3_process_event_buf(dwc, i); | ||
| 1931 | if (status == IRQ_HANDLED) | ||
| 1932 | ret = status; | ||
| 1933 | } | ||
| 1934 | |||
| 1935 | spin_unlock(&dwc->lock); | ||
| 1936 | |||
| 1937 | return ret; | ||
| 1938 | } | ||
| 1939 | |||
| 1940 | /** | ||
| 1941 | * dwc3_gadget_init - Initializes gadget related registers | ||
| 1942 | * @dwc: Pointer to out controller context structure | ||
| 1943 | * | ||
| 1944 | * Returns 0 on success otherwise negative errno. | ||
| 1945 | */ | ||
| 1946 | int __devinit dwc3_gadget_init(struct dwc3 *dwc) | ||
| 1947 | { | ||
| 1948 | u32 reg; | ||
| 1949 | int ret; | ||
| 1950 | int irq; | ||
| 1951 | |||
| 1952 | dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req), | ||
| 1953 | &dwc->ctrl_req_addr, GFP_KERNEL); | ||
| 1954 | if (!dwc->ctrl_req) { | ||
| 1955 | dev_err(dwc->dev, "failed to allocate ctrl request\n"); | ||
| 1956 | ret = -ENOMEM; | ||
| 1957 | goto err0; | ||
| 1958 | } | ||
| 1959 | |||
| 1960 | dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | ||
| 1961 | &dwc->ep0_trb_addr, GFP_KERNEL); | ||
| 1962 | if (!dwc->ep0_trb) { | ||
| 1963 | dev_err(dwc->dev, "failed to allocate ep0 trb\n"); | ||
| 1964 | ret = -ENOMEM; | ||
| 1965 | goto err1; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | dwc->setup_buf = dma_alloc_coherent(dwc->dev, | ||
| 1969 | sizeof(*dwc->setup_buf) * 2, | ||
| 1970 | &dwc->setup_buf_addr, GFP_KERNEL); | ||
| 1971 | if (!dwc->setup_buf) { | ||
| 1972 | dev_err(dwc->dev, "failed to allocate setup buffer\n"); | ||
| 1973 | ret = -ENOMEM; | ||
| 1974 | goto err2; | ||
| 1975 | } | ||
| 1976 | |||
| 1977 | dwc->ep0_bounce = dma_alloc_coherent(dwc->dev, | ||
| 1978 | 512, &dwc->ep0_bounce_addr, GFP_KERNEL); | ||
| 1979 | if (!dwc->ep0_bounce) { | ||
| 1980 | dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n"); | ||
| 1981 | ret = -ENOMEM; | ||
| 1982 | goto err3; | ||
| 1983 | } | ||
| 1984 | |||
| 1985 | dev_set_name(&dwc->gadget.dev, "gadget"); | ||
| 1986 | |||
| 1987 | dwc->gadget.ops = &dwc3_gadget_ops; | ||
| 1988 | dwc->gadget.is_dualspeed = true; | ||
| 1989 | dwc->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1990 | dwc->gadget.dev.parent = dwc->dev; | ||
| 1991 | |||
| 1992 | dma_set_coherent_mask(&dwc->gadget.dev, dwc->dev->coherent_dma_mask); | ||
| 1993 | |||
| 1994 | dwc->gadget.dev.dma_parms = dwc->dev->dma_parms; | ||
| 1995 | dwc->gadget.dev.dma_mask = dwc->dev->dma_mask; | ||
| 1996 | dwc->gadget.dev.release = dwc3_gadget_release; | ||
| 1997 | dwc->gadget.name = "dwc3-gadget"; | ||
| 1998 | |||
| 1999 | /* | ||
| 2000 | * REVISIT: Here we should clear all pending IRQs to be | ||
| 2001 | * sure we're starting from a well known location. | ||
| 2002 | */ | ||
| 2003 | |||
| 2004 | ret = dwc3_gadget_init_endpoints(dwc); | ||
| 2005 | if (ret) | ||
| 2006 | goto err4; | ||
| 2007 | |||
| 2008 | irq = platform_get_irq(to_platform_device(dwc->dev), 0); | ||
| 2009 | |||
| 2010 | ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, | ||
| 2011 | "dwc3", dwc); | ||
| 2012 | if (ret) { | ||
| 2013 | dev_err(dwc->dev, "failed to request irq #%d --> %d\n", | ||
| 2014 | irq, ret); | ||
| 2015 | goto err5; | ||
| 2016 | } | ||
| 2017 | |||
| 2018 | /* Enable all but Start and End of Frame IRQs */ | ||
| 2019 | reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN | | ||
| 2020 | DWC3_DEVTEN_EVNTOVERFLOWEN | | ||
| 2021 | DWC3_DEVTEN_CMDCMPLTEN | | ||
| 2022 | DWC3_DEVTEN_ERRTICERREN | | ||
| 2023 | DWC3_DEVTEN_WKUPEVTEN | | ||
| 2024 | DWC3_DEVTEN_ULSTCNGEN | | ||
| 2025 | DWC3_DEVTEN_CONNECTDONEEN | | ||
| 2026 | DWC3_DEVTEN_USBRSTEN | | ||
| 2027 | DWC3_DEVTEN_DISCONNEVTEN); | ||
| 2028 | dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); | ||
| 2029 | |||
| 2030 | ret = device_register(&dwc->gadget.dev); | ||
| 2031 | if (ret) { | ||
| 2032 | dev_err(dwc->dev, "failed to register gadget device\n"); | ||
| 2033 | put_device(&dwc->gadget.dev); | ||
| 2034 | goto err6; | ||
| 2035 | } | ||
| 2036 | |||
| 2037 | ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); | ||
| 2038 | if (ret) { | ||
| 2039 | dev_err(dwc->dev, "failed to register udc\n"); | ||
| 2040 | goto err7; | ||
| 2041 | } | ||
| 2042 | |||
| 2043 | return 0; | ||
| 2044 | |||
| 2045 | err7: | ||
| 2046 | device_unregister(&dwc->gadget.dev); | ||
| 2047 | |||
| 2048 | err6: | ||
| 2049 | dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); | ||
| 2050 | free_irq(irq, dwc); | ||
| 2051 | |||
| 2052 | err5: | ||
| 2053 | dwc3_gadget_free_endpoints(dwc); | ||
| 2054 | |||
| 2055 | err4: | ||
| 2056 | dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce, | ||
| 2057 | dwc->ep0_bounce_addr); | ||
| 2058 | |||
| 2059 | err3: | ||
| 2060 | dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2, | ||
| 2061 | dwc->setup_buf, dwc->setup_buf_addr); | ||
| 2062 | |||
| 2063 | err2: | ||
| 2064 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | ||
| 2065 | dwc->ep0_trb, dwc->ep0_trb_addr); | ||
| 2066 | |||
| 2067 | err1: | ||
| 2068 | dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), | ||
| 2069 | dwc->ctrl_req, dwc->ctrl_req_addr); | ||
| 2070 | |||
| 2071 | err0: | ||
| 2072 | return ret; | ||
| 2073 | } | ||
| 2074 | |||
| 2075 | void dwc3_gadget_exit(struct dwc3 *dwc) | ||
| 2076 | { | ||
| 2077 | int irq; | ||
| 2078 | int i; | ||
| 2079 | |||
| 2080 | usb_del_gadget_udc(&dwc->gadget); | ||
| 2081 | irq = platform_get_irq(to_platform_device(dwc->dev), 0); | ||
| 2082 | |||
| 2083 | dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); | ||
| 2084 | free_irq(irq, dwc); | ||
| 2085 | |||
| 2086 | for (i = 0; i < ARRAY_SIZE(dwc->eps); i++) | ||
| 2087 | __dwc3_gadget_ep_disable(dwc->eps[i]); | ||
| 2088 | |||
| 2089 | dwc3_gadget_free_endpoints(dwc); | ||
| 2090 | |||
| 2091 | dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce, | ||
| 2092 | dwc->ep0_bounce_addr); | ||
| 2093 | |||
| 2094 | dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2, | ||
| 2095 | dwc->setup_buf, dwc->setup_buf_addr); | ||
| 2096 | |||
| 2097 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | ||
| 2098 | dwc->ep0_trb, dwc->ep0_trb_addr); | ||
| 2099 | |||
| 2100 | dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), | ||
| 2101 | dwc->ctrl_req, dwc->ctrl_req_addr); | ||
| 2102 | |||
| 2103 | device_unregister(&dwc->gadget.dev); | ||
| 2104 | } | ||
| @@ -0,0 +1,211 @@ | |||
| 1 | /** | ||
| 2 | * gadget.h - DesignWare USB3 DRD Gadget Header | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #ifndef __DRIVERS_USB_DWC3_GADGET_H | ||
| 40 | #define __DRIVERS_USB_DWC3_GADGET_H | ||
| 41 | |||
| 42 | #include <linux/list.h> | ||
| 43 | #include <linux/usb/gadget.h> | ||
| 44 | #include "io.h" | ||
| 45 | |||
| 46 | struct dwc3; | ||
| 47 | #define to_dwc3_ep(ep) (container_of(ep, struct dwc3_ep, endpoint)) | ||
| 48 | #define gadget_to_dwc(g) (container_of(g, struct dwc3, gadget)) | ||
| 49 | |||
| 50 | /* DEPCFG parameter 1 */ | ||
| 51 | #define DWC3_DEPCFG_INT_NUM(n) ((n) << 0) | ||
| 52 | #define DWC3_DEPCFG_XFER_COMPLETE_EN (1 << 8) | ||
| 53 | #define DWC3_DEPCFG_XFER_IN_PROGRESS_EN (1 << 9) | ||
| 54 | #define DWC3_DEPCFG_XFER_NOT_READY_EN (1 << 10) | ||
| 55 | #define DWC3_DEPCFG_FIFO_ERROR_EN (1 << 11) | ||
| 56 | #define DWC3_DEPCFG_STREAM_EVENT_EN (1 << 13) | ||
| 57 | #define DWC3_DEPCFG_BINTERVAL_M1(n) ((n) << 16) | ||
| 58 | #define DWC3_DEPCFG_STREAM_CAPABLE (1 << 24) | ||
| 59 | #define DWC3_DEPCFG_EP_NUMBER(n) ((n) << 25) | ||
| 60 | #define DWC3_DEPCFG_BULK_BASED (1 << 30) | ||
| 61 | #define DWC3_DEPCFG_FIFO_BASED (1 << 31) | ||
| 62 | |||
| 63 | /* DEPCFG parameter 0 */ | ||
| 64 | #define DWC3_DEPCFG_EP_TYPE(n) ((n) << 1) | ||
| 65 | #define DWC3_DEPCFG_MAX_PACKET_SIZE(n) ((n) << 3) | ||
| 66 | #define DWC3_DEPCFG_FIFO_NUMBER(n) ((n) << 17) | ||
| 67 | #define DWC3_DEPCFG_BURST_SIZE(n) ((n) << 22) | ||
| 68 | #define DWC3_DEPCFG_DATA_SEQ_NUM(n) ((n) << 26) | ||
| 69 | #define DWC3_DEPCFG_IGN_SEQ_NUM (1 << 31) | ||
| 70 | |||
| 71 | /* DEPXFERCFG parameter 0 */ | ||
| 72 | #define DWC3_DEPXFERCFG_NUM_XFER_RES(n) ((n) & 0xffff) | ||
| 73 | |||
| 74 | struct dwc3_gadget_ep_cmd_params { | ||
| 75 | u32 param2; | ||
| 76 | u32 param1; | ||
| 77 | u32 param0; | ||
| 78 | }; | ||
| 79 | |||
| 80 | /* -------------------------------------------------------------------------- */ | ||
| 81 | |||
| 82 | struct dwc3_request { | ||
| 83 | struct usb_request request; | ||
| 84 | struct list_head list; | ||
| 85 | struct dwc3_ep *dep; | ||
| 86 | |||
| 87 | u8 epnum; | ||
| 88 | struct dwc3_trb_hw *trb; | ||
| 89 | dma_addr_t trb_dma; | ||
| 90 | |||
| 91 | unsigned direction:1; | ||
| 92 | unsigned mapped:1; | ||
| 93 | unsigned queued:1; | ||
| 94 | }; | ||
| 95 | #define to_dwc3_request(r) (container_of(r, struct dwc3_request, request)) | ||
| 96 | |||
| 97 | static inline struct dwc3_request *next_request(struct list_head *list) | ||
| 98 | { | ||
| 99 | if (list_empty(list)) | ||
| 100 | return NULL; | ||
| 101 | |||
| 102 | return list_first_entry(list, struct dwc3_request, list); | ||
| 103 | } | ||
| 104 | |||
| 105 | static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req) | ||
| 106 | { | ||
| 107 | struct dwc3_ep *dep = req->dep; | ||
| 108 | |||
| 109 | req->queued = true; | ||
| 110 | list_move_tail(&req->list, &dep->req_queued); | ||
| 111 | } | ||
| 112 | |||
| 113 | #if defined(CONFIG_USB_GADGET_DWC3) || defined(CONFIG_USB_GADGET_DWC3_MODULE) | ||
| 114 | int dwc3_gadget_init(struct dwc3 *dwc); | ||
| 115 | void dwc3_gadget_exit(struct dwc3 *dwc); | ||
| 116 | #else | ||
| 117 | static inline int dwc3_gadget_init(struct dwc3 *dwc) { return 0; } | ||
| 118 | static inline void dwc3_gadget_exit(struct dwc3 *dwc) { } | ||
| 119 | static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | ||
| 120 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params) | ||
| 121 | { | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | #endif | ||
| 125 | |||
| 126 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | ||
| 127 | int status); | ||
| 128 | |||
| 129 | void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event); | ||
| 130 | void dwc3_ep0_out_start(struct dwc3 *dwc); | ||
| 131 | int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, | ||
| 132 | gfp_t gfp_flags); | ||
| 133 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); | ||
| 134 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | ||
| 135 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); | ||
| 136 | void dwc3_map_buffer_to_dma(struct dwc3_request *req); | ||
| 137 | void dwc3_unmap_buffer_from_dma(struct dwc3_request *req); | ||
| 138 | |||
| 139 | /** | ||
| 140 | * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW | ||
| 141 | * @dwc: DesignWare USB3 Pointer | ||
| 142 | * @number: DWC endpoint number | ||
| 143 | * | ||
| 144 | * Caller should take care of locking | ||
| 145 | */ | ||
| 146 | static inline u32 dwc3_gadget_ep_get_transfer_index(struct dwc3 *dwc, u8 number) | ||
| 147 | { | ||
| 148 | u32 res_id; | ||
| 149 | |||
| 150 | res_id = dwc3_readl(dwc->regs, DWC3_DEPCMD(number)); | ||
| 151 | |||
| 152 | return DWC3_DEPCMD_GET_RSC_IDX(res_id); | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 156 | * dwc3_gadget_event_string - returns event name | ||
| 157 | * @event: the event code | ||
| 158 | */ | ||
| 159 | static inline const char *dwc3_gadget_event_string(u8 event) | ||
| 160 | { | ||
| 161 | switch (event) { | ||
| 162 | case DWC3_DEVICE_EVENT_DISCONNECT: | ||
| 163 | return "Disconnect"; | ||
| 164 | case DWC3_DEVICE_EVENT_RESET: | ||
| 165 | return "Reset"; | ||
| 166 | case DWC3_DEVICE_EVENT_CONNECT_DONE: | ||
| 167 | return "Connection Done"; | ||
| 168 | case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: | ||
| 169 | return "Link Status Change"; | ||
| 170 | case DWC3_DEVICE_EVENT_WAKEUP: | ||
| 171 | return "WakeUp"; | ||
| 172 | case DWC3_DEVICE_EVENT_EOPF: | ||
| 173 | return "End-Of-Frame"; | ||
| 174 | case DWC3_DEVICE_EVENT_SOF: | ||
| 175 | return "Start-Of-Frame"; | ||
| 176 | case DWC3_DEVICE_EVENT_ERRATIC_ERROR: | ||
| 177 | return "Erratic Error"; | ||
| 178 | case DWC3_DEVICE_EVENT_CMD_CMPL: | ||
| 179 | return "Command Complete"; | ||
| 180 | case DWC3_DEVICE_EVENT_OVERFLOW: | ||
| 181 | return "Overflow"; | ||
| 182 | } | ||
| 183 | |||
| 184 | return "UNKNOWN"; | ||
| 185 | } | ||
| 186 | |||
| 187 | /** | ||
| 188 | * dwc3_ep_event_string - returns event name | ||
| 189 | * @event: then event code | ||
| 190 | */ | ||
| 191 | static inline const char *dwc3_ep_event_string(u8 event) | ||
| 192 | { | ||
| 193 | switch (event) { | ||
| 194 | case DWC3_DEPEVT_XFERCOMPLETE: | ||
| 195 | return "Transfer Complete"; | ||
| 196 | case DWC3_DEPEVT_XFERINPROGRESS: | ||
| 197 | return "Transfer In-Progress"; | ||
| 198 | case DWC3_DEPEVT_XFERNOTREADY: | ||
| 199 | return "Transfer Not Ready"; | ||
| 200 | case DWC3_DEPEVT_RXTXFIFOEVT: | ||
| 201 | return "FIFO"; | ||
| 202 | case DWC3_DEPEVT_STREAMEVT: | ||
| 203 | return "Stream"; | ||
| 204 | case DWC3_DEPEVT_EPCMDCMPLT: | ||
| 205 | return "Endpoint Command Complete"; | ||
| 206 | } | ||
| 207 | |||
| 208 | return "UNKNOWN"; | ||
| 209 | } | ||
| 210 | |||
| 211 | #endif /* __DRIVERS_USB_DWC3_GADGET_H */ | ||
| @@ -0,0 +1,54 @@ | |||
| 1 | /** | ||
| 2 | * io.h - DesignWare USB3 DRD IO Header | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * | ||
| 6 | * Authors: Felipe Balbi <balbi@ti.com>, | ||
| 7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions, and the following disclaimer, | ||
| 14 | * without modification. | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in the | ||
| 17 | * documentation and/or other materials provided with the distribution. | ||
| 18 | * 3. The names of the above-listed copyright holders may not be used | ||
| 19 | * to endorse or promote products derived from this software without | ||
| 20 | * specific prior written permission. | ||
| 21 | * | ||
| 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
| 23 | * GNU General Public License ("GPL") version 2, as published by the Free | ||
| 24 | * Software Foundation. | ||
| 25 | * | ||
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
| 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 37 | */ | ||
| 38 | |||
| 39 | #ifndef __DRIVERS_USB_DWC3_IO_H | ||
| 40 | #define __DRIVERS_USB_DWC3_IO_H | ||
| 41 | |||
| 42 | #include <asm/io.h> | ||
| 43 | |||
| 44 | static inline u32 dwc3_readl(void __iomem *base, u32 offset) | ||
| 45 | { | ||
| 46 | return readl(base + offset); | ||
| 47 | } | ||
| 48 | |||
| 49 | static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value) | ||
| 50 | { | ||
| 51 | writel(value, base + offset); | ||
| 52 | } | ||
| 53 | |||
| 54 | #endif /* __DRIVERS_USB_DWC3_IO_H */ | ||
| @@ -96,6 +96,22 @@ config USB_GADGET_VBUS_DRAW · 95 unmodified lines | |||
| 96 | This value will be used except for system-specific gadget | 96 | This value will be used except for system-specific gadget |
| 97 | drivers that have more specific information. | 97 | drivers that have more specific information. |
| 98 | 98 | ||
| 99 | config USB_GADGET_STORAGE_NUM_BUFFERS | ||
| 100 | int "Number of storage pipeline buffers" | ||
| 101 | range 2 4 | ||
| 102 | default 2 | ||
| 103 | help | ||
| 104 | Usually 2 buffers are enough to establish a good buffering | ||
| 105 | pipeline. The number may be increased in order to compensate | ||
| 106 | for a bursty VFS behaviour. For instance there may be CPU wake up | ||
| 107 | latencies that makes the VFS to appear bursty in a system with | ||
| 108 | an CPU on-demand governor. Especially if DMA is doing IO to | ||
| 109 | offload the CPU. In this case the CPU will go into power | ||
| 110 | save often and spin up occasionally to move data within VFS. | ||
| 111 | If selecting USB_GADGET_DEBUG_FILES this value may be set by | ||
| 112 | a module parameter as well. | ||
| 113 | If unsure, say 2. | ||
| 114 | |||
| 99 | # | 115 | # |
| 100 | # USB Peripheral Controller Support | 116 | # USB Peripheral Controller Support |
| 101 | # | 117 | # |
| @@ -255,12 +271,11 @@ config USB_S3C_HSOTG · 153 unmodified lines | |||
| 255 | integrated into the S3C64XX series SoC. | 271 | integrated into the S3C64XX series SoC. |
| 256 | 272 | ||
| 257 | config USB_IMX | 273 | config USB_IMX |
| 258 | tristate "Freescale IMX USB Peripheral Controller" | 274 | tristate "Freescale i.MX1 USB Peripheral Controller" |
| 259 | depends on ARCH_MX1 | 275 | depends on ARCH_MXC |
| 260 | help | 276 | help |
| 261 | Freescale's IMX series include an integrated full speed | 277 | Freescale's i.MX1 includes an integrated full speed |
| 262 | USB 1.1 device controller. The controller in the IMX series | 278 | USB 1.1 device controller. |
| 263 | is register-compatible. | ||
| 264 | 279 | ||
| 265 | It has Six fixed-function endpoints, as well as endpoint | 280 | It has Six fixed-function endpoints, as well as endpoint |
| 266 | zero (for control transfers). | 281 | zero (for control transfers). |
| @@ -303,6 +318,18 @@ config USB_PXA_U2O · 36 unmodified lines | |||
| 303 | PXA9xx Processor series include a high speed USB2.0 device | 318 | PXA9xx Processor series include a high speed USB2.0 device |
| 304 | controller, which support high speed and full speed USB peripheral. | 319 | controller, which support high speed and full speed USB peripheral. |
| 305 | 320 | ||
| 321 | config USB_GADGET_DWC3 | ||
| 322 | tristate "DesignWare USB3.0 (DRD) Controller" | ||
| 323 | depends on USB_DWC3 | ||
| 324 | select USB_GADGET_DUALSPEED | ||
| 325 | select USB_GADGET_SUPERSPEED | ||
| 326 | help | ||
| 327 | DesignWare USB3.0 controller is a SuperSpeed USB3.0 Controller | ||
| 328 | which can be configured for peripheral-only, host-only, hub-only | ||
| 329 | and Dual-Role operation. This Controller was first integrated into | ||
| 330 | the OMAP5 series of processors. More information about the OMAP5 | ||
| 331 | version of this controller, refer to http://www.ti.com/omap5. | ||
| 332 | |||
| 306 | # | 333 | # |
| 307 | # Controllers available in both integrated and discrete versions | 334 | # Controllers available in both integrated and discrete versions |
| 308 | # | 335 | # |
| @@ -846,6 +873,16 @@ config USB_G_NOKIA · 537 unmodified lines | |||
| 846 | It's only really useful for N900 hardware. If you're building | 873 | It's only really useful for N900 hardware. If you're building |
| 847 | a kernel for N900, say Y or M here. If unsure, say N. | 874 | a kernel for N900, say Y or M here. If unsure, say N. |
| 848 | 875 | ||
| 876 | config USB_G_ACM_MS | ||
| 877 | tristate "CDC Composite Device (ACM and mass storage)" | ||
| 878 | depends on BLOCK | ||
| 879 | help | ||
| 880 | This driver provides two functions in one configuration: | ||
| 881 | a mass storage, and a CDC ACM (serial port) link. | ||
| 882 | |||
| 883 | Say "y" to link the driver statically, or "m" to build a | ||
| 884 | dynamically linked module called "g_acm_ms". | ||
| 885 | |||
| 849 | config USB_G_MULTI | 886 | config USB_G_MULTI |
| 850 | tristate "Multifunction Composite Gadget (EXPERIMENTAL)" | 887 | tristate "Multifunction Composite Gadget (EXPERIMENTAL)" |
| 851 | depends on BLOCK && NET | 888 | depends on BLOCK && NET |
| @@ -28,7 +28,7 @@ obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o · 27 unmodified lines | |||
| 28 | obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o | 28 | obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o |
| 29 | obj-$(CONFIG_USB_EG20T) += pch_udc.o | 29 | obj-$(CONFIG_USB_EG20T) += pch_udc.o |
| 30 | obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o | 30 | obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o |
| 31 | mv_udc-y := mv_udc_core.o mv_udc_phy.o | 31 | mv_udc-y := mv_udc_core.o |
| 32 | obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o | 32 | obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o |
| 33 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o | 33 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o |
| 34 | 34 | ||
| @@ -51,6 +51,7 @@ g_dbgp-y := dbgp.o · 16 unmodified lines | |||
| 51 | g_nokia-y := nokia.o | 51 | g_nokia-y := nokia.o |
| 52 | g_webcam-y := webcam.o | 52 | g_webcam-y := webcam.o |
| 53 | g_ncm-y := ncm.o | 53 | g_ncm-y := ncm.o |
| 54 | g_acm_ms-y := acm_ms.o | ||
| 54 | 55 | ||
| 55 | obj-$(CONFIG_USB_ZERO) += g_zero.o | 56 | obj-$(CONFIG_USB_ZERO) += g_zero.o |
| 56 | obj-$(CONFIG_USB_AUDIO) += g_audio.o | 57 | obj-$(CONFIG_USB_AUDIO) += g_audio.o |
| @@ -69,3 +70,4 @@ obj-$(CONFIG_USB_G_MULTI) += g_multi.o · 12 unmodified lines | |||
| 69 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o | 70 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o |
| 70 | obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o | 71 | obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o |
| 71 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o | 72 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o |
| 73 | obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o | ||
| @@ -0,0 +1,256 @@ | |||
| 1 | /* | ||
| 2 | * acm_ms.c -- Composite driver, with ACM and mass storage support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 David Brownell | ||
| 5 | * Copyright (C) 2008 Nokia Corporation | ||
| 6 | * Author: David Brownell | ||
| 7 | * Modified: Klaus Schwarzkopf <schwarzkopf@sensortherm.de> | ||
| 8 | * | ||
| 9 | * Heavily based on multi.c and cdc2.c | ||
| 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/kernel.h> | ||
| 18 | #include <linux/utsname.h> | ||
| 19 | |||
| 20 | #include "u_serial.h" | ||
| 21 | |||
| 22 | #define DRIVER_DESC "Composite Gadget (ACM + MS)" | ||
| 23 | #define DRIVER_VERSION "2011/10/10" | ||
| 24 | |||
| 25 | /*-------------------------------------------------------------------------*/ | ||
| 26 | |||
| 27 | /* | ||
| 28 | * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! | ||
| 29 | * Instead: allocate your own, using normal USB-IF procedures. | ||
| 30 | */ | ||
| 31 | #define ACM_MS_VENDOR_NUM 0x1d6b /* Linux Foundation */ | ||
| 32 | #define ACM_MS_PRODUCT_NUM 0x0106 /* Composite Gadget: ACM + MS*/ | ||
| 33 | |||
| 34 | /*-------------------------------------------------------------------------*/ | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Kbuild is not very cooperative with respect to linking separately | ||
| 38 | * compiled library objects into one module. So for now we won't use | ||
| 39 | * separate compilation ... ensuring init/exit sections work to shrink | ||
| 40 | * the runtime footprint, and giving us at least some parts of what | ||
| 41 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
| 42 | */ | ||
| 43 | |||
| 44 | #include "composite.c" | ||
| 45 | #include "usbstring.c" | ||
| 46 | #include "config.c" | ||
| 47 | #include "epautoconf.c" | ||
| 48 | #include "u_serial.c" | ||
| 49 | #include "f_acm.c" | ||
| 50 | #include "f_mass_storage.c" | ||
| 51 | |||
| 52 | /*-------------------------------------------------------------------------*/ | ||
| 53 | |||
| 54 | static struct usb_device_descriptor device_desc = { | ||
| 55 | .bLength = sizeof device_desc, | ||
| 56 | .bDescriptorType = USB_DT_DEVICE, | ||
| 57 | |||
| 58 | .bcdUSB = cpu_to_le16(0x0200), | ||
| 59 | |||
| 60 | .bDeviceClass = USB_CLASS_MISC /* 0xEF */, | ||
| 61 | .bDeviceSubClass = 2, | ||
| 62 | .bDeviceProtocol = 1, | ||
| 63 | |||
| 64 | /* .bMaxPacketSize0 = f(hardware) */ | ||
| 65 | |||
| 66 | /* Vendor and product id can be overridden by module parameters. */ | ||
| 67 | .idVendor = cpu_to_le16(ACM_MS_VENDOR_NUM), | ||
| 68 | .idProduct = cpu_to_le16(ACM_MS_PRODUCT_NUM), | ||
| 69 | /* .bcdDevice = f(hardware) */ | ||
| 70 | /* .iManufacturer = DYNAMIC */ | ||
| 71 | /* .iProduct = DYNAMIC */ | ||
| 72 | /* NO SERIAL NUMBER */ | ||
| 73 | /*.bNumConfigurations = DYNAMIC*/ | ||
| 74 | }; | ||
| 75 | |||
| 76 | static struct usb_otg_descriptor otg_descriptor = { | ||
| 77 | .bLength = sizeof otg_descriptor, | ||
| 78 | .bDescriptorType = USB_DT_OTG, | ||
| 79 | |||
| 80 | /* | ||
| 81 | * REVISIT SRP-only hardware is possible, although | ||
| 82 | * it would not be called "OTG" ... | ||
| 83 | */ | ||
| 84 | .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static const struct usb_descriptor_header *otg_desc[] = { | ||
| 88 | (struct usb_descriptor_header *) &otg_descriptor, | ||
| 89 | NULL, | ||
| 90 | }; | ||
| 91 | |||
| 92 | |||
| 93 | /* string IDs are assigned dynamically */ | ||
| 94 | |||
| 95 | #define STRING_MANUFACTURER_IDX 0 | ||
| 96 | #define STRING_PRODUCT_IDX 1 | ||
| 97 | |||
| 98 | static char manufacturer[50]; | ||
| 99 | |||
| 100 | static struct usb_string strings_dev[] = { | ||
| 101 | [STRING_MANUFACTURER_IDX].s = manufacturer, | ||
| 102 | [STRING_PRODUCT_IDX].s = DRIVER_DESC, | ||
| 103 | { } /* end of list */ | ||
| 104 | }; | ||
| 105 | |||
| 106 | static struct usb_gadget_strings stringtab_dev = { | ||
| 107 | .language = 0x0409, /* en-us */ | ||
| 108 | .strings = strings_dev, | ||
| 109 | }; | ||
| 110 | |||
| 111 | static struct usb_gadget_strings *dev_strings[] = { | ||
| 112 | &stringtab_dev, | ||
| 113 | NULL, | ||
| 114 | }; | ||
| 115 | |||
| 116 | /****************************** Configurations ******************************/ | ||
| 117 | |||
| 118 | static struct fsg_module_parameters fsg_mod_data = { .stall = 1 }; | ||
| 119 | FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); | ||
| 120 | |||
| 121 | static struct fsg_common fsg_common; | ||
| 122 | |||
| 123 | /*-------------------------------------------------------------------------*/ | ||
| 124 | |||
| 125 | /* | ||
| 126 | * We _always_ have both ACM and mass storage functions. | ||
| 127 | */ | ||
| 128 | static int __init acm_ms_do_config(struct usb_configuration *c) | ||
| 129 | { | ||
| 130 | int status; | ||
| 131 | |||
| 132 | if (gadget_is_otg(c->cdev->gadget)) { | ||
| 133 | c->descriptors = otg_desc; | ||
| 134 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
| 135 | } | ||
| 136 | |||
| 137 | |||
| 138 | status = acm_bind_config(c, 0); | ||
| 139 | if (status < 0) | ||
| 140 | return status; | ||
| 141 | |||
| 142 | status = fsg_bind_config(c->cdev, c, &fsg_common); | ||
| 143 | if (status < 0) | ||
| 144 | return status; | ||
| 145 | |||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | static struct usb_configuration acm_ms_config_driver = { | ||
| 150 | .label = DRIVER_DESC, | ||
| 151 | .bConfigurationValue = 1, | ||
| 152 | /* .iConfiguration = DYNAMIC */ | ||
| 153 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | ||
| 154 | }; | ||
| 155 | |||
| 156 | /*-------------------------------------------------------------------------*/ | ||
| 157 | |||
| 158 | static int __init acm_ms_bind(struct usb_composite_dev *cdev) | ||
| 159 | { | ||
| 160 | int gcnum; | ||
| 161 | struct usb_gadget *gadget = cdev->gadget; | ||
| 162 | int status; | ||
| 163 | void *retp; | ||
| 164 | |||
| 165 | /* set up serial link layer */ | ||
| 166 | status = gserial_setup(cdev->gadget, 1); | ||
| 167 | if (status < 0) | ||
| 168 | return status; | ||
| 169 | |||
| 170 | /* set up mass storage function */ | ||
| 171 | retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data); | ||
| 172 | if (IS_ERR(retp)) { | ||
| 173 | status = PTR_ERR(retp); | ||
| 174 | goto fail0; | ||
| 175 | } | ||
| 176 | |||
| 177 | /* set bcdDevice */ | ||
| 178 | gcnum = usb_gadget_controller_number(gadget); | ||
| 179 | if (gcnum >= 0) { | ||
| 180 | device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); | ||
| 181 | } else { | ||
| 182 | WARNING(cdev, "controller '%s' not recognized; trying %s\n", | ||
| 183 | gadget->name, | ||
| 184 | acm_ms_config_driver.label); | ||
| 185 | device_desc.bcdDevice = | ||
| 186 | cpu_to_le16(0x0300 | 0x0099); | ||
| 187 | } | ||
| 188 | |||
| 189 | /* | ||
| 190 | * Allocate string descriptor numbers ... note that string | ||
| 191 | * contents can be overridden by the composite_dev glue. | ||
| 192 | */ | ||
| 193 | |||
| 194 | /* device descriptor strings: manufacturer, product */ | ||
| 195 | snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", | ||
| 196 | init_utsname()->sysname, init_utsname()->release, | ||
| 197 | gadget->name); | ||
| 198 | status = usb_string_id(cdev); | ||
| 199 | if (status < 0) | ||
| 200 | goto fail1; | ||
| 201 | strings_dev[STRING_MANUFACTURER_IDX].id = status; | ||
| 202 | device_desc.iManufacturer = status; | ||
| 203 | |||
| 204 | status = usb_string_id(cdev); | ||
| 205 | if (status < 0) | ||
| 206 | goto fail1; | ||
| 207 | strings_dev[STRING_PRODUCT_IDX].id = status; | ||
| 208 | device_desc.iProduct = status; | ||
| 209 | |||
| 210 | /* register our configuration */ | ||
| 211 | status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config); | ||
| 212 | if (status < 0) | ||
| 213 | goto fail1; | ||
| 214 | |||
| 215 | dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", | ||
| 216 | DRIVER_DESC); | ||
| 217 | fsg_common_put(&fsg_common); | ||
| 218 | return 0; | ||
| 219 | |||
| 220 | /* error recovery */ | ||
| 221 | fail1: | ||
| 222 | fsg_common_put(&fsg_common); | ||
| 223 | fail0: | ||
| 224 | gserial_cleanup(); | ||
| 225 | return status; | ||
| 226 | } | ||
| 227 | |||
| 228 | static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) | ||
| 229 | { | ||
| 230 | gserial_cleanup(); | ||
| 231 | |||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | static struct usb_composite_driver acm_ms_driver = { | ||
| 236 | .name = "g_acm_ms", | ||
| 237 | .dev = &device_desc, | ||
| 238 | .strings = dev_strings, | ||
| 239 | .unbind = __exit_p(acm_ms_unbind), | ||
| 240 | }; | ||
| 241 | |||
| 242 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 243 | MODULE_AUTHOR("Klaus Schwarzkopf <schwarzkopf@sensortherm.de>"); | ||
| 244 | MODULE_LICENSE("GPL v2"); | ||
| 245 | |||
| 246 | static int __init init(void) | ||
| 247 | { | ||
| 248 | return usb_composite_probe(&acm_ms_driver, acm_ms_bind); | ||
| 249 | } | ||
| 250 | module_init(init); | ||
| 251 | |||
| 252 | static void __exit cleanup(void) | ||
| 253 | { | ||
| 254 | usb_composite_unregister(&acm_ms_driver); | ||
| 255 | } | ||
| 256 | module_exit(cleanup); | ||
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | /* | 13 | /* |
| @@ -354,7 +345,7 @@ udc_ep_enable(struct usb_ep *usbep, const struct usb_endpoint_descriptor *desc) · 331 unmodified lines | |||
| 354 | writel(tmp, &dev->ep[ep->num].regs->ctl); | 345 | writel(tmp, &dev->ep[ep->num].regs->ctl); |
| 355 | 346 | ||
| 356 | /* set max packet size */ | 347 | /* set max packet size */ |
| 357 | maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 348 | maxpacket = usb_endpoint_maxp(desc); |
| 358 | tmp = readl(&dev->ep[ep->num].regs->bufout_maxpkt); | 349 | tmp = readl(&dev->ep[ep->num].regs->bufout_maxpkt); |
| 359 | tmp = AMD_ADDBITS(tmp, maxpacket, UDC_EP_MAX_PKT_SIZE); | 350 | tmp = AMD_ADDBITS(tmp, maxpacket, UDC_EP_MAX_PKT_SIZE); |
| 360 | ep->ep.maxpacket = maxpacket; | 351 | ep->ep.maxpacket = maxpacket; |
| @@ -3014,13 +3005,8 @@ __acquires(dev->lock) · 2653 unmodified lines | |||
| 3014 | 3005 | ||
| 3015 | /* link up all endpoints */ | 3006 | /* link up all endpoints */ |
| 3016 | udc_setup_endpoints(dev); | 3007 | udc_setup_endpoints(dev); |
| 3017 | if (dev->gadget.speed == USB_SPEED_HIGH) { | 3008 | dev_info(&dev->pdev->dev, "Connect: %s\n", |
| 3018 | dev_info(&dev->pdev->dev, "Connect: speed = %s\n", | 3009 | usb_speed_string(dev->gadget.speed)); |
| 3019 | "high"); | ||
| 3020 | } else if (dev->gadget.speed == USB_SPEED_FULL) { | ||
| 3021 | dev_info(&dev->pdev->dev, "Connect: speed = %s\n", | ||
| 3022 | "full"); | ||
| 3023 | } | ||
| 3024 | 3010 | ||
| 3025 | /* init ep 0 */ | 3011 | /* init ep 0 */ |
| 3026 | activate_control_endpoints(dev); | 3012 | activate_control_endpoints(dev); |
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | #ifndef AMD5536UDC_H | 13 | #ifndef AMD5536UDC_H |
| @@ -9,16 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the | ||
| 20 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 21 | * Boston, MA 02111-1307, USA. | ||
| 22 | */ | 12 | */ |
| 23 | 13 | ||
| 24 | #undef VERBOSE_DEBUG | 14 | #undef VERBOSE_DEBUG |
| @@ -460,7 +450,7 @@ static void nuke(struct at91_ep *ep, int status) · 435 unmodified lines | |||
| 460 | { | 450 | { |
| 461 | struct at91_request *req; | 451 | struct at91_request *req; |
| 462 | 452 | ||
| 463 | // terminer chaque requete dans la queue | 453 | /* terminate any request in the queue */ |
| 464 | ep->stopped = 1; | 454 | ep->stopped = 1; |
| 465 | if (list_empty(&ep->queue)) | 455 | if (list_empty(&ep->queue)) |
| 466 | return; | 456 | return; |
| @@ -487,7 +477,7 @@ static int at91_ep_enable(struct usb_ep *_ep, · 20 unmodified lines | |||
| 487 | || !desc || ep->desc | 477 | || !desc || ep->desc |
| 488 | || _ep->name == ep0name | 478 | || _ep->name == ep0name |
| 489 | || desc->bDescriptorType != USB_DT_ENDPOINT | 479 | || desc->bDescriptorType != USB_DT_ENDPOINT |
| 490 | || (maxpacket = le16_to_cpu(desc->wMaxPacketSize)) == 0 | 480 | || (maxpacket = usb_endpoint_maxp(desc)) == 0 |
| 491 | || maxpacket > ep->maxpacket) { | 481 | || maxpacket > ep->maxpacket) { |
| 492 | DBG("bad ep or descriptor\n"); | 482 | DBG("bad ep or descriptor\n"); |
| 493 | return -EINVAL; | 483 | return -EINVAL; |
| @@ -788,7 +778,7 @@ static const struct usb_ep_ops at91_ep_ops = { · 294 unmodified lines | |||
| 788 | .queue = at91_ep_queue, | 778 | .queue = at91_ep_queue, |
| 789 | .dequeue = at91_ep_dequeue, | 779 | .dequeue = at91_ep_dequeue, |
| 790 | .set_halt = at91_ep_set_halt, | 780 | .set_halt = at91_ep_set_halt, |
| 791 | // there's only imprecise fifo status reporting | 781 | /* there's only imprecise fifo status reporting */ |
| 792 | }; | 782 | }; |
| 793 | 783 | ||
| 794 | /*-------------------------------------------------------------------------*/ | 784 | /*-------------------------------------------------------------------------*/ |
| @@ -846,7 +836,7 @@ static void udc_reinit(struct at91_udc *udc) · 51 unmodified lines | |||
| 846 | ep->fifo_bank = 0; | 836 | ep->fifo_bank = 0; |
| 847 | ep->ep.maxpacket = ep->maxpacket; | 837 | ep->ep.maxpacket = ep->maxpacket; |
| 848 | ep->creg = (void __iomem *) udc->udp_baseaddr + AT91_UDP_CSR(i); | 838 | ep->creg = (void __iomem *) udc->udp_baseaddr + AT91_UDP_CSR(i); |
| 849 | // initialiser une queue par endpoint | 839 | /* initialize one queue per endpoint */ |
| 850 | INIT_LIST_HEAD(&ep->queue); | 840 | INIT_LIST_HEAD(&ep->queue); |
| 851 | } | 841 | } |
| 852 | } | 842 | } |
| @@ -952,7 +942,7 @@ static int at91_vbus_session(struct usb_gadget *gadget, int is_active) · 99 unmodified lines | |||
| 952 | struct at91_udc *udc = to_udc(gadget); | 942 | struct at91_udc *udc = to_udc(gadget); |
| 953 | unsigned long flags; | 943 | unsigned long flags; |
| 954 | 944 | ||
| 955 | // VDBG("vbus %s\n", is_active ? "on" : "off"); | 945 | /* VDBG("vbus %s\n", is_active ? "on" : "off"); */ |
| 956 | spin_lock_irqsave(&udc->lock, flags); | 946 | spin_lock_irqsave(&udc->lock, flags); |
| 957 | udc->vbus = (is_active != 0); | 947 | udc->vbus = (is_active != 0); |
| 958 | if (udc->driver) | 948 | if (udc->driver) |
| @@ -1003,7 +993,7 @@ static const struct usb_gadget_ops at91_udc_ops = { · 44 unmodified lines | |||
| 1003 | * VBUS-powered devices may also also want to support bigger | 993 | * VBUS-powered devices may also also want to support bigger |
| 1004 | * power budgets after an appropriate SET_CONFIGURATION. | 994 | * power budgets after an appropriate SET_CONFIGURATION. |
| 1005 | */ | 995 | */ |
| 1006 | // .vbus_power = at91_vbus_power, | 996 | /* .vbus_power = at91_vbus_power, */ |
| 1007 | }; | 997 | }; |
| 1008 | 998 | ||
| 1009 | /*-------------------------------------------------------------------------*/ | 999 | /*-------------------------------------------------------------------------*/ |
| @@ -1072,7 +1062,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) · 62 unmodified lines | |||
| 1072 | ep->is_in = 0; | 1062 | ep->is_in = 0; |
| 1073 | } | 1063 | } |
| 1074 | } else { | 1064 | } else { |
| 1075 | // REVISIT this happens sometimes under load; why?? | 1065 | /* REVISIT this happens sometimes under load; why?? */ |
| 1076 | ERR("SETUP len %d, csr %08x\n", rxcount, csr); | 1066 | ERR("SETUP len %d, csr %08x\n", rxcount, csr); |
| 1077 | status = -EINVAL; | 1067 | status = -EINVAL; |
| 1078 | } | 1068 | } |
| @@ -1451,7 +1441,7 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) · 372 unmodified lines | |||
| 1451 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXSUSP); | 1441 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXSUSP); |
| 1452 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXRSM); | 1442 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXRSM); |
| 1453 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXSUSP); | 1443 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXSUSP); |
| 1454 | // VDBG("bus suspend\n"); | 1444 | /* VDBG("bus suspend\n"); */ |
| 1455 | if (udc->suspended) | 1445 | if (udc->suspended) |
| 1456 | continue; | 1446 | continue; |
| 1457 | udc->suspended = 1; | 1447 | udc->suspended = 1; |
| @@ -1473,7 +1463,7 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) · 15 unmodified lines | |||
| 1473 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); | 1463 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); |
| 1474 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXSUSP); | 1464 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXSUSP); |
| 1475 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); | 1465 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); |
| 1476 | // VDBG("bus resume\n"); | 1466 | /* VDBG("bus resume\n"); */ |
| 1477 | if (!udc->suspended) | 1467 | if (!udc->suspended) |
| 1478 | continue; | 1468 | continue; |
| 1479 | udc->suspended = 0; | 1469 | udc->suspended = 0; |
| @@ -1820,7 +1810,7 @@ static int __init at91udc_probe(struct platform_device *pdev) · 340 unmodified lines | |||
| 1820 | /* request UDC and maybe VBUS irqs */ | 1810 | /* request UDC and maybe VBUS irqs */ |
| 1821 | udc->udp_irq = platform_get_irq(pdev, 0); | 1811 | udc->udp_irq = platform_get_irq(pdev, 0); |
| 1822 | retval = request_irq(udc->udp_irq, at91_udc_irq, | 1812 | retval = request_irq(udc->udp_irq, at91_udc_irq, |
| 1823 | IRQF_DISABLED, driver_name, udc); | 1813 | 0, driver_name, udc); |
| 1824 | if (retval < 0) { | 1814 | if (retval < 0) { |
| 1825 | DBG("request irq %d failed\n", udc->udp_irq); | 1815 | DBG("request irq %d failed\n", udc->udp_irq); |
| 1826 | goto fail1; | 1816 | goto fail1; |
| @@ -1848,7 +1838,7 @@ static int __init at91udc_probe(struct platform_device *pdev) · 21 unmodified lines | |||
| 1848 | jiffies + VBUS_POLL_TIMEOUT); | 1838 | jiffies + VBUS_POLL_TIMEOUT); |
| 1849 | } else { | 1839 | } else { |
| 1850 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, | 1840 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, |
| 1851 | IRQF_DISABLED, driver_name, udc)) { | 1841 | 0, driver_name, udc)) { |
| 1852 | DBG("request vbus irq %d failed\n", | 1842 | DBG("request vbus irq %d failed\n", |
| 1853 | udc->board.vbus_pin); | 1843 | udc->board.vbus_pin); |
| 1854 | retval = -EBUSY; | 1844 | retval = -EBUSY; |
| @@ -7,16 +7,6 @@ · 6 unmodified lines | |||
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the | ||
| 18 | * Free Software Foundation, Inc., | ||
| 19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 20 | */ | 10 | */ |
| 21 | 11 | ||
| 22 | #ifndef AT91_UDC_H | 12 | #ifndef AT91_UDC_H |
| @@ -527,7 +527,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) · 526 unmodified lines | |||
| 527 | 527 | ||
| 528 | DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc); | 528 | DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc); |
| 529 | 529 | ||
| 530 | maxpacket = le16_to_cpu(desc->wMaxPacketSize) & 0x7ff; | 530 | maxpacket = usb_endpoint_maxp(desc) & 0x7ff; |
| 531 | 531 | ||
| 532 | if (((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != ep->index) | 532 | if (((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != ep->index) |
| 533 | || ep->index == 0 | 533 | || ep->index == 0 |
| @@ -571,7 +571,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) · 37 unmodified lines | |||
| 571 | * Bits 11:12 specify number of _additional_ | 571 | * Bits 11:12 specify number of _additional_ |
| 572 | * transactions per microframe. | 572 | * transactions per microframe. |
| 573 | */ | 573 | */ |
| 574 | nr_trans = ((le16_to_cpu(desc->wMaxPacketSize) >> 11) & 3) + 1; | 574 | nr_trans = ((usb_endpoint_maxp(desc) >> 11) & 3) + 1; |
| 575 | if (nr_trans > 3) | 575 | if (nr_trans > 3) |
| 576 | return -EINVAL; | 576 | return -EINVAL; |
| 577 | 577 | ||
| @@ -1718,13 +1718,12 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) · 1140 unmodified lines | |||
| 1718 | spin_lock(&udc->lock); | 1718 | spin_lock(&udc->lock); |
| 1719 | } | 1719 | } |
| 1720 | 1720 | ||
| 1721 | if (status & USBA_HIGH_SPEED) { | 1721 | if (status & USBA_HIGH_SPEED) |
| 1722 | DBG(DBG_BUS, "High-speed bus reset detected\n"); | ||
| 1723 | udc->gadget.speed = USB_SPEED_HIGH; | 1722 | udc->gadget.speed = USB_SPEED_HIGH; |
| 1724 | } else { | 1723 | else |
| 1725 | DBG(DBG_BUS, "Full-speed bus reset detected\n"); | ||
| 1726 | udc->gadget.speed = USB_SPEED_FULL; | 1724 | udc->gadget.speed = USB_SPEED_FULL; |
| 1727 | } | 1725 | DBG(DBG_BUS, "%s bus reset detected\n", |
| 1726 | usb_speed_string(udc->gadget.speed)); | ||
| 1728 | 1727 | ||
| 1729 | ep0 = &usba_ep[0]; | 1728 | ep0 = &usba_ep[0]; |
| 1730 | ep0->desc = &usba_ep0_desc; | 1729 | ep0->desc = &usba_ep0_desc; |
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| @@ -3,17 +3,6 @@ · 2 unmodified lines | |||
| 3 | * This program is free software; you can redistribute it and/or modify | 3 | * This program is free software; you can redistribute it and/or modify |
| 4 | * it under the terms of the GNU General Public License version 2 and | 4 | * it under the terms of the GNU General Public License version 2 and |
| 5 | * only version 2 as published by the Free Software Foundation. | 5 | * only version 2 as published by the Free Software Foundation. |
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 15 | * 02110-1301, USA. | ||
| 16 | * | ||
| 17 | */ | 6 | */ |
| 18 | 7 | ||
| 19 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| @@ -2101,7 +2101,7 @@ static int ep_enable(struct usb_ep *ep, · 2100 unmodified lines | |||
| 2101 | mEp->num = usb_endpoint_num(desc); | 2101 | mEp->num = usb_endpoint_num(desc); |
| 2102 | mEp->type = usb_endpoint_type(desc); | 2102 | mEp->type = usb_endpoint_type(desc); |
| 2103 | 2103 | ||
| 2104 | mEp->ep.maxpacket = __constant_le16_to_cpu(desc->wMaxPacketSize); | 2104 | mEp->ep.maxpacket = usb_endpoint_maxp(desc); |
| 2105 | 2105 | ||
| 2106 | dbg_event(_usb_addr(mEp), "ENABLE", 0); | 2106 | dbg_event(_usb_addr(mEp), "ENABLE", 0); |
| 2107 | 2107 | ||
| @@ -7,15 +7,6 @@ · 6 unmodified lines | |||
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | 10 | */ |
| 20 | 11 | ||
| 21 | /* #define VERBOSE_DEBUG */ | 12 | /* #define VERBOSE_DEBUG */ |
| @@ -164,7 +155,7 @@ int config_ep_by_speed(struct usb_gadget *g, · 142 unmodified lines | |||
| 164 | 155 | ||
| 165 | ep_found: | 156 | ep_found: |
| 166 | /* commit results */ | 157 | /* commit results */ |
| 167 | _ep->maxpacket = le16_to_cpu(chosen_desc->wMaxPacketSize); | 158 | _ep->maxpacket = usb_endpoint_maxp(chosen_desc); |
| 168 | _ep->desc = chosen_desc; | 159 | _ep->desc = chosen_desc; |
| 169 | _ep->comp_desc = NULL; | 160 | _ep->comp_desc = NULL; |
| 170 | _ep->maxburst = 0; | 161 | _ep->maxburst = 0; |
| @@ -551,9 +542,9 @@ static int bos_desc(struct usb_composite_dev *cdev) · 380 unmodified lines | |||
| 551 | if (cdev->gadget->ops->get_config_params) | 542 | if (cdev->gadget->ops->get_config_params) |
| 552 | cdev->gadget->ops->get_config_params(&dcd_config_params); | 543 | cdev->gadget->ops->get_config_params(&dcd_config_params); |
| 553 | else { | 544 | else { |
| 554 | dcd_config_params.bU1devExitLat = USB_DEFULT_U1_DEV_EXIT_LAT; | 545 | dcd_config_params.bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT; |
| 555 | dcd_config_params.bU2DevExitLat = | 546 | dcd_config_params.bU2DevExitLat = |
| 556 | cpu_to_le16(USB_DEFULT_U2_DEV_EXIT_LAT); | 547 | cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT); |
| 557 | } | 548 | } |
| 558 | ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat; | 549 | ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat; |
| 559 | ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat; | 550 | ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat; |
| @@ -626,25 +617,9 @@ static int set_config(struct usb_composite_dev *cdev, · 66 unmodified lines | |||
| 626 | result = 0; | 617 | result = 0; |
| 627 | } | 618 | } |
| 628 | 619 | ||
| 629 | INFO(cdev, "%s speed config #%d: %s\n", | 620 | INFO(cdev, "%s config #%d: %s\n", |
| 630 | ({ char *speed; | 621 | usb_speed_string(gadget->speed), |
| 631 | switch (gadget->speed) { | 622 | number, c ? c->label : "unconfigured"); |
| 632 | case USB_SPEED_LOW: | ||
| 633 | speed = "low"; | ||
| 634 | break; | ||
| 635 | case USB_SPEED_FULL: | ||
| 636 | speed = "full"; | ||
| 637 | break; | ||
| 638 | case USB_SPEED_HIGH: | ||
| 639 | speed = "high"; | ||
| 640 | break; | ||
| 641 | case USB_SPEED_SUPER: | ||
| 642 | speed = "super"; | ||
| 643 | break; | ||
| 644 | default: | ||
| 645 | speed = "?"; | ||
| 646 | break; | ||
| 647 | } ; speed; }), number, c ? c->label : "unconfigured"); | ||
| 648 | 623 | ||
| 649 | if (!c) | 624 | if (!c) |
| 650 | goto done; | 625 | goto done; |
| @@ -7,15 +7,6 @@ · 6 unmodified lines | |||
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | 10 | */ |
| 20 | 11 | ||
| 21 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
| @@ -4,7 +4,6 @@ · 3 unmodified lines | |||
| 4 | * Copyright (C) 2010 Stephane Duverger | 4 | * Copyright (C) 2010 Stephane Duverger |
| 5 | * | 5 | * |
| 6 | * Released under the GPLv2. | 6 | * Released under the GPLv2. |
| 7 | * | ||
| 8 | */ | 7 | */ |
| 9 | 8 | ||
| 10 | /* verbose messages */ | 9 | /* verbose messages */ |
| @@ -10,15 +10,6 @@ · 9 unmodified lines | |||
| 10 | * it under the terms of the GNU General Public License as published by | 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 | 11 | * the Free Software Foundation; either version 2 of the License, or |
| 12 | * (at your option) any later version. | 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 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | */ | 13 | */ |
| 23 | 14 | ||
| 24 | 15 | ||
| @@ -439,7 +430,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) · 414 unmodified lines | |||
| 439 | * maximum packet size. | 430 | * maximum packet size. |
| 440 | * For SS devices the wMaxPacketSize is limited by 1024. | 431 | * For SS devices the wMaxPacketSize is limited by 1024. |
| 441 | */ | 432 | */ |
| 442 | max = le16_to_cpu(desc->wMaxPacketSize) & 0x7ff; | 433 | max = usb_endpoint_maxp(desc) & 0x7ff; |
| 443 | 434 | ||
| 444 | /* drivers must not request bad settings, since lower levels | 435 | /* drivers must not request bad settings, since lower levels |
| 445 | * (hardware or its drivers) may not check. some endpoints | 436 | * (hardware or its drivers) may not check. some endpoints |
| @@ -1277,7 +1268,7 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) · 831 unmodified lines | |||
| 1277 | int tmp; | 1268 | int tmp; |
| 1278 | 1269 | ||
| 1279 | /* high bandwidth mode */ | 1270 | /* high bandwidth mode */ |
| 1280 | tmp = le16_to_cpu(ep->desc->wMaxPacketSize); | 1271 | tmp = usb_endpoint_maxp(ep->desc); |
| 1281 | tmp = (tmp >> 11) & 0x03; | 1272 | tmp = (tmp >> 11) & 0x03; |
| 1282 | tmp *= 8 /* applies to entire frame */; | 1273 | tmp *= 8 /* applies to entire frame */; |
| 1283 | limit += limit * tmp; | 1274 | limit += limit * tmp; |
| @@ -7,16 +7,6 @@ · 6 unmodified lines | |||
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | * | ||
| 20 | */ | 10 | */ |
| 21 | 11 | ||
| 22 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| @@ -158,7 +148,7 @@ ep_matches ( · 135 unmodified lines | |||
| 158 | * where it's an output parameter representing the full speed limit. | 148 | * where it's an output parameter representing the full speed limit. |
| 159 | * the usb spec fixes high speed bulk maxpacket at 512 bytes. | 149 | * the usb spec fixes high speed bulk maxpacket at 512 bytes. |
| 160 | */ | 150 | */ |
| 161 | max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize); | 151 | max = 0x7ff & usb_endpoint_maxp(desc); |
| 162 | switch (type) { | 152 | switch (type) { |
| 163 | case USB_ENDPOINT_XFER_INT: | 153 | case USB_ENDPOINT_XFER_INT: |
| 164 | /* INT: limit 64 bytes full speed, 1024 high/super speed */ | 154 | /* INT: limit 64 bytes full speed, 1024 high/super speed */ |
| @@ -9,15 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | 12 | */ |
| 22 | 13 | ||
| 23 | /* #define VERBOSE_DEBUG */ | 14 | /* #define VERBOSE_DEBUG */ |
| @@ -460,7 +460,7 @@ static int audio_set_endpoint_req(struct usb_function *f, · 459 unmodified lines | |||
| 460 | 460 | ||
| 461 | switch (ctrl->bRequest) { | 461 | switch (ctrl->bRequest) { |
| 462 | case UAC_SET_CUR: | 462 | case UAC_SET_CUR: |
| 463 | value = 0; | 463 | value = len; |
| 464 | break; | 464 | break; |
| 465 | 465 | ||
| 466 | case UAC_SET_MIN: | 466 | case UAC_SET_MIN: |
| @@ -499,7 +499,7 @@ static int audio_get_endpoint_req(struct usb_function *f, · 32 unmodified lines | |||
| 499 | case UAC_GET_MIN: | 499 | case UAC_GET_MIN: |
| 500 | case UAC_GET_MAX: | 500 | case UAC_GET_MAX: |
| 501 | case UAC_GET_RES: | 501 | case UAC_GET_RES: |
| 502 | value = 3; | 502 | value = len; |
| 503 | break; | 503 | break; |
| 504 | case UAC_GET_MEM: | 504 | case UAC_GET_MEM: |
| 505 | break; | 505 | break; |
| @@ -681,17 +681,18 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) · 175 unmodified lines | |||
| 681 | 681 | ||
| 682 | status = -ENOMEM; | 682 | status = -ENOMEM; |
| 683 | 683 | ||
| 684 | /* supcard all relevant hardware speeds... we expect that when | 684 | /* copy descriptors, and track endpoint copies */ |
| 685 | f->descriptors = usb_copy_descriptors(f_audio_desc); | ||
| 686 | |||
| 687 | /* | ||
| 688 | * support all relevant hardware speeds... we expect that when | ||
| 685 | * hardware is dual speed, all bulk-capable endpoints work at | 689 | * hardware is dual speed, all bulk-capable endpoints work at |
| 686 | * both speeds | 690 | * both speeds |
| 687 | */ | 691 | */ |
| 688 | |||
| 689 | /* copy descriptors, and track endpoint copies */ | ||
| 690 | if (gadget_is_dualspeed(c->cdev->gadget)) { | 692 | if (gadget_is_dualspeed(c->cdev->gadget)) { |
| 691 | c->highspeed = true; | 693 | c->highspeed = true; |
| 692 | f->hs_descriptors = usb_copy_descriptors(f_audio_desc); | 694 | f->hs_descriptors = usb_copy_descriptors(f_audio_desc); |
| 693 | } else | 695 | } |
| 694 | f->descriptors = usb_copy_descriptors(f_audio_desc); | ||
| 695 | 696 | ||
| 696 | return 0; | 697 | return 0; |
| 697 | 698 | ||
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | /* #define VERBOSE_DEBUG */ | 13 | /* #define VERBOSE_DEBUG */ |
| @@ -9,15 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | 12 | */ |
| 22 | 13 | ||
| 23 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| @@ -12,15 +12,6 @@ · 11 unmodified lines | |||
| 12 | * it under the terms of the GNU General Public License as published by | 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 | 13 | * the Free Software Foundation; either version 2 of the License, or |
| 14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 24 | */ | 15 | */ |
| 25 | 16 | ||
| 26 | 17 | ||
| @@ -7,15 +7,6 @@ · 6 unmodified lines | |||
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | 10 | */ |
| 20 | 11 | ||
| 21 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | /* #define VERBOSE_DEBUG */ | 13 | /* #define VERBOSE_DEBUG */ |
| @@ -112,8 +112,7 @@ · 111 unmodified lines | |||
| 112 | * is not loaded (an empty string as "filename" in the fsg_config | 112 | * is not loaded (an empty string as "filename" in the fsg_config |
| 113 | * structure causes error). The CD-ROM emulation includes a single | 113 | * structure causes error). The CD-ROM emulation includes a single |
| 114 | * data track and no audio tracks; hence there need be only one | 114 | * data track and no audio tracks; hence there need be only one |
| 115 | * backing file per LUN. Note also that the CD-ROM block length is | 115 | * backing file per LUN. |
| 116 | * set to 512 rather than the more common value 2048. | ||
| 117 | * | 116 | * |
| 118 | * | 117 | * |
| 119 | * MSF includes support for module parameters. If gadget using it | 118 | * MSF includes support for module parameters. If gadget using it |
| @@ -363,7 +362,7 @@ struct fsg_common { · 243 unmodified lines | |||
| 363 | 362 | ||
| 364 | struct fsg_buffhd *next_buffhd_to_fill; | 363 | struct fsg_buffhd *next_buffhd_to_fill; |
| 365 | struct fsg_buffhd *next_buffhd_to_drain; | 364 | struct fsg_buffhd *next_buffhd_to_drain; |
| 366 | struct fsg_buffhd buffhds[FSG_NUM_BUFFERS]; | 365 | struct fsg_buffhd *buffhds; |
| 367 | 366 | ||
| 368 | int cmnd_size; | 367 | int cmnd_size; |
| 369 | u8 cmnd[MAX_COMMAND_SIZE]; | 368 | u8 cmnd[MAX_COMMAND_SIZE]; |
| @@ -745,7 +744,6 @@ static int do_read(struct fsg_common *common) · 375 unmodified lines | |||
| 745 | u32 amount_left; | 744 | u32 amount_left; |
| 746 | loff_t file_offset, file_offset_tmp; | 745 | loff_t file_offset, file_offset_tmp; |
| 747 | unsigned int amount; | 746 | unsigned int amount; |
| 748 | unsigned int partial_page; | ||
| 749 | ssize_t nread; | 747 | ssize_t nread; |
| 750 | 748 | ||
| 751 | /* | 749 | /* |
| @@ -771,7 +769,7 @@ static int do_read(struct fsg_common *common) · 19 unmodified lines | |||
| 771 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 769 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 772 | return -EINVAL; | 770 | return -EINVAL; |
| 773 | } | 771 | } |
| 774 | file_offset = ((loff_t) lba) << 9; | 772 | file_offset = ((loff_t) lba) << curlun->blkbits; |
| 775 | 773 | ||
| 776 | /* Carry out the file reads */ | 774 | /* Carry out the file reads */ |
| 777 | amount_left = common->data_size_from_cmnd; | 775 | amount_left = common->data_size_from_cmnd; |
| @@ -784,18 +782,10 @@ static int do_read(struct fsg_common *common) · 6 unmodified lines | |||
| 784 | * Try to read the remaining amount. | 782 | * Try to read the remaining amount. |
| 785 | * But don't read more than the buffer size. | 783 | * But don't read more than the buffer size. |
| 786 | * And don't try to read past the end of the file. | 784 | * And don't try to read past the end of the file. |
| 787 | * Finally, if we're not at a page boundary, don't read past | ||
| 788 | * the next page. | ||
| 789 | * If this means reading 0 then we were asked to read past | ||
| 790 | * the end of file. | ||
| 791 | */ | 785 | */ |
| 792 | amount = min(amount_left, FSG_BUFLEN); | 786 | amount = min(amount_left, FSG_BUFLEN); |
| 793 | amount = min((loff_t)amount, | 787 | amount = min((loff_t)amount, |
| 794 | curlun->file_length - file_offset); | 788 | curlun->file_length - file_offset); |
| 795 | partial_page = file_offset & (PAGE_CACHE_SIZE - 1); | ||
| 796 | if (partial_page > 0) | ||
| 797 | amount = min(amount, (unsigned int)PAGE_CACHE_SIZE - | ||
| 798 | partial_page); | ||
| 799 | 789 | ||
| 800 | /* Wait for the next buffer to become available */ | 790 | /* Wait for the next buffer to become available */ |
| 801 | bh = common->next_buffhd_to_fill; | 791 | bh = common->next_buffhd_to_fill; |
| @@ -812,7 +802,8 @@ static int do_read(struct fsg_common *common) · 10 unmodified lines | |||
| 812 | if (amount == 0) { | 802 | if (amount == 0) { |
| 813 | curlun->sense_data = | 803 | curlun->sense_data = |
| 814 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 804 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 815 | curlun->sense_data_info = file_offset >> 9; | 805 | curlun->sense_data_info = |
| 806 | file_offset >> curlun->blkbits; | ||
| 816 | curlun->info_valid = 1; | 807 | curlun->info_valid = 1; |
| 817 | bh->inreq->length = 0; | 808 | bh->inreq->length = 0; |
| 818 | bh->state = BUF_STATE_FULL; | 809 | bh->state = BUF_STATE_FULL; |
| @@ -835,18 +826,25 @@ static int do_read(struct fsg_common *common) · 16 unmodified lines | |||
| 835 | } else if (nread < amount) { | 826 | } else if (nread < amount) { |
| 836 | LDBG(curlun, "partial file read: %d/%u\n", | 827 | LDBG(curlun, "partial file read: %d/%u\n", |
| 837 | (int)nread, amount); | 828 | (int)nread, amount); |
| 838 | nread -= (nread & 511); /* Round down to a block */ | 829 | nread = round_down(nread, curlun->blksize); |
| 839 | } | 830 | } |
| 840 | file_offset += nread; | 831 | file_offset += nread; |
| 841 | amount_left -= nread; | 832 | amount_left -= nread; |
| 842 | common->residue -= nread; | 833 | common->residue -= nread; |
| 834 | |||
| 835 | /* | ||
| 836 | * Except at the end of the transfer, nread will be | ||
| 837 | * equal to the buffer size, which is divisible by the | ||
| 838 | * bulk-in maxpacket size. | ||
| 839 | */ | ||
| 843 | bh->inreq->length = nread; | 840 | bh->inreq->length = nread; |
| 844 | bh->state = BUF_STATE_FULL; | 841 | bh->state = BUF_STATE_FULL; |
| 845 | 842 | ||
| 846 | /* If an error occurred, report it and its position */ | 843 | /* If an error occurred, report it and its position */ |
| 847 | if (nread < amount) { | 844 | if (nread < amount) { |
| 848 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 845 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
| 849 | curlun->sense_data_info = file_offset >> 9; | 846 | curlun->sense_data_info = |
| 847 | file_offset >> curlun->blkbits; | ||
| 850 | curlun->info_valid = 1; | 848 | curlun->info_valid = 1; |
| 851 | break; | 849 | break; |
| 852 | } | 850 | } |
| @@ -877,7 +875,6 @@ static int do_write(struct fsg_common *common) · 24 unmodified lines | |||
| 877 | u32 amount_left_to_req, amount_left_to_write; | 875 | u32 amount_left_to_req, amount_left_to_write; |
| 878 | loff_t usb_offset, file_offset, file_offset_tmp; | 876 | loff_t usb_offset, file_offset, file_offset_tmp; |
| 879 | unsigned int amount; | 877 | unsigned int amount; |
| 880 | unsigned int partial_page; | ||
| 881 | ssize_t nwritten; | 878 | ssize_t nwritten; |
| 882 | int rc; | 879 | int rc; |
| 883 | 880 | ||
| @@ -921,7 +918,7 @@ static int do_write(struct fsg_common *common) · 37 unmodified lines | |||
| 921 | 918 | ||
| 922 | /* Carry out the file writes */ | 919 | /* Carry out the file writes */ |
| 923 | get_some_more = 1; | 920 | get_some_more = 1; |
| 924 | file_offset = usb_offset = ((loff_t) lba) << 9; | 921 | file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits; |
| 925 | amount_left_to_req = common->data_size_from_cmnd; | 922 | amount_left_to_req = common->data_size_from_cmnd; |
| 926 | amount_left_to_write = common->data_size_from_cmnd; | 923 | amount_left_to_write = common->data_size_from_cmnd; |
| 927 | 924 | ||
| @@ -933,41 +930,21 @@ static int do_write(struct fsg_common *common) · 5 unmodified lines | |||
| 933 | 930 | ||
| 934 | /* | 931 | /* |
| 935 | * Figure out how much we want to get: | 932 | * Figure out how much we want to get: |
| 936 | * Try to get the remaining amount. | 933 | * Try to get the remaining amount, |
| 937 | * But don't get more than the buffer size. | 934 | * but not more than the buffer size. |
| 938 | * And don't try to go past the end of the file. | ||
| 939 | * If we're not at a page boundary, | ||
| 940 | * don't go past the next page. | ||
| 941 | * If this means getting 0, then we were asked | ||
| 942 | * to write past the end of file. | ||
| 943 | * Finally, round down to a block boundary. | ||
| 944 | */ | 935 | */ |
| 945 | amount = min(amount_left_to_req, FSG_BUFLEN); | 936 | amount = min(amount_left_to_req, FSG_BUFLEN); |
| 946 | amount = min((loff_t)amount, | 937 | |
| 947 | curlun->file_length - usb_offset); | 938 | /* Beyond the end of the backing file? */ |
| 948 | partial_page = usb_offset & (PAGE_CACHE_SIZE - 1); | 939 | if (usb_offset >= curlun->file_length) { |
| 949 | if (partial_page > 0) | ||
| 950 | amount = min(amount, | ||
| 951 | (unsigned int)PAGE_CACHE_SIZE - partial_page); | ||
| 952 | |||
| 953 | if (amount == 0) { | ||
| 954 | get_some_more = 0; | 940 | get_some_more = 0; |
| 955 | curlun->sense_data = | 941 | curlun->sense_data = |
| 956 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 942 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 957 | curlun->sense_data_info = usb_offset >> 9; | 943 | curlun->sense_data_info = |
| 944 | usb_offset >> curlun->blkbits; | ||
| 958 | curlun->info_valid = 1; | 945 | curlun->info_valid = 1; |
| 959 | continue; | 946 | continue; |
| 960 | } | 947 | } |
| 961 | amount -= amount & 511; | ||
| 962 | if (amount == 0) { | ||
| 963 | |||
| 964 | /* | ||
| 965 | * Why were we were asked to transfer a | ||
| 966 | * partial block? | ||
| 967 | */ | ||
| 968 | get_some_more = 0; | ||
| 969 | continue; | ||
| 970 | } | ||
| 971 | 948 | ||
| 972 | /* Get the next buffer */ | 949 | /* Get the next buffer */ |
| 973 | usb_offset += amount; | 950 | usb_offset += amount; |
| @@ -977,12 +954,11 @@ static int do_write(struct fsg_common *common) · 3 unmodified lines | |||
| 977 | get_some_more = 0; | 954 | get_some_more = 0; |
| 978 | 955 | ||
| 979 | /* | 956 | /* |
| 980 | * amount is always divisible by 512, hence by | 957 | * Except at the end of the transfer, amount will be |
| 981 | * the bulk-out maxpacket size | 958 | * equal to the buffer size, which is divisible by |
| 959 | * the bulk-out maxpacket size. | ||
| 982 | */ | 960 | */ |
| 983 | bh->outreq->length = amount; | 961 | set_bulk_out_req_length(common, bh, amount); |
| 984 | bh->bulk_out_intended_length = amount; | ||
| 985 | bh->outreq->short_not_ok = 1; | ||
| 986 | if (!start_out_transfer(common, bh)) | 962 | if (!start_out_transfer(common, bh)) |
| 987 | /* Dunno what to do if common->fsg is NULL */ | 963 | /* Dunno what to do if common->fsg is NULL */ |
| 988 | return -EIO; | 964 | return -EIO; |
| @@ -1002,7 +978,8 @@ static int do_write(struct fsg_common *common) · 13 unmodified lines | |||
| 1002 | /* Did something go wrong with the transfer? */ | 978 | /* Did something go wrong with the transfer? */ |
| 1003 | if (bh->outreq->status != 0) { | 979 | if (bh->outreq->status != 0) { |
| 1004 | curlun->sense_data = SS_COMMUNICATION_FAILURE; | 980 | curlun->sense_data = SS_COMMUNICATION_FAILURE; |
| 1005 | curlun->sense_data_info = file_offset >> 9; | 981 | curlun->sense_data_info = |
| 982 | file_offset >> curlun->blkbits; | ||
| 1006 | curlun->info_valid = 1; | 983 | curlun->info_valid = 1; |
| 1007 | break; | 984 | break; |
| 1008 | } | 985 | } |
| @@ -1016,6 +993,16 @@ static int do_write(struct fsg_common *common) · 7 unmodified lines | |||
| 1016 | amount = curlun->file_length - file_offset; | 993 | amount = curlun->file_length - file_offset; |
| 1017 | } | 994 | } |
| 1018 | 995 | ||
| 996 | /* Don't accept excess data. The spec doesn't say | ||
| 997 | * what to do in this case. We'll ignore the error. | ||
| 998 | */ | ||
| 999 | amount = min(amount, bh->bulk_out_intended_length); | ||
| 1000 | |||
| 1001 | /* Don't write a partial block */ | ||
| 1002 | amount = round_down(amount, curlun->blksize); | ||
| 1003 | if (amount == 0) | ||
| 1004 | goto empty_write; | ||
| 1005 | |||
| 1019 | /* Perform the write */ | 1006 | /* Perform the write */ |
| 1020 | file_offset_tmp = file_offset; | 1007 | file_offset_tmp = file_offset; |
| 1021 | nwritten = vfs_write(curlun->filp, | 1008 | nwritten = vfs_write(curlun->filp, |
| @@ -1033,8 +1020,7 @@ static int do_write(struct fsg_common *common) · 11 unmodified lines | |||
| 1033 | } else if (nwritten < amount) { | 1020 | } else if (nwritten < amount) { |
| 1034 | LDBG(curlun, "partial file write: %d/%u\n", | 1021 | LDBG(curlun, "partial file write: %d/%u\n", |
| 1035 | (int)nwritten, amount); | 1022 | (int)nwritten, amount); |
| 1036 | nwritten -= (nwritten & 511); | 1023 | nwritten = round_down(nwritten, curlun->blksize); |
| 1037 | /* Round down to a block */ | ||
| 1038 | } | 1024 | } |
| 1039 | file_offset += nwritten; | 1025 | file_offset += nwritten; |
| 1040 | amount_left_to_write -= nwritten; | 1026 | amount_left_to_write -= nwritten; |
| @@ -1043,13 +1029,15 @@ static int do_write(struct fsg_common *common) · 2 unmodified lines | |||
| 1043 | /* If an error occurred, report it and its position */ | 1029 | /* If an error occurred, report it and its position */ |
| 1044 | if (nwritten < amount) { | 1030 | if (nwritten < amount) { |
| 1045 | curlun->sense_data = SS_WRITE_ERROR; | 1031 | curlun->sense_data = SS_WRITE_ERROR; |
| 1046 | curlun->sense_data_info = file_offset >> 9; | 1032 | curlun->sense_data_info = |
| 1033 | file_offset >> curlun->blkbits; | ||
| 1047 | curlun->info_valid = 1; | 1034 | curlun->info_valid = 1; |
| 1048 | break; | 1035 | break; |
| 1049 | } | 1036 | } |
| 1050 | 1037 | ||
| 1038 | empty_write: | ||
| 1051 | /* Did the host decide to stop early? */ | 1039 | /* Did the host decide to stop early? */ |
| 1052 | if (bh->outreq->actual != bh->outreq->length) { | 1040 | if (bh->outreq->actual < bh->bulk_out_intended_length) { |
| 1053 | common->short_packet_received = 1; | 1041 | common->short_packet_received = 1; |
| 1054 | break; | 1042 | break; |
| 1055 | } | 1043 | } |
| @@ -1129,8 +1117,8 @@ static int do_verify(struct fsg_common *common) · 73 unmodified lines | |||
| 1129 | return -EIO; /* No default reply */ | 1117 | return -EIO; /* No default reply */ |
| 1130 | 1118 | ||
| 1131 | /* Prepare to carry out the file verify */ | 1119 | /* Prepare to carry out the file verify */ |
| 1132 | amount_left = verification_length << 9; | 1120 | amount_left = verification_length << curlun->blkbits; |
| 1133 | file_offset = ((loff_t) lba) << 9; | 1121 | file_offset = ((loff_t) lba) << curlun->blkbits; |
| 1134 | 1122 | ||
| 1135 | /* Write out all the dirty buffers before invalidating them */ | 1123 | /* Write out all the dirty buffers before invalidating them */ |
| 1136 | fsg_lun_fsync_sub(curlun); | 1124 | fsg_lun_fsync_sub(curlun); |
| @@ -1148,8 +1136,6 @@ static int do_verify(struct fsg_common *common) · 11 unmodified lines | |||
| 1148 | * Try to read the remaining amount, but not more than | 1136 | * Try to read the remaining amount, but not more than |
| 1149 | * the buffer size. | 1137 | * the buffer size. |
| 1150 | * And don't try to read past the end of the file. | 1138 | * And don't try to read past the end of the file. |
| 1151 | * If this means reading 0 then we were asked to read | ||
| 1152 | * past the end of file. | ||
| 1153 | */ | 1139 | */ |
| 1154 | amount = min(amount_left, FSG_BUFLEN); | 1140 | amount = min(amount_left, FSG_BUFLEN); |
| 1155 | amount = min((loff_t)amount, | 1141 | amount = min((loff_t)amount, |
| @@ -1157,7 +1143,8 @@ static int do_verify(struct fsg_common *common) · 1 unmodified line | |||
| 1157 | if (amount == 0) { | 1143 | if (amount == 0) { |
| 1158 | curlun->sense_data = | 1144 | curlun->sense_data = |
| 1159 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1145 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 1160 | curlun->sense_data_info = file_offset >> 9; | 1146 | curlun->sense_data_info = |
| 1147 | file_offset >> curlun->blkbits; | ||
| 1161 | curlun->info_valid = 1; | 1148 | curlun->info_valid = 1; |
| 1162 | break; | 1149 | break; |
| 1163 | } | 1150 | } |
| @@ -1179,11 +1166,12 @@ static int do_verify(struct fsg_common *common) · 15 unmodified lines | |||
| 1179 | } else if (nread < amount) { | 1166 | } else if (nread < amount) { |
| 1180 | LDBG(curlun, "partial file verify: %d/%u\n", | 1167 | LDBG(curlun, "partial file verify: %d/%u\n", |
| 1181 | (int)nread, amount); | 1168 | (int)nread, amount); |
| 1182 | nread -= nread & 511; /* Round down to a sector */ | 1169 | nread = round_down(nread, curlun->blksize); |
| 1183 | } | 1170 | } |
| 1184 | if (nread == 0) { | 1171 | if (nread == 0) { |
| 1185 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 1172 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
| 1186 | curlun->sense_data_info = file_offset >> 9; | 1173 | curlun->sense_data_info = |
| 1174 | file_offset >> curlun->blkbits; | ||
| 1187 | curlun->info_valid = 1; | 1175 | curlun->info_valid = 1; |
| 1188 | break; | 1176 | break; |
| 1189 | } | 1177 | } |
| @@ -1289,7 +1277,7 @@ static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh) · 99 unmodified lines | |||
| 1289 | 1277 | ||
| 1290 | put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); | 1278 | put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); |
| 1291 | /* Max logical block */ | 1279 | /* Max logical block */ |
| 1292 | put_unaligned_be32(512, &buf[4]); /* Block length */ | 1280 | put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */ |
| 1293 | return 8; | 1281 | return 8; |
| 1294 | } | 1282 | } |
| 1295 | 1283 | ||
| @@ -1527,7 +1515,7 @@ static int do_read_format_capacities(struct fsg_common *common, · 231 unmodified lines | |||
| 1527 | 1515 | ||
| 1528 | put_unaligned_be32(curlun->num_sectors, &buf[0]); | 1516 | put_unaligned_be32(curlun->num_sectors, &buf[0]); |
| 1529 | /* Number of blocks */ | 1517 | /* Number of blocks */ |
| 1530 | put_unaligned_be32(512, &buf[4]); /* Block length */ | 1518 | put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */ |
| 1531 | buf[4] = 0x02; /* Current capacity */ | 1519 | buf[4] = 0x02; /* Current capacity */ |
| 1532 | return 12; | 1520 | return 12; |
| 1533 | } | 1521 | } |
| @@ -1607,7 +1595,7 @@ static int throw_away_data(struct fsg_common *common) · 73 unmodified lines | |||
| 1607 | common->next_buffhd_to_drain = bh->next; | 1595 | common->next_buffhd_to_drain = bh->next; |
| 1608 | 1596 | ||
| 1609 | /* A short packet or an error ends everything */ | 1597 | /* A short packet or an error ends everything */ |
| 1610 | if (bh->outreq->actual != bh->outreq->length || | 1598 | if (bh->outreq->actual < bh->bulk_out_intended_length || |
| 1611 | bh->outreq->status != 0) { | 1599 | bh->outreq->status != 0) { |
| 1612 | raise_exception(common, | 1600 | raise_exception(common, |
| 1613 | FSG_STATE_ABORT_BULK_OUT); | 1601 | FSG_STATE_ABORT_BULK_OUT); |
| @@ -1623,12 +1611,11 @@ static int throw_away_data(struct fsg_common *common) · 9 unmodified lines | |||
| 1623 | amount = min(common->usb_amount_left, FSG_BUFLEN); | 1611 | amount = min(common->usb_amount_left, FSG_BUFLEN); |
| 1624 | 1612 | ||
| 1625 | /* | 1613 | /* |
| 1626 | * amount is always divisible by 512, hence by | 1614 | * Except at the end of the transfer, amount will be |
| 1615 | * equal to the buffer size, which is divisible by | ||
| 1627 | * the bulk-out maxpacket size. | 1616 | * the bulk-out maxpacket size. |
| 1628 | */ | 1617 | */ |
| 1629 | bh->outreq->length = amount; | 1618 | set_bulk_out_req_length(common, bh, amount); |
| 1630 | bh->bulk_out_intended_length = amount; | ||
| 1631 | bh->outreq->short_not_ok = 1; | ||
| 1632 | if (!start_out_transfer(common, bh)) | 1619 | if (!start_out_transfer(common, bh)) |
| 1633 | /* Dunno what to do if common->fsg is NULL */ | 1620 | /* Dunno what to do if common->fsg is NULL */ |
| 1634 | return -EIO; | 1621 | return -EIO; |
| @@ -2022,7 +2009,8 @@ static int do_scsi_command(struct fsg_common *common) · 387 unmodified lines | |||
| 2022 | 2009 | ||
| 2023 | case READ_6: | 2010 | case READ_6: |
| 2024 | i = common->cmnd[4]; | 2011 | i = common->cmnd[4]; |
| 2025 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; | 2012 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << |
| 2013 | common->curlun->blkbits; | ||
| 2026 | reply = check_command(common, 6, DATA_DIR_TO_HOST, | 2014 | reply = check_command(common, 6, DATA_DIR_TO_HOST, |
| 2027 | (7<<1) | (1<<4), 1, | 2015 | (7<<1) | (1<<4), 1, |
| 2028 | "READ(6)"); | 2016 | "READ(6)"); |
| @@ -2032,7 +2020,8 @@ static int do_scsi_command(struct fsg_common *common) · 3 unmodified lines | |||
| 2032 | 2020 | ||
| 2033 | case READ_10: | 2021 | case READ_10: |
| 2034 | common->data_size_from_cmnd = | 2022 | common->data_size_from_cmnd = |
| 2035 | get_unaligned_be16(&common->cmnd[7]) << 9; | 2023 | get_unaligned_be16(&common->cmnd[7]) << |
| 2024 | common->curlun->blkbits; | ||
| 2036 | reply = check_command(common, 10, DATA_DIR_TO_HOST, | 2025 | reply = check_command(common, 10, DATA_DIR_TO_HOST, |
| 2037 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2026 | (1<<1) | (0xf<<2) | (3<<7), 1, |
| 2038 | "READ(10)"); | 2027 | "READ(10)"); |
| @@ -2042,7 +2031,8 @@ static int do_scsi_command(struct fsg_common *common) · 3 unmodified lines | |||
| 2042 | 2031 | ||
| 2043 | case READ_12: | 2032 | case READ_12: |
| 2044 | common->data_size_from_cmnd = | 2033 | common->data_size_from_cmnd = |
| 2045 | get_unaligned_be32(&common->cmnd[6]) << 9; | 2034 | get_unaligned_be32(&common->cmnd[6]) << |
| 2035 | common->curlun->blkbits; | ||
| 2046 | reply = check_command(common, 12, DATA_DIR_TO_HOST, | 2036 | reply = check_command(common, 12, DATA_DIR_TO_HOST, |
| 2047 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2037 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
| 2048 | "READ(12)"); | 2038 | "READ(12)"); |
| @@ -2142,7 +2132,8 @@ static int do_scsi_command(struct fsg_common *common) · 93 unmodified lines | |||
| 2142 | 2132 | ||
| 2143 | case WRITE_6: | 2133 | case WRITE_6: |
| 2144 | i = common->cmnd[4]; | 2134 | i = common->cmnd[4]; |
| 2145 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; | 2135 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << |
| 2136 | common->curlun->blkbits; | ||
| 2146 | reply = check_command(common, 6, DATA_DIR_FROM_HOST, | 2137 | reply = check_command(common, 6, DATA_DIR_FROM_HOST, |
| 2147 | (7<<1) | (1<<4), 1, | 2138 | (7<<1) | (1<<4), 1, |
| 2148 | "WRITE(6)"); | 2139 | "WRITE(6)"); |
| @@ -2152,7 +2143,8 @@ static int do_scsi_command(struct fsg_common *common) · 3 unmodified lines | |||
| 2152 | 2143 | ||
| 2153 | case WRITE_10: | 2144 | case WRITE_10: |
| 2154 | common->data_size_from_cmnd = | 2145 | common->data_size_from_cmnd = |
| 2155 | get_unaligned_be16(&common->cmnd[7]) << 9; | 2146 | get_unaligned_be16(&common->cmnd[7]) << |
| 2147 | common->curlun->blkbits; | ||
| 2156 | reply = check_command(common, 10, DATA_DIR_FROM_HOST, | 2148 | reply = check_command(common, 10, DATA_DIR_FROM_HOST, |
| 2157 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2149 | (1<<1) | (0xf<<2) | (3<<7), 1, |
| 2158 | "WRITE(10)"); | 2150 | "WRITE(10)"); |
| @@ -2162,7 +2154,8 @@ static int do_scsi_command(struct fsg_common *common) · 3 unmodified lines | |||
| 2162 | 2154 | ||
| 2163 | case WRITE_12: | 2155 | case WRITE_12: |
| 2164 | common->data_size_from_cmnd = | 2156 | common->data_size_from_cmnd = |
| 2165 | get_unaligned_be32(&common->cmnd[6]) << 9; | 2157 | get_unaligned_be32(&common->cmnd[6]) << |
| 2158 | common->curlun->blkbits; | ||
| 2166 | reply = check_command(common, 12, DATA_DIR_FROM_HOST, | 2159 | reply = check_command(common, 12, DATA_DIR_FROM_HOST, |
| 2167 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2160 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
| 2168 | "WRITE(12)"); | 2161 | "WRITE(12)"); |
| @@ -2297,7 +2290,6 @@ static int get_next_command(struct fsg_common *common) · 128 unmodified lines | |||
| 2297 | 2290 | ||
| 2298 | /* Queue a request to read a Bulk-only CBW */ | 2291 | /* Queue a request to read a Bulk-only CBW */ |
| 2299 | set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); | 2292 | set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); |
| 2300 | bh->outreq->short_not_ok = 1; | ||
| 2301 | if (!start_out_transfer(common, bh)) | 2293 | if (!start_out_transfer(common, bh)) |
| 2302 | /* Don't know what to do if common->fsg is NULL */ | 2294 | /* Don't know what to do if common->fsg is NULL */ |
| 2303 | return -EIO; | 2295 | return -EIO; |
| @@ -2348,7 +2340,7 @@ reset: · 44 unmodified lines | |||
| 2348 | if (common->fsg) { | 2340 | if (common->fsg) { |
| 2349 | fsg = common->fsg; | 2341 | fsg = common->fsg; |
| 2350 | 2342 | ||
| 2351 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2343 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2352 | struct fsg_buffhd *bh = &common->buffhds[i]; | 2344 | struct fsg_buffhd *bh = &common->buffhds[i]; |
| 2353 | 2345 | ||
| 2354 | if (bh->inreq) { | 2346 | if (bh->inreq) { |
| @@ -2401,12 +2393,11 @@ reset: · 46 unmodified lines | |||
| 2401 | goto reset; | 2393 | goto reset; |
| 2402 | fsg->bulk_out->driver_data = common; | 2394 | fsg->bulk_out->driver_data = common; |
| 2403 | fsg->bulk_out_enabled = 1; | 2395 | fsg->bulk_out_enabled = 1; |
| 2404 | common->bulk_out_maxpacket = | 2396 | common->bulk_out_maxpacket = usb_endpoint_maxp(fsg->bulk_out->desc); |
| 2405 | le16_to_cpu(fsg->bulk_out->desc->wMaxPacketSize); | ||
| 2406 | clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); | 2397 | clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); |
| 2407 | 2398 | ||
| 2408 | /* Allocate the requests */ | 2399 | /* Allocate the requests */ |
| 2409 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2400 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2410 | struct fsg_buffhd *bh = &common->buffhds[i]; | 2401 | struct fsg_buffhd *bh = &common->buffhds[i]; |
| 2411 | 2402 | ||
| 2412 | rc = alloc_request(common, fsg->bulk_in, &bh->inreq); | 2403 | rc = alloc_request(common, fsg->bulk_in, &bh->inreq); |
| @@ -2475,7 +2466,7 @@ static void handle_exception(struct fsg_common *common) · 62 unmodified lines | |||
| 2475 | 2466 | ||
| 2476 | /* Cancel all the pending transfers */ | 2467 | /* Cancel all the pending transfers */ |
| 2477 | if (likely(common->fsg)) { | 2468 | if (likely(common->fsg)) { |
| 2478 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2469 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2479 | bh = &common->buffhds[i]; | 2470 | bh = &common->buffhds[i]; |
| 2480 | if (bh->inreq_busy) | 2471 | if (bh->inreq_busy) |
| 2481 | usb_ep_dequeue(common->fsg->bulk_in, bh->inreq); | 2472 | usb_ep_dequeue(common->fsg->bulk_in, bh->inreq); |
| @@ -2487,7 +2478,7 @@ static void handle_exception(struct fsg_common *common) · 5 unmodified lines | |||
| 2487 | /* Wait until everything is idle */ | 2478 | /* Wait until everything is idle */ |
| 2488 | for (;;) { | 2479 | for (;;) { |
| 2489 | int num_active = 0; | 2480 | int num_active = 0; |
| 2490 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2481 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2491 | bh = &common->buffhds[i]; | 2482 | bh = &common->buffhds[i]; |
| 2492 | num_active += bh->inreq_busy + bh->outreq_busy; | 2483 | num_active += bh->inreq_busy + bh->outreq_busy; |
| 2493 | } | 2484 | } |
| @@ -2510,7 +2501,7 @@ static void handle_exception(struct fsg_common *common) · 16 unmodified lines | |||
| 2510 | */ | 2501 | */ |
| 2511 | spin_lock_irq(&common->lock); | 2502 | spin_lock_irq(&common->lock); |
| 2512 | 2503 | ||
| 2513 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2504 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2514 | bh = &common->buffhds[i]; | 2505 | bh = &common->buffhds[i]; |
| 2515 | bh->state = BUF_STATE_EMPTY; | 2506 | bh->state = BUF_STATE_EMPTY; |
| 2516 | } | 2507 | } |
| @@ -2719,6 +2710,10 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, · 202 unmodified lines | |||
| 2719 | int nluns, i, rc; | 2710 | int nluns, i, rc; |
| 2720 | char *pathbuf; | 2711 | char *pathbuf; |
| 2721 | 2712 | ||
| 2713 | rc = fsg_num_buffers_validate(); | ||
| 2714 | if (rc != 0) | ||
| 2715 | return ERR_PTR(rc); | ||
| 2716 | |||
| 2722 | /* Find out how many LUNs there should be */ | 2717 | /* Find out how many LUNs there should be */ |
| 2723 | nluns = cfg->nluns; | 2718 | nluns = cfg->nluns; |
| 2724 | if (nluns < 1 || nluns > FSG_MAX_LUNS) { | 2719 | if (nluns < 1 || nluns > FSG_MAX_LUNS) { |
| @@ -2737,6 +2732,14 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, · 12 unmodified lines | |||
| 2737 | common->free_storage_on_release = 0; | 2732 | common->free_storage_on_release = 0; |
| 2738 | } | 2733 | } |
| 2739 | 2734 | ||
| 2735 | common->buffhds = kcalloc(fsg_num_buffers, | ||
| 2736 | sizeof *(common->buffhds), GFP_KERNEL); | ||
| 2737 | if (!common->buffhds) { | ||
| 2738 | if (common->free_storage_on_release) | ||
| 2739 | kfree(common); | ||
| 2740 | return ERR_PTR(-ENOMEM); | ||
| 2741 | } | ||
| 2742 | |||
| 2740 | common->ops = cfg->ops; | 2743 | common->ops = cfg->ops; |
| 2741 | common->private_data = cfg->private_data; | 2744 | common->private_data = cfg->private_data; |
| 2742 | 2745 | ||
| @@ -2814,7 +2817,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, · 71 unmodified lines | |||
| 2814 | 2817 | ||
| 2815 | /* Data buffers cyclic list */ | 2818 | /* Data buffers cyclic list */ |
| 2816 | bh = common->buffhds; | 2819 | bh = common->buffhds; |
| 2817 | i = FSG_NUM_BUFFERS; | 2820 | i = fsg_num_buffers; |
| 2818 | goto buffhds_first_it; | 2821 | goto buffhds_first_it; |
| 2819 | do { | 2822 | do { |
| 2820 | bh->next = bh + 1; | 2823 | bh->next = bh + 1; |
| @@ -2940,12 +2943,13 @@ static void fsg_common_release(struct kref *ref) · 119 unmodified lines | |||
| 2940 | 2943 | ||
| 2941 | { | 2944 | { |
| 2942 | struct fsg_buffhd *bh = common->buffhds; | 2945 | struct fsg_buffhd *bh = common->buffhds; |
| 2943 | unsigned i = FSG_NUM_BUFFERS; | 2946 | unsigned i = fsg_num_buffers; |
| 2944 | do { | 2947 | do { |
| 2945 | kfree(bh->buf); | 2948 | kfree(bh->buf); |
| 2946 | } while (++bh, --i); | 2949 | } while (++bh, --i); |
| 2947 | } | 2950 | } |
| 2948 | 2951 | ||
| 2952 | kfree(common->buffhds); | ||
| 2949 | if (common->free_storage_on_release) | 2953 | if (common->free_storage_on_release) |
| 2950 | kfree(common); | 2954 | kfree(common); |
| 2951 | } | 2955 | } |
| @@ -3019,6 +3023,28 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) · 67 unmodified lines | |||
| 3019 | } | 3023 | } |
| 3020 | } | 3024 | } |
| 3021 | 3025 | ||
| 3026 | if (gadget_is_superspeed(gadget)) { | ||
| 3027 | unsigned max_burst; | ||
| 3028 | |||
| 3029 | /* Calculate bMaxBurst, we know packet size is 1024 */ | ||
| 3030 | max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15); | ||
| 3031 | |||
| 3032 | fsg_ss_bulk_in_desc.bEndpointAddress = | ||
| 3033 | fsg_fs_bulk_in_desc.bEndpointAddress; | ||
| 3034 | fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; | ||
| 3035 | |||
| 3036 | fsg_ss_bulk_out_desc.bEndpointAddress = | ||
| 3037 | fsg_fs_bulk_out_desc.bEndpointAddress; | ||
| 3038 | fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; | ||
| 3039 | |||
| 3040 | f->ss_descriptors = usb_copy_descriptors(fsg_ss_function); | ||
| 3041 | if (unlikely(!f->ss_descriptors)) { | ||
| 3042 | usb_free_descriptors(f->hs_descriptors); | ||
| 3043 | usb_free_descriptors(f->descriptors); | ||
| 3044 | return -ENOMEM; | ||
| 3045 | } | ||
| 3046 | } | ||
| 3047 | |||
| 3022 | return 0; | 3048 | return 0; |
| 3023 | 3049 | ||
| 3024 | autoconf_fail: | 3050 | autoconf_fail: |
| @@ -0,0 +1,998 @@ | |||
| 1 | /* | ||
| 2 | * f_midi.c -- USB MIDI class function driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Thumtronics Pty Ltd. | ||
| 5 | * Developed for Thumtronics by Grey Innovation | ||
| 6 | * Ben Williamson <ben.williamson@greyinnovation.com> | ||
| 7 | * | ||
| 8 | * Rewritten for the composite framework | ||
| 9 | * Copyright (C) 2011 Daniel Mack <zonque@gmail.com> | ||
| 10 | * | ||
| 11 | * Based on drivers/usb/gadget/f_audio.c, | ||
| 12 | * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> | ||
| 13 | * Copyright (C) 2008 Analog Devices, Inc | ||
| 14 | * | ||
| 15 | * and drivers/usb/gadget/midi.c, | ||
| 16 | * Copyright (C) 2006 Thumtronics Pty Ltd. | ||
| 17 | * Ben Williamson <ben.williamson@greyinnovation.com> | ||
| 18 | * | ||
| 19 | * Licensed under the GPL-2 or later. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/utsname.h> | ||
| 25 | #include <linux/device.h> | ||
| 26 | |||
| 27 | #include <sound/core.h> | ||
| 28 | #include <sound/initval.h> | ||
| 29 | #include <sound/rawmidi.h> | ||
| 30 | |||
| 31 | #include <linux/usb/ch9.h> | ||
| 32 | #include <linux/usb/gadget.h> | ||
| 33 | #include <linux/usb/audio.h> | ||
| 34 | #include <linux/usb/midi.h> | ||
| 35 | |||
| 36 | MODULE_AUTHOR("Ben Williamson"); | ||
| 37 | MODULE_LICENSE("GPL v2"); | ||
| 38 | |||
| 39 | static const char f_midi_shortname[] = "f_midi"; | ||
| 40 | static const char f_midi_longname[] = "MIDI Gadget"; | ||
| 41 | |||
| 42 | /* | ||
| 43 | * We can only handle 16 cables on one single endpoint, as cable numbers are | ||
| 44 | * stored in 4-bit fields. And as the interface currently only holds one | ||
| 45 | * single endpoint, this is the maximum number of ports we can allow. | ||
| 46 | */ | ||
| 47 | #define MAX_PORTS 16 | ||
| 48 | |||
| 49 | /* | ||
| 50 | * This is a gadget, and the IN/OUT naming is from the host's perspective. | ||
| 51 | * USB -> OUT endpoint -> rawmidi | ||
| 52 | * USB <- IN endpoint <- rawmidi | ||
| 53 | */ | ||
| 54 | struct gmidi_in_port { | ||
| 55 | struct f_midi *midi; | ||
| 56 | int active; | ||
| 57 | uint8_t cable; | ||
| 58 | uint8_t state; | ||
| 59 | #define STATE_UNKNOWN 0 | ||
| 60 | #define STATE_1PARAM 1 | ||
| 61 | #define STATE_2PARAM_1 2 | ||
| 62 | #define STATE_2PARAM_2 3 | ||
| 63 | #define STATE_SYSEX_0 4 | ||
| 64 | #define STATE_SYSEX_1 5 | ||
| 65 | #define STATE_SYSEX_2 6 | ||
| 66 | uint8_t data[2]; | ||
| 67 | }; | ||
| 68 | |||
| 69 | struct f_midi { | ||
| 70 | struct usb_function func; | ||
| 71 | struct usb_gadget *gadget; | ||
| 72 | struct usb_ep *in_ep, *out_ep; | ||
| 73 | struct snd_card *card; | ||
| 74 | struct snd_rawmidi *rmidi; | ||
| 75 | |||
| 76 | struct snd_rawmidi_substream *in_substream[MAX_PORTS]; | ||
| 77 | struct snd_rawmidi_substream *out_substream[MAX_PORTS]; | ||
| 78 | struct gmidi_in_port *in_port[MAX_PORTS]; | ||
| 79 | |||
| 80 | unsigned long out_triggered; | ||
| 81 | struct tasklet_struct tasklet; | ||
| 82 | unsigned int in_ports; | ||
| 83 | unsigned int out_ports; | ||
| 84 | int index; | ||
| 85 | char *id; | ||
| 86 | unsigned int buflen, qlen; | ||
| 87 | }; | ||
| 88 | |||
| 89 | static inline struct f_midi *func_to_midi(struct usb_function *f) | ||
| 90 | { | ||
| 91 | return container_of(f, struct f_midi, func); | ||
| 92 | } | ||
| 93 | |||
| 94 | static void f_midi_transmit(struct f_midi *midi, struct usb_request *req); | ||
| 95 | |||
| 96 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); | ||
| 97 | DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); | ||
| 98 | DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(16); | ||
| 99 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); | ||
| 100 | |||
| 101 | /* B.3.1 Standard AC Interface Descriptor */ | ||
| 102 | static struct usb_interface_descriptor ac_interface_desc __initdata = { | ||
| 103 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 104 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 105 | /* .bInterfaceNumber = DYNAMIC */ | ||
| 106 | /* .bNumEndpoints = DYNAMIC */ | ||
| 107 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
| 108 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, | ||
| 109 | /* .iInterface = DYNAMIC */ | ||
| 110 | }; | ||
| 111 | |||
| 112 | /* B.3.2 Class-Specific AC Interface Descriptor */ | ||
| 113 | static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = { | ||
| 114 | .bLength = UAC_DT_AC_HEADER_SIZE(1), | ||
| 115 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 116 | .bDescriptorSubtype = USB_MS_HEADER, | ||
| 117 | .bcdADC = cpu_to_le16(0x0100), | ||
| 118 | .wTotalLength = cpu_to_le16(UAC_DT_AC_HEADER_SIZE(1)), | ||
| 119 | .bInCollection = 1, | ||
| 120 | /* .baInterfaceNr = DYNAMIC */ | ||
| 121 | }; | ||
| 122 | |||
| 123 | /* B.4.1 Standard MS Interface Descriptor */ | ||
| 124 | static struct usb_interface_descriptor ms_interface_desc __initdata = { | ||
| 125 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 126 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 127 | /* .bInterfaceNumber = DYNAMIC */ | ||
| 128 | .bNumEndpoints = 2, | ||
| 129 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
| 130 | .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING, | ||
| 131 | /* .iInterface = DYNAMIC */ | ||
| 132 | }; | ||
| 133 | |||
| 134 | /* B.4.2 Class-Specific MS Interface Descriptor */ | ||
| 135 | static struct usb_ms_header_descriptor ms_header_desc __initdata = { | ||
| 136 | .bLength = USB_DT_MS_HEADER_SIZE, | ||
| 137 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 138 | .bDescriptorSubtype = USB_MS_HEADER, | ||
| 139 | .bcdMSC = cpu_to_le16(0x0100), | ||
| 140 | /* .wTotalLength = DYNAMIC */ | ||
| 141 | }; | ||
| 142 | |||
| 143 | /* B.4.3 Embedded MIDI IN Jack Descriptor */ | ||
| 144 | static struct usb_midi_in_jack_descriptor jack_in_emb_desc = { | ||
| 145 | .bLength = USB_DT_MIDI_IN_SIZE, | ||
| 146 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 147 | .bDescriptorSubtype = USB_MS_MIDI_IN_JACK, | ||
| 148 | .bJackType = USB_MS_EMBEDDED, | ||
| 149 | /* .bJackID = DYNAMIC */ | ||
| 150 | }; | ||
| 151 | |||
| 152 | /* B.4.4 Embedded MIDI OUT Jack Descriptor */ | ||
| 153 | static struct usb_midi_out_jack_descriptor_16 jack_out_emb_desc = { | ||
| 154 | /* .bLength = DYNAMIC */ | ||
| 155 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 156 | .bDescriptorSubtype = USB_MS_MIDI_OUT_JACK, | ||
| 157 | .bJackType = USB_MS_EMBEDDED, | ||
| 158 | /* .bJackID = DYNAMIC */ | ||
| 159 | /* .bNrInputPins = DYNAMIC */ | ||
| 160 | /* .pins = DYNAMIC */ | ||
| 161 | }; | ||
| 162 | |||
| 163 | /* B.5.1 Standard Bulk OUT Endpoint Descriptor */ | ||
| 164 | static struct usb_endpoint_descriptor bulk_out_desc = { | ||
| 165 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | ||
| 166 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 167 | .bEndpointAddress = USB_DIR_OUT, | ||
| 168 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 169 | }; | ||
| 170 | |||
| 171 | /* B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor */ | ||
| 172 | static struct usb_ms_endpoint_descriptor_16 ms_out_desc = { | ||
| 173 | /* .bLength = DYNAMIC */ | ||
| 174 | .bDescriptorType = USB_DT_CS_ENDPOINT, | ||
| 175 | .bDescriptorSubtype = USB_MS_GENERAL, | ||
| 176 | /* .bNumEmbMIDIJack = DYNAMIC */ | ||
| 177 | /* .baAssocJackID = DYNAMIC */ | ||
| 178 | }; | ||
| 179 | |||
| 180 | /* B.6.1 Standard Bulk IN Endpoint Descriptor */ | ||
| 181 | static struct usb_endpoint_descriptor bulk_in_desc = { | ||
| 182 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | ||
| 183 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 184 | .bEndpointAddress = USB_DIR_IN, | ||
| 185 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 186 | }; | ||
| 187 | |||
| 188 | /* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */ | ||
| 189 | static struct usb_ms_endpoint_descriptor_16 ms_in_desc = { | ||
| 190 | /* .bLength = DYNAMIC */ | ||
| 191 | .bDescriptorType = USB_DT_CS_ENDPOINT, | ||
| 192 | .bDescriptorSubtype = USB_MS_GENERAL, | ||
| 193 | /* .bNumEmbMIDIJack = DYNAMIC */ | ||
| 194 | /* .baAssocJackID = DYNAMIC */ | ||
| 195 | }; | ||
| 196 | |||
| 197 | /* string IDs are assigned dynamically */ | ||
| 198 | |||
| 199 | #define STRING_FUNC_IDX 0 | ||
| 200 | |||
| 201 | static struct usb_string midi_string_defs[] = { | ||
| 202 | [STRING_FUNC_IDX].s = "MIDI function", | ||
| 203 | { } /* end of list */ | ||
| 204 | }; | ||
| 205 | |||
| 206 | static struct usb_gadget_strings midi_stringtab = { | ||
| 207 | .language = 0x0409, /* en-us */ | ||
| 208 | .strings = midi_string_defs, | ||
| 209 | }; | ||
| 210 | |||
| 211 | static struct usb_gadget_strings *midi_strings[] = { | ||
| 212 | &midi_stringtab, | ||
| 213 | NULL, | ||
| 214 | }; | ||
| 215 | |||
| 216 | static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length) | ||
| 217 | { | ||
| 218 | struct usb_request *req; | ||
| 219 | |||
| 220 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); | ||
| 221 | if (req) { | ||
| 222 | req->length = length; | ||
| 223 | req->buf = kmalloc(length, GFP_ATOMIC); | ||
| 224 | if (!req->buf) { | ||
| 225 | usb_ep_free_request(ep, req); | ||
| 226 | req = NULL; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | return req; | ||
| 230 | } | ||
| 231 | |||
| 232 | static void free_ep_req(struct usb_ep *ep, struct usb_request *req) | ||
| 233 | { | ||
| 234 | kfree(req->buf); | ||
| 235 | usb_ep_free_request(ep, req); | ||
| 236 | } | ||
| 237 | |||
| 238 | static const uint8_t f_midi_cin_length[] = { | ||
| 239 | 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1 | ||
| 240 | }; | ||
| 241 | |||
| 242 | /* | ||
| 243 | * Receives a chunk of MIDI data. | ||
| 244 | */ | ||
| 245 | static void f_midi_read_data(struct usb_ep *ep, int cable, | ||
| 246 | uint8_t *data, int length) | ||
| 247 | { | ||
| 248 | struct f_midi *midi = ep->driver_data; | ||
| 249 | struct snd_rawmidi_substream *substream = midi->out_substream[cable]; | ||
| 250 | |||
| 251 | if (!substream) | ||
| 252 | /* Nobody is listening - throw it on the floor. */ | ||
| 253 | return; | ||
| 254 | |||
| 255 | if (!test_bit(cable, &midi->out_triggered)) | ||
| 256 | return; | ||
| 257 | |||
| 258 | snd_rawmidi_receive(substream, data, length); | ||
| 259 | } | ||
| 260 | |||
| 261 | static void f_midi_handle_out_data(struct usb_ep *ep, struct usb_request *req) | ||
| 262 | { | ||
| 263 | unsigned int i; | ||
| 264 | u8 *buf = req->buf; | ||
| 265 | |||
| 266 | for (i = 0; i + 3 < req->actual; i += 4) | ||
| 267 | if (buf[i] != 0) { | ||
| 268 | int cable = buf[i] >> 4; | ||
| 269 | int length = f_midi_cin_length[buf[i] & 0x0f]; | ||
| 270 | f_midi_read_data(ep, cable, &buf[i + 1], length); | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | static void | ||
| 275 | f_midi_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 276 | { | ||
| 277 | struct f_midi *midi = ep->driver_data; | ||
| 278 | struct usb_composite_dev *cdev = midi->func.config->cdev; | ||
| 279 | int status = req->status; | ||
| 280 | |||
| 281 | switch (status) { | ||
| 282 | case 0: /* normal completion */ | ||
| 283 | if (ep == midi->out_ep) { | ||
| 284 | /* We received stuff. req is queued again, below */ | ||
| 285 | f_midi_handle_out_data(ep, req); | ||
| 286 | } else if (ep == midi->in_ep) { | ||
| 287 | /* Our transmit completed. See if there's more to go. | ||
| 288 | * f_midi_transmit eats req, don't queue it again. */ | ||
| 289 | f_midi_transmit(midi, req); | ||
| 290 | return; | ||
| 291 | } | ||
| 292 | break; | ||
| 293 | |||
| 294 | /* this endpoint is normally active while we're configured */ | ||
| 295 | case -ECONNABORTED: /* hardware forced ep reset */ | ||
| 296 | case -ECONNRESET: /* request dequeued */ | ||
| 297 | case -ESHUTDOWN: /* disconnect from host */ | ||
| 298 | VDBG(cdev, "%s gone (%d), %d/%d\n", ep->name, status, | ||
| 299 | req->actual, req->length); | ||
| 300 | if (ep == midi->out_ep) | ||
| 301 | f_midi_handle_out_data(ep, req); | ||
| 302 | |||
| 303 | free_ep_req(ep, req); | ||
| 304 | return; | ||
| 305 | |||
| 306 | case -EOVERFLOW: /* buffer overrun on read means that | ||
| 307 | * we didn't provide a big enough buffer. | ||
| 308 | */ | ||
| 309 | default: | ||
| 310 | DBG(cdev, "%s complete --> %d, %d/%d\n", ep->name, | ||
| 311 | status, req->actual, req->length); | ||
| 312 | break; | ||
| 313 | case -EREMOTEIO: /* short read */ | ||
| 314 | break; | ||
| 315 | } | ||
| 316 | |||
| 317 | status = usb_ep_queue(ep, req, GFP_ATOMIC); | ||
| 318 | if (status) { | ||
| 319 | ERROR(cdev, "kill %s: resubmit %d bytes --> %d\n", | ||
| 320 | ep->name, req->length, status); | ||
| 321 | usb_ep_set_halt(ep); | ||
| 322 | /* FIXME recover later ... somehow */ | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | static int f_midi_start_ep(struct f_midi *midi, | ||
| 327 | struct usb_function *f, | ||
| 328 | struct usb_ep *ep) | ||
| 329 | { | ||
| 330 | int err; | ||
| 331 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 332 | |||
| 333 | if (ep->driver_data) | ||
| 334 | usb_ep_disable(ep); | ||
| 335 | |||
| 336 | err = config_ep_by_speed(midi->gadget, f, ep); | ||
| 337 | if (err) { | ||
| 338 | ERROR(cdev, "can't configure %s: %d\n", ep->name, err); | ||
| 339 | return err; | ||
| 340 | } | ||
| 341 | |||
| 342 | err = usb_ep_enable(ep); | ||
| 343 | if (err) { | ||
| 344 | ERROR(cdev, "can't start %s: %d\n", ep->name, err); | ||
| 345 | return err; | ||
| 346 | } | ||
| 347 | |||
| 348 | ep->driver_data = midi; | ||
| 349 | |||
| 350 | return 0; | ||
| 351 | } | ||
| 352 | |||
| 353 | static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | ||
| 354 | { | ||
| 355 | struct f_midi *midi = func_to_midi(f); | ||
| 356 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 357 | unsigned i; | ||
| 358 | int err; | ||
| 359 | |||
| 360 | err = f_midi_start_ep(midi, f, midi->in_ep); | ||
| 361 | if (err) | ||
| 362 | return err; | ||
| 363 | |||
| 364 | err = f_midi_start_ep(midi, f, midi->out_ep); | ||
| 365 | if (err) | ||
| 366 | return err; | ||
| 367 | |||
| 368 | if (midi->out_ep->driver_data) | ||
| 369 | usb_ep_disable(midi->out_ep); | ||
| 370 | |||
| 371 | err = config_ep_by_speed(midi->gadget, f, midi->out_ep); | ||
| 372 | if (err) { | ||
| 373 | ERROR(cdev, "can't configure %s: %d\n", | ||
| 374 | midi->out_ep->name, err); | ||
| 375 | return err; | ||
| 376 | } | ||
| 377 | |||
| 378 | err = usb_ep_enable(midi->out_ep); | ||
| 379 | if (err) { | ||
| 380 | ERROR(cdev, "can't start %s: %d\n", | ||
| 381 | midi->out_ep->name, err); | ||
| 382 | return err; | ||
| 383 | } | ||
| 384 | |||
| 385 | midi->out_ep->driver_data = midi; | ||
| 386 | |||
| 387 | /* allocate a bunch of read buffers and queue them all at once. */ | ||
| 388 | for (i = 0; i < midi->qlen && err == 0; i++) { | ||
| 389 | struct usb_request *req = | ||
| 390 | alloc_ep_req(midi->out_ep, midi->buflen); | ||
| 391 | if (req == NULL) | ||
| 392 | return -ENOMEM; | ||
| 393 | |||
| 394 | req->complete = f_midi_complete; | ||
| 395 | err = usb_ep_queue(midi->out_ep, req, GFP_ATOMIC); | ||
| 396 | if (err) { | ||
| 397 | ERROR(midi, "%s queue req: %d\n", | ||
| 398 | midi->out_ep->name, err); | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | return 0; | ||
| 403 | } | ||
| 404 | |||
| 405 | static void f_midi_disable(struct usb_function *f) | ||
| 406 | { | ||
| 407 | struct f_midi *midi = func_to_midi(f); | ||
| 408 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 409 | |||
| 410 | DBG(cdev, "disable\n"); | ||
| 411 | |||
| 412 | /* | ||
| 413 | * just disable endpoints, forcing completion of pending i/o. | ||
| 414 | * all our completion handlers free their requests in this case. | ||
| 415 | */ | ||
| 416 | usb_ep_disable(midi->in_ep); | ||
| 417 | usb_ep_disable(midi->out_ep); | ||
| 418 | } | ||
| 419 | |||
| 420 | static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) | ||
| 421 | { | ||
| 422 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 423 | struct f_midi *midi = func_to_midi(f); | ||
| 424 | struct snd_card *card; | ||
| 425 | |||
| 426 | DBG(cdev, "unbind\n"); | ||
| 427 | |||
| 428 | /* just to be sure */ | ||
| 429 | f_midi_disable(f); | ||
| 430 | |||
| 431 | card = midi->card; | ||
| 432 | midi->card = NULL; | ||
| 433 | if (card) | ||
| 434 | snd_card_free(card); | ||
| 435 | |||
| 436 | kfree(midi->id); | ||
| 437 | midi->id = NULL; | ||
| 438 | |||
| 439 | usb_free_descriptors(f->descriptors); | ||
| 440 | kfree(midi); | ||
| 441 | } | ||
| 442 | |||
| 443 | static int f_midi_snd_free(struct snd_device *device) | ||
| 444 | { | ||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | static void f_midi_transmit_packet(struct usb_request *req, uint8_t p0, | ||
| 449 | uint8_t p1, uint8_t p2, uint8_t p3) | ||
| 450 | { | ||
| 451 | unsigned length = req->length; | ||
| 452 | u8 *buf = (u8 *)req->buf + length; | ||
| 453 | |||
| 454 | buf[0] = p0; | ||
| 455 | buf[1] = p1; | ||
| 456 | buf[2] = p2; | ||
| 457 | buf[3] = p3; | ||
| 458 | req->length = length + 4; | ||
| 459 | } | ||
| 460 | |||
| 461 | /* | ||
| 462 | * Converts MIDI commands to USB MIDI packets. | ||
| 463 | */ | ||
| 464 | static void f_midi_transmit_byte(struct usb_request *req, | ||
| 465 | struct gmidi_in_port *port, uint8_t b) | ||
| 466 | { | ||
| 467 | uint8_t p0 = port->cable << 4; | ||
| 468 | |||
| 469 | if (b >= 0xf8) { | ||
| 470 | f_midi_transmit_packet(req, p0 | 0x0f, b, 0, 0); | ||
| 471 | } else if (b >= 0xf0) { | ||
| 472 | switch (b) { | ||
| 473 | case 0xf0: | ||
| 474 | port->data[0] = b; | ||
| 475 | port->state = STATE_SYSEX_1; | ||
| 476 | break; | ||
| 477 | case 0xf1: | ||
| 478 | case 0xf3: | ||
| 479 | port->data[0] = b; | ||
| 480 | port->state = STATE_1PARAM; | ||
| 481 | break; | ||
| 482 | case 0xf2: | ||
| 483 | port->data[0] = b; | ||
| 484 | port->state = STATE_2PARAM_1; | ||
| 485 | break; | ||
| 486 | case 0xf4: | ||
| 487 | case 0xf5: | ||
| 488 | port->state = STATE_UNKNOWN; | ||
| 489 | break; | ||
| 490 | case 0xf6: | ||
| 491 | f_midi_transmit_packet(req, p0 | 0x05, 0xf6, 0, 0); | ||
| 492 | port->state = STATE_UNKNOWN; | ||
| 493 | break; | ||
| 494 | case 0xf7: | ||
| 495 | switch (port->state) { | ||
| 496 | case STATE_SYSEX_0: | ||
| 497 | f_midi_transmit_packet(req, | ||
| 498 | p0 | 0x05, 0xf7, 0, 0); | ||
| 499 | break; | ||
| 500 | case STATE_SYSEX_1: | ||
| 501 | f_midi_transmit_packet(req, | ||
| 502 | p0 | 0x06, port->data[0], 0xf7, 0); | ||
| 503 | break; | ||
| 504 | case STATE_SYSEX_2: | ||
| 505 | f_midi_transmit_packet(req, | ||
| 506 | p0 | 0x07, port->data[0], | ||
| 507 | port->data[1], 0xf7); | ||
| 508 | break; | ||
| 509 | } | ||
| 510 | port->state = STATE_UNKNOWN; | ||
| 511 | break; | ||
| 512 | } | ||
| 513 | } else if (b >= 0x80) { | ||
| 514 | port->data[0] = b; | ||
| 515 | if (b >= 0xc0 && b <= 0xdf) | ||
| 516 | port->state = STATE_1PARAM; | ||
| 517 | else | ||
| 518 | port->state = STATE_2PARAM_1; | ||
| 519 | } else { /* b < 0x80 */ | ||
| 520 | switch (port->state) { | ||
| 521 | case STATE_1PARAM: | ||
| 522 | if (port->data[0] < 0xf0) { | ||
| 523 | p0 |= port->data[0] >> 4; | ||
| 524 | } else { | ||
| 525 | p0 |= 0x02; | ||
| 526 | port->state = STATE_UNKNOWN; | ||
| 527 | } | ||
| 528 | f_midi_transmit_packet(req, p0, port->data[0], b, 0); | ||
| 529 | break; | ||
| 530 | case STATE_2PARAM_1: | ||
| 531 | port->data[1] = b; | ||
| 532 | port->state = STATE_2PARAM_2; | ||
| 533 | break; | ||
| 534 | case STATE_2PARAM_2: | ||
| 535 | if (port->data[0] < 0xf0) { | ||
| 536 | p0 |= port->data[0] >> 4; | ||
| 537 | port->state = STATE_2PARAM_1; | ||
| 538 | } else { | ||
| 539 | p0 |= 0x03; | ||
| 540 | port->state = STATE_UNKNOWN; | ||
| 541 | } | ||
| 542 | f_midi_transmit_packet(req, | ||
| 543 | p0, port->data[0], port->data[1], b); | ||
| 544 | break; | ||
| 545 | case STATE_SYSEX_0: | ||
| 546 | port->data[0] = b; | ||
| 547 | port->state = STATE_SYSEX_1; | ||
| 548 | break; | ||
| 549 | case STATE_SYSEX_1: | ||
| 550 | port->data[1] = b; | ||
| 551 | port->state = STATE_SYSEX_2; | ||
| 552 | break; | ||
| 553 | case STATE_SYSEX_2: | ||
| 554 | f_midi_transmit_packet(req, | ||
| 555 | p0 | 0x04, port->data[0], port->data[1], b); | ||
| 556 | port->state = STATE_SYSEX_0; | ||
| 557 | break; | ||
| 558 | } | ||
| 559 | } | ||
| 560 | } | ||
| 561 | |||
| 562 | static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) | ||
| 563 | { | ||
| 564 | struct usb_ep *ep = midi->in_ep; | ||
| 565 | int i; | ||
| 566 | |||
| 567 | if (!ep) | ||
| 568 | return; | ||
| 569 | |||
| 570 | if (!req) | ||
| 571 | req = alloc_ep_req(ep, midi->buflen); | ||
| 572 | |||
| 573 | if (!req) { | ||
| 574 | ERROR(midi, "gmidi_transmit: alloc_ep_request failed\n"); | ||
| 575 | return; | ||
| 576 | } | ||
| 577 | req->length = 0; | ||
| 578 | req->complete = f_midi_complete; | ||
| 579 | |||
| 580 | for (i = 0; i < MAX_PORTS; i++) { | ||
| 581 | struct gmidi_in_port *port = midi->in_port[i]; | ||
| 582 | struct snd_rawmidi_substream *substream = midi->in_substream[i]; | ||
| 583 | |||
| 584 | if (!port || !port->active || !substream) | ||
| 585 | continue; | ||
| 586 | |||
| 587 | while (req->length + 3 < midi->buflen) { | ||
| 588 | uint8_t b; | ||
| 589 | if (snd_rawmidi_transmit(substream, &b, 1) != 1) { | ||
| 590 | port->active = 0; | ||
| 591 | break; | ||
| 592 | } | ||
| 593 | f_midi_transmit_byte(req, port, b); | ||
| 594 | } | ||
| 595 | } | ||
| 596 | |||
| 597 | if (req->length > 0) | ||
| 598 | usb_ep_queue(ep, req, GFP_ATOMIC); | ||
| 599 | else | ||
| 600 | free_ep_req(ep, req); | ||
| 601 | } | ||
| 602 | |||
| 603 | static void f_midi_in_tasklet(unsigned long data) | ||
| 604 | { | ||
| 605 | struct f_midi *midi = (struct f_midi *) data; | ||
| 606 | f_midi_transmit(midi, NULL); | ||
| 607 | } | ||
| 608 | |||
| 609 | static int f_midi_in_open(struct snd_rawmidi_substream *substream) | ||
| 610 | { | ||
| 611 | struct f_midi *midi = substream->rmidi->private_data; | ||
| 612 | |||
| 613 | if (!midi->in_port[substream->number]) | ||
| 614 | return -EINVAL; | ||
| 615 | |||
| 616 | VDBG(midi, "%s()\n", __func__); | ||
| 617 | midi->in_substream[substream->number] = substream; | ||
| 618 | midi->in_port[substream->number]->state = STATE_UNKNOWN; | ||
| 619 | return 0; | ||
| 620 | } | ||
| 621 | |||
| 622 | static int f_midi_in_close(struct snd_rawmidi_substream *substream) | ||
| 623 | { | ||
| 624 | struct f_midi *midi = substream->rmidi->private_data; | ||
| 625 | |||
| 626 | VDBG(midi, "%s()\n", __func__); | ||
| 627 | return 0; | ||
| 628 | } | ||
| 629 | |||
| 630 | static void f_midi_in_trigger(struct snd_rawmidi_substream *substream, int up) | ||
| 631 | { | ||
| 632 | struct f_midi *midi = substream->rmidi->private_data; | ||
| 633 | |||
| 634 | if (!midi->in_port[substream->number]) | ||
| 635 | return; | ||
| 636 | |||
| 637 | VDBG(midi, "%s() %d\n", __func__, up); | ||
| 638 | midi->in_port[substream->number]->active = up; | ||
| 639 | if (up) | ||
| 640 | tasklet_hi_schedule(&midi->tasklet); | ||
| 641 | } | ||
| 642 | |||
| 643 | static int f_midi_out_open(struct snd_rawmidi_substream *substream) | ||
| 644 | { | ||
| 645 | struct f_midi *midi = substream->rmidi->private_data; | ||
| 646 | |||
| 647 | if (substream->number >= MAX_PORTS) | ||
| 648 | return -EINVAL; | ||
| 649 | |||
| 650 | VDBG(midi, "%s()\n", __func__); | ||
| 651 | midi->out_substream[substream->number] = substream; | ||
| 652 | return 0; | ||
| 653 | } | ||
| 654 | |||
| 655 | static int f_midi_out_close(struct snd_rawmidi_substream *substream) | ||
| 656 | { | ||
| 657 | struct f_midi *midi = substream->rmidi->private_data; | ||
| 658 | |||
| 659 | VDBG(midi, "%s()\n", __func__); | ||
| 660 | return 0; | ||
| 661 | } | ||
| 662 | |||
| 663 | static void f_midi_out_trigger(struct snd_rawmidi_substream *substream, int up) | ||
| 664 | { | ||
| 665 | struct f_midi *midi = substream->rmidi->private_data; | ||
| 666 | |||
| 667 | VDBG(midi, "%s()\n", __func__); | ||
| 668 | |||
| 669 | if (up) | ||
| 670 | set_bit(substream->number, &midi->out_triggered); | ||
| 671 | else | ||
| 672 | clear_bit(substream->number, &midi->out_triggered); | ||
| 673 | } | ||
| 674 | |||
| 675 | static struct snd_rawmidi_ops gmidi_in_ops = { | ||
| 676 | .open = f_midi_in_open, | ||
| 677 | .close = f_midi_in_close, | ||
| 678 | .trigger = f_midi_in_trigger, | ||
| 679 | }; | ||
| 680 | |||
| 681 | static struct snd_rawmidi_ops gmidi_out_ops = { | ||
| 682 | .open = f_midi_out_open, | ||
| 683 | .close = f_midi_out_close, | ||
| 684 | .trigger = f_midi_out_trigger | ||
| 685 | }; | ||
| 686 | |||
| 687 | /* register as a sound "card" */ | ||
| 688 | static int f_midi_register_card(struct f_midi *midi) | ||
| 689 | { | ||
| 690 | struct snd_card *card; | ||
| 691 | struct snd_rawmidi *rmidi; | ||
| 692 | int err; | ||
| 693 | static struct snd_device_ops ops = { | ||
| 694 | .dev_free = f_midi_snd_free, | ||
| 695 | }; | ||
| 696 | |||
| 697 | err = snd_card_create(midi->index, midi->id, THIS_MODULE, 0, &card); | ||
| 698 | if (err < 0) { | ||
| 699 | ERROR(midi, "snd_card_create() failed\n"); | ||
| 700 | goto fail; | ||
| 701 | } | ||
| 702 | midi->card = card; | ||
| 703 | |||
| 704 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, midi, &ops); | ||
| 705 | if (err < 0) { | ||
| 706 | ERROR(midi, "snd_device_new() failed: error %d\n", err); | ||
| 707 | goto fail; | ||
| 708 | } | ||
| 709 | |||
| 710 | strcpy(card->driver, f_midi_longname); | ||
| 711 | strcpy(card->longname, f_midi_longname); | ||
| 712 | strcpy(card->shortname, f_midi_shortname); | ||
| 713 | |||
| 714 | /* Set up rawmidi */ | ||
| 715 | snd_component_add(card, "MIDI"); | ||
| 716 | err = snd_rawmidi_new(card, card->longname, 0, | ||
| 717 | midi->out_ports, midi->in_ports, &rmidi); | ||
| 718 | if (err < 0) { | ||
| 719 | ERROR(midi, "snd_rawmidi_new() failed: error %d\n", err); | ||
| 720 | goto fail; | ||
| 721 | } | ||
| 722 | midi->rmidi = rmidi; | ||
| 723 | strcpy(rmidi->name, card->shortname); | ||
| 724 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | | ||
| 725 | SNDRV_RAWMIDI_INFO_INPUT | | ||
| 726 | SNDRV_RAWMIDI_INFO_DUPLEX; | ||
| 727 | rmidi->private_data = midi; | ||
| 728 | |||
| 729 | /* | ||
| 730 | * Yes, rawmidi OUTPUT = USB IN, and rawmidi INPUT = USB OUT. | ||
| 731 | * It's an upside-down world being a gadget. | ||
| 732 | */ | ||
| 733 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &gmidi_in_ops); | ||
| 734 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &gmidi_out_ops); | ||
| 735 | |||
| 736 | snd_card_set_dev(card, &midi->gadget->dev); | ||
| 737 | |||
| 738 | /* register it - we're ready to go */ | ||
| 739 | err = snd_card_register(card); | ||
| 740 | if (err < 0) { | ||
| 741 | ERROR(midi, "snd_card_register() failed\n"); | ||
| 742 | goto fail; | ||
| 743 | } | ||
| 744 | |||
| 745 | VDBG(midi, "%s() finished ok\n", __func__); | ||
| 746 | return 0; | ||
| 747 | |||
| 748 | fail: | ||
| 749 | if (midi->card) { | ||
| 750 | snd_card_free(midi->card); | ||
| 751 | midi->card = NULL; | ||
| 752 | } | ||
| 753 | return err; | ||
| 754 | } | ||
| 755 | |||
| 756 | /* MIDI function driver setup/binding */ | ||
| 757 | |||
| 758 | static int __init | ||
| 759 | f_midi_bind(struct usb_configuration *c, struct usb_function *f) | ||
| 760 | { | ||
| 761 | struct usb_descriptor_header *midi_function[(MAX_PORTS * 2) + 12]; | ||
| 762 | struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS]; | ||
| 763 | struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS]; | ||
| 764 | struct usb_composite_dev *cdev = c->cdev; | ||
| 765 | struct f_midi *midi = func_to_midi(f); | ||
| 766 | int status, n, jack = 1, i = 0; | ||
| 767 | |||
| 768 | /* maybe allocate device-global string ID */ | ||
| 769 | if (midi_string_defs[0].id == 0) { | ||
| 770 | status = usb_string_id(c->cdev); | ||
| 771 | if (status < 0) | ||
| 772 | goto fail; | ||
| 773 | midi_string_defs[0].id = status; | ||
| 774 | } | ||
| 775 | |||
| 776 | /* We have two interfaces, AudioControl and MIDIStreaming */ | ||
| 777 | status = usb_interface_id(c, f); | ||
| 778 | if (status < 0) | ||
| 779 | goto fail; | ||
| 780 | ac_interface_desc.bInterfaceNumber = status; | ||
| 781 | |||
| 782 | status = usb_interface_id(c, f); | ||
| 783 | if (status < 0) | ||
| 784 | goto fail; | ||
| 785 | ms_interface_desc.bInterfaceNumber = status; | ||
| 786 | ac_header_desc.baInterfaceNr[0] = status; | ||
| 787 | |||
| 788 | status = -ENODEV; | ||
| 789 | |||
| 790 | /* allocate instance-specific endpoints */ | ||
| 791 | midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc); | ||
| 792 | if (!midi->in_ep) | ||
| 793 | goto fail; | ||
| 794 | midi->in_ep->driver_data = cdev; /* claim */ | ||
| 795 | |||
| 796 | midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc); | ||
| 797 | if (!midi->out_ep) | ||
| 798 | goto fail; | ||
| 799 | midi->out_ep->driver_data = cdev; /* claim */ | ||
| 800 | |||
| 801 | /* | ||
| 802 | * construct the function's descriptor set. As the number of | ||
| 803 | * input and output MIDI ports is configurable, we have to do | ||
| 804 | * it that way. | ||
| 805 | */ | ||
| 806 | |||
| 807 | /* add the headers - these are always the same */ | ||
| 808 | midi_function[i++] = (struct usb_descriptor_header *) &ac_interface_desc; | ||
| 809 | midi_function[i++] = (struct usb_descriptor_header *) &ac_header_desc; | ||
| 810 | midi_function[i++] = (struct usb_descriptor_header *) &ms_interface_desc; | ||
| 811 | |||
| 812 | /* calculate the header's wTotalLength */ | ||
| 813 | n = USB_DT_MS_HEADER_SIZE | ||
| 814 | + (1 + midi->in_ports) * USB_DT_MIDI_IN_SIZE | ||
| 815 | + (1 + midi->out_ports) * USB_DT_MIDI_OUT_SIZE(1); | ||
| 816 | ms_header_desc.wTotalLength = cpu_to_le16(n); | ||
| 817 | |||
| 818 | midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc; | ||
| 819 | |||
| 820 | /* we have one embedded IN jack */ | ||
| 821 | jack_in_emb_desc.bJackID = jack++; | ||
| 822 | midi_function[i++] = (struct usb_descriptor_header *) &jack_in_emb_desc; | ||
| 823 | |||
| 824 | /* and a dynamic amount of external IN jacks */ | ||
| 825 | for (n = 0; n < midi->in_ports; n++) { | ||
| 826 | struct usb_midi_in_jack_descriptor *ext = &jack_in_ext_desc[n]; | ||
| 827 | |||
| 828 | ext->bLength = USB_DT_MIDI_IN_SIZE; | ||
| 829 | ext->bDescriptorType = USB_DT_CS_INTERFACE; | ||
| 830 | ext->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; | ||
| 831 | ext->bJackType = USB_MS_EXTERNAL; | ||
| 832 | ext->bJackID = jack++; | ||
| 833 | ext->iJack = 0; | ||
| 834 | |||
| 835 | midi_function[i++] = (struct usb_descriptor_header *) ext; | ||
| 836 | } | ||
| 837 | |||
| 838 | /* one embedded OUT jack ... */ | ||
| 839 | jack_out_emb_desc.bLength = USB_DT_MIDI_OUT_SIZE(midi->in_ports); | ||
| 840 | jack_out_emb_desc.bJackID = jack++; | ||
| 841 | jack_out_emb_desc.bNrInputPins = midi->in_ports; | ||
| 842 | /* ... which referencess all external IN jacks */ | ||
| 843 | for (n = 0; n < midi->in_ports; n++) { | ||
| 844 | jack_out_emb_desc.pins[n].baSourceID = jack_in_ext_desc[n].bJackID; | ||
| 845 | jack_out_emb_desc.pins[n].baSourcePin = 1; | ||
| 846 | } | ||
| 847 | |||
| 848 | midi_function[i++] = (struct usb_descriptor_header *) &jack_out_emb_desc; | ||
| 849 | |||
| 850 | /* and multiple external OUT jacks ... */ | ||
| 851 | for (n = 0; n < midi->out_ports; n++) { | ||
| 852 | struct usb_midi_out_jack_descriptor_1 *ext = &jack_out_ext_desc[n]; | ||
| 853 | int m; | ||
| 854 | |||
| 855 | ext->bLength = USB_DT_MIDI_OUT_SIZE(1); | ||
| 856 | ext->bDescriptorType = USB_DT_CS_INTERFACE; | ||
| 857 | ext->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; | ||
| 858 | ext->bJackType = USB_MS_EXTERNAL; | ||
| 859 | ext->bJackID = jack++; | ||
| 860 | ext->bNrInputPins = 1; | ||
| 861 | ext->iJack = 0; | ||
| 862 | /* ... which all reference the same embedded IN jack */ | ||
| 863 | for (m = 0; m < midi->out_ports; m++) { | ||
| 864 | ext->pins[m].baSourceID = jack_in_emb_desc.bJackID; | ||
| 865 | ext->pins[m].baSourcePin = 1; | ||
| 866 | } | ||
| 867 | |||
| 868 | midi_function[i++] = (struct usb_descriptor_header *) ext; | ||
| 869 | } | ||
| 870 | |||
| 871 | /* configure the endpoint descriptors ... */ | ||
| 872 | ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); | ||
| 873 | ms_out_desc.bNumEmbMIDIJack = midi->in_ports; | ||
| 874 | for (n = 0; n < midi->in_ports; n++) | ||
| 875 | ms_out_desc.baAssocJackID[n] = jack_in_emb_desc.bJackID; | ||
| 876 | |||
| 877 | ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); | ||
| 878 | ms_in_desc.bNumEmbMIDIJack = midi->out_ports; | ||
| 879 | for (n = 0; n < midi->out_ports; n++) | ||
| 880 | ms_in_desc.baAssocJackID[n] = jack_out_emb_desc.bJackID; | ||
| 881 | |||
| 882 | /* ... and add them to the list */ | ||
| 883 | midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc; | ||
| 884 | midi_function[i++] = (struct usb_descriptor_header *) &ms_out_desc; | ||
| 885 | midi_function[i++] = (struct usb_descriptor_header *) &bulk_in_desc; | ||
| 886 | midi_function[i++] = (struct usb_descriptor_header *) &ms_in_desc; | ||
| 887 | midi_function[i++] = NULL; | ||
| 888 | |||
| 889 | /* | ||
| 890 | * support all relevant hardware speeds... we expect that when | ||
| 891 | * hardware is dual speed, all bulk-capable endpoints work at | ||
| 892 | * both speeds | ||
| 893 | */ | ||
| 894 | /* copy descriptors, and track endpoint copies */ | ||
| 895 | if (gadget_is_dualspeed(c->cdev->gadget)) { | ||
| 896 | c->highspeed = true; | ||
| 897 | bulk_in_desc.wMaxPacketSize = cpu_to_le16(512); | ||
| 898 | bulk_out_desc.wMaxPacketSize = cpu_to_le16(512); | ||
| 899 | f->hs_descriptors = usb_copy_descriptors(midi_function); | ||
| 900 | } else { | ||
| 901 | f->descriptors = usb_copy_descriptors(midi_function); | ||
| 902 | } | ||
| 903 | |||
| 904 | return 0; | ||
| 905 | |||
| 906 | fail: | ||
| 907 | /* we might as well release our claims on endpoints */ | ||
| 908 | if (midi->out_ep) | ||
| 909 | midi->out_ep->driver_data = NULL; | ||
| 910 | if (midi->in_ep) | ||
| 911 | midi->in_ep->driver_data = NULL; | ||
| 912 | |||
| 913 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | ||
| 914 | |||
| 915 | return status; | ||
| 916 | } | ||
| 917 | |||
| 918 | /** | ||
| 919 | * f_midi_bind_config - add USB MIDI function to a configuration | ||
| 920 | * @c: the configuration to supcard the USB audio function | ||
| 921 | * @index: the soundcard index to use for the ALSA device creation | ||
| 922 | * @id: the soundcard id to use for the ALSA device creation | ||
| 923 | * @buflen: the buffer length to use | ||
| 924 | * @qlen the number of read requests to pre-allocate | ||
| 925 | * Context: single threaded during gadget setup | ||
| 926 | * | ||
| 927 | * Returns zero on success, else negative errno. | ||
| 928 | */ | ||
| 929 | int __init f_midi_bind_config(struct usb_configuration *c, | ||
| 930 | int index, char *id, | ||
| 931 | unsigned int in_ports, | ||
| 932 | unsigned int out_ports, | ||
| 933 | unsigned int buflen, | ||
| 934 | unsigned int qlen) | ||
| 935 | { | ||
| 936 | struct f_midi *midi; | ||
| 937 | int status, i; | ||
| 938 | |||
| 939 | /* sanity check */ | ||
| 940 | if (in_ports > MAX_PORTS || out_ports > MAX_PORTS) | ||
| 941 | return -EINVAL; | ||
| 942 | |||
| 943 | /* allocate and initialize one new instance */ | ||
| 944 | midi = kzalloc(sizeof *midi, GFP_KERNEL); | ||
| 945 | if (!midi) { | ||
| 946 | status = -ENOMEM; | ||
| 947 | goto fail; | ||
| 948 | } | ||
| 949 | |||
| 950 | for (i = 0; i < in_ports; i++) { | ||
| 951 | struct gmidi_in_port *port = kzalloc(sizeof(*port), GFP_KERNEL); | ||
| 952 | if (!port) { | ||
| 953 | status = -ENOMEM; | ||
| 954 | goto setup_fail; | ||
| 955 | } | ||
| 956 | |||
| 957 | port->midi = midi; | ||
| 958 | port->active = 0; | ||
| 959 | port->cable = i; | ||
| 960 | midi->in_port[i] = port; | ||
| 961 | } | ||
| 962 | |||
| 963 | midi->gadget = c->cdev->gadget; | ||
| 964 | tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi); | ||
| 965 | |||
| 966 | /* set up ALSA midi devices */ | ||
| 967 | midi->in_ports = in_ports; | ||
| 968 | midi->out_ports = out_ports; | ||
| 969 | status = f_midi_register_card(midi); | ||
| 970 | if (status < 0) | ||
| 971 | goto setup_fail; | ||
| 972 | |||
| 973 | midi->func.name = "gmidi function"; | ||
| 974 | midi->func.strings = midi_strings; | ||
| 975 | midi->func.bind = f_midi_bind; | ||
| 976 | midi->func.unbind = f_midi_unbind; | ||
| 977 | midi->func.set_alt = f_midi_set_alt; | ||
| 978 | midi->func.disable = f_midi_disable; | ||
| 979 | |||
| 980 | midi->id = kstrdup(id, GFP_KERNEL); | ||
| 981 | midi->index = index; | ||
| 982 | midi->buflen = buflen; | ||
| 983 | midi->qlen = qlen; | ||
| 984 | |||
| 985 | status = usb_add_function(c, &midi->func); | ||
| 986 | if (status) | ||
| 987 | goto setup_fail; | ||
| 988 | |||
| 989 | return 0; | ||
| 990 | |||
| 991 | setup_fail: | ||
| 992 | for (--i; i >= 0; i--) | ||
| 993 | kfree(midi->in_port[i]); | ||
| 994 | kfree(midi); | ||
| 995 | fail: | ||
| 996 | return status; | ||
| 997 | } | ||
| 998 | |||
| @@ -13,15 +13,6 @@ · 12 unmodified lines | |||
| 13 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
| 14 | * the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License, or |
| 15 | * (at your option) any later version. | 15 | * (at your option) any later version. |
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License | ||
| 23 | * along with this program; if not, write to the Free Software | ||
| 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 25 | */ | 16 | */ |
| 26 | 17 | ||
| 27 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| @@ -10,15 +10,6 @@ · 9 unmodified lines | |||
| 10 | * it under the terms of the GNU General Public License as published by | 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 | 11 | * the Free Software Foundation; either version 2 of the License, or |
| 12 | * (at your option) any later version. | 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 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | */ | 13 | */ |
| 23 | 14 | ||
| 24 | /* #define VERBOSE_DEBUG */ | 15 | /* #define VERBOSE_DEBUG */ |
| @@ -8,16 +8,6 @@ · 7 unmodified lines | |||
| 8 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU General Public License | 9 | * modify it under the terms of the GNU General Public License |
| 10 | * version 2 as published by the Free Software Foundation. | 10 | * version 2 as published by the Free Software Foundation. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, but | ||
| 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 20 | * 02110-1301 USA | ||
| 21 | */ | 11 | */ |
| 22 | 12 | ||
| 23 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
| @@ -11,15 +11,6 @@ · 10 unmodified lines | |||
| 11 | * it under the terms of the GNU General Public License as published by | 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 | 12 | * the Free Software Foundation; either version 2 of the License, or |
| 13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 23 | */ | 14 | */ |
| 24 | 15 | ||
| 25 | /* #define VERBOSE_DEBUG */ | 16 | /* #define VERBOSE_DEBUG */ |
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | /* #define VERBOSE_DEBUG */ | 13 | /* #define VERBOSE_DEBUG */ |
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | */ | 11 | */ |
| 13 | 12 | ||
| 14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | */ | 11 | */ |
| 13 | 12 | ||
| 14 | #ifndef _F_UVC_H_ | 13 | #ifndef _F_UVC_H_ |
| @@ -69,8 +69,7 @@ · 68 unmodified lines | |||
| 69 | * each LUN would be settable independently as a disk drive or a CD-ROM | 69 | * each LUN would be settable independently as a disk drive or a CD-ROM |
| 70 | * drive, but currently all LUNs have to be the same type. The CD-ROM | 70 | * drive, but currently all LUNs have to be the same type. The CD-ROM |
| 71 | * emulation includes a single data track and no audio tracks; hence there | 71 | * emulation includes a single data track and no audio tracks; hence there |
| 72 | * need be only one backing file per LUN. Note also that the CD-ROM block | 72 | * need be only one backing file per LUN. |
| 73 | * length is set to 512 rather than the more common value 2048. | ||
| 74 | * | 73 | * |
| 75 | * Requirements are modest; only a bulk-in and a bulk-out endpoint are | 74 | * Requirements are modest; only a bulk-in and a bulk-out endpoint are |
| 76 | * needed (an interrupt-out endpoint is also needed for CBI). The memory | 75 | * needed (an interrupt-out endpoint is also needed for CBI). The memory |
| @@ -461,7 +460,6 @@ struct fsg_dev { · 384 unmodified lines | |||
| 461 | 460 | ||
| 462 | struct fsg_buffhd *next_buffhd_to_fill; | 461 | struct fsg_buffhd *next_buffhd_to_fill; |
| 463 | struct fsg_buffhd *next_buffhd_to_drain; | 462 | struct fsg_buffhd *next_buffhd_to_drain; |
| 464 | struct fsg_buffhd buffhds[FSG_NUM_BUFFERS]; | ||
| 465 | 463 | ||
| 466 | int thread_wakeup_needed; | 464 | int thread_wakeup_needed; |
| 467 | struct completion thread_notifier; | 465 | struct completion thread_notifier; |
| @@ -488,6 +486,8 @@ struct fsg_dev { · 20 unmodified lines | |||
| 488 | unsigned int nluns; | 486 | unsigned int nluns; |
| 489 | struct fsg_lun *luns; | 487 | struct fsg_lun *luns; |
| 490 | struct fsg_lun *curlun; | 488 | struct fsg_lun *curlun; |
| 489 | /* Must be the last entry */ | ||
| 490 | struct fsg_buffhd buffhds[]; | ||
| 491 | }; | 491 | }; |
| 492 | 492 | ||
| 493 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 493 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
| @@ -586,7 +586,19 @@ dev_qualifier = { · 92 unmodified lines | |||
| 586 | .bNumConfigurations = 1, | 586 | .bNumConfigurations = 1, |
| 587 | }; | 587 | }; |
| 588 | 588 | ||
| 589 | static int populate_bos(struct fsg_dev *fsg, u8 *buf) | ||
| 590 | { | ||
| 591 | memcpy(buf, &fsg_bos_desc, USB_DT_BOS_SIZE); | ||
| 592 | buf += USB_DT_BOS_SIZE; | ||
| 593 | |||
| 594 | memcpy(buf, &fsg_ext_cap_desc, USB_DT_USB_EXT_CAP_SIZE); | ||
| 595 | buf += USB_DT_USB_EXT_CAP_SIZE; | ||
| 589 | 596 | ||
| 597 | memcpy(buf, &fsg_ss_cap_desc, USB_DT_USB_SS_CAP_SIZE); | ||
| 598 | |||
| 599 | return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE | ||
| 600 | + USB_DT_USB_EXT_CAP_SIZE; | ||
| 601 | } | ||
| 590 | 602 | ||
| 591 | /* | 603 | /* |
| 592 | * Config descriptors must agree with the code that sets configurations | 604 | * Config descriptors must agree with the code that sets configurations |
| @@ -935,7 +947,8 @@ static int standard_setup_req(struct fsg_dev *fsg, · 342 unmodified lines | |||
| 935 | break; | 947 | break; |
| 936 | case USB_DT_DEVICE_QUALIFIER: | 948 | case USB_DT_DEVICE_QUALIFIER: |
| 937 | VDBG(fsg, "get device qualifier\n"); | 949 | VDBG(fsg, "get device qualifier\n"); |
| 938 | if (!gadget_is_dualspeed(fsg->gadget)) | 950 | if (!gadget_is_dualspeed(fsg->gadget) || |
| 951 | fsg->gadget->speed == USB_SPEED_SUPER) | ||
| 939 | break; | 952 | break; |
| 940 | /* | 953 | /* |
| 941 | * Assume ep0 uses the same maxpacket value for both | 954 | * Assume ep0 uses the same maxpacket value for both |
| @@ -948,7 +961,8 @@ static int standard_setup_req(struct fsg_dev *fsg, · 6 unmodified lines | |||
| 948 | 961 | ||
| 949 | case USB_DT_OTHER_SPEED_CONFIG: | 962 | case USB_DT_OTHER_SPEED_CONFIG: |
| 950 | VDBG(fsg, "get other-speed config descriptor\n"); | 963 | VDBG(fsg, "get other-speed config descriptor\n"); |
| 951 | if (!gadget_is_dualspeed(fsg->gadget)) | 964 | if (!gadget_is_dualspeed(fsg->gadget) || |
| 965 | fsg->gadget->speed == USB_SPEED_SUPER) | ||
| 952 | break; | 966 | break; |
| 953 | goto get_config; | 967 | goto get_config; |
| 954 | case USB_DT_CONFIG: | 968 | case USB_DT_CONFIG: |
| @@ -967,7 +981,15 @@ get_config: · 12 unmodified lines | |||
| 967 | value = usb_gadget_get_string(&fsg_stringtab, | 981 | value = usb_gadget_get_string(&fsg_stringtab, |
| 968 | w_value & 0xff, req->buf); | 982 | w_value & 0xff, req->buf); |
| 969 | break; | 983 | break; |
| 984 | |||
| 985 | case USB_DT_BOS: | ||
| 986 | VDBG(fsg, "get bos descriptor\n"); | ||
| 987 | |||
| 988 | if (gadget_is_superspeed(fsg->gadget)) | ||
| 989 | value = populate_bos(fsg, req->buf); | ||
| 990 | break; | ||
| 970 | } | 991 | } |
| 992 | |||
| 971 | break; | 993 | break; |
| 972 | 994 | ||
| 973 | /* One config, two speeds */ | 995 | /* One config, two speeds */ |
| @@ -1136,7 +1158,6 @@ static int do_read(struct fsg_dev *fsg) · 162 unmodified lines | |||
| 1136 | u32 amount_left; | 1158 | u32 amount_left; |
| 1137 | loff_t file_offset, file_offset_tmp; | 1159 | loff_t file_offset, file_offset_tmp; |
| 1138 | unsigned int amount; | 1160 | unsigned int amount; |
| 1139 | unsigned int partial_page; | ||
| 1140 | ssize_t nread; | 1161 | ssize_t nread; |
| 1141 | 1162 | ||
| 1142 | /* Get the starting Logical Block Address and check that it's | 1163 | /* Get the starting Logical Block Address and check that it's |
| @@ -1158,7 +1179,7 @@ static int do_read(struct fsg_dev *fsg) · 15 unmodified lines | |||
| 1158 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1179 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 1159 | return -EINVAL; | 1180 | return -EINVAL; |
| 1160 | } | 1181 | } |
| 1161 | file_offset = ((loff_t) lba) << 9; | 1182 | file_offset = ((loff_t) lba) << curlun->blkbits; |
| 1162 | 1183 | ||
| 1163 | /* Carry out the file reads */ | 1184 | /* Carry out the file reads */ |
| 1164 | amount_left = fsg->data_size_from_cmnd; | 1185 | amount_left = fsg->data_size_from_cmnd; |
| @@ -1171,17 +1192,10 @@ static int do_read(struct fsg_dev *fsg) · 6 unmodified lines | |||
| 1171 | * Try to read the remaining amount. | 1192 | * Try to read the remaining amount. |
| 1172 | * But don't read more than the buffer size. | 1193 | * But don't read more than the buffer size. |
| 1173 | * And don't try to read past the end of the file. | 1194 | * And don't try to read past the end of the file. |
| 1174 | * Finally, if we're not at a page boundary, don't read past | 1195 | */ |
| 1175 | * the next page. | ||
| 1176 | * If this means reading 0 then we were asked to read past | ||
| 1177 | * the end of file. */ | ||
| 1178 | amount = min((unsigned int) amount_left, mod_data.buflen); | 1196 | amount = min((unsigned int) amount_left, mod_data.buflen); |
| 1179 | amount = min((loff_t) amount, | 1197 | amount = min((loff_t) amount, |
| 1180 | curlun->file_length - file_offset); | 1198 | curlun->file_length - file_offset); |
| 1181 | partial_page = file_offset & (PAGE_CACHE_SIZE - 1); | ||
| 1182 | if (partial_page > 0) | ||
| 1183 | amount = min(amount, (unsigned int) PAGE_CACHE_SIZE - | ||
| 1184 | partial_page); | ||
| 1185 | 1199 | ||
| 1186 | /* Wait for the next buffer to become available */ | 1200 | /* Wait for the next buffer to become available */ |
| 1187 | bh = fsg->next_buffhd_to_fill; | 1201 | bh = fsg->next_buffhd_to_fill; |
| @@ -1196,7 +1210,7 @@ static int do_read(struct fsg_dev *fsg) · 8 unmodified lines | |||
| 1196 | if (amount == 0) { | 1210 | if (amount == 0) { |
| 1197 | curlun->sense_data = | 1211 | curlun->sense_data = |
| 1198 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1212 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 1199 | curlun->sense_data_info = file_offset >> 9; | 1213 | curlun->sense_data_info = file_offset >> curlun->blkbits; |
| 1200 | curlun->info_valid = 1; | 1214 | curlun->info_valid = 1; |
| 1201 | bh->inreq->length = 0; | 1215 | bh->inreq->length = 0; |
| 1202 | bh->state = BUF_STATE_FULL; | 1216 | bh->state = BUF_STATE_FULL; |
| @@ -1221,18 +1235,23 @@ static int do_read(struct fsg_dev *fsg) · 18 unmodified lines | |||
| 1221 | } else if (nread < amount) { | 1235 | } else if (nread < amount) { |
| 1222 | LDBG(curlun, "partial file read: %d/%u\n", | 1236 | LDBG(curlun, "partial file read: %d/%u\n", |
| 1223 | (int) nread, amount); | 1237 | (int) nread, amount); |
| 1224 | nread -= (nread & 511); // Round down to a block | 1238 | nread = round_down(nread, curlun->blksize); |
| 1225 | } | 1239 | } |
| 1226 | file_offset += nread; | 1240 | file_offset += nread; |
| 1227 | amount_left -= nread; | 1241 | amount_left -= nread; |
| 1228 | fsg->residue -= nread; | 1242 | fsg->residue -= nread; |
| 1243 | |||
| 1244 | /* Except at the end of the transfer, nread will be | ||
| 1245 | * equal to the buffer size, which is divisible by the | ||
| 1246 | * bulk-in maxpacket size. | ||
| 1247 | */ | ||
| 1229 | bh->inreq->length = nread; | 1248 | bh->inreq->length = nread; |
| 1230 | bh->state = BUF_STATE_FULL; | 1249 | bh->state = BUF_STATE_FULL; |
| 1231 | 1250 | ||
| 1232 | /* If an error occurred, report it and its position */ | 1251 | /* If an error occurred, report it and its position */ |
| 1233 | if (nread < amount) { | 1252 | if (nread < amount) { |
| 1234 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 1253 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
| 1235 | curlun->sense_data_info = file_offset >> 9; | 1254 | curlun->sense_data_info = file_offset >> curlun->blkbits; |
| 1236 | curlun->info_valid = 1; | 1255 | curlun->info_valid = 1; |
| 1237 | break; | 1256 | break; |
| 1238 | } | 1257 | } |
| @@ -1262,7 +1281,6 @@ static int do_write(struct fsg_dev *fsg) · 23 unmodified lines | |||
| 1262 | u32 amount_left_to_req, amount_left_to_write; | 1281 | u32 amount_left_to_req, amount_left_to_write; |
| 1263 | loff_t usb_offset, file_offset, file_offset_tmp; | 1282 | loff_t usb_offset, file_offset, file_offset_tmp; |
| 1264 | unsigned int amount; | 1283 | unsigned int amount; |
| 1265 | unsigned int partial_page; | ||
| 1266 | ssize_t nwritten; | 1284 | ssize_t nwritten; |
| 1267 | int rc; | 1285 | int rc; |
| 1268 | 1286 | ||
| @@ -1303,7 +1321,7 @@ static int do_write(struct fsg_dev *fsg) · 34 unmodified lines | |||
| 1303 | 1321 | ||
| 1304 | /* Carry out the file writes */ | 1322 | /* Carry out the file writes */ |
| 1305 | get_some_more = 1; | 1323 | get_some_more = 1; |
| 1306 | file_offset = usb_offset = ((loff_t) lba) << 9; | 1324 | file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits; |
| 1307 | amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd; | 1325 | amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd; |
| 1308 | 1326 | ||
| 1309 | while (amount_left_to_write > 0) { | 1327 | while (amount_left_to_write > 0) { |
| @@ -1313,38 +1331,20 @@ static int do_write(struct fsg_dev *fsg) · 3 unmodified lines | |||
| 1313 | if (bh->state == BUF_STATE_EMPTY && get_some_more) { | 1331 | if (bh->state == BUF_STATE_EMPTY && get_some_more) { |
| 1314 | 1332 | ||
| 1315 | /* Figure out how much we want to get: | 1333 | /* Figure out how much we want to get: |
| 1316 | * Try to get the remaining amount. | 1334 | * Try to get the remaining amount, |
| 1317 | * But don't get more than the buffer size. | 1335 | * but not more than the buffer size. |
| 1318 | * And don't try to go past the end of the file. | 1336 | */ |
| 1319 | * If we're not at a page boundary, | ||
| 1320 | * don't go past the next page. | ||
| 1321 | * If this means getting 0, then we were asked | ||
| 1322 | * to write past the end of file. | ||
| 1323 | * Finally, round down to a block boundary. */ | ||
| 1324 | amount = min(amount_left_to_req, mod_data.buflen); | 1337 | amount = min(amount_left_to_req, mod_data.buflen); |
| 1325 | amount = min((loff_t) amount, curlun->file_length - | 1338 | |
| 1326 | usb_offset); | 1339 | /* Beyond the end of the backing file? */ |
| 1327 | partial_page = usb_offset & (PAGE_CACHE_SIZE - 1); | 1340 | if (usb_offset >= curlun->file_length) { |
| 1328 | if (partial_page > 0) | ||
| 1329 | amount = min(amount, | ||
| 1330 | (unsigned int) PAGE_CACHE_SIZE - partial_page); | ||
| 1331 | |||
| 1332 | if (amount == 0) { | ||
| 1333 | get_some_more = 0; | 1341 | get_some_more = 0; |
| 1334 | curlun->sense_data = | 1342 | curlun->sense_data = |
| 1335 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1343 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 1336 | curlun->sense_data_info = usb_offset >> 9; | 1344 | curlun->sense_data_info = usb_offset >> curlun->blkbits; |
| 1337 | curlun->info_valid = 1; | 1345 | curlun->info_valid = 1; |
| 1338 | continue; | 1346 | continue; |
| 1339 | } | 1347 | } |
| 1340 | amount -= (amount & 511); | ||
| 1341 | if (amount == 0) { | ||
| 1342 | |||
| 1343 | /* Why were we were asked to transfer a | ||
| 1344 | * partial block? */ | ||
| 1345 | get_some_more = 0; | ||
| 1346 | continue; | ||
| 1347 | } | ||
| 1348 | 1348 | ||
| 1349 | /* Get the next buffer */ | 1349 | /* Get the next buffer */ |
| 1350 | usb_offset += amount; | 1350 | usb_offset += amount; |
| @@ -1353,11 +1353,11 @@ static int do_write(struct fsg_dev *fsg) · 2 unmodified lines | |||
| 1353 | if (amount_left_to_req == 0) | 1353 | if (amount_left_to_req == 0) |
| 1354 | get_some_more = 0; | 1354 | get_some_more = 0; |
| 1355 | 1355 | ||
| 1356 | /* amount is always divisible by 512, hence by | 1356 | /* Except at the end of the transfer, amount will be |
| 1357 | * the bulk-out maxpacket size */ | 1357 | * equal to the buffer size, which is divisible by |
| 1358 | bh->outreq->length = bh->bulk_out_intended_length = | 1358 | * the bulk-out maxpacket size. |
| 1359 | amount; | 1359 | */ |
| 1360 | bh->outreq->short_not_ok = 1; | 1360 | set_bulk_out_req_length(fsg, bh, amount); |
| 1361 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | 1361 | start_transfer(fsg, fsg->bulk_out, bh->outreq, |
| 1362 | &bh->outreq_busy, &bh->state); | 1362 | &bh->outreq_busy, &bh->state); |
| 1363 | fsg->next_buffhd_to_fill = bh->next; | 1363 | fsg->next_buffhd_to_fill = bh->next; |
| @@ -1376,7 +1376,7 @@ static int do_write(struct fsg_dev *fsg) · 12 unmodified lines | |||
| 1376 | /* Did something go wrong with the transfer? */ | 1376 | /* Did something go wrong with the transfer? */ |
| 1377 | if (bh->outreq->status != 0) { | 1377 | if (bh->outreq->status != 0) { |
| 1378 | curlun->sense_data = SS_COMMUNICATION_FAILURE; | 1378 | curlun->sense_data = SS_COMMUNICATION_FAILURE; |
| 1379 | curlun->sense_data_info = file_offset >> 9; | 1379 | curlun->sense_data_info = file_offset >> curlun->blkbits; |
| 1380 | curlun->info_valid = 1; | 1380 | curlun->info_valid = 1; |
| 1381 | break; | 1381 | break; |
| 1382 | } | 1382 | } |
| @@ -1390,6 +1390,16 @@ static int do_write(struct fsg_dev *fsg) · 7 unmodified lines | |||
| 1390 | amount = curlun->file_length - file_offset; | 1390 | amount = curlun->file_length - file_offset; |
| 1391 | } | 1391 | } |
| 1392 | 1392 | ||
| 1393 | /* Don't accept excess data. The spec doesn't say | ||
| 1394 | * what to do in this case. We'll ignore the error. | ||
| 1395 | */ | ||
| 1396 | amount = min(amount, bh->bulk_out_intended_length); | ||
| 1397 | |||
| 1398 | /* Don't write a partial block */ | ||
| 1399 | amount = round_down(amount, curlun->blksize); | ||
| 1400 | if (amount == 0) | ||
| 1401 | goto empty_write; | ||
| 1402 | |||
| 1393 | /* Perform the write */ | 1403 | /* Perform the write */ |
| 1394 | file_offset_tmp = file_offset; | 1404 | file_offset_tmp = file_offset; |
| 1395 | nwritten = vfs_write(curlun->filp, | 1405 | nwritten = vfs_write(curlun->filp, |
| @@ -1408,8 +1418,7 @@ static int do_write(struct fsg_dev *fsg) · 12 unmodified lines | |||
| 1408 | } else if (nwritten < amount) { | 1418 | } else if (nwritten < amount) { |
| 1409 | LDBG(curlun, "partial file write: %d/%u\n", | 1419 | LDBG(curlun, "partial file write: %d/%u\n", |
| 1410 | (int) nwritten, amount); | 1420 | (int) nwritten, amount); |
| 1411 | nwritten -= (nwritten & 511); | 1421 | nwritten = round_down(nwritten, curlun->blksize); |
| 1412 | // Round down to a block | ||
| 1413 | } | 1422 | } |
| 1414 | file_offset += nwritten; | 1423 | file_offset += nwritten; |
| 1415 | amount_left_to_write -= nwritten; | 1424 | amount_left_to_write -= nwritten; |
| @@ -1418,13 +1427,14 @@ static int do_write(struct fsg_dev *fsg) · 2 unmodified lines | |||
| 1418 | /* If an error occurred, report it and its position */ | 1427 | /* If an error occurred, report it and its position */ |
| 1419 | if (nwritten < amount) { | 1428 | if (nwritten < amount) { |
| 1420 | curlun->sense_data = SS_WRITE_ERROR; | 1429 | curlun->sense_data = SS_WRITE_ERROR; |
| 1421 | curlun->sense_data_info = file_offset >> 9; | 1430 | curlun->sense_data_info = file_offset >> curlun->blkbits; |
| 1422 | curlun->info_valid = 1; | 1431 | curlun->info_valid = 1; |
| 1423 | break; | 1432 | break; |
| 1424 | } | 1433 | } |
| 1425 | 1434 | ||
| 1435 | empty_write: | ||
| 1426 | /* Did the host decide to stop early? */ | 1436 | /* Did the host decide to stop early? */ |
| 1427 | if (bh->outreq->actual != bh->outreq->length) { | 1437 | if (bh->outreq->actual < bh->bulk_out_intended_length) { |
| 1428 | fsg->short_packet_received = 1; | 1438 | fsg->short_packet_received = 1; |
| 1429 | break; | 1439 | break; |
| 1430 | } | 1440 | } |
| @@ -1500,8 +1510,8 @@ static int do_verify(struct fsg_dev *fsg) · 69 unmodified lines | |||
| 1500 | return -EIO; // No default reply | 1510 | return -EIO; // No default reply |
| 1501 | 1511 | ||
| 1502 | /* Prepare to carry out the file verify */ | 1512 | /* Prepare to carry out the file verify */ |
| 1503 | amount_left = verification_length << 9; | 1513 | amount_left = verification_length << curlun->blkbits; |
| 1504 | file_offset = ((loff_t) lba) << 9; | 1514 | file_offset = ((loff_t) lba) << curlun->blkbits; |
| 1505 | 1515 | ||
| 1506 | /* Write out all the dirty buffers before invalidating them */ | 1516 | /* Write out all the dirty buffers before invalidating them */ |
| 1507 | fsg_lun_fsync_sub(curlun); | 1517 | fsg_lun_fsync_sub(curlun); |
| @@ -1519,15 +1529,14 @@ static int do_verify(struct fsg_dev *fsg) · 11 unmodified lines | |||
| 1519 | * Try to read the remaining amount, but not more than | 1529 | * Try to read the remaining amount, but not more than |
| 1520 | * the buffer size. | 1530 | * the buffer size. |
| 1521 | * And don't try to read past the end of the file. | 1531 | * And don't try to read past the end of the file. |
| 1522 | * If this means reading 0 then we were asked to read | 1532 | */ |
| 1523 | * past the end of file. */ | ||
| 1524 | amount = min((unsigned int) amount_left, mod_data.buflen); | 1533 | amount = min((unsigned int) amount_left, mod_data.buflen); |
| 1525 | amount = min((loff_t) amount, | 1534 | amount = min((loff_t) amount, |
| 1526 | curlun->file_length - file_offset); | 1535 | curlun->file_length - file_offset); |
| 1527 | if (amount == 0) { | 1536 | if (amount == 0) { |
| 1528 | curlun->sense_data = | 1537 | curlun->sense_data = |
| 1529 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1538 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 1530 | curlun->sense_data_info = file_offset >> 9; | 1539 | curlun->sense_data_info = file_offset >> curlun->blkbits; |
| 1531 | curlun->info_valid = 1; | 1540 | curlun->info_valid = 1; |
| 1532 | break; | 1541 | break; |
| 1533 | } | 1542 | } |
| @@ -1550,11 +1559,11 @@ static int do_verify(struct fsg_dev *fsg) · 16 unmodified lines | |||
| 1550 | } else if (nread < amount) { | 1559 | } else if (nread < amount) { |
| 1551 | LDBG(curlun, "partial file verify: %d/%u\n", | 1560 | LDBG(curlun, "partial file verify: %d/%u\n", |
| 1552 | (int) nread, amount); | 1561 | (int) nread, amount); |
| 1553 | nread -= (nread & 511); // Round down to a sector | 1562 | nread = round_down(nread, curlun->blksize); |
| 1554 | } | 1563 | } |
| 1555 | if (nread == 0) { | 1564 | if (nread == 0) { |
| 1556 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 1565 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
| 1557 | curlun->sense_data_info = file_offset >> 9; | 1566 | curlun->sense_data_info = file_offset >> curlun->blkbits; |
| 1558 | curlun->info_valid = 1; | 1567 | curlun->info_valid = 1; |
| 1559 | break; | 1568 | break; |
| 1560 | } | 1569 | } |
| @@ -1668,7 +1677,7 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) · 107 unmodified lines | |||
| 1668 | 1677 | ||
| 1669 | put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); | 1678 | put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); |
| 1670 | /* Max logical block */ | 1679 | /* Max logical block */ |
| 1671 | put_unaligned_be32(512, &buf[4]); /* Block length */ | 1680 | put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ |
| 1672 | return 8; | 1681 | return 8; |
| 1673 | } | 1682 | } |
| 1674 | 1683 | ||
| @@ -1890,7 +1899,7 @@ static int do_read_format_capacities(struct fsg_dev *fsg, · 215 unmodified lines | |||
| 1890 | 1899 | ||
| 1891 | put_unaligned_be32(curlun->num_sectors, &buf[0]); | 1900 | put_unaligned_be32(curlun->num_sectors, &buf[0]); |
| 1892 | /* Number of blocks */ | 1901 | /* Number of blocks */ |
| 1893 | put_unaligned_be32(512, &buf[4]); /* Block length */ | 1902 | put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ |
| 1894 | buf[4] = 0x02; /* Current capacity */ | 1903 | buf[4] = 0x02; /* Current capacity */ |
| 1895 | return 12; | 1904 | return 12; |
| 1896 | } | 1905 | } |
| @@ -1969,7 +1978,7 @@ static int throw_away_data(struct fsg_dev *fsg) · 72 unmodified lines | |||
| 1969 | fsg->next_buffhd_to_drain = bh->next; | 1978 | fsg->next_buffhd_to_drain = bh->next; |
| 1970 | 1979 | ||
| 1971 | /* A short packet or an error ends everything */ | 1980 | /* A short packet or an error ends everything */ |
| 1972 | if (bh->outreq->actual != bh->outreq->length || | 1981 | if (bh->outreq->actual < bh->bulk_out_intended_length || |
| 1973 | bh->outreq->status != 0) { | 1982 | bh->outreq->status != 0) { |
| 1974 | raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); | 1983 | raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); |
| 1975 | return -EINTR; | 1984 | return -EINTR; |
| @@ -1983,11 +1992,11 @@ static int throw_away_data(struct fsg_dev *fsg) · 7 unmodified lines | |||
| 1983 | amount = min(fsg->usb_amount_left, | 1992 | amount = min(fsg->usb_amount_left, |
| 1984 | (u32) mod_data.buflen); | 1993 | (u32) mod_data.buflen); |
| 1985 | 1994 | ||
| 1986 | /* amount is always divisible by 512, hence by | 1995 | /* Except at the end of the transfer, amount will be |
| 1987 | * the bulk-out maxpacket size */ | 1996 | * equal to the buffer size, which is divisible by |
| 1988 | bh->outreq->length = bh->bulk_out_intended_length = | 1997 | * the bulk-out maxpacket size. |
| 1989 | amount; | 1998 | */ |
| 1990 | bh->outreq->short_not_ok = 1; | 1999 | set_bulk_out_req_length(fsg, bh, amount); |
| 1991 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | 2000 | start_transfer(fsg, fsg->bulk_out, bh->outreq, |
| 1992 | &bh->outreq_busy, &bh->state); | 2001 | &bh->outreq_busy, &bh->state); |
| 1993 | fsg->next_buffhd_to_fill = bh->next; | 2002 | fsg->next_buffhd_to_fill = bh->next; |
| @@ -2415,7 +2424,7 @@ static int do_scsi_command(struct fsg_dev *fsg) · 421 unmodified lines | |||
| 2415 | 2424 | ||
| 2416 | case READ_6: | 2425 | case READ_6: |
| 2417 | i = fsg->cmnd[4]; | 2426 | i = fsg->cmnd[4]; |
| 2418 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; | 2427 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits; |
| 2419 | if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, | 2428 | if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, |
| 2420 | (7<<1) | (1<<4), 1, | 2429 | (7<<1) | (1<<4), 1, |
| 2421 | "READ(6)")) == 0) | 2430 | "READ(6)")) == 0) |
| @@ -2424,7 +2433,7 @@ static int do_scsi_command(struct fsg_dev *fsg) · 2 unmodified lines | |||
| 2424 | 2433 | ||
| 2425 | case READ_10: | 2434 | case READ_10: |
| 2426 | fsg->data_size_from_cmnd = | 2435 | fsg->data_size_from_cmnd = |
| 2427 | get_unaligned_be16(&fsg->cmnd[7]) << 9; | 2436 | get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits; |
| 2428 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2437 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, |
| 2429 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2438 | (1<<1) | (0xf<<2) | (3<<7), 1, |
| 2430 | "READ(10)")) == 0) | 2439 | "READ(10)")) == 0) |
| @@ -2433,7 +2442,7 @@ static int do_scsi_command(struct fsg_dev *fsg) · 2 unmodified lines | |||
| 2433 | 2442 | ||
| 2434 | case READ_12: | 2443 | case READ_12: |
| 2435 | fsg->data_size_from_cmnd = | 2444 | fsg->data_size_from_cmnd = |
| 2436 | get_unaligned_be32(&fsg->cmnd[6]) << 9; | 2445 | get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits; |
| 2437 | if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, | 2446 | if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, |
| 2438 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2447 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
| 2439 | "READ(12)")) == 0) | 2448 | "READ(12)")) == 0) |
| @@ -2519,7 +2528,7 @@ static int do_scsi_command(struct fsg_dev *fsg) · 79 unmodified lines | |||
| 2519 | 2528 | ||
| 2520 | case WRITE_6: | 2529 | case WRITE_6: |
| 2521 | i = fsg->cmnd[4]; | 2530 | i = fsg->cmnd[4]; |
| 2522 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; | 2531 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits; |
| 2523 | if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, | 2532 | if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, |
| 2524 | (7<<1) | (1<<4), 1, | 2533 | (7<<1) | (1<<4), 1, |
| 2525 | "WRITE(6)")) == 0) | 2534 | "WRITE(6)")) == 0) |
| @@ -2528,7 +2537,7 @@ static int do_scsi_command(struct fsg_dev *fsg) · 2 unmodified lines | |||
| 2528 | 2537 | ||
| 2529 | case WRITE_10: | 2538 | case WRITE_10: |
| 2530 | fsg->data_size_from_cmnd = | 2539 | fsg->data_size_from_cmnd = |
| 2531 | get_unaligned_be16(&fsg->cmnd[7]) << 9; | 2540 | get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits; |
| 2532 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, | 2541 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, |
| 2533 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2542 | (1<<1) | (0xf<<2) | (3<<7), 1, |
| 2534 | "WRITE(10)")) == 0) | 2543 | "WRITE(10)")) == 0) |
| @@ -2537,7 +2546,7 @@ static int do_scsi_command(struct fsg_dev *fsg) · 2 unmodified lines | |||
| 2537 | 2546 | ||
| 2538 | case WRITE_12: | 2547 | case WRITE_12: |
| 2539 | fsg->data_size_from_cmnd = | 2548 | fsg->data_size_from_cmnd = |
| 2540 | get_unaligned_be32(&fsg->cmnd[6]) << 9; | 2549 | get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits; |
| 2541 | if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, | 2550 | if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, |
| 2542 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2551 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
| 2543 | "WRITE(12)")) == 0) | 2552 | "WRITE(12)")) == 0) |
| @@ -2666,7 +2675,6 @@ static int get_next_command(struct fsg_dev *fsg) · 122 unmodified lines | |||
| 2666 | 2675 | ||
| 2667 | /* Queue a request to read a Bulk-only CBW */ | 2676 | /* Queue a request to read a Bulk-only CBW */ |
| 2668 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); | 2677 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); |
| 2669 | bh->outreq->short_not_ok = 1; | ||
| 2670 | start_transfer(fsg, fsg->bulk_out, bh->outreq, | 2678 | start_transfer(fsg, fsg->bulk_out, bh->outreq, |
| 2671 | &bh->outreq_busy, &bh->state); | 2679 | &bh->outreq_busy, &bh->state); |
| 2672 | 2680 | ||
| @@ -2752,7 +2760,7 @@ static int do_set_interface(struct fsg_dev *fsg, int altsetting) · 79 unmodified lines | |||
| 2752 | 2760 | ||
| 2753 | reset: | 2761 | reset: |
| 2754 | /* Deallocate the requests */ | 2762 | /* Deallocate the requests */ |
| 2755 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2763 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2756 | struct fsg_buffhd *bh = &fsg->buffhds[i]; | 2764 | struct fsg_buffhd *bh = &fsg->buffhds[i]; |
| 2757 | 2765 | ||
| 2758 | if (bh->inreq) { | 2766 | if (bh->inreq) { |
| @@ -2791,29 +2799,32 @@ reset: · 32 unmodified lines | |||
| 2791 | 2799 | ||
| 2792 | /* Enable the endpoints */ | 2800 | /* Enable the endpoints */ |
| 2793 | d = fsg_ep_desc(fsg->gadget, | 2801 | d = fsg_ep_desc(fsg->gadget, |
| 2794 | &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc); | 2802 | &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc, |
| 2803 | &fsg_ss_bulk_in_desc); | ||
| 2795 | if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0) | 2804 | if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0) |
| 2796 | goto reset; | 2805 | goto reset; |
| 2797 | fsg->bulk_in_enabled = 1; | 2806 | fsg->bulk_in_enabled = 1; |
| 2798 | 2807 | ||
| 2799 | d = fsg_ep_desc(fsg->gadget, | 2808 | d = fsg_ep_desc(fsg->gadget, |
| 2800 | &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc); | 2809 | &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc, |
| 2810 | &fsg_ss_bulk_out_desc); | ||
| 2801 | if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) | 2811 | if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) |
| 2802 | goto reset; | 2812 | goto reset; |
| 2803 | fsg->bulk_out_enabled = 1; | 2813 | fsg->bulk_out_enabled = 1; |
| 2804 | fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); | 2814 | fsg->bulk_out_maxpacket = usb_endpoint_maxp(d); |
| 2805 | clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); | 2815 | clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); |
| 2806 | 2816 | ||
| 2807 | if (transport_is_cbi()) { | 2817 | if (transport_is_cbi()) { |
| 2808 | d = fsg_ep_desc(fsg->gadget, | 2818 | d = fsg_ep_desc(fsg->gadget, |
| 2809 | &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc); | 2819 | &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc, |
| 2820 | &fsg_ss_intr_in_desc); | ||
| 2810 | if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0) | 2821 | if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0) |
| 2811 | goto reset; | 2822 | goto reset; |
| 2812 | fsg->intr_in_enabled = 1; | 2823 | fsg->intr_in_enabled = 1; |
| 2813 | } | 2824 | } |
| 2814 | 2825 | ||
| 2815 | /* Allocate the requests */ | 2826 | /* Allocate the requests */ |
| 2816 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2827 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2817 | struct fsg_buffhd *bh = &fsg->buffhds[i]; | 2828 | struct fsg_buffhd *bh = &fsg->buffhds[i]; |
| 2818 | 2829 | ||
| 2819 | if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0) | 2830 | if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0) |
| @@ -2862,17 +2873,10 @@ static int do_set_config(struct fsg_dev *fsg, u8 new_config) · 42 unmodified lines | |||
| 2862 | fsg->config = new_config; | 2873 | fsg->config = new_config; |
| 2863 | if ((rc = do_set_interface(fsg, 0)) != 0) | 2874 | if ((rc = do_set_interface(fsg, 0)) != 0) |
| 2864 | fsg->config = 0; // Reset on errors | 2875 | fsg->config = 0; // Reset on errors |
| 2865 | else { | 2876 | else |
| 2866 | char *speed; | 2877 | INFO(fsg, "%s config #%d\n", |
| 2867 | 2878 | usb_speed_string(fsg->gadget->speed), | |
| 2868 | switch (fsg->gadget->speed) { | 2879 | fsg->config); |
| 2869 | case USB_SPEED_LOW: speed = "low"; break; | ||
| 2870 | case USB_SPEED_FULL: speed = "full"; break; | ||
| 2871 | case USB_SPEED_HIGH: speed = "high"; break; | ||
| 2872 | default: speed = "?"; break; | ||
| 2873 | } | ||
| 2874 | INFO(fsg, "%s speed config #%d\n", speed, fsg->config); | ||
| 2875 | } | ||
| 2876 | } | 2880 | } |
| 2877 | return rc; | 2881 | return rc; |
| 2878 | } | 2882 | } |
| @@ -2909,7 +2913,7 @@ static void handle_exception(struct fsg_dev *fsg) · 30 unmodified lines | |||
| 2909 | /* Cancel all the pending transfers */ | 2913 | /* Cancel all the pending transfers */ |
| 2910 | if (fsg->intreq_busy) | 2914 | if (fsg->intreq_busy) |
| 2911 | usb_ep_dequeue(fsg->intr_in, fsg->intreq); | 2915 | usb_ep_dequeue(fsg->intr_in, fsg->intreq); |
| 2912 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2916 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2913 | bh = &fsg->buffhds[i]; | 2917 | bh = &fsg->buffhds[i]; |
| 2914 | if (bh->inreq_busy) | 2918 | if (bh->inreq_busy) |
| 2915 | usb_ep_dequeue(fsg->bulk_in, bh->inreq); | 2919 | usb_ep_dequeue(fsg->bulk_in, bh->inreq); |
| @@ -2920,7 +2924,7 @@ static void handle_exception(struct fsg_dev *fsg) · 4 unmodified lines | |||
| 2920 | /* Wait until everything is idle */ | 2924 | /* Wait until everything is idle */ |
| 2921 | for (;;) { | 2925 | for (;;) { |
| 2922 | num_active = fsg->intreq_busy; | 2926 | num_active = fsg->intreq_busy; |
| 2923 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2927 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2924 | bh = &fsg->buffhds[i]; | 2928 | bh = &fsg->buffhds[i]; |
| 2925 | num_active += bh->inreq_busy + bh->outreq_busy; | 2929 | num_active += bh->inreq_busy + bh->outreq_busy; |
| 2926 | } | 2930 | } |
| @@ -2942,7 +2946,7 @@ static void handle_exception(struct fsg_dev *fsg) · 15 unmodified lines | |||
| 2942 | * state, and the exception. Then invoke the handler. */ | 2946 | * state, and the exception. Then invoke the handler. */ |
| 2943 | spin_lock_irq(&fsg->lock); | 2947 | spin_lock_irq(&fsg->lock); |
| 2944 | 2948 | ||
| 2945 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2949 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 2946 | bh = &fsg->buffhds[i]; | 2950 | bh = &fsg->buffhds[i]; |
| 2947 | bh->state = BUF_STATE_EMPTY; | 2951 | bh->state = BUF_STATE_EMPTY; |
| 2948 | } | 2952 | } |
| @@ -3149,6 +3153,15 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) · 200 unmodified lines | |||
| 3149 | DBG(fsg, "unbind\n"); | 3153 | DBG(fsg, "unbind\n"); |
| 3150 | clear_bit(REGISTERED, &fsg->atomic_bitflags); | 3154 | clear_bit(REGISTERED, &fsg->atomic_bitflags); |
| 3151 | 3155 | ||
| 3156 | /* If the thread isn't already dead, tell it to exit now */ | ||
| 3157 | if (fsg->state != FSG_STATE_TERMINATED) { | ||
| 3158 | raise_exception(fsg, FSG_STATE_EXIT); | ||
| 3159 | wait_for_completion(&fsg->thread_notifier); | ||
| 3160 | |||
| 3161 | /* The cleanup routine waits for this completion also */ | ||
| 3162 | complete(&fsg->thread_notifier); | ||
| 3163 | } | ||
| 3164 | |||
| 3152 | /* Unregister the sysfs attribute files and the LUNs */ | 3165 | /* Unregister the sysfs attribute files and the LUNs */ |
| 3153 | for (i = 0; i < fsg->nluns; ++i) { | 3166 | for (i = 0; i < fsg->nluns; ++i) { |
| 3154 | curlun = &fsg->luns[i]; | 3167 | curlun = &fsg->luns[i]; |
| @@ -3162,17 +3175,8 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) · 7 unmodified lines | |||
| 3162 | } | 3175 | } |
| 3163 | } | 3176 | } |
| 3164 | 3177 | ||
| 3165 | /* If the thread isn't already dead, tell it to exit now */ | ||
| 3166 | if (fsg->state != FSG_STATE_TERMINATED) { | ||
| 3167 | raise_exception(fsg, FSG_STATE_EXIT); | ||
| 3168 | wait_for_completion(&fsg->thread_notifier); | ||
| 3169 | |||
| 3170 | /* The cleanup routine waits for this completion also */ | ||
| 3171 | complete(&fsg->thread_notifier); | ||
| 3172 | } | ||
| 3173 | |||
| 3174 | /* Free the data buffers */ | 3178 | /* Free the data buffers */ |
| 3175 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) | 3179 | for (i = 0; i < fsg_num_buffers; ++i) |
| 3176 | kfree(fsg->buffhds[i].buf); | 3180 | kfree(fsg->buffhds[i].buf); |
| 3177 | 3181 | ||
| 3178 | /* Free the request and buffer for endpoint 0 */ | 3182 | /* Free the request and buffer for endpoint 0 */ |
| @@ -3445,6 +3449,24 @@ static int __init fsg_bind(struct usb_gadget *gadget) · 266 unmodified lines | |||
| 3445 | fsg_fs_intr_in_desc.bEndpointAddress; | 3449 | fsg_fs_intr_in_desc.bEndpointAddress; |
| 3446 | } | 3450 | } |
| 3447 | 3451 | ||
| 3452 | if (gadget_is_superspeed(gadget)) { | ||
| 3453 | unsigned max_burst; | ||
| 3454 | |||
| 3455 | fsg_ss_function[i + FSG_SS_FUNCTION_PRE_EP_ENTRIES] = NULL; | ||
| 3456 | |||
| 3457 | /* Calculate bMaxBurst, we know packet size is 1024 */ | ||
| 3458 | max_burst = min_t(unsigned, mod_data.buflen / 1024, 15); | ||
| 3459 | |||
| 3460 | /* Assume endpoint addresses are the same for both speeds */ | ||
| 3461 | fsg_ss_bulk_in_desc.bEndpointAddress = | ||
| 3462 | fsg_fs_bulk_in_desc.bEndpointAddress; | ||
| 3463 | fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; | ||
| 3464 | |||
| 3465 | fsg_ss_bulk_out_desc.bEndpointAddress = | ||
| 3466 | fsg_fs_bulk_out_desc.bEndpointAddress; | ||
| 3467 | fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; | ||
| 3468 | } | ||
| 3469 | |||
| 3448 | if (gadget_is_otg(gadget)) | 3470 | if (gadget_is_otg(gadget)) |
| 3449 | fsg_otg_desc.bmAttributes |= USB_OTG_HNP; | 3471 | fsg_otg_desc.bmAttributes |= USB_OTG_HNP; |
| 3450 | 3472 | ||
| @@ -3460,7 +3482,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) · 9 unmodified lines | |||
| 3460 | req->complete = ep0_complete; | 3482 | req->complete = ep0_complete; |
| 3461 | 3483 | ||
| 3462 | /* Allocate the data buffers */ | 3484 | /* Allocate the data buffers */ |
| 3463 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 3485 | for (i = 0; i < fsg_num_buffers; ++i) { |
| 3464 | struct fsg_buffhd *bh = &fsg->buffhds[i]; | 3486 | struct fsg_buffhd *bh = &fsg->buffhds[i]; |
| 3465 | 3487 | ||
| 3466 | /* Allocate for the bulk-in endpoint. We assume that | 3488 | /* Allocate for the bulk-in endpoint. We assume that |
| @@ -3471,7 +3493,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) · 4 unmodified lines | |||
| 3471 | goto out; | 3493 | goto out; |
| 3472 | bh->next = bh + 1; | 3494 | bh->next = bh + 1; |
| 3473 | } | 3495 | } |
| 3474 | fsg->buffhds[FSG_NUM_BUFFERS - 1].next = &fsg->buffhds[0]; | 3496 | fsg->buffhds[fsg_num_buffers - 1].next = &fsg->buffhds[0]; |
| 3475 | 3497 | ||
| 3476 | /* This should reflect the actual gadget power source */ | 3498 | /* This should reflect the actual gadget power source */ |
| 3477 | usb_gadget_set_selfpowered(gadget); | 3499 | usb_gadget_set_selfpowered(gadget); |
| @@ -3561,11 +3583,7 @@ static void fsg_resume(struct usb_gadget *gadget) · 83 unmodified lines | |||
| 3561 | /*-------------------------------------------------------------------------*/ | 3583 | /*-------------------------------------------------------------------------*/ |
| 3562 | 3584 | ||
| 3563 | static struct usb_gadget_driver fsg_driver = { | 3585 | static struct usb_gadget_driver fsg_driver = { |
| 3564 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 3586 | .speed = USB_SPEED_SUPER, |
| 3565 | .speed = USB_SPEED_HIGH, | ||
| 3566 | #else | ||
| 3567 | .speed = USB_SPEED_FULL, | ||
| 3568 | #endif | ||
| 3569 | .function = (char *) fsg_string_product, | 3587 | .function = (char *) fsg_string_product, |
| 3570 | .unbind = fsg_unbind, | 3588 | .unbind = fsg_unbind, |
| 3571 | .disconnect = fsg_disconnect, | 3589 | .disconnect = fsg_disconnect, |
| @@ -3587,7 +3605,9 @@ static int __init fsg_alloc(void) · 15 unmodified lines | |||
| 3587 | { | 3605 | { |
| 3588 | struct fsg_dev *fsg; | 3606 | struct fsg_dev *fsg; |
| 3589 | 3607 | ||
| 3590 | fsg = kzalloc(sizeof *fsg, GFP_KERNEL); | 3608 | fsg = kzalloc(sizeof *fsg + |
| 3609 | fsg_num_buffers * sizeof *(fsg->buffhds), GFP_KERNEL); | ||
| 3610 | |||
| 3591 | if (!fsg) | 3611 | if (!fsg) |
| 3592 | return -ENOMEM; | 3612 | return -ENOMEM; |
| 3593 | spin_lock_init(&fsg->lock); | 3613 | spin_lock_init(&fsg->lock); |
| @@ -3605,6 +3625,10 @@ static int __init fsg_init(void) · 11 unmodified lines | |||
| 3605 | int rc; | 3625 | int rc; |
| 3606 | struct fsg_dev *fsg; | 3626 | struct fsg_dev *fsg; |
| 3607 | 3627 | ||
| 3628 | rc = fsg_num_buffers_validate(); | ||
| 3629 | if (rc != 0) | ||
| 3630 | return rc; | ||
| 3631 | |||
| 3608 | if ((rc = fsg_alloc()) != 0) | 3632 | if ((rc = fsg_alloc()) != 0) |
| 3609 | return rc; | 3633 | return rc; |
| 3610 | fsg = the_fsg; | 3634 | fsg = the_fsg; |
| @@ -540,7 +540,7 @@ static int qe_ep_init(struct qe_udc *udc, · 539 unmodified lines | |||
| 540 | int reval = 0; | 540 | int reval = 0; |
| 541 | u16 max = 0; | 541 | u16 max = 0; |
| 542 | 542 | ||
| 543 | max = le16_to_cpu(desc->wMaxPacketSize); | 543 | max = usb_endpoint_maxp(desc); |
| 544 | 544 | ||
| 545 | /* check the max package size validate for this endpoint */ | 545 | /* check the max package size validate for this endpoint */ |
| 546 | /* Refer to USB2.0 spec table 9-13, | 546 | /* Refer to USB2.0 spec table 9-13, |
| @@ -559,7 +559,7 @@ static int fsl_ep_enable(struct usb_ep *_ep, · 558 unmodified lines | |||
| 559 | if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) | 559 | if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) |
| 560 | return -ESHUTDOWN; | 560 | return -ESHUTDOWN; |
| 561 | 561 | ||
| 562 | max = le16_to_cpu(desc->wMaxPacketSize); | 562 | max = usb_endpoint_maxp(desc); |
| 563 | 563 | ||
| 564 | /* Disable automatic zlp generation. Driver is responsible to indicate | 564 | /* Disable automatic zlp generation. Driver is responsible to indicate |
| 565 | * explicitly through req->req.zero. This is needed to enable multi-td | 565 | * explicitly through req->req.zero. This is needed to enable multi-td |
| @@ -1715,34 +1715,31 @@ static void dtd_complete_irq(struct fsl_udc *udc) · 1149 unmodified lines | |||
| 1715 | } | 1715 | } |
| 1716 | } | 1716 | } |
| 1717 | 1717 | ||
| 1718 | static inline enum usb_device_speed portscx_device_speed(u32 reg) | ||
| 1719 | { | ||
| 1720 | switch (speed & PORTSCX_PORT_SPEED_MASK) { | ||
| 1721 | case PORTSCX_PORT_SPEED_HIGH: | ||
| 1722 | return USB_SPEED_HIGH; | ||
| 1723 | case PORTSCX_PORT_SPEED_FULL: | ||
| 1724 | return USB_SPEED_FULL; | ||
| 1725 | case PORTSCX_PORT_SPEED_LOW: | ||
| 1726 | return USB_SPEED_LOW; | ||
| 1727 | default: | ||
| 1728 | return USB_SPEED_UNKNOWN; | ||
| 1729 | } | ||
| 1730 | } | ||
| 1731 | |||
| 1718 | /* Process a port change interrupt */ | 1732 | /* Process a port change interrupt */ |
| 1719 | static void port_change_irq(struct fsl_udc *udc) | 1733 | static void port_change_irq(struct fsl_udc *udc) |
| 1720 | { | 1734 | { |
| 1721 | u32 speed; | ||
| 1722 | |||
| 1723 | if (udc->bus_reset) | 1735 | if (udc->bus_reset) |
| 1724 | udc->bus_reset = 0; | 1736 | udc->bus_reset = 0; |
| 1725 | 1737 | ||
| 1726 | /* Bus resetting is finished */ | 1738 | /* Bus resetting is finished */ |
| 1727 | if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { | 1739 | if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) |
| 1728 | /* Get the speed */ | 1740 | /* Get the speed */ |
| 1729 | speed = (fsl_readl(&dr_regs->portsc1) | 1741 | udc->gadget.speed = |
| 1730 | & PORTSCX_PORT_SPEED_MASK); | 1742 | portscx_device_speed(fsl_readl(&dr_regs->portsc1)); |
| 1731 | switch (speed) { | ||
| 1732 | case PORTSCX_PORT_SPEED_HIGH: | ||
| 1733 | udc->gadget.speed = USB_SPEED_HIGH; | ||
| 1734 | break; | ||
| 1735 | case PORTSCX_PORT_SPEED_FULL: | ||
| 1736 | udc->gadget.speed = USB_SPEED_FULL; | ||
| 1737 | break; | ||
| 1738 | case PORTSCX_PORT_SPEED_LOW: | ||
| 1739 | udc->gadget.speed = USB_SPEED_LOW; | ||
| 1740 | break; | ||
| 1741 | default: | ||
| 1742 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1743 | break; | ||
| 1744 | } | ||
| 1745 | } | ||
| 1746 | 1743 | ||
| 1747 | /* Update USB state */ | 1744 | /* Update USB state */ |
| 1748 | if (!udc->resume_state) | 1745 | if (!udc->resume_state) |
| @@ -2167,20 +2164,8 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, · 418 unmodified lines | |||
| 2167 | default: | 2164 | default: |
| 2168 | s = "None"; break; | 2165 | s = "None"; break; |
| 2169 | } | 2166 | } |
| 2170 | s;} ), ( { | 2167 | s;} ), |
| 2171 | char *s; | 2168 | usb_speed_string(portscx_device_speed(tmp_reg)), |
| 2172 | switch (tmp_reg & PORTSCX_PORT_SPEED_UNDEF) { | ||
| 2173 | case PORTSCX_PORT_SPEED_FULL: | ||
| 2174 | s = "Full Speed"; break; | ||
| 2175 | case PORTSCX_PORT_SPEED_LOW: | ||
| 2176 | s = "Low Speed"; break; | ||
| 2177 | case PORTSCX_PORT_SPEED_HIGH: | ||
| 2178 | s = "High Speed"; break; | ||
| 2179 | default: | ||
| 2180 | s = "Undefined"; break; | ||
| 2181 | } | ||
| 2182 | s; | ||
| 2183 | } ), | ||
| 2184 | (tmp_reg & PORTSCX_PHY_LOW_POWER_SPD) ? | 2169 | (tmp_reg & PORTSCX_PHY_LOW_POWER_SPD) ? |
| 2185 | "Normal PHY mode" : "Low power mode", | 2170 | "Normal PHY mode" : "Low power mode", |
| 2186 | (tmp_reg & PORTSCX_PORT_RESET) ? "In Reset" : | 2171 | (tmp_reg & PORTSCX_PORT_RESET) ? "In Reset" : |
| @@ -8,16 +8,6 @@ · 7 unmodified lines | |||
| 8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; version 2 of the License. | 10 | * the Free Software Foundation; version 2 of the License. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | * | ||
| 21 | */ | 11 | */ |
| 22 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
| 23 | #include <linux/err.h> | 13 | #include <linux/err.h> |
| @@ -220,7 +210,7 @@ static int config_ep(struct fusb300_ep *ep, · 196 unmodified lines | |||
| 220 | 210 | ||
| 221 | info.type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 211 | info.type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
| 222 | info.dir_in = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? 1 : 0; | 212 | info.dir_in = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? 1 : 0; |
| 223 | info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 213 | info.maxpacket = usb_endpoint_maxp(desc); |
| 224 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 214 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; |
| 225 | 215 | ||
| 226 | if ((info.type == USB_ENDPOINT_XFER_INT) || | 216 | if ((info.type == USB_ENDPOINT_XFER_INT) || |
| @@ -1479,7 +1469,7 @@ static int __init fusb300_probe(struct platform_device *pdev) · 1252 unmodified lines | |||
| 1479 | fusb300->gadget.name = udc_name; | 1469 | fusb300->gadget.name = udc_name; |
| 1480 | fusb300->reg = reg; | 1470 | fusb300->reg = reg; |
| 1481 | 1471 | ||
| 1482 | ret = request_irq(ires->start, fusb300_irq, IRQF_DISABLED | IRQF_SHARED, | 1472 | ret = request_irq(ires->start, fusb300_irq, IRQF_SHARED, |
| 1483 | udc_name, fusb300); | 1473 | udc_name, fusb300); |
| 1484 | if (ret < 0) { | 1474 | if (ret < 0) { |
| 1485 | pr_err("request_irq error (%d)\n", ret); | 1475 | pr_err("request_irq error (%d)\n", ret); |
| @@ -1487,7 +1477,7 @@ static int __init fusb300_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 1487 | } | 1477 | } |
| 1488 | 1478 | ||
| 1489 | ret = request_irq(ires1->start, fusb300_irq, | 1479 | ret = request_irq(ires1->start, fusb300_irq, |
| 1490 | IRQF_DISABLED | IRQF_SHARED, udc_name, fusb300); | 1480 | IRQF_SHARED, udc_name, fusb300); |
| 1491 | if (ret < 0) { | 1481 | if (ret < 0) { |
| 1492 | pr_err("request_irq1 error (%d)\n", ret); | 1482 | pr_err("request_irq1 error (%d)\n", ret); |
| 1493 | goto clean_up; | 1483 | goto clean_up; |
| @@ -8,16 +8,6 @@ · 7 unmodified lines | |||
| 8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; version 2 of the License. | 10 | * the Free Software Foundation; version 2 of the License. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | * | ||
| 21 | */ | 11 | */ |
| 22 | 12 | ||
| 23 | 13 | ||
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | #define pr_fmt(fmt) "g_ffs: " fmt | 13 | #define pr_fmt(fmt) "g_ffs: " fmt |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | |||
| 31 | #define gadget_is_ci13xxx_msm(g) (!strcmp("ci13xxx_msm", (g)->name)) | 31 | #define gadget_is_ci13xxx_msm(g) (!strcmp("ci13xxx_msm", (g)->name)) |
| 32 | #define gadget_is_ci13xxx_pci(g) (!strcmp("ci13xxx_pci", (g)->name)) | 32 | #define gadget_is_ci13xxx_pci(g) (!strcmp("ci13xxx_pci", (g)->name)) |
| 33 | #define gadget_is_dummy(g) (!strcmp("dummy_udc", (g)->name)) | 33 | #define gadget_is_dummy(g) (!strcmp("dummy_udc", (g)->name)) |
| 34 | #define gadget_is_dwc3(g) (!strcmp("dwc3-gadget", (g)->name)) | ||
| 34 | #define gadget_is_fsl_qe(g) (!strcmp("fsl_qe_udc", (g)->name)) | 35 | #define gadget_is_fsl_qe(g) (!strcmp("fsl_qe_udc", (g)->name)) |
| 35 | #define gadget_is_fsl_usb2(g) (!strcmp("fsl-usb2-udc", (g)->name)) | 36 | #define gadget_is_fsl_usb2(g) (!strcmp("fsl-usb2-udc", (g)->name)) |
| 36 | #define gadget_is_goku(g) (!strcmp("goku_udc", (g)->name)) | 37 | #define gadget_is_goku(g) (!strcmp("goku_udc", (g)->name)) |
| @@ -115,6 +116,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) · 78 unmodified lines | |||
| 115 | return 0x30; | 116 | return 0x30; |
| 116 | else if (gadget_is_net2272(gadget)) | 117 | else if (gadget_is_net2272(gadget)) |
| 117 | return 0x31; | 118 | return 0x31; |
| 119 | else if (gadget_is_dwc3(gadget)) | ||
| 120 | return 0x32; | ||
| 118 | 121 | ||
| 119 | return -ENOENT; | 122 | return -ENOENT; |
| 120 | } | 123 | } |
| @@ -36,134 +36,43 @@ · 35 unmodified lines | |||
| 36 | 36 | ||
| 37 | #include "gadget_chips.h" | 37 | #include "gadget_chips.h" |
| 38 | 38 | ||
| 39 | 39 | #include "composite.c" | |
| 40 | /* | ||
| 41 | * Kbuild is not very cooperative with respect to linking separately | ||
| 42 | * compiled library objects into one module. So for now we won't use | ||
| 43 | * separate compilation ... ensuring init/exit sections work to shrink | ||
| 44 | * the runtime footprint, and giving us at least some parts of what | ||
| 45 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
| 46 | */ | ||
| 47 | #include "usbstring.c" | 40 | #include "usbstring.c" |
| 48 | #include "config.c" | 41 | #include "config.c" |
| 49 | #include "epautoconf.c" | 42 | #include "epautoconf.c" |
| 43 | #include "f_midi.c" | ||
| 50 | 44 | ||
| 51 | /*-------------------------------------------------------------------------*/ | 45 | /*-------------------------------------------------------------------------*/ |
| 52 | 46 | ||
| 53 | |||
| 54 | MODULE_AUTHOR("Ben Williamson"); | 47 | MODULE_AUTHOR("Ben Williamson"); |
| 55 | MODULE_LICENSE("GPL v2"); | 48 | MODULE_LICENSE("GPL v2"); |
| 56 | 49 | ||
| 57 | #define DRIVER_VERSION "25 Jul 2006" | ||
| 58 | |||
| 59 | static const char shortname[] = "g_midi"; | 50 | static const char shortname[] = "g_midi"; |
| 60 | static const char longname[] = "MIDI Gadget"; | 51 | static const char longname[] = "MIDI Gadget"; |
| 61 | 52 | ||
| 62 | static int index = SNDRV_DEFAULT_IDX1; | 53 | static int index = SNDRV_DEFAULT_IDX1; |
| 63 | static char *id = SNDRV_DEFAULT_STR1; | 54 | module_param(index, int, S_IRUGO); |
| 64 | |||
| 65 | module_param(index, int, 0444); | ||
| 66 | MODULE_PARM_DESC(index, "Index value for the USB MIDI Gadget adapter."); | 55 | MODULE_PARM_DESC(index, "Index value for the USB MIDI Gadget adapter."); |
| 67 | module_param(id, charp, 0444); | ||
| 68 | MODULE_PARM_DESC(id, "ID string for the USB MIDI Gadget adapter."); | ||
| 69 | |||
| 70 | /* Some systems will want different product identifiers published in the | ||
| 71 | * device descriptor, either numbers or strings or both. These string | ||
| 72 | * parameters are in UTF-8 (superset of ASCII's 7 bit characters). | ||
| 73 | */ | ||
| 74 | |||
| 75 | static ushort idVendor; | ||
| 76 | module_param(idVendor, ushort, S_IRUGO); | ||
| 77 | MODULE_PARM_DESC(idVendor, "USB Vendor ID"); | ||
| 78 | |||
| 79 | static ushort idProduct; | ||
| 80 | module_param(idProduct, ushort, S_IRUGO); | ||
| 81 | MODULE_PARM_DESC(idProduct, "USB Product ID"); | ||
| 82 | |||
| 83 | static ushort bcdDevice; | ||
| 84 | module_param(bcdDevice, ushort, S_IRUGO); | ||
| 85 | MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); | ||
| 86 | |||
| 87 | static char *iManufacturer; | ||
| 88 | module_param(iManufacturer, charp, S_IRUGO); | ||
| 89 | MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); | ||
| 90 | |||
| 91 | static char *iProduct; | ||
| 92 | module_param(iProduct, charp, S_IRUGO); | ||
| 93 | MODULE_PARM_DESC(iProduct, "USB Product string"); | ||
| 94 | |||
| 95 | static char *iSerialNumber; | ||
| 96 | module_param(iSerialNumber, charp, S_IRUGO); | ||
| 97 | MODULE_PARM_DESC(iSerialNumber, "SerialNumber"); | ||
| 98 | |||
| 99 | /* | ||
| 100 | * this version autoconfigures as much as possible, | ||
| 101 | * which is reasonable for most "bulk-only" drivers. | ||
| 102 | */ | ||
| 103 | static const char *EP_IN_NAME; | ||
| 104 | static const char *EP_OUT_NAME; | ||
| 105 | 56 | ||
| 57 | static char *id = SNDRV_DEFAULT_STR1; | ||
| 58 | module_param(id, charp, S_IRUGO); | ||
| 59 | MODULE_PARM_DESC(id, "ID string for the USB MIDI Gadget adapter."); | ||
| 106 | 60 | ||
| 107 | /* big enough to hold our biggest descriptor */ | 61 | static unsigned int buflen = 256; |
| 108 | #define USB_BUFSIZ 256 | ||
| 109 | |||
| 110 | |||
| 111 | /* This is a gadget, and the IN/OUT naming is from the host's perspective. | ||
| 112 | USB -> OUT endpoint -> rawmidi | ||
| 113 | USB <- IN endpoint <- rawmidi */ | ||
| 114 | struct gmidi_in_port { | ||
| 115 | struct gmidi_device* dev; | ||
| 116 | int active; | ||
| 117 | uint8_t cable; /* cable number << 4 */ | ||
| 118 | uint8_t state; | ||
| 119 | #define STATE_UNKNOWN 0 | ||
| 120 | #define STATE_1PARAM 1 | ||
| 121 | #define STATE_2PARAM_1 2 | ||
| 122 | #define STATE_2PARAM_2 3 | ||
| 123 | #define STATE_SYSEX_0 4 | ||
| 124 | #define STATE_SYSEX_1 5 | ||
| 125 | #define STATE_SYSEX_2 6 | ||
| 126 | uint8_t data[2]; | ||
| 127 | }; | ||
| 128 | |||
| 129 | struct gmidi_device { | ||
| 130 | spinlock_t lock; | ||
| 131 | struct usb_gadget *gadget; | ||
| 132 | struct usb_request *req; /* for control responses */ | ||
| 133 | u8 config; | ||
| 134 | struct usb_ep *in_ep, *out_ep; | ||
| 135 | struct snd_card *card; | ||
| 136 | struct snd_rawmidi *rmidi; | ||
| 137 | struct snd_rawmidi_substream *in_substream; | ||
| 138 | struct snd_rawmidi_substream *out_substream; | ||
| 139 | |||
| 140 | /* For the moment we only support one port in | ||
| 141 | each direction, but in_port is kept as a | ||
| 142 | separate struct so we can have more later. */ | ||
| 143 | struct gmidi_in_port in_port; | ||
| 144 | unsigned long out_triggered; | ||
| 145 | struct tasklet_struct tasklet; | ||
| 146 | }; | ||
| 147 | |||
| 148 | static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req); | ||
| 149 | |||
| 150 | |||
| 151 | #define DBG(d, fmt, args...) \ | ||
| 152 | dev_dbg(&(d)->gadget->dev , fmt , ## args) | ||
| 153 | #define VDBG(d, fmt, args...) \ | ||
| 154 | dev_vdbg(&(d)->gadget->dev , fmt , ## args) | ||
| 155 | #define ERROR(d, fmt, args...) \ | ||
| 156 | dev_err(&(d)->gadget->dev , fmt , ## args) | ||
| 157 | #define INFO(d, fmt, args...) \ | ||
| 158 | dev_info(&(d)->gadget->dev , fmt , ## args) | ||
| 159 | |||
| 160 | |||
| 161 | static unsigned buflen = 256; | ||
| 162 | static unsigned qlen = 32; | ||
| 163 | |||
| 164 | module_param(buflen, uint, S_IRUGO); | 62 | module_param(buflen, uint, S_IRUGO); |
| 63 | MODULE_PARM_DESC(buflen, "MIDI buffer length"); | ||
| 64 | |||
| 65 | static unsigned int qlen = 32; | ||
| 165 | module_param(qlen, uint, S_IRUGO); | 66 | module_param(qlen, uint, S_IRUGO); |
| 67 | MODULE_PARM_DESC(qlen, "USB read request queue length"); | ||
| 166 | 68 | ||
| 69 | static unsigned int in_ports = 1; | ||
| 70 | module_param(in_ports, uint, S_IRUGO); | ||
| 71 | MODULE_PARM_DESC(in_ports, "Number of MIDI input ports"); | ||
| 72 | |||
| 73 | static unsigned int out_ports = 1; | ||
| 74 | module_param(out_ports, uint, S_IRUGO); | ||
| 75 | MODULE_PARM_DESC(out_ports, "Number of MIDI output ports"); | ||
| 167 | 76 | ||
| 168 | /* Thanks to Grey Innovation for donating this product ID. | 77 | /* Thanks to Grey Innovation for donating this product ID. |
| 169 | * | 78 | * |
| @@ -173,1149 +82,124 @@ module_param(qlen, uint, S_IRUGO); · 3 unmodified lines | |||
| 173 | #define DRIVER_VENDOR_NUM 0x17b3 /* Grey Innovation */ | 82 | #define DRIVER_VENDOR_NUM 0x17b3 /* Grey Innovation */ |
| 174 | #define DRIVER_PRODUCT_NUM 0x0004 /* Linux-USB "MIDI Gadget" */ | 83 | #define DRIVER_PRODUCT_NUM 0x0004 /* Linux-USB "MIDI Gadget" */ |
| 175 | 84 | ||
| 85 | /* string IDs are assigned dynamically */ | ||
| 176 | 86 | ||
| 177 | /* | 87 | #define STRING_MANUFACTURER_IDX 0 |
| 178 | * DESCRIPTORS ... most are static, but strings and (full) | 88 | #define STRING_PRODUCT_IDX 1 |
| 179 | * configuration descriptors are built on demand. | 89 | #define STRING_DESCRIPTION_IDX 2 |
| 180 | */ | ||
| 181 | |||
| 182 | #define STRING_MANUFACTURER 25 | ||
| 183 | #define STRING_PRODUCT 42 | ||
| 184 | #define STRING_SERIAL 101 | ||
| 185 | #define STRING_MIDI_GADGET 250 | ||
| 186 | 90 | ||
| 187 | /* We only have the one configuration, it's number 1. */ | ||
| 188 | #define GMIDI_CONFIG 1 | ||
| 189 | |||
| 190 | /* We have two interfaces- AudioControl and MIDIStreaming */ | ||
| 191 | #define GMIDI_AC_INTERFACE 0 | ||
| 192 | #define GMIDI_MS_INTERFACE 1 | ||
| 193 | #define GMIDI_NUM_INTERFACES 2 | ||
| 194 | |||
| 195 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); | ||
| 196 | DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); | ||
| 197 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1); | ||
| 198 | |||
| 199 | /* B.1 Device Descriptor */ | ||
| 200 | static struct usb_device_descriptor device_desc = { | 91 | static struct usb_device_descriptor device_desc = { |
| 201 | .bLength = USB_DT_DEVICE_SIZE, | 92 | .bLength = USB_DT_DEVICE_SIZE, |
| 202 | .bDescriptorType = USB_DT_DEVICE, | 93 | .bDescriptorType = USB_DT_DEVICE, |
| 203 | .bcdUSB = cpu_to_le16(0x0200), | 94 | .bcdUSB = __constant_cpu_to_le16(0x0200), |
| 204 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 95 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
| 205 | .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), | 96 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), |
| 206 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM), | 97 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), |
| 207 | .iManufacturer = STRING_MANUFACTURER, | 98 | /* .iManufacturer = DYNAMIC */ |
| 208 | .iProduct = STRING_PRODUCT, | 99 | /* .iProduct = DYNAMIC */ |
| 209 | .bNumConfigurations = 1, | 100 | .bNumConfigurations = 1, |
| 210 | }; | 101 | }; |
| 211 | 102 | ||
| 212 | /* B.2 Configuration Descriptor */ | 103 | static struct usb_string strings_dev[] = { |
| 213 | static struct usb_config_descriptor config_desc = { | 104 | [STRING_MANUFACTURER_IDX].s = "Grey Innovation", |
| 214 | .bLength = USB_DT_CONFIG_SIZE, | 105 | [STRING_PRODUCT_IDX].s = "MIDI Gadget", |
| 215 | .bDescriptorType = USB_DT_CONFIG, | 106 | [STRING_DESCRIPTION_IDX].s = "MIDI", |
| 216 | /* compute wTotalLength on the fly */ | 107 | { } /* end of list */ |
| 217 | .bNumInterfaces = GMIDI_NUM_INTERFACES, | ||
| 218 | .bConfigurationValue = GMIDI_CONFIG, | ||
| 219 | .iConfiguration = STRING_MIDI_GADGET, | ||
| 220 | /* | ||
| 221 | * FIXME: When embedding this driver in a device, | ||
| 222 | * these need to be set to reflect the actual | ||
| 223 | * power properties of the device. Is it selfpowered? | ||
| 224 | */ | ||
| 225 | .bmAttributes = USB_CONFIG_ATT_ONE, | ||
| 226 | .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, | ||
| 227 | }; | ||
| 228 | |||
| 229 | /* B.3.1 Standard AC Interface Descriptor */ | ||
| 230 | static const struct usb_interface_descriptor ac_interface_desc = { | ||
| 231 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 232 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 233 | .bInterfaceNumber = GMIDI_AC_INTERFACE, | ||
| 234 | .bNumEndpoints = 0, | ||
| 235 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
| 236 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, | ||
| 237 | .iInterface = STRING_MIDI_GADGET, | ||
| 238 | }; | ||
| 239 | |||
| 240 | /* B.3.2 Class-Specific AC Interface Descriptor */ | ||
| 241 | static const struct uac1_ac_header_descriptor_1 ac_header_desc = { | ||
| 242 | .bLength = UAC_DT_AC_HEADER_SIZE(1), | ||
| 243 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 244 | .bDescriptorSubtype = USB_MS_HEADER, | ||
| 245 | .bcdADC = cpu_to_le16(0x0100), | ||
| 246 | .wTotalLength = cpu_to_le16(UAC_DT_AC_HEADER_SIZE(1)), | ||
| 247 | .bInCollection = 1, | ||
| 248 | .baInterfaceNr = { | ||
| 249 | [0] = GMIDI_MS_INTERFACE, | ||
| 250 | } | ||
| 251 | }; | ||
| 252 | |||
| 253 | /* B.4.1 Standard MS Interface Descriptor */ | ||
| 254 | static const struct usb_interface_descriptor ms_interface_desc = { | ||
| 255 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 256 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 257 | .bInterfaceNumber = GMIDI_MS_INTERFACE, | ||
| 258 | .bNumEndpoints = 2, | ||
| 259 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
| 260 | .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING, | ||
| 261 | .iInterface = STRING_MIDI_GADGET, | ||
| 262 | }; | 108 | }; |
| 263 | 109 | ||
| 264 | /* B.4.2 Class-Specific MS Interface Descriptor */ | 110 | static struct usb_gadget_strings stringtab_dev = { |
| 265 | static const struct usb_ms_header_descriptor ms_header_desc = { | ||
| 266 | .bLength = USB_DT_MS_HEADER_SIZE, | ||
| 267 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 268 | .bDescriptorSubtype = USB_MS_HEADER, | ||
| 269 | .bcdMSC = cpu_to_le16(0x0100), | ||
| 270 | .wTotalLength = cpu_to_le16(USB_DT_MS_HEADER_SIZE | ||
| 271 | + 2*USB_DT_MIDI_IN_SIZE | ||
| 272 | + 2*USB_DT_MIDI_OUT_SIZE(1)), | ||
| 273 | }; | ||
| 274 | |||
| 275 | #define JACK_IN_EMB 1 | ||
| 276 | #define JACK_IN_EXT 2 | ||
| 277 | #define JACK_OUT_EMB 3 | ||
| 278 | #define JACK_OUT_EXT 4 | ||
| 279 | |||
| 280 | /* B.4.3 MIDI IN Jack Descriptors */ | ||
| 281 | static const struct usb_midi_in_jack_descriptor jack_in_emb_desc = { | ||
| 282 | .bLength = USB_DT_MIDI_IN_SIZE, | ||
| 283 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 284 | .bDescriptorSubtype = USB_MS_MIDI_IN_JACK, | ||
| 285 | .bJackType = USB_MS_EMBEDDED, | ||
| 286 | .bJackID = JACK_IN_EMB, | ||
| 287 | }; | ||
| 288 | |||
| 289 | static const struct usb_midi_in_jack_descriptor jack_in_ext_desc = { | ||
| 290 | .bLength = USB_DT_MIDI_IN_SIZE, | ||
| 291 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 292 | .bDescriptorSubtype = USB_MS_MIDI_IN_JACK, | ||
| 293 | .bJackType = USB_MS_EXTERNAL, | ||
| 294 | .bJackID = JACK_IN_EXT, | ||
| 295 | }; | ||
| 296 | |||
| 297 | /* B.4.4 MIDI OUT Jack Descriptors */ | ||
| 298 | static const struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc = { | ||
| 299 | .bLength = USB_DT_MIDI_OUT_SIZE(1), | ||
| 300 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 301 | .bDescriptorSubtype = USB_MS_MIDI_OUT_JACK, | ||
| 302 | .bJackType = USB_MS_EMBEDDED, | ||
| 303 | .bJackID = JACK_OUT_EMB, | ||
| 304 | .bNrInputPins = 1, | ||
| 305 | .pins = { | ||
| 306 | [0] = { | ||
| 307 | .baSourceID = JACK_IN_EXT, | ||
| 308 | .baSourcePin = 1, | ||
| 309 | } | ||
| 310 | } | ||
| 311 | }; | ||
| 312 | |||
| 313 | static const struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc = { | ||
| 314 | .bLength = USB_DT_MIDI_OUT_SIZE(1), | ||
| 315 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 316 | .bDescriptorSubtype = USB_MS_MIDI_OUT_JACK, | ||
| 317 | .bJackType = USB_MS_EXTERNAL, | ||
| 318 | .bJackID = JACK_OUT_EXT, | ||
| 319 | .bNrInputPins = 1, | ||
| 320 | .pins = { | ||
| 321 | [0] = { | ||
| 322 | .baSourceID = JACK_IN_EMB, | ||
| 323 | .baSourcePin = 1, | ||
| 324 | } | ||
| 325 | } | ||
| 326 | }; | ||
| 327 | |||
| 328 | /* B.5.1 Standard Bulk OUT Endpoint Descriptor */ | ||
| 329 | static struct usb_endpoint_descriptor bulk_out_desc = { | ||
| 330 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | ||
| 331 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 332 | .bEndpointAddress = USB_DIR_OUT, | ||
| 333 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 334 | }; | ||
| 335 | |||
| 336 | /* B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor */ | ||
| 337 | static const struct usb_ms_endpoint_descriptor_1 ms_out_desc = { | ||
| 338 | .bLength = USB_DT_MS_ENDPOINT_SIZE(1), | ||
| 339 | .bDescriptorType = USB_DT_CS_ENDPOINT, | ||
| 340 | .bDescriptorSubtype = USB_MS_GENERAL, | ||
| 341 | .bNumEmbMIDIJack = 1, | ||
| 342 | .baAssocJackID = { | ||
| 343 | [0] = JACK_IN_EMB, | ||
| 344 | } | ||
| 345 | }; | ||
| 346 | |||
| 347 | /* B.6.1 Standard Bulk IN Endpoint Descriptor */ | ||
| 348 | static struct usb_endpoint_descriptor bulk_in_desc = { | ||
| 349 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | ||
| 350 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 351 | .bEndpointAddress = USB_DIR_IN, | ||
| 352 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 353 | }; | ||
| 354 | |||
| 355 | /* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */ | ||
| 356 | static const struct usb_ms_endpoint_descriptor_1 ms_in_desc = { | ||
| 357 | .bLength = USB_DT_MS_ENDPOINT_SIZE(1), | ||
| 358 | .bDescriptorType = USB_DT_CS_ENDPOINT, | ||
| 359 | .bDescriptorSubtype = USB_MS_GENERAL, | ||
| 360 | .bNumEmbMIDIJack = 1, | ||
| 361 | .baAssocJackID = { | ||
| 362 | [0] = JACK_OUT_EMB, | ||
| 363 | } | ||
| 364 | }; | ||
| 365 | |||
| 366 | static const struct usb_descriptor_header *gmidi_function [] = { | ||
| 367 | (struct usb_descriptor_header *)&ac_interface_desc, | ||
| 368 | (struct usb_descriptor_header *)&ac_header_desc, | ||
| 369 | (struct usb_descriptor_header *)&ms_interface_desc, | ||
| 370 | |||
| 371 | (struct usb_descriptor_header *)&ms_header_desc, | ||
| 372 | (struct usb_descriptor_header *)&jack_in_emb_desc, | ||
| 373 | (struct usb_descriptor_header *)&jack_in_ext_desc, | ||
| 374 | (struct usb_descriptor_header *)&jack_out_emb_desc, | ||
| 375 | (struct usb_descriptor_header *)&jack_out_ext_desc, | ||
| 376 | /* If you add more jacks, update ms_header_desc.wTotalLength */ | ||
| 377 | |||
| 378 | (struct usb_descriptor_header *)&bulk_out_desc, | ||
| 379 | (struct usb_descriptor_header *)&ms_out_desc, | ||
| 380 | (struct usb_descriptor_header *)&bulk_in_desc, | ||
| 381 | (struct usb_descriptor_header *)&ms_in_desc, | ||
| 382 | NULL, | ||
| 383 | }; | ||
| 384 | |||
| 385 | static char manufacturer[50]; | ||
| 386 | static char product_desc[40] = "MIDI Gadget"; | ||
| 387 | static char serial_number[20]; | ||
| 388 | |||
| 389 | /* static strings, in UTF-8 */ | ||
| 390 | static struct usb_string strings [] = { | ||
| 391 | { STRING_MANUFACTURER, manufacturer, }, | ||
| 392 | { STRING_PRODUCT, product_desc, }, | ||
| 393 | { STRING_SERIAL, serial_number, }, | ||
| 394 | { STRING_MIDI_GADGET, longname, }, | ||
| 395 | { } /* end of list */ | ||
| 396 | }; | ||
| 397 | |||
| 398 | static struct usb_gadget_strings stringtab = { | ||
| 399 | .language = 0x0409, /* en-us */ | 111 | .language = 0x0409, /* en-us */ |
| 400 | .strings = strings, | 112 | .strings = strings_dev, |
| 401 | }; | 113 | }; |
| 402 | 114 | ||
| 403 | static int config_buf(struct usb_gadget *gadget, | 115 | static struct usb_gadget_strings *dev_strings[] = { |
| 404 | u8 *buf, u8 type, unsigned index) | 116 | &stringtab_dev, |
| 405 | { | 117 | NULL, |
| 406 | int len; | ||
| 407 | |||
| 408 | /* only one configuration */ | ||
| 409 | if (index != 0) { | ||
| 410 | return -EINVAL; | ||
| 411 | } | ||
| 412 | len = usb_gadget_config_buf(&config_desc, | ||
| 413 | buf, USB_BUFSIZ, gmidi_function); | ||
| 414 | if (len < 0) { | ||
| 415 | return len; | ||
| 416 | } | ||
| 417 | ((struct usb_config_descriptor *)buf)->bDescriptorType = type; | ||
| 418 | return len; | ||
| 419 | } | ||
| 420 | |||
| 421 | static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length) | ||
| 422 | { | ||
| 423 | struct usb_request *req; | ||
| 424 | |||
| 425 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); | ||
| 426 | if (req) { | ||
| 427 | req->length = length; | ||
| 428 | req->buf = kmalloc(length, GFP_ATOMIC); | ||
| 429 | if (!req->buf) { | ||
| 430 | usb_ep_free_request(ep, req); | ||
| 431 | req = NULL; | ||
| 432 | } | ||
| 433 | } | ||
| 434 | return req; | ||
| 435 | } | ||
| 436 | |||
| 437 | static void free_ep_req(struct usb_ep *ep, struct usb_request *req) | ||
| 438 | { | ||
| 439 | kfree(req->buf); | ||
| 440 | usb_ep_free_request(ep, req); | ||
| 441 | } | ||
| 442 | |||
| 443 | static const uint8_t gmidi_cin_length[] = { | ||
| 444 | 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1 | ||
| 445 | }; | 118 | }; |
| 446 | 119 | ||
| 447 | /* | 120 | static int __exit midi_unbind(struct usb_composite_dev *dev) |
| 448 | * Receives a chunk of MIDI data. | ||
| 449 | */ | ||
| 450 | static void gmidi_read_data(struct usb_ep *ep, int cable, | ||
| 451 | uint8_t *data, int length) | ||
| 452 | { | ||
| 453 | struct gmidi_device *dev = ep->driver_data; | ||
| 454 | /* cable is ignored, because for now we only have one. */ | ||
| 455 | |||
| 456 | if (!dev->out_substream) { | ||
| 457 | /* Nobody is listening - throw it on the floor. */ | ||
| 458 | return; | ||
| 459 | } | ||
| 460 | if (!test_bit(dev->out_substream->number, &dev->out_triggered)) { | ||
| 461 | return; | ||
| 462 | } | ||
| 463 | snd_rawmidi_receive(dev->out_substream, data, length); | ||
| 464 | } | ||
| 465 | |||
| 466 | static void gmidi_handle_out_data(struct usb_ep *ep, struct usb_request *req) | ||
| 467 | { | ||
| 468 | unsigned i; | ||
| 469 | u8 *buf = req->buf; | ||
| 470 | |||
| 471 | for (i = 0; i + 3 < req->actual; i += 4) { | ||
| 472 | if (buf[i] != 0) { | ||
| 473 | int cable = buf[i] >> 4; | ||
| 474 | int length = gmidi_cin_length[buf[i] & 0x0f]; | ||
| 475 | gmidi_read_data(ep, cable, &buf[i + 1], length); | ||
| 476 | } | ||
| 477 | } | ||
| 478 | } | ||
| 479 | |||
| 480 | static void gmidi_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 481 | { | ||
| 482 | struct gmidi_device *dev = ep->driver_data; | ||
| 483 | int status = req->status; | ||
| 484 | |||
| 485 | switch (status) { | ||
| 486 | case 0: /* normal completion */ | ||
| 487 | if (ep == dev->out_ep) { | ||
| 488 | /* we received stuff. | ||
| 489 | req is queued again, below */ | ||
| 490 | gmidi_handle_out_data(ep, req); | ||
| 491 | } else if (ep == dev->in_ep) { | ||
| 492 | /* our transmit completed. | ||
| 493 | see if there's more to go. | ||
| 494 | gmidi_transmit eats req, don't queue it again. */ | ||
| 495 | gmidi_transmit(dev, req); | ||
| 496 | return; | ||
| 497 | } | ||
| 498 | break; | ||
| 499 | |||
| 500 | /* this endpoint is normally active while we're configured */ | ||
| 501 | case -ECONNABORTED: /* hardware forced ep reset */ | ||
| 502 | case -ECONNRESET: /* request dequeued */ | ||
| 503 | case -ESHUTDOWN: /* disconnect from host */ | ||
| 504 | VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, | ||
| 505 | req->actual, req->length); | ||
| 506 | if (ep == dev->out_ep) { | ||
| 507 | gmidi_handle_out_data(ep, req); | ||
| 508 | } | ||
| 509 | free_ep_req(ep, req); | ||
| 510 | return; | ||
| 511 | |||
| 512 | case -EOVERFLOW: /* buffer overrun on read means that | ||
| 513 | * we didn't provide a big enough | ||
| 514 | * buffer. | ||
| 515 | */ | ||
| 516 | default: | ||
| 517 | DBG(dev, "%s complete --> %d, %d/%d\n", ep->name, | ||
| 518 | status, req->actual, req->length); | ||
| 519 | break; | ||
| 520 | case -EREMOTEIO: /* short read */ | ||
| 521 | break; | ||
| 522 | } | ||
| 523 | |||
| 524 | status = usb_ep_queue(ep, req, GFP_ATOMIC); | ||
| 525 | if (status) { | ||
| 526 | ERROR(dev, "kill %s: resubmit %d bytes --> %d\n", | ||
| 527 | ep->name, req->length, status); | ||
| 528 | usb_ep_set_halt(ep); | ||
| 529 | /* FIXME recover later ... somehow */ | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 533 | static int set_gmidi_config(struct gmidi_device *dev, gfp_t gfp_flags) | ||
| 534 | { | ||
| 535 | int err = 0; | ||
| 536 | struct usb_request *req; | ||
| 537 | struct usb_ep *ep; | ||
| 538 | unsigned i; | ||
| 539 | |||
| 540 | dev->in_ep->desc = &bulk_in_desc; | ||
| 541 | err = usb_ep_enable(dev->in_ep); | ||
| 542 | if (err) { | ||
| 543 | ERROR(dev, "can't start %s: %d\n", dev->in_ep->name, err); | ||
| 544 | goto fail; | ||
| 545 | } | ||
| 546 | dev->in_ep->driver_data = dev; | ||
| 547 | |||
| 548 | dev->out_ep->desc = &bulk_out_desc; | ||
| 549 | err = usb_ep_enable(dev->out_ep); | ||
| 550 | if (err) { | ||
| 551 | ERROR(dev, "can't start %s: %d\n", dev->out_ep->name, err); | ||
| 552 | goto fail; | ||
| 553 | } | ||
| 554 | dev->out_ep->driver_data = dev; | ||
| 555 | |||
| 556 | /* allocate a bunch of read buffers and queue them all at once. */ | ||
| 557 | ep = dev->out_ep; | ||
| 558 | for (i = 0; i < qlen && err == 0; i++) { | ||
| 559 | req = alloc_ep_req(ep, buflen); | ||
| 560 | if (req) { | ||
| 561 | req->complete = gmidi_complete; | ||
| 562 | err = usb_ep_queue(ep, req, GFP_ATOMIC); | ||
| 563 | if (err) { | ||
| 564 | DBG(dev, "%s queue req: %d\n", ep->name, err); | ||
| 565 | } | ||
| 566 | } else { | ||
| 567 | err = -ENOMEM; | ||
| 568 | } | ||
| 569 | } | ||
| 570 | fail: | ||
| 571 | /* caller is responsible for cleanup on error */ | ||
| 572 | return err; | ||
| 573 | } | ||
| 574 | |||
| 575 | |||
| 576 | static void gmidi_reset_config(struct gmidi_device *dev) | ||
| 577 | { | ||
| 578 | if (dev->config == 0) { | ||
| 579 | return; | ||
| 580 | } | ||
| 581 | |||
| 582 | DBG(dev, "reset config\n"); | ||
| 583 | |||
| 584 | /* just disable endpoints, forcing completion of pending i/o. | ||
| 585 | * all our completion handlers free their requests in this case. | ||
| 586 | */ | ||
| 587 | usb_ep_disable(dev->in_ep); | ||
| 588 | usb_ep_disable(dev->out_ep); | ||
| 589 | dev->config = 0; | ||
| 590 | } | ||
| 591 | |||
| 592 | /* change our operational config. this code must agree with the code | ||
| 593 | * that returns config descriptors, and altsetting code. | ||
| 594 | * | ||
| 595 | * it's also responsible for power management interactions. some | ||
| 596 | * configurations might not work with our current power sources. | ||
| 597 | * | ||
| 598 | * note that some device controller hardware will constrain what this | ||
| 599 | * code can do, perhaps by disallowing more than one configuration or | ||
| 600 | * by limiting configuration choices (like the pxa2xx). | ||
| 601 | */ | ||
| 602 | static int | ||
| 603 | gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags) | ||
| 604 | { | ||
| 605 | int result = 0; | ||
| 606 | struct usb_gadget *gadget = dev->gadget; | ||
| 607 | |||
| 608 | #if 0 | ||
| 609 | /* FIXME */ | ||
| 610 | /* Hacking this bit out fixes a bug where on receipt of two | ||
| 611 | USB_REQ_SET_CONFIGURATION messages, we end up with no | ||
| 612 | buffered OUT requests waiting for data. This is clearly | ||
| 613 | hiding a bug elsewhere, because if the config didn't | ||
| 614 | change then we really shouldn't do anything. */ | ||
| 615 | /* Having said that, when we do "change" from config 1 | ||
| 616 | to config 1, we at least gmidi_reset_config() which | ||
| 617 | clears out any requests on endpoints, so it's not like | ||
| 618 | we leak or anything. */ | ||
| 619 | if (number == dev->config) { | ||
| 620 | return 0; | ||
| 621 | } | ||
| 622 | #endif | ||
| 623 | |||
| 624 | gmidi_reset_config(dev); | ||
| 625 | |||
| 626 | switch (number) { | ||
| 627 | case GMIDI_CONFIG: | ||
| 628 | result = set_gmidi_config(dev, gfp_flags); | ||
| 629 | break; | ||
| 630 | default: | ||
| 631 | result = -EINVAL; | ||
| 632 | /* FALL THROUGH */ | ||
| 633 | case 0: | ||
| 634 | return result; | ||
| 635 | } | ||
| 636 | |||
| 637 | if (!result && (!dev->in_ep || !dev->out_ep)) { | ||
| 638 | result = -ENODEV; | ||
| 639 | } | ||
| 640 | if (result) { | ||
| 641 | gmidi_reset_config(dev); | ||
| 642 | } else { | ||
| 643 | char *speed; | ||
| 644 | |||
| 645 | switch (gadget->speed) { | ||
| 646 | case USB_SPEED_LOW: speed = "low"; break; | ||
| 647 | case USB_SPEED_FULL: speed = "full"; break; | ||
| 648 | case USB_SPEED_HIGH: speed = "high"; break; | ||
| 649 | default: speed = "?"; break; | ||
| 650 | } | ||
| 651 | |||
| 652 | dev->config = number; | ||
| 653 | INFO(dev, "%s speed\n", speed); | ||
| 654 | } | ||
| 655 | return result; | ||
| 656 | } | ||
| 657 | |||
| 658 | |||
| 659 | static void gmidi_setup_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 660 | { | ||
| 661 | if (req->status || req->actual != req->length) { | ||
| 662 | DBG((struct gmidi_device *) ep->driver_data, | ||
| 663 | "setup complete --> %d, %d/%d\n", | ||
| 664 | req->status, req->actual, req->length); | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | /* | ||
| 669 | * The setup() callback implements all the ep0 functionality that's | ||
| 670 | * not handled lower down, in hardware or the hardware driver (like | ||
| 671 | * device and endpoint feature flags, and their status). It's all | ||
| 672 | * housekeeping for the gadget function we're implementing. Most of | ||
| 673 | * the work is in config-specific setup. | ||
| 674 | */ | ||
| 675 | static int gmidi_setup(struct usb_gadget *gadget, | ||
| 676 | const struct usb_ctrlrequest *ctrl) | ||
| 677 | { | ||
| 678 | struct gmidi_device *dev = get_gadget_data(gadget); | ||
| 679 | struct usb_request *req = dev->req; | ||
| 680 | int value = -EOPNOTSUPP; | ||
| 681 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
| 682 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 683 | u16 w_length = le16_to_cpu(ctrl->wLength); | ||
| 684 | |||
| 685 | /* usually this stores reply data in the pre-allocated ep0 buffer, | ||
| 686 | * but config change events will reconfigure hardware. | ||
| 687 | */ | ||
| 688 | req->zero = 0; | ||
| 689 | switch (ctrl->bRequest) { | ||
| 690 | |||
| 691 | case USB_REQ_GET_DESCRIPTOR: | ||
| 692 | if (ctrl->bRequestType != USB_DIR_IN) { | ||
| 693 | goto unknown; | ||
| 694 | } | ||
| 695 | switch (w_value >> 8) { | ||
| 696 | |||
| 697 | case USB_DT_DEVICE: | ||
| 698 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
| 699 | value = min(w_length, (u16) sizeof(device_desc)); | ||
| 700 | memcpy(req->buf, &device_desc, value); | ||
| 701 | break; | ||
| 702 | case USB_DT_CONFIG: | ||
| 703 | value = config_buf(gadget, req->buf, | ||
| 704 | w_value >> 8, | ||
| 705 | w_value & 0xff); | ||
| 706 | if (value >= 0) { | ||
| 707 | value = min(w_length, (u16)value); | ||
| 708 | } | ||
| 709 | break; | ||
| 710 | |||
| 711 | case USB_DT_STRING: | ||
| 712 | /* wIndex == language code. | ||
| 713 | * this driver only handles one language, you can | ||
| 714 | * add string tables for other languages, using | ||
| 715 | * any UTF-8 characters | ||
| 716 | */ | ||
| 717 | value = usb_gadget_get_string(&stringtab, | ||
| 718 | w_value & 0xff, req->buf); | ||
| 719 | if (value >= 0) { | ||
| 720 | value = min(w_length, (u16)value); | ||
| 721 | } | ||
| 722 | break; | ||
| 723 | } | ||
| 724 | break; | ||
| 725 | |||
| 726 | /* currently two configs, two speeds */ | ||
| 727 | case USB_REQ_SET_CONFIGURATION: | ||
| 728 | if (ctrl->bRequestType != 0) { | ||
| 729 | goto unknown; | ||
| 730 | } | ||
| 731 | if (gadget->a_hnp_support) { | ||
| 732 | DBG(dev, "HNP available\n"); | ||
| 733 | } else if (gadget->a_alt_hnp_support) { | ||
| 734 | DBG(dev, "HNP needs a different root port\n"); | ||
| 735 | } else { | ||
| 736 | VDBG(dev, "HNP inactive\n"); | ||
| 737 | } | ||
| 738 | spin_lock(&dev->lock); | ||
| 739 | value = gmidi_set_config(dev, w_value, GFP_ATOMIC); | ||
| 740 | spin_unlock(&dev->lock); | ||
| 741 | break; | ||
| 742 | case USB_REQ_GET_CONFIGURATION: | ||
| 743 | if (ctrl->bRequestType != USB_DIR_IN) { | ||
| 744 | goto unknown; | ||
| 745 | } | ||
| 746 | *(u8 *)req->buf = dev->config; | ||
| 747 | value = min(w_length, (u16)1); | ||
| 748 | break; | ||
| 749 | |||
| 750 | /* until we add altsetting support, or other interfaces, | ||
| 751 | * only 0/0 are possible. pxa2xx only supports 0/0 (poorly) | ||
| 752 | * and already killed pending endpoint I/O. | ||
| 753 | */ | ||
| 754 | case USB_REQ_SET_INTERFACE: | ||
| 755 | if (ctrl->bRequestType != USB_RECIP_INTERFACE) { | ||
| 756 | goto unknown; | ||
| 757 | } | ||
| 758 | spin_lock(&dev->lock); | ||
| 759 | if (dev->config && w_index < GMIDI_NUM_INTERFACES | ||
| 760 | && w_value == 0) | ||
| 761 | { | ||
| 762 | u8 config = dev->config; | ||
| 763 | |||
| 764 | /* resets interface configuration, forgets about | ||
| 765 | * previous transaction state (queued bufs, etc) | ||
| 766 | * and re-inits endpoint state (toggle etc) | ||
| 767 | * no response queued, just zero status == success. | ||
| 768 | * if we had more than one interface we couldn't | ||
| 769 | * use this "reset the config" shortcut. | ||
| 770 | */ | ||
| 771 | gmidi_reset_config(dev); | ||
| 772 | gmidi_set_config(dev, config, GFP_ATOMIC); | ||
| 773 | value = 0; | ||
| 774 | } | ||
| 775 | spin_unlock(&dev->lock); | ||
| 776 | break; | ||
| 777 | case USB_REQ_GET_INTERFACE: | ||
| 778 | if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) { | ||
| 779 | goto unknown; | ||
| 780 | } | ||
| 781 | if (!dev->config) { | ||
| 782 | break; | ||
| 783 | } | ||
| 784 | if (w_index >= GMIDI_NUM_INTERFACES) { | ||
| 785 | value = -EDOM; | ||
| 786 | break; | ||
| 787 | } | ||
| 788 | *(u8 *)req->buf = 0; | ||
| 789 | value = min(w_length, (u16)1); | ||
| 790 | break; | ||
| 791 | |||
| 792 | default: | ||
| 793 | unknown: | ||
| 794 | VDBG(dev, "unknown control req%02x.%02x v%04x i%04x l%d\n", | ||
| 795 | ctrl->bRequestType, ctrl->bRequest, | ||
| 796 | w_value, w_index, w_length); | ||
| 797 | } | ||
| 798 | |||
| 799 | /* respond with data transfer before status phase? */ | ||
| 800 | if (value >= 0) { | ||
| 801 | req->length = value; | ||
| 802 | req->zero = value < w_length; | ||
| 803 | value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | ||
| 804 | if (value < 0) { | ||
| 805 | DBG(dev, "ep_queue --> %d\n", value); | ||
| 806 | req->status = 0; | ||
| 807 | gmidi_setup_complete(gadget->ep0, req); | ||
| 808 | } | ||
| 809 | } | ||
| 810 | |||
| 811 | /* device either stalls (value < 0) or reports success */ | ||
| 812 | return value; | ||
| 813 | } | ||
| 814 | |||
| 815 | static void gmidi_disconnect(struct usb_gadget *gadget) | ||
| 816 | { | ||
| 817 | struct gmidi_device *dev = get_gadget_data(gadget); | ||
| 818 | unsigned long flags; | ||
| 819 | |||
| 820 | spin_lock_irqsave(&dev->lock, flags); | ||
| 821 | gmidi_reset_config(dev); | ||
| 822 | |||
| 823 | /* a more significant application might have some non-usb | ||
| 824 | * activities to quiesce here, saving resources like power | ||
| 825 | * or pushing the notification up a network stack. | ||
| 826 | */ | ||
| 827 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 828 | |||
| 829 | /* next we may get setup() calls to enumerate new connections; | ||
| 830 | * or an unbind() during shutdown (including removing module). | ||
| 831 | */ | ||
| 832 | } | ||
| 833 | |||
| 834 | static void /* __init_or_exit */ gmidi_unbind(struct usb_gadget *gadget) | ||
| 835 | { | ||
| 836 | struct gmidi_device *dev = get_gadget_data(gadget); | ||
| 837 | struct snd_card *card; | ||
| 838 | |||
| 839 | DBG(dev, "unbind\n"); | ||
| 840 | |||
| 841 | card = dev->card; | ||
| 842 | dev->card = NULL; | ||
| 843 | if (card) { | ||
| 844 | snd_card_free(card); | ||
| 845 | } | ||
| 846 | |||
| 847 | /* we've already been disconnected ... no i/o is active */ | ||
| 848 | if (dev->req) { | ||
| 849 | dev->req->length = USB_BUFSIZ; | ||
| 850 | free_ep_req(gadget->ep0, dev->req); | ||
| 851 | } | ||
| 852 | kfree(dev); | ||
| 853 | set_gadget_data(gadget, NULL); | ||
| 854 | } | ||
| 855 | |||
| 856 | static int gmidi_snd_free(struct snd_device *device) | ||
| 857 | { | 121 | { |
| 858 | return 0; | 122 | return 0; |
| 859 | } | 123 | } |
| 860 | 124 | ||
| 861 | static void gmidi_transmit_packet(struct usb_request *req, uint8_t p0, | 125 | static struct usb_configuration midi_config = { |
| 862 | uint8_t p1, uint8_t p2, uint8_t p3) | 126 | .label = "MIDI Gadget", |
| 863 | { | 127 | .bConfigurationValue = 1, |
| 864 | unsigned length = req->length; | 128 | /* .iConfiguration = DYNAMIC */ |
| 865 | u8 *buf = (u8 *)req->buf + length; | 129 | .bmAttributes = USB_CONFIG_ATT_ONE, |
| 866 | 130 | .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, | |
| 867 | buf[0] = p0; | ||
| 868 | buf[1] = p1; | ||
| 869 | buf[2] = p2; | ||
| 870 | buf[3] = p3; | ||
| 871 | req->length = length + 4; | ||
| 872 | } | ||
| 873 | |||
| 874 | /* | ||
| 875 | * Converts MIDI commands to USB MIDI packets. | ||
| 876 | */ | ||
| 877 | static void gmidi_transmit_byte(struct usb_request *req, | ||
| 878 | struct gmidi_in_port *port, uint8_t b) | ||
| 879 | { | ||
| 880 | uint8_t p0 = port->cable; | ||
| 881 | |||
| 882 | if (b >= 0xf8) { | ||
| 883 | gmidi_transmit_packet(req, p0 | 0x0f, b, 0, 0); | ||
| 884 | } else if (b >= 0xf0) { | ||
| 885 | switch (b) { | ||
| 886 | case 0xf0: | ||
| 887 | port->data[0] = b; | ||
| 888 | port->state = STATE_SYSEX_1; | ||
| 889 | break; | ||
| 890 | case 0xf1: | ||
| 891 | case 0xf3: | ||
| 892 | port->data[0] = b; | ||
| 893 | port->state = STATE_1PARAM; | ||
| 894 | break; | ||
| 895 | case 0xf2: | ||
| 896 | port->data[0] = b; | ||
| 897 | port->state = STATE_2PARAM_1; | ||
| 898 | break; | ||
| 899 | case 0xf4: | ||
| 900 | case 0xf5: | ||
| 901 | port->state = STATE_UNKNOWN; | ||
| 902 | break; | ||
| 903 | case 0xf6: | ||
| 904 | gmidi_transmit_packet(req, p0 | 0x05, 0xf6, 0, 0); | ||
| 905 | port->state = STATE_UNKNOWN; | ||
| 906 | break; | ||
| 907 | case 0xf7: | ||
| 908 | switch (port->state) { | ||
| 909 | case STATE_SYSEX_0: | ||
| 910 | gmidi_transmit_packet(req, | ||
| 911 | p0 | 0x05, 0xf7, 0, 0); | ||
| 912 | break; | ||
| 913 | case STATE_SYSEX_1: | ||
| 914 | gmidi_transmit_packet(req, | ||
| 915 | p0 | 0x06, port->data[0], 0xf7, 0); | ||
| 916 | break; | ||
| 917 | case STATE_SYSEX_2: | ||
| 918 | gmidi_transmit_packet(req, | ||
| 919 | p0 | 0x07, port->data[0], | ||
| 920 | port->data[1], 0xf7); | ||
| 921 | break; | ||
| 922 | } | ||
| 923 | port->state = STATE_UNKNOWN; | ||
| 924 | break; | ||
| 925 | } | ||
| 926 | } else if (b >= 0x80) { | ||
| 927 | port->data[0] = b; | ||
| 928 | if (b >= 0xc0 && b <= 0xdf) | ||
| 929 | port->state = STATE_1PARAM; | ||
| 930 | else | ||
| 931 | port->state = STATE_2PARAM_1; | ||
| 932 | } else { /* b < 0x80 */ | ||
| 933 | switch (port->state) { | ||
| 934 | case STATE_1PARAM: | ||
| 935 | if (port->data[0] < 0xf0) { | ||
| 936 | p0 |= port->data[0] >> 4; | ||
| 937 | } else { | ||
| 938 | p0 |= 0x02; | ||
| 939 | port->state = STATE_UNKNOWN; | ||
| 940 | } | ||
| 941 | gmidi_transmit_packet(req, p0, port->data[0], b, 0); | ||
| 942 | break; | ||
| 943 | case STATE_2PARAM_1: | ||
| 944 | port->data[1] = b; | ||
| 945 | port->state = STATE_2PARAM_2; | ||
| 946 | break; | ||
| 947 | case STATE_2PARAM_2: | ||
| 948 | if (port->data[0] < 0xf0) { | ||
| 949 | p0 |= port->data[0] >> 4; | ||
| 950 | port->state = STATE_2PARAM_1; | ||
| 951 | } else { | ||
| 952 | p0 |= 0x03; | ||
| 953 | port->state = STATE_UNKNOWN; | ||
| 954 | } | ||
| 955 | gmidi_transmit_packet(req, | ||
| 956 | p0, port->data[0], port->data[1], b); | ||
| 957 | break; | ||
| 958 | case STATE_SYSEX_0: | ||
| 959 | port->data[0] = b; | ||
| 960 | port->state = STATE_SYSEX_1; | ||
| 961 | break; | ||
| 962 | case STATE_SYSEX_1: | ||
| 963 | port->data[1] = b; | ||
| 964 | port->state = STATE_SYSEX_2; | ||
| 965 | break; | ||
| 966 | case STATE_SYSEX_2: | ||
| 967 | gmidi_transmit_packet(req, | ||
| 968 | p0 | 0x04, port->data[0], port->data[1], b); | ||
| 969 | port->state = STATE_SYSEX_0; | ||
| 970 | break; | ||
| 971 | } | ||
| 972 | } | ||
| 973 | } | ||
| 974 | |||
| 975 | static void gmidi_transmit(struct gmidi_device *dev, struct usb_request *req) | ||
| 976 | { | ||
| 977 | struct usb_ep *ep = dev->in_ep; | ||
| 978 | struct gmidi_in_port *port = &dev->in_port; | ||
| 979 | |||
| 980 | if (!ep) { | ||
| 981 | return; | ||
| 982 | } | ||
| 983 | if (!req) { | ||
| 984 | req = alloc_ep_req(ep, buflen); | ||
| 985 | } | ||
| 986 | if (!req) { | ||
| 987 | ERROR(dev, "gmidi_transmit: alloc_ep_request failed\n"); | ||
| 988 | return; | ||
| 989 | } | ||
| 990 | req->length = 0; | ||
| 991 | req->complete = gmidi_complete; | ||
| 992 | |||
| 993 | if (port->active) { | ||
| 994 | while (req->length + 3 < buflen) { | ||
| 995 | uint8_t b; | ||
| 996 | if (snd_rawmidi_transmit(dev->in_substream, &b, 1) | ||
| 997 | != 1) | ||
| 998 | { | ||
| 999 | port->active = 0; | ||
| 1000 | break; | ||
| 1001 | } | ||
| 1002 | gmidi_transmit_byte(req, port, b); | ||
| 1003 | } | ||
| 1004 | } | ||
| 1005 | if (req->length > 0) { | ||
| 1006 | usb_ep_queue(ep, req, GFP_ATOMIC); | ||
| 1007 | } else { | ||
| 1008 | free_ep_req(ep, req); | ||
| 1009 | } | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | static void gmidi_in_tasklet(unsigned long data) | ||
| 1013 | { | ||
| 1014 | struct gmidi_device *dev = (struct gmidi_device *)data; | ||
| 1015 | |||
| 1016 | gmidi_transmit(dev, NULL); | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | static int gmidi_in_open(struct snd_rawmidi_substream *substream) | ||
| 1020 | { | ||
| 1021 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
| 1022 | |||
| 1023 | VDBG(dev, "gmidi_in_open\n"); | ||
| 1024 | dev->in_substream = substream; | ||
| 1025 | dev->in_port.state = STATE_UNKNOWN; | ||
| 1026 | return 0; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | static int gmidi_in_close(struct snd_rawmidi_substream *substream) | ||
| 1030 | { | ||
| 1031 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
| 1032 | |||
| 1033 | VDBG(dev, "gmidi_in_close\n"); | ||
| 1034 | return 0; | ||
| 1035 | } | ||
| 1036 | |||
| 1037 | static void gmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) | ||
| 1038 | { | ||
| 1039 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
| 1040 | |||
| 1041 | VDBG(dev, "gmidi_in_trigger %d\n", up); | ||
| 1042 | dev->in_port.active = up; | ||
| 1043 | if (up) { | ||
| 1044 | tasklet_hi_schedule(&dev->tasklet); | ||
| 1045 | } | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | static int gmidi_out_open(struct snd_rawmidi_substream *substream) | ||
| 1049 | { | ||
| 1050 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
| 1051 | |||
| 1052 | VDBG(dev, "gmidi_out_open\n"); | ||
| 1053 | dev->out_substream = substream; | ||
| 1054 | return 0; | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | static int gmidi_out_close(struct snd_rawmidi_substream *substream) | ||
| 1058 | { | ||
| 1059 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
| 1060 | |||
| 1061 | VDBG(dev, "gmidi_out_close\n"); | ||
| 1062 | return 0; | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | static void gmidi_out_trigger(struct snd_rawmidi_substream *substream, int up) | ||
| 1066 | { | ||
| 1067 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
| 1068 | |||
| 1069 | VDBG(dev, "gmidi_out_trigger %d\n", up); | ||
| 1070 | if (up) { | ||
| 1071 | set_bit(substream->number, &dev->out_triggered); | ||
| 1072 | } else { | ||
| 1073 | clear_bit(substream->number, &dev->out_triggered); | ||
| 1074 | } | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | static struct snd_rawmidi_ops gmidi_in_ops = { | ||
| 1078 | .open = gmidi_in_open, | ||
| 1079 | .close = gmidi_in_close, | ||
| 1080 | .trigger = gmidi_in_trigger, | ||
| 1081 | }; | 131 | }; |
| 1082 | 132 | ||
| 1083 | static struct snd_rawmidi_ops gmidi_out_ops = { | 133 | static int __init midi_bind_config(struct usb_configuration *c) |
| 1084 | .open = gmidi_out_open, | ||
| 1085 | .close = gmidi_out_close, | ||
| 1086 | .trigger = gmidi_out_trigger | ||
| 1087 | }; | ||
| 1088 | |||
| 1089 | /* register as a sound "card" */ | ||
| 1090 | static int gmidi_register_card(struct gmidi_device *dev) | ||
| 1091 | { | 134 | { |
| 1092 | struct snd_card *card; | 135 | return f_midi_bind_config(c, index, id, |
| 1093 | struct snd_rawmidi *rmidi; | 136 | in_ports, out_ports, |
| 1094 | int err; | 137 | buflen, qlen); |
| 1095 | int out_ports = 1; | ||
| 1096 | int in_ports = 1; | ||
| 1097 | static struct snd_device_ops ops = { | ||
| 1098 | .dev_free = gmidi_snd_free, | ||
| 1099 | }; | ||
| 1100 | |||
| 1101 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); | ||
| 1102 | if (err < 0) { | ||
| 1103 | ERROR(dev, "snd_card_create failed\n"); | ||
| 1104 | goto fail; | ||
| 1105 | } | ||
| 1106 | dev->card = card; | ||
| 1107 | |||
| 1108 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, dev, &ops); | ||
| 1109 | if (err < 0) { | ||
| 1110 | ERROR(dev, "snd_device_new failed: error %d\n", err); | ||
| 1111 | goto fail; | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | strcpy(card->driver, longname); | ||
| 1115 | strcpy(card->longname, longname); | ||
| 1116 | strcpy(card->shortname, shortname); | ||
| 1117 | |||
| 1118 | /* Set up rawmidi */ | ||
| 1119 | dev->in_port.dev = dev; | ||
| 1120 | dev->in_port.active = 0; | ||
| 1121 | snd_component_add(card, "MIDI"); | ||
| 1122 | err = snd_rawmidi_new(card, "USB MIDI Gadget", 0, | ||
| 1123 | out_ports, in_ports, &rmidi); | ||
| 1124 | if (err < 0) { | ||
| 1125 | ERROR(dev, "snd_rawmidi_new failed: error %d\n", err); | ||
| 1126 | goto fail; | ||
| 1127 | } | ||
| 1128 | dev->rmidi = rmidi; | ||
| 1129 | strcpy(rmidi->name, card->shortname); | ||
| 1130 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | | ||
| 1131 | SNDRV_RAWMIDI_INFO_INPUT | | ||
| 1132 | SNDRV_RAWMIDI_INFO_DUPLEX; | ||
| 1133 | rmidi->private_data = dev; | ||
| 1134 | |||
| 1135 | /* Yes, rawmidi OUTPUT = USB IN, and rawmidi INPUT = USB OUT. | ||
| 1136 | It's an upside-down world being a gadget. */ | ||
| 1137 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &gmidi_in_ops); | ||
| 1138 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &gmidi_out_ops); | ||
| 1139 | |||
| 1140 | snd_card_set_dev(card, &dev->gadget->dev); | ||
| 1141 | |||
| 1142 | /* register it - we're ready to go */ | ||
| 1143 | err = snd_card_register(card); | ||
| 1144 | if (err < 0) { | ||
| 1145 | ERROR(dev, "snd_card_register failed\n"); | ||
| 1146 | goto fail; | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | VDBG(dev, "gmidi_register_card finished ok\n"); | ||
| 1150 | return 0; | ||
| 1151 | |||
| 1152 | fail: | ||
| 1153 | if (dev->card) { | ||
| 1154 | snd_card_free(dev->card); | ||
| 1155 | dev->card = NULL; | ||
| 1156 | } | ||
| 1157 | return err; | ||
| 1158 | } | 138 | } |
| 1159 | 139 | ||
| 1160 | /* | 140 | static int __init midi_bind(struct usb_composite_dev *cdev) |
| 1161 | * Creates an output endpoint, and initializes output ports. | ||
| 1162 | */ | ||
| 1163 | static int __init gmidi_bind(struct usb_gadget *gadget) | ||
| 1164 | { | 141 | { |
| 1165 | struct gmidi_device *dev; | 142 | struct usb_gadget *gadget = cdev->gadget; |
| 1166 | struct usb_ep *in_ep, *out_ep; | 143 | int gcnum, status; |
| 1167 | int gcnum, err = 0; | ||
| 1168 | 144 | ||
| 1169 | /* support optional vendor/distro customization */ | 145 | status = usb_string_id(cdev); |
| 1170 | if (idVendor) { | 146 | if (status < 0) |
| 1171 | if (!idProduct) { | 147 | return status; |
| 1172 | pr_err("idVendor needs idProduct!\n"); | 148 | strings_dev[STRING_MANUFACTURER_IDX].id = status; |
| 1173 | return -ENODEV; | 149 | device_desc.iManufacturer = status; |
| 1174 | } | ||
| 1175 | device_desc.idVendor = cpu_to_le16(idVendor); | ||
| 1176 | device_desc.idProduct = cpu_to_le16(idProduct); | ||
| 1177 | if (bcdDevice) { | ||
| 1178 | device_desc.bcdDevice = cpu_to_le16(bcdDevice); | ||
| 1179 | } | ||
| 1180 | } | ||
| 1181 | if (iManufacturer) { | ||
| 1182 | strlcpy(manufacturer, iManufacturer, sizeof(manufacturer)); | ||
| 1183 | } else { | ||
| 1184 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | ||
| 1185 | init_utsname()->sysname, init_utsname()->release, | ||
| 1186 | gadget->name); | ||
| 1187 | } | ||
| 1188 | if (iProduct) { | ||
| 1189 | strlcpy(product_desc, iProduct, sizeof(product_desc)); | ||
| 1190 | } | ||
| 1191 | if (iSerialNumber) { | ||
| 1192 | device_desc.iSerialNumber = STRING_SERIAL, | ||
| 1193 | strlcpy(serial_number, iSerialNumber, sizeof(serial_number)); | ||
| 1194 | } | ||
| 1195 | 150 | ||
| 1196 | /* Bulk-only drivers like this one SHOULD be able to | 151 | status = usb_string_id(cdev); |
| 1197 | * autoconfigure on any sane usb controller driver, | 152 | if (status < 0) |
| 1198 | * but there may also be important quirks to address. | 153 | return status; |
| 1199 | */ | 154 | strings_dev[STRING_PRODUCT_IDX].id = status; |
| 1200 | usb_ep_autoconfig_reset(gadget); | 155 | device_desc.iProduct = status; |
| 1201 | in_ep = usb_ep_autoconfig(gadget, &bulk_in_desc); | ||
| 1202 | if (!in_ep) { | ||
| 1203 | autoconf_fail: | ||
| 1204 | pr_err("%s: can't autoconfigure on %s\n", | ||
| 1205 | shortname, gadget->name); | ||
| 1206 | return -ENODEV; | ||
| 1207 | } | ||
| 1208 | EP_IN_NAME = in_ep->name; | ||
| 1209 | in_ep->driver_data = in_ep; /* claim */ | ||
| 1210 | 156 | ||
| 1211 | out_ep = usb_ep_autoconfig(gadget, &bulk_out_desc); | 157 | /* config description */ |
| 1212 | if (!out_ep) { | 158 | status = usb_string_id(cdev); |
| 1213 | goto autoconf_fail; | 159 | if (status < 0) |
| 1214 | } | 160 | return status; |
| 1215 | EP_OUT_NAME = out_ep->name; | 161 | strings_dev[STRING_DESCRIPTION_IDX].id = status; |
| 1216 | out_ep->driver_data = out_ep; /* claim */ | 162 | |
| 163 | midi_config.iConfiguration = status; | ||
| 1217 | 164 | ||
| 1218 | gcnum = usb_gadget_controller_number(gadget); | 165 | gcnum = usb_gadget_controller_number(gadget); |
| 1219 | if (gcnum >= 0) { | 166 | if (gcnum < 0) { |
| 1220 | device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); | ||
| 1221 | } else { | ||
| 1222 | /* gmidi is so simple (no altsettings) that | 167 | /* gmidi is so simple (no altsettings) that |
| 1223 | * it SHOULD NOT have problems with bulk-capable hardware. | 168 | * it SHOULD NOT have problems with bulk-capable hardware. |
| 1224 | * so warn about unrecognized controllers, don't panic. | 169 | * so warn about unrecognized controllers, don't panic. |
| 1225 | */ | 170 | */ |
| 1226 | pr_warning("%s: controller '%s' not recognized\n", | 171 | pr_warning("%s: controller '%s' not recognized\n", |
| 1227 | shortname, gadget->name); | 172 | __func__, gadget->name); |
| 1228 | device_desc.bcdDevice = cpu_to_le16(0x9999); | 173 | device_desc.bcdDevice = cpu_to_le16(0x9999); |
| 174 | } else { | ||
| 175 | device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); | ||
| 1229 | } | 176 | } |
| 1230 | 177 | ||
| 178 | status = usb_add_config(cdev, &midi_config, midi_bind_config); | ||
| 179 | if (status < 0) | ||
| 180 | return status; | ||
| 1231 | 181 | ||
| 1232 | /* ok, we made sense of the hardware ... */ | 182 | pr_info("%s\n", longname); |
| 1233 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 1234 | if (!dev) { | ||
| 1235 | return -ENOMEM; | ||
| 1236 | } | ||
| 1237 | spin_lock_init(&dev->lock); | ||
| 1238 | dev->gadget = gadget; | ||
| 1239 | dev->in_ep = in_ep; | ||
| 1240 | dev->out_ep = out_ep; | ||
| 1241 | set_gadget_data(gadget, dev); | ||
| 1242 | tasklet_init(&dev->tasklet, gmidi_in_tasklet, (unsigned long)dev); | ||
| 1243 | |||
| 1244 | /* preallocate control response and buffer */ | ||
| 1245 | dev->req = alloc_ep_req(gadget->ep0, USB_BUFSIZ); | ||
| 1246 | if (!dev->req) { | ||
| 1247 | err = -ENOMEM; | ||
| 1248 | goto fail; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | dev->req->complete = gmidi_setup_complete; | ||
| 1252 | |||
| 1253 | gadget->ep0->driver_data = dev; | ||
| 1254 | |||
| 1255 | INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname); | ||
| 1256 | INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, | ||
| 1257 | EP_OUT_NAME, EP_IN_NAME); | ||
| 1258 | |||
| 1259 | /* register as an ALSA sound card */ | ||
| 1260 | err = gmidi_register_card(dev); | ||
| 1261 | if (err < 0) { | ||
| 1262 | goto fail; | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | VDBG(dev, "gmidi_bind finished ok\n"); | ||
| 1266 | return 0; | 183 | return 0; |
| 1267 | |||
| 1268 | fail: | ||
| 1269 | gmidi_unbind(gadget); | ||
| 1270 | return err; | ||
| 1271 | } | ||
| 1272 | |||
| 1273 | |||
| 1274 | static void gmidi_suspend(struct usb_gadget *gadget) | ||
| 1275 | { | ||
| 1276 | struct gmidi_device *dev = get_gadget_data(gadget); | ||
| 1277 | |||
| 1278 | if (gadget->speed == USB_SPEED_UNKNOWN) { | ||
| 1279 | return; | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | DBG(dev, "suspend\n"); | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | static void gmidi_resume(struct usb_gadget *gadget) | ||
| 1286 | { | ||
| 1287 | struct gmidi_device *dev = get_gadget_data(gadget); | ||
| 1288 | |||
| 1289 | DBG(dev, "resume\n"); | ||
| 1290 | } | 184 | } |
| 1291 | 185 | ||
| 1292 | 186 | static struct usb_composite_driver midi_driver = { | |
| 1293 | static struct usb_gadget_driver gmidi_driver = { | 187 | .name = (char *) longname, |
| 1294 | .speed = USB_SPEED_FULL, | 188 | .dev = &device_desc, |
| 1295 | .function = (char *)longname, | 189 | .strings = dev_strings, |
| 1296 | .unbind = gmidi_unbind, | 190 | .max_speed = USB_SPEED_HIGH, |
| 1297 | 191 | .unbind = __exit_p(midi_unbind), | |
| 1298 | .setup = gmidi_setup, | ||
| 1299 | .disconnect = gmidi_disconnect, | ||
| 1300 | |||
| 1301 | .suspend = gmidi_suspend, | ||
| 1302 | .resume = gmidi_resume, | ||
| 1303 | |||
| 1304 | .driver = { | ||
| 1305 | .name = (char *)shortname, | ||
| 1306 | .owner = THIS_MODULE, | ||
| 1307 | }, | ||
| 1308 | }; | 192 | }; |
| 1309 | 193 | ||
| 1310 | static int __init gmidi_init(void) | 194 | static int __init midi_init(void) |
| 1311 | { | 195 | { |
| 1312 | return usb_gadget_probe_driver(&gmidi_driver, gmidi_bind); | 196 | return usb_composite_probe(&midi_driver, midi_bind); |
| 1313 | } | 197 | } |
| 1314 | module_init(gmidi_init); | 198 | module_init(midi_init); |
| 1315 | 199 | ||
| 1316 | static void __exit gmidi_cleanup(void) | 200 | static void __exit midi_cleanup(void) |
| 1317 | { | 201 | { |
| 1318 | usb_gadget_unregister_driver(&gmidi_driver); | 202 | usb_composite_unregister(&midi_driver); |
| 1319 | } | 203 | } |
| 1320 | module_exit(gmidi_cleanup); | 204 | module_exit(midi_cleanup); |
| 1321 | 205 | ||
| @@ -9,15 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | 12 | */ |
| 22 | 13 | ||
| 23 | 14 | ||
| @@ -689,7 +689,7 @@ static int imx_ep_enable(struct usb_ep *usb_ep, · 688 unmodified lines | |||
| 689 | return -EINVAL; | 689 | return -EINVAL; |
| 690 | } | 690 | } |
| 691 | 691 | ||
| 692 | if (imx_ep->fifosize < le16_to_cpu(desc->wMaxPacketSize)) { | 692 | if (imx_ep->fifosize < usb_endpoint_maxp(desc)) { |
| 693 | D_ERR(imx_usb->dev, | 693 | D_ERR(imx_usb->dev, |
| 694 | "<%s> bad %s maxpacket\n", __func__, usb_ep->name); | 694 | "<%s> bad %s maxpacket\n", __func__, usb_ep->name); |
| 695 | return -ERANGE; | 695 | return -ERANGE; |
| @@ -1478,7 +1478,7 @@ static int __init imx_udc_probe(struct platform_device *pdev) · 782 unmodified lines | |||
| 1478 | 1478 | ||
| 1479 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) { | 1479 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) { |
| 1480 | ret = request_irq(imx_usb->usbd_int[i], intr_handler(i), | 1480 | ret = request_irq(imx_usb->usbd_int[i], intr_handler(i), |
| 1481 | IRQF_DISABLED, driver_name, imx_usb); | 1481 | 0, driver_name, imx_usb); |
| 1482 | if (ret) { | 1482 | if (ret) { |
| 1483 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", | 1483 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", |
| 1484 | imx_usb->usbd_int[i], ret); | 1484 | imx_usb->usbd_int[i], ret); |
| @@ -8,11 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | */ | 11 | */ |
| 17 | 12 | ||
| 18 | #ifndef __LINUX_USB_GADGET_IMX_H | 13 | #ifndef __LINUX_USB_GADGET_IMX_H |
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | 13 | ||
| @@ -5,16 +5,6 @@ · 4 unmodified lines | |||
| 5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
| 6 | * under the terms and conditions of the GNU General Public License, | 6 | * under the terms and conditions of the GNU General Public License, |
| 7 | * version 2, as published by the Free Software Foundation. | 7 | * version 2, as published by the Free Software Foundation. |
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along with | ||
| 15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | * | ||
| 18 | */ | 8 | */ |
| 19 | 9 | ||
| 20 | 10 | ||
| @@ -60,9 +50,6 @@ static const char driver_name[] = "langwell_udc"; · 39 unmodified lines | |||
| 60 | static const char driver_desc[] = DRIVER_DESC; | 50 | static const char driver_desc[] = DRIVER_DESC; |
| 61 | 51 | ||
| 62 | 52 | ||
| 63 | /* controller device global variable */ | ||
| 64 | static struct langwell_udc *the_controller; | ||
| 65 | |||
| 66 | /* for endpoint 0 operations */ | 53 | /* for endpoint 0 operations */ |
| 67 | static const struct usb_endpoint_descriptor | 54 | static const struct usb_endpoint_descriptor |
| 68 | langwell_ep0_desc = { | 55 | langwell_ep0_desc = { |
| @@ -283,7 +270,7 @@ static int langwell_ep_enable(struct usb_ep *_ep, · 214 unmodified lines | |||
| 283 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | 270 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) |
| 284 | return -ESHUTDOWN; | 271 | return -ESHUTDOWN; |
| 285 | 272 | ||
| 286 | max = le16_to_cpu(desc->wMaxPacketSize); | 273 | max = usb_endpoint_maxp(desc); |
| 287 | 274 | ||
| 288 | /* | 275 | /* |
| 289 | * disable HW zero length termination select | 276 | * disable HW zero length termination select |
| @@ -1321,9 +1308,12 @@ static int langwell_pullup(struct usb_gadget *_gadget, int is_on) · 1031 unmodified lines | |||
| 1321 | return 0; | 1308 | return 0; |
| 1322 | } | 1309 | } |
| 1323 | 1310 | ||
| 1324 | static int langwell_start(struct usb_gadget_driver *driver, | 1311 | static int langwell_start(struct usb_gadget *g, |
| 1325 | int (*bind)(struct usb_gadget *)); | 1312 | struct usb_gadget_driver *driver); |
| 1326 | static int langwell_stop(struct usb_gadget_driver *driver); | 1313 | |
| 1314 | static int langwell_stop(struct usb_gadget *g, | ||
| 1315 | struct usb_gadget_driver *driver); | ||
| 1316 | |||
| 1327 | /* device controller usb_gadget_ops structure */ | 1317 | /* device controller usb_gadget_ops structure */ |
| 1328 | static const struct usb_gadget_ops langwell_ops = { | 1318 | static const struct usb_gadget_ops langwell_ops = { |
| 1329 | 1319 | ||
| @@ -1345,8 +1335,8 @@ static const struct usb_gadget_ops langwell_ops = { · 15 unmodified lines | |||
| 1345 | /* D+ pullup, software-controlled connect/disconnect to USB host */ | 1335 | /* D+ pullup, software-controlled connect/disconnect to USB host */ |
| 1346 | .pullup = langwell_pullup, | 1336 | .pullup = langwell_pullup, |
| 1347 | 1337 | ||
| 1348 | .start = langwell_start, | 1338 | .udc_start = langwell_start, |
| 1349 | .stop = langwell_stop, | 1339 | .udc_stop = langwell_stop, |
| 1350 | }; | 1340 | }; |
| 1351 | 1341 | ||
| 1352 | 1342 | ||
| @@ -1561,7 +1551,7 @@ static void stop_activity(struct langwell_udc *dev, · 208 unmodified lines | |||
| 1561 | static ssize_t show_function(struct device *_dev, | 1551 | static ssize_t show_function(struct device *_dev, |
| 1562 | struct device_attribute *attr, char *buf) | 1552 | struct device_attribute *attr, char *buf) |
| 1563 | { | 1553 | { |
| 1564 | struct langwell_udc *dev = the_controller; | 1554 | struct langwell_udc *dev = dev_get_drvdata(_dev); |
| 1565 | 1555 | ||
| 1566 | if (!dev->driver || !dev->driver->function | 1556 | if (!dev->driver || !dev->driver->function |
| 1567 | || strlen(dev->driver->function) > PAGE_SIZE) | 1557 | || strlen(dev->driver->function) > PAGE_SIZE) |
| @@ -1572,11 +1562,25 @@ static ssize_t show_function(struct device *_dev, · 4 unmodified lines | |||
| 1572 | static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); | 1562 | static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); |
| 1573 | 1563 | ||
| 1574 | 1564 | ||
| 1565 | static inline enum usb_device_speed lpm_device_speed(u32 reg) | ||
| 1566 | { | ||
| 1567 | switch (LPM_PSPD(reg)) { | ||
| 1568 | case LPM_SPEED_HIGH: | ||
| 1569 | return USB_SPEED_HIGH; | ||
| 1570 | case LPM_SPEED_FULL: | ||
| 1571 | return USB_SPEED_FULL; | ||
| 1572 | case LPM_SPEED_LOW: | ||
| 1573 | return USB_SPEED_LOW; | ||
| 1574 | default: | ||
| 1575 | return USB_SPEED_UNKNOWN; | ||
| 1576 | } | ||
| 1577 | } | ||
| 1578 | |||
| 1575 | /* device "langwell_udc" sysfs attribute file */ | 1579 | /* device "langwell_udc" sysfs attribute file */ |
| 1576 | static ssize_t show_langwell_udc(struct device *_dev, | 1580 | static ssize_t show_langwell_udc(struct device *_dev, |
| 1577 | struct device_attribute *attr, char *buf) | 1581 | struct device_attribute *attr, char *buf) |
| 1578 | { | 1582 | { |
| 1579 | struct langwell_udc *dev = the_controller; | 1583 | struct langwell_udc *dev = dev_get_drvdata(_dev); |
| 1580 | struct langwell_request *req; | 1584 | struct langwell_request *req; |
| 1581 | struct langwell_ep *ep = NULL; | 1585 | struct langwell_ep *ep = NULL; |
| 1582 | char *next; | 1586 | char *next; |
| @@ -1700,20 +1704,7 @@ static ssize_t show_langwell_udc(struct device *_dev, · 117 unmodified lines | |||
| 1700 | "BmAttributes: %d\n\n", | 1704 | "BmAttributes: %d\n\n", |
| 1701 | LPM_PTS(tmp_reg), | 1705 | LPM_PTS(tmp_reg), |
| 1702 | (tmp_reg & LPM_STS) ? 1 : 0, | 1706 | (tmp_reg & LPM_STS) ? 1 : 0, |
| 1703 | ({ | 1707 | usb_speed_string(lpm_device_speed(tmp_reg)), |
| 1704 | char *s; | ||
| 1705 | switch (LPM_PSPD(tmp_reg)) { | ||
| 1706 | case LPM_SPEED_FULL: | ||
| 1707 | s = "Full Speed"; break; | ||
| 1708 | case LPM_SPEED_LOW: | ||
| 1709 | s = "Low Speed"; break; | ||
| 1710 | case LPM_SPEED_HIGH: | ||
| 1711 | s = "High Speed"; break; | ||
| 1712 | default: | ||
| 1713 | s = "Unknown Speed"; break; | ||
| 1714 | } | ||
| 1715 | s; | ||
| 1716 | }), | ||
| 1717 | (tmp_reg & LPM_PFSC) ? "Force Full Speed" : "Not Force", | 1708 | (tmp_reg & LPM_PFSC) ? "Force Full Speed" : "Not Force", |
| 1718 | (tmp_reg & LPM_PHCD) ? "Disabled" : "Enabled", | 1709 | (tmp_reg & LPM_PHCD) ? "Disabled" : "Enabled", |
| 1719 | LPM_BA(tmp_reg)); | 1710 | LPM_BA(tmp_reg)); |
| @@ -1821,7 +1812,7 @@ static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL); · 101 unmodified lines | |||
| 1821 | static ssize_t store_remote_wakeup(struct device *_dev, | 1812 | static ssize_t store_remote_wakeup(struct device *_dev, |
| 1822 | struct device_attribute *attr, const char *buf, size_t count) | 1813 | struct device_attribute *attr, const char *buf, size_t count) |
| 1823 | { | 1814 | { |
| 1824 | struct langwell_udc *dev = the_controller; | 1815 | struct langwell_udc *dev = dev_get_drvdata(_dev); |
| 1825 | unsigned long flags; | 1816 | unsigned long flags; |
| 1826 | ssize_t rc = count; | 1817 | ssize_t rc = count; |
| 1827 | 1818 | ||
| @@ -1857,21 +1848,15 @@ static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup); · 29 unmodified lines | |||
| 1857 | * the driver might get unbound. | 1848 | * the driver might get unbound. |
| 1858 | */ | 1849 | */ |
| 1859 | 1850 | ||
| 1860 | static int langwell_start(struct usb_gadget_driver *driver, | 1851 | static int langwell_start(struct usb_gadget *g, |
| 1861 | int (*bind)(struct usb_gadget *)) | 1852 | struct usb_gadget_driver *driver) |
| 1862 | { | 1853 | { |
| 1863 | struct langwell_udc *dev = the_controller; | 1854 | struct langwell_udc *dev = gadget_to_langwell(g); |
| 1864 | unsigned long flags; | 1855 | unsigned long flags; |
| 1865 | int retval; | 1856 | int retval; |
| 1866 | 1857 | ||
| 1867 | if (!dev) | ||
| 1868 | return -ENODEV; | ||
| 1869 | |||
| 1870 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 1858 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
| 1871 | 1859 | ||
| 1872 | if (dev->driver) | ||
| 1873 | return -EBUSY; | ||
| 1874 | |||
| 1875 | spin_lock_irqsave(&dev->lock, flags); | 1860 | spin_lock_irqsave(&dev->lock, flags); |
| 1876 | 1861 | ||
| 1877 | /* hook up the driver ... */ | 1862 | /* hook up the driver ... */ |
| @@ -1881,18 +1866,9 @@ static int langwell_start(struct usb_gadget_driver *driver, · 3 unmodified lines | |||
| 1881 | 1866 | ||
| 1882 | spin_unlock_irqrestore(&dev->lock, flags); | 1867 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1883 | 1868 | ||
| 1884 | retval = bind(&dev->gadget); | ||
| 1885 | if (retval) { | ||
| 1886 | dev_dbg(&dev->pdev->dev, "bind to driver %s --> %d\n", | ||
| 1887 | driver->driver.name, retval); | ||
| 1888 | dev->driver = NULL; | ||
| 1889 | dev->gadget.dev.driver = NULL; | ||
| 1890 | return retval; | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | retval = device_create_file(&dev->pdev->dev, &dev_attr_function); | 1869 | retval = device_create_file(&dev->pdev->dev, &dev_attr_function); |
| 1894 | if (retval) | 1870 | if (retval) |
| 1895 | goto err_unbind; | 1871 | goto err; |
| 1896 | 1872 | ||
| 1897 | dev->usb_state = USB_STATE_ATTACHED; | 1873 | dev->usb_state = USB_STATE_ATTACHED; |
| 1898 | dev->ep0_state = WAIT_FOR_SETUP; | 1874 | dev->ep0_state = WAIT_FOR_SETUP; |
| @@ -1909,31 +1885,27 @@ static int langwell_start(struct usb_gadget_driver *driver, · 10 unmodified lines | |||
| 1909 | dev_info(&dev->pdev->dev, "register driver: %s\n", | 1885 | dev_info(&dev->pdev->dev, "register driver: %s\n", |
| 1910 | driver->driver.name); | 1886 | driver->driver.name); |
| 1911 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 1887 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
| 1888 | |||
| 1912 | return 0; | 1889 | return 0; |
| 1913 | 1890 | ||
| 1914 | err_unbind: | 1891 | err: |
| 1915 | driver->unbind(&dev->gadget); | ||
| 1916 | dev->gadget.dev.driver = NULL; | 1892 | dev->gadget.dev.driver = NULL; |
| 1917 | dev->driver = NULL; | 1893 | dev->driver = NULL; |
| 1918 | 1894 | ||
| 1919 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 1895 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
| 1896 | |||
| 1920 | return retval; | 1897 | return retval; |
| 1921 | } | 1898 | } |
| 1922 | 1899 | ||
| 1923 | /* unregister gadget driver */ | 1900 | /* unregister gadget driver */ |
| 1924 | static int langwell_stop(struct usb_gadget_driver *driver) | 1901 | static int langwell_stop(struct usb_gadget *g, |
| 1902 | struct usb_gadget_driver *driver) | ||
| 1925 | { | 1903 | { |
| 1926 | struct langwell_udc *dev = the_controller; | 1904 | struct langwell_udc *dev = gadget_to_langwell(g); |
| 1927 | unsigned long flags; | 1905 | unsigned long flags; |
| 1928 | 1906 | ||
| 1929 | if (!dev) | ||
| 1930 | return -ENODEV; | ||
| 1931 | |||
| 1932 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 1907 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
| 1933 | 1908 | ||
| 1934 | if (unlikely(!driver || !driver->unbind)) | ||
| 1935 | return -EINVAL; | ||
| 1936 | |||
| 1937 | /* exit PHY low power suspend */ | 1909 | /* exit PHY low power suspend */ |
| 1938 | if (dev->pdev->device != 0x0829) | 1910 | if (dev->pdev->device != 0x0829) |
| 1939 | langwell_phy_low_power(dev, 0); | 1911 | langwell_phy_low_power(dev, 0); |
| @@ -1956,8 +1928,6 @@ static int langwell_stop(struct usb_gadget_driver *driver) · 16 unmodified lines | |||
| 1956 | stop_activity(dev, driver); | 1928 | stop_activity(dev, driver); |
| 1957 | spin_unlock_irqrestore(&dev->lock, flags); | 1929 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1958 | 1930 | ||
| 1959 | /* unbind gadget driver */ | ||
| 1960 | driver->unbind(&dev->gadget); | ||
| 1961 | dev->gadget.dev.driver = NULL; | 1931 | dev->gadget.dev.driver = NULL; |
| 1962 | dev->driver = NULL; | 1932 | dev->driver = NULL; |
| 1963 | 1933 | ||
| @@ -1966,6 +1936,7 @@ static int langwell_stop(struct usb_gadget_driver *driver) · 2 unmodified lines | |||
| 1966 | dev_info(&dev->pdev->dev, "unregistered driver '%s'\n", | 1936 | dev_info(&dev->pdev->dev, "unregistered driver '%s'\n", |
| 1967 | driver->driver.name); | 1937 | driver->driver.name); |
| 1968 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 1938 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
| 1939 | |||
| 1969 | return 0; | 1940 | return 0; |
| 1970 | } | 1941 | } |
| 1971 | 1942 | ||
| @@ -2657,12 +2628,10 @@ done: · 685 unmodified lines | |||
| 2657 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 2628 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
| 2658 | } | 2629 | } |
| 2659 | 2630 | ||
| 2660 | |||
| 2661 | /* port change detect interrupt handler */ | 2631 | /* port change detect interrupt handler */ |
| 2662 | static void handle_port_change(struct langwell_udc *dev) | 2632 | static void handle_port_change(struct langwell_udc *dev) |
| 2663 | { | 2633 | { |
| 2664 | u32 portsc1, devlc; | 2634 | u32 portsc1, devlc; |
| 2665 | u32 speed; | ||
| 2666 | 2635 | ||
| 2667 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | 2636 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); |
| 2668 | 2637 | ||
| @@ -2677,24 +2646,9 @@ static void handle_port_change(struct langwell_udc *dev) · 8 unmodified lines | |||
| 2677 | /* bus reset is finished */ | 2646 | /* bus reset is finished */ |
| 2678 | if (!(portsc1 & PORTS_PR)) { | 2647 | if (!(portsc1 & PORTS_PR)) { |
| 2679 | /* get the speed */ | 2648 | /* get the speed */ |
| 2680 | speed = LPM_PSPD(devlc); | 2649 | dev->gadget.speed = lpm_device_speed(devlc); |
| 2681 | switch (speed) { | 2650 | dev_vdbg(&dev->pdev->dev, "dev->gadget.speed = %d\n", |
| 2682 | case LPM_SPEED_HIGH: | 2651 | dev->gadget.speed); |
| 2683 | dev->gadget.speed = USB_SPEED_HIGH; | ||
| 2684 | break; | ||
| 2685 | case LPM_SPEED_FULL: | ||
| 2686 | dev->gadget.speed = USB_SPEED_FULL; | ||
| 2687 | break; | ||
| 2688 | case LPM_SPEED_LOW: | ||
| 2689 | dev->gadget.speed = USB_SPEED_LOW; | ||
| 2690 | break; | ||
| 2691 | default: | ||
| 2692 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 2693 | break; | ||
| 2694 | } | ||
| 2695 | dev_vdbg(&dev->pdev->dev, | ||
| 2696 | "speed = %d, dev->gadget.speed = %d\n", | ||
| 2697 | speed, dev->gadget.speed); | ||
| 2698 | } | 2652 | } |
| 2699 | 2653 | ||
| 2700 | /* LPM L0 to L1 */ | 2654 | /* LPM L0 to L1 */ |
| @@ -2999,7 +2953,7 @@ static irqreturn_t langwell_irq(int irq, void *_dev) · 298 unmodified lines | |||
| 2999 | /* release device structure */ | 2953 | /* release device structure */ |
| 3000 | static void gadget_release(struct device *_dev) | 2954 | static void gadget_release(struct device *_dev) |
| 3001 | { | 2955 | { |
| 3002 | struct langwell_udc *dev = the_controller; | 2956 | struct langwell_udc *dev = dev_get_drvdata(_dev); |
| 3003 | 2957 | ||
| 3004 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 2958 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
| 3005 | 2959 | ||
| @@ -3057,7 +3011,7 @@ static void sram_deinit(struct langwell_udc *dev) · 51 unmodified lines | |||
| 3057 | /* tear down the binding between this driver and the pci device */ | 3011 | /* tear down the binding between this driver and the pci device */ |
| 3058 | static void langwell_udc_remove(struct pci_dev *pdev) | 3012 | static void langwell_udc_remove(struct pci_dev *pdev) |
| 3059 | { | 3013 | { |
| 3060 | struct langwell_udc *dev = the_controller; | 3014 | struct langwell_udc *dev = pci_get_drvdata(pdev); |
| 3061 | 3015 | ||
| 3062 | DECLARE_COMPLETION(done); | 3016 | DECLARE_COMPLETION(done); |
| 3063 | 3017 | ||
| @@ -3124,8 +3078,6 @@ static void langwell_udc_remove(struct pci_dev *pdev) · 60 unmodified lines | |||
| 3124 | 3078 | ||
| 3125 | /* free dev, wait for the release() finished */ | 3079 | /* free dev, wait for the release() finished */ |
| 3126 | wait_for_completion(&done); | 3080 | wait_for_completion(&done); |
| 3127 | |||
| 3128 | the_controller = NULL; | ||
| 3129 | } | 3081 | } |
| 3130 | 3082 | ||
| 3131 | 3083 | ||
| @@ -3144,11 +3096,6 @@ static int langwell_udc_probe(struct pci_dev *pdev, · 12 unmodified lines | |||
| 3144 | size_t size; | 3096 | size_t size; |
| 3145 | int retval; | 3097 | int retval; |
| 3146 | 3098 | ||
| 3147 | if (the_controller) { | ||
| 3148 | dev_warn(&pdev->dev, "ignoring\n"); | ||
| 3149 | return -EBUSY; | ||
| 3150 | } | ||
| 3151 | |||
| 3152 | /* alloc, and start init */ | 3099 | /* alloc, and start init */ |
| 3153 | dev = kzalloc(sizeof *dev, GFP_KERNEL); | 3100 | dev = kzalloc(sizeof *dev, GFP_KERNEL); |
| 3154 | if (dev == NULL) { | 3101 | if (dev == NULL) { |
| @@ -3368,8 +3315,6 @@ static int langwell_udc_probe(struct pci_dev *pdev, · 213 unmodified lines | |||
| 3368 | "After langwell_udc_probe(), print all registers:\n"); | 3315 | "After langwell_udc_probe(), print all registers:\n"); |
| 3369 | print_all_registers(dev); | 3316 | print_all_registers(dev); |
| 3370 | 3317 | ||
| 3371 | the_controller = dev; | ||
| 3372 | |||
| 3373 | retval = device_register(&dev->gadget.dev); | 3318 | retval = device_register(&dev->gadget.dev); |
| 3374 | if (retval) | 3319 | if (retval) |
| 3375 | goto error; | 3320 | goto error; |
| @@ -3404,7 +3349,7 @@ error: · 28 unmodified lines | |||
| 3404 | /* device controller suspend */ | 3349 | /* device controller suspend */ |
| 3405 | static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) | 3350 | static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) |
| 3406 | { | 3351 | { |
| 3407 | struct langwell_udc *dev = the_controller; | 3352 | struct langwell_udc *dev = pci_get_drvdata(pdev); |
| 3408 | 3353 | ||
| 3409 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 3354 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
| 3410 | 3355 | ||
| @@ -3452,7 +3397,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) · 41 unmodified lines | |||
| 3452 | /* device controller resume */ | 3397 | /* device controller resume */ |
| 3453 | static int langwell_udc_resume(struct pci_dev *pdev) | 3398 | static int langwell_udc_resume(struct pci_dev *pdev) |
| 3454 | { | 3399 | { |
| 3455 | struct langwell_udc *dev = the_controller; | 3400 | struct langwell_udc *dev = pci_get_drvdata(pdev); |
| 3456 | size_t size; | 3401 | size_t size; |
| 3457 | 3402 | ||
| 3458 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 3403 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
| @@ -3534,7 +3479,7 @@ static int langwell_udc_resume(struct pci_dev *pdev) · 75 unmodified lines | |||
| 3534 | /* pci driver shutdown */ | 3479 | /* pci driver shutdown */ |
| 3535 | static void langwell_udc_shutdown(struct pci_dev *pdev) | 3480 | static void langwell_udc_shutdown(struct pci_dev *pdev) |
| 3536 | { | 3481 | { |
| 3537 | struct langwell_udc *dev = the_controller; | 3482 | struct langwell_udc *dev = pci_get_drvdata(pdev); |
| 3538 | u32 usbmode; | 3483 | u32 usbmode; |
| 3539 | 3484 | ||
| 3540 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 3485 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
| @@ -5,16 +5,6 @@ · 4 unmodified lines | |||
| 5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
| 6 | * under the terms and conditions of the GNU General Public License, | 6 | * under the terms and conditions of the GNU General Public License, |
| 7 | * version 2, as published by the Free Software Foundation. | 7 | * version 2, as published by the Free Software Foundation. |
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along with | ||
| 15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | * | ||
| 18 | */ | 8 | */ |
| 19 | 9 | ||
| 20 | #include <linux/usb/langwell_udc.h> | 10 | #include <linux/usb/langwell_udc.h> |
| @@ -231,3 +221,5 @@ struct langwell_udc { · 210 unmodified lines | |||
| 231 | u16 dev_status; | 221 | u16 dev_status; |
| 232 | }; | 222 | }; |
| 233 | 223 | ||
| 224 | #define gadget_to_langwell(g) container_of((g), struct langwell_udc, gadget) | ||
| 225 | |||
| @@ -8,16 +8,6 @@ · 7 unmodified lines | |||
| 8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; version 2 of the License. | 10 | * the Free Software Foundation; version 2 of the License. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | * | ||
| 21 | */ | 11 | */ |
| 22 | 12 | ||
| 23 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| @@ -370,7 +360,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, · 346 unmodified lines | |||
| 370 | 360 | ||
| 371 | ep->pipectr = get_pipectr_addr(pipenum); | 361 | ep->pipectr = get_pipectr_addr(pipenum); |
| 372 | ep->pipenum = pipenum; | 362 | ep->pipenum = pipenum; |
| 373 | ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 363 | ep->ep.maxpacket = usb_endpoint_maxp(desc); |
| 374 | m66592->pipenum2ep[pipenum] = ep; | 364 | m66592->pipenum2ep[pipenum] = ep; |
| 375 | m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; | 365 | m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; |
| 376 | INIT_LIST_HEAD(&ep->queue); | 366 | INIT_LIST_HEAD(&ep->queue); |
| @@ -447,7 +437,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, · 70 unmodified lines | |||
| 447 | ep->type = info.type; | 437 | ep->type = info.type; |
| 448 | 438 | ||
| 449 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 439 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; |
| 450 | info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 440 | info.maxpacket = usb_endpoint_maxp(desc); |
| 451 | info.interval = desc->bInterval; | 441 | info.interval = desc->bInterval; |
| 452 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 442 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
| 453 | info.dir_in = 1; | 443 | info.dir_in = 1; |
| @@ -1674,7 +1664,7 @@ static int __init m66592_probe(struct platform_device *pdev) · 1220 unmodified lines | |||
| 1674 | m66592->timer.data = (unsigned long)m66592; | 1664 | m66592->timer.data = (unsigned long)m66592; |
| 1675 | m66592->reg = reg; | 1665 | m66592->reg = reg; |
| 1676 | 1666 | ||
| 1677 | ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED, | 1667 | ret = request_irq(ires->start, m66592_irq, IRQF_SHARED, |
| 1678 | udc_name, m66592); | 1668 | udc_name, m66592); |
| 1679 | if (ret < 0) { | 1669 | if (ret < 0) { |
| 1680 | pr_err("request_irq error (%d)\n", ret); | 1670 | pr_err("request_irq error (%d)\n", ret); |
| @@ -8,16 +8,6 @@ · 7 unmodified lines | |||
| 8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; version 2 of the License. | 10 | * the Free Software Foundation; version 2 of the License. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | * | ||
| 21 | */ | 11 | */ |
| 22 | 12 | ||
| 23 | #ifndef __M66592_UDC_H__ | 13 | #ifndef __M66592_UDC_H__ |
| @@ -10,15 +10,6 @@ · 9 unmodified lines | |||
| 10 | * it under the terms of the GNU General Public License as published by | 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 | 11 | * the Free Software Foundation; either version 2 of the License, or |
| 12 | * (at your option) any later version. | 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 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | */ | 13 | */ |
| 23 | 14 | ||
| 24 | 15 | ||
| @@ -169,7 +160,7 @@ static struct usb_composite_driver msg_driver = { · 144 unmodified lines | |||
| 169 | .name = "g_mass_storage", | 160 | .name = "g_mass_storage", |
| 170 | .dev = &msg_device_desc, | 161 | .dev = &msg_device_desc, |
| 171 | .iProduct = DRIVER_DESC, | 162 | .iProduct = DRIVER_DESC, |
| 172 | .max_speed = USB_SPEED_HIGH, | 163 | .max_speed = USB_SPEED_SUPER, |
| 173 | .needs_serial = 1, | 164 | .needs_serial = 1, |
| 174 | }; | 165 | }; |
| 175 | 166 | ||
| @@ -10,15 +10,6 @@ · 9 unmodified lines | |||
| 10 | * it under the terms of the GNU General Public License as published by | 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 | 11 | * the Free Software Foundation; either version 2 of the License, or |
| 12 | * (at your option) any later version. | 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 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | */ | 13 | */ |
| 23 | 14 | ||
| 24 | 15 | ||
| @@ -1,3 +1,11 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Marvell International Ltd. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 1 | 9 | ||
| 2 | #ifndef __MV_UDC_H | 10 | #ifndef __MV_UDC_H |
| 3 | #define __MV_UDC_H | 11 | #define __MV_UDC_H |
| @@ -194,14 +202,25 @@ struct mv_udc { · 190 unmodified lines | |||
| 194 | unsigned int ep0_dir; | 202 | unsigned int ep0_dir; |
| 195 | 203 | ||
| 196 | unsigned int dev_addr; | 204 | unsigned int dev_addr; |
| 205 | unsigned int test_mode; | ||
| 197 | 206 | ||
| 198 | int errors; | 207 | int errors; |
| 199 | unsigned softconnect:1, | 208 | unsigned softconnect:1, |
| 200 | vbus_active:1, | 209 | vbus_active:1, |
| 201 | remote_wakeup:1, | 210 | remote_wakeup:1, |
| 202 | softconnected:1, | 211 | softconnected:1, |
| 203 | force_fs:1; | 212 | force_fs:1, |
| 204 | struct clk *clk; | 213 | clock_gating:1, |
| 214 | active:1; | ||
| 215 | |||
| 216 | struct work_struct vbus_work; | ||
| 217 | struct workqueue_struct *qwork; | ||
| 218 | |||
| 219 | struct mv_usb_platform_data *pdata; | ||
| 220 | |||
| 221 | /* some SOC has mutiple clock sources for USB*/ | ||
| 222 | unsigned int clknum; | ||
| 223 | struct clk *clk[0]; | ||
| 205 | }; | 224 | }; |
| 206 | 225 | ||
| 207 | /* endpoint data structure */ | 226 | /* endpoint data structure */ |
| @@ -225,6 +244,7 @@ struct mv_req { · 17 unmodified lines | |||
| 225 | struct mv_dtd *dtd, *head, *tail; | 244 | struct mv_dtd *dtd, *head, *tail; |
| 226 | struct mv_ep *ep; | 245 | struct mv_ep *ep; |
| 227 | struct list_head queue; | 246 | struct list_head queue; |
| 247 | unsigned int test_mode; | ||
| 228 | unsigned dtd_count; | 248 | unsigned dtd_count; |
| 229 | unsigned mapped:1; | 249 | unsigned mapped:1; |
| 230 | }; | 250 | }; |
| @@ -289,6 +309,4 @@ struct mv_dtd { · 58 unmodified lines | |||
| 289 | struct mv_dtd *next_dtd_virt; | 309 | struct mv_dtd *next_dtd_virt; |
| 290 | }; | 310 | }; |
| 291 | 311 | ||
| 292 | extern int mv_udc_phy_init(unsigned int base); | ||
| 293 | |||
| 294 | #endif | 312 | #endif |
| @@ -1,3 +1,14 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Marvell International Ltd. All rights reserved. | ||
| 3 | * Author: Chao Xie <chao.xie@marvell.com> | ||
| 4 | * Neil Zhang <zhangwm@marvell.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 1 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 2 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
| 3 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
| @@ -22,6 +33,7 @@ · 18 unmodified lines | |||
| 22 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
| 23 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
| 24 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
| 36 | #include <linux/platform_data/mv_usb.h> | ||
| 25 | #include <asm/system.h> | 37 | #include <asm/system.h> |
| 26 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
| 27 | 39 | ||
| @@ -45,6 +57,8 @@ · 17 unmodified lines | |||
| 45 | #define LOOPS_USEC (1 << LOOPS_USEC_SHIFT) | 57 | #define LOOPS_USEC (1 << LOOPS_USEC_SHIFT) |
| 46 | #define LOOPS(timeout) ((timeout) >> LOOPS_USEC_SHIFT) | 58 | #define LOOPS(timeout) ((timeout) >> LOOPS_USEC_SHIFT) |
| 47 | 59 | ||
| 60 | static DECLARE_COMPLETION(release_done); | ||
| 61 | |||
| 48 | static const char driver_name[] = "mv_udc"; | 62 | static const char driver_name[] = "mv_udc"; |
| 49 | static const char driver_desc[] = DRIVER_DESC; | 63 | static const char driver_desc[] = DRIVER_DESC; |
| 50 | 64 | ||
| @@ -53,6 +67,7 @@ static struct mv_udc *the_controller; · 2 unmodified lines | |||
| 53 | int mv_usb_otgsc; | 67 | int mv_usb_otgsc; |
| 54 | 68 | ||
| 55 | static void nuke(struct mv_ep *ep, int status); | 69 | static void nuke(struct mv_ep *ep, int status); |
| 70 | static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver); | ||
| 56 | 71 | ||
| 57 | /* for endpoint 0 operations */ | 72 | /* for endpoint 0 operations */ |
| 58 | static const struct usb_endpoint_descriptor mv_ep0_desc = { | 73 | static const struct usb_endpoint_descriptor mv_ep0_desc = { |
| @@ -82,14 +97,16 @@ static void ep0_reset(struct mv_udc *udc) · 23 unmodified lines | |||
| 82 | (EP0_MAX_PKT_SIZE << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) | 97 | (EP0_MAX_PKT_SIZE << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) |
| 83 | | EP_QUEUE_HEAD_IOS; | 98 | | EP_QUEUE_HEAD_IOS; |
| 84 | 99 | ||
| 100 | ep->dqh->next_dtd_ptr = EP_QUEUE_HEAD_NEXT_TERMINATE; | ||
| 101 | |||
| 85 | epctrlx = readl(&udc->op_regs->epctrlx[0]); | 102 | epctrlx = readl(&udc->op_regs->epctrlx[0]); |
| 86 | if (i) { /* TX */ | 103 | if (i) { /* TX */ |
| 87 | epctrlx |= EPCTRL_TX_ENABLE | EPCTRL_TX_DATA_TOGGLE_RST | 104 | epctrlx |= EPCTRL_TX_ENABLE |
| 88 | | (USB_ENDPOINT_XFER_CONTROL | 105 | | (USB_ENDPOINT_XFER_CONTROL |
| 89 | << EPCTRL_TX_EP_TYPE_SHIFT); | 106 | << EPCTRL_TX_EP_TYPE_SHIFT); |
| 90 | 107 | ||
| 91 | } else { /* RX */ | 108 | } else { /* RX */ |
| 92 | epctrlx |= EPCTRL_RX_ENABLE | EPCTRL_RX_DATA_TOGGLE_RST | 109 | epctrlx |= EPCTRL_RX_ENABLE |
| 93 | | (USB_ENDPOINT_XFER_CONTROL | 110 | | (USB_ENDPOINT_XFER_CONTROL |
| 94 | << EPCTRL_RX_EP_TYPE_SHIFT); | 111 | << EPCTRL_RX_EP_TYPE_SHIFT); |
| 95 | } | 112 | } |
| @@ -122,6 +139,7 @@ static int process_ep_req(struct mv_udc *udc, int index, · 26 unmodified lines | |||
| 122 | int i, direction; | 139 | int i, direction; |
| 123 | int retval = 0; | 140 | int retval = 0; |
| 124 | u32 errors; | 141 | u32 errors; |
| 142 | u32 bit_pos; | ||
| 125 | 143 | ||
| 126 | curr_dqh = &udc->ep_dqh[index]; | 144 | curr_dqh = &udc->ep_dqh[index]; |
| 127 | direction = index % 2; | 145 | direction = index % 2; |
| @@ -139,10 +157,20 @@ static int process_ep_req(struct mv_udc *udc, int index, · 11 unmodified lines | |||
| 139 | 157 | ||
| 140 | errors = curr_dtd->size_ioc_sts & DTD_ERROR_MASK; | 158 | errors = curr_dtd->size_ioc_sts & DTD_ERROR_MASK; |
| 141 | if (!errors) { | 159 | if (!errors) { |
| 142 | remaining_length += | 160 | remaining_length = |
| 143 | (curr_dtd->size_ioc_sts & DTD_PACKET_SIZE) | 161 | (curr_dtd->size_ioc_sts & DTD_PACKET_SIZE) |
| 144 | >> DTD_LENGTH_BIT_POS; | 162 | >> DTD_LENGTH_BIT_POS; |
| 145 | actual -= remaining_length; | 163 | actual -= remaining_length; |
| 164 | |||
| 165 | if (remaining_length) { | ||
| 166 | if (direction) { | ||
| 167 | dev_dbg(&udc->dev->dev, | ||
| 168 | "TX dTD remains data\n"); | ||
| 169 | retval = -EPROTO; | ||
| 170 | break; | ||
| 171 | } else | ||
| 172 | break; | ||
| 173 | } | ||
| 146 | } else { | 174 | } else { |
| 147 | dev_info(&udc->dev->dev, | 175 | dev_info(&udc->dev->dev, |
| 148 | "complete_tr error: ep=%d %s: error = 0x%x\n", | 176 | "complete_tr error: ep=%d %s: error = 0x%x\n", |
| @@ -164,6 +192,20 @@ static int process_ep_req(struct mv_udc *udc, int index, · 15 unmodified lines | |||
| 164 | if (retval) | 192 | if (retval) |
| 165 | return retval; | 193 | return retval; |
| 166 | 194 | ||
| 195 | if (direction == EP_DIR_OUT) | ||
| 196 | bit_pos = 1 << curr_req->ep->ep_num; | ||
| 197 | else | ||
| 198 | bit_pos = 1 << (16 + curr_req->ep->ep_num); | ||
| 199 | |||
| 200 | while ((curr_dqh->curr_dtd_ptr == curr_dtd->td_dma)) { | ||
| 201 | if (curr_dtd->dtd_next == EP_QUEUE_HEAD_NEXT_TERMINATE) { | ||
| 202 | while (readl(&udc->op_regs->epstatus) & bit_pos) | ||
| 203 | udelay(1); | ||
| 204 | break; | ||
| 205 | } | ||
| 206 | udelay(1); | ||
| 207 | } | ||
| 208 | |||
| 167 | curr_req->req.actual = actual; | 209 | curr_req->req.actual = actual; |
| 168 | 210 | ||
| 169 | return 0; | 211 | return 0; |
| @@ -481,6 +523,7 @@ static int mv_ep_enable(struct usb_ep *_ep, · 311 unmodified lines | |||
| 481 | u16 max = 0; | 523 | u16 max = 0; |
| 482 | u32 bit_pos, epctrlx, direction; | 524 | u32 bit_pos, epctrlx, direction; |
| 483 | unsigned char zlt = 0, ios = 0, mult = 0; | 525 | unsigned char zlt = 0, ios = 0, mult = 0; |
| 526 | unsigned long flags; | ||
| 484 | 527 | ||
| 485 | ep = container_of(_ep, struct mv_ep, ep); | 528 | ep = container_of(_ep, struct mv_ep, ep); |
| 486 | udc = ep->udc; | 529 | udc = ep->udc; |
| @@ -493,7 +536,7 @@ static int mv_ep_enable(struct usb_ep *_ep, · 6 unmodified lines | |||
| 493 | return -ESHUTDOWN; | 536 | return -ESHUTDOWN; |
| 494 | 537 | ||
| 495 | direction = ep_dir(ep); | 538 | direction = ep_dir(ep); |
| 496 | max = le16_to_cpu(desc->wMaxPacketSize); | 539 | max = usb_endpoint_maxp(desc); |
| 497 | 540 | ||
| 498 | /* | 541 | /* |
| 499 | * disable HW zero length termination select | 542 | * disable HW zero length termination select |
| @@ -501,9 +544,6 @@ static int mv_ep_enable(struct usb_ep *_ep, · 1 unmodified line | |||
| 501 | */ | 544 | */ |
| 502 | zlt = 1; | 545 | zlt = 1; |
| 503 | 546 | ||
| 504 | /* Get the endpoint queue head address */ | ||
| 505 | dqh = (struct mv_dqh *)ep->dqh; | ||
| 506 | |||
| 507 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); | 547 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); |
| 508 | 548 | ||
| 509 | /* Check if the Endpoint is Primed */ | 549 | /* Check if the Endpoint is Primed */ |
| @@ -532,7 +572,7 @@ static int mv_ep_enable(struct usb_ep *_ep, · 22 unmodified lines | |||
| 532 | case USB_ENDPOINT_XFER_ISOC: | 572 | case USB_ENDPOINT_XFER_ISOC: |
| 533 | /* Calculate transactions needed for high bandwidth iso */ | 573 | /* Calculate transactions needed for high bandwidth iso */ |
| 534 | mult = (unsigned char)(1 + ((max >> 11) & 0x03)); | 574 | mult = (unsigned char)(1 + ((max >> 11) & 0x03)); |
| 535 | max = max & 0x8ff; /* bit 0~10 */ | 575 | max = max & 0x7ff; /* bit 0~10 */ |
| 536 | /* 3 transactions at most */ | 576 | /* 3 transactions at most */ |
| 537 | if (mult > 3) | 577 | if (mult > 3) |
| 538 | goto en_done; | 578 | goto en_done; |
| @@ -540,6 +580,10 @@ static int mv_ep_enable(struct usb_ep *_ep, · 1 unmodified line | |||
| 540 | default: | 580 | default: |
| 541 | goto en_done; | 581 | goto en_done; |
| 542 | } | 582 | } |
| 583 | |||
| 584 | spin_lock_irqsave(&udc->lock, flags); | ||
| 585 | /* Get the endpoint queue head address */ | ||
| 586 | dqh = ep->dqh; | ||
| 543 | dqh->max_packet_length = (max << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) | 587 | dqh->max_packet_length = (max << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) |
| 544 | | (mult << EP_QUEUE_HEAD_MULT_POS) | 588 | | (mult << EP_QUEUE_HEAD_MULT_POS) |
| 545 | | (zlt ? EP_QUEUE_HEAD_ZLT_SEL : 0) | 589 | | (zlt ? EP_QUEUE_HEAD_ZLT_SEL : 0) |
| @@ -572,18 +616,20 @@ static int mv_ep_enable(struct usb_ep *_ep, · 26 unmodified lines | |||
| 572 | */ | 616 | */ |
| 573 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); | 617 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); |
| 574 | if ((epctrlx & EPCTRL_RX_ENABLE) == 0) { | 618 | if ((epctrlx & EPCTRL_RX_ENABLE) == 0) { |
| 575 | epctrlx |= ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 619 | epctrlx |= (USB_ENDPOINT_XFER_BULK |
| 576 | << EPCTRL_RX_EP_TYPE_SHIFT); | 620 | << EPCTRL_RX_EP_TYPE_SHIFT); |
| 577 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); | 621 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); |
| 578 | } | 622 | } |
| 579 | 623 | ||
| 580 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); | 624 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); |
| 581 | if ((epctrlx & EPCTRL_TX_ENABLE) == 0) { | 625 | if ((epctrlx & EPCTRL_TX_ENABLE) == 0) { |
| 582 | epctrlx |= ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 626 | epctrlx |= (USB_ENDPOINT_XFER_BULK |
| 583 | << EPCTRL_TX_EP_TYPE_SHIFT); | 627 | << EPCTRL_TX_EP_TYPE_SHIFT); |
| 584 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); | 628 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); |
| 585 | } | 629 | } |
| 586 | 630 | ||
| 631 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 632 | |||
| 587 | return 0; | 633 | return 0; |
| 588 | en_done: | 634 | en_done: |
| 589 | return -EINVAL; | 635 | return -EINVAL; |
| @@ -595,6 +641,7 @@ static int mv_ep_disable(struct usb_ep *_ep) · 5 unmodified lines | |||
| 595 | struct mv_ep *ep; | 641 | struct mv_ep *ep; |
| 596 | struct mv_dqh *dqh; | 642 | struct mv_dqh *dqh; |
| 597 | u32 bit_pos, epctrlx, direction; | 643 | u32 bit_pos, epctrlx, direction; |
| 644 | unsigned long flags; | ||
| 598 | 645 | ||
| 599 | ep = container_of(_ep, struct mv_ep, ep); | 646 | ep = container_of(_ep, struct mv_ep, ep); |
| 600 | if ((_ep == NULL) || !ep->desc) | 647 | if ((_ep == NULL) || !ep->desc) |
| @@ -605,6 +652,8 @@ static int mv_ep_disable(struct usb_ep *_ep) · 4 unmodified lines | |||
| 605 | /* Get the endpoint queue head address */ | 652 | /* Get the endpoint queue head address */ |
| 606 | dqh = ep->dqh; | 653 | dqh = ep->dqh; |
| 607 | 654 | ||
| 655 | spin_lock_irqsave(&udc->lock, flags); | ||
| 656 | |||
| 608 | direction = ep_dir(ep); | 657 | direction = ep_dir(ep); |
| 609 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); | 658 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); |
| 610 | 659 | ||
| @@ -623,6 +672,9 @@ static int mv_ep_disable(struct usb_ep *_ep) · 12 unmodified lines | |||
| 623 | 672 | ||
| 624 | ep->desc = NULL; | 673 | ep->desc = NULL; |
| 625 | ep->stopped = 1; | 674 | ep->stopped = 1; |
| 675 | |||
| 676 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 677 | |||
| 626 | return 0; | 678 | return 0; |
| 627 | } | 679 | } |
| 628 | 680 | ||
| @@ -655,37 +707,28 @@ static void mv_ep_fifo_flush(struct usb_ep *_ep) · 26 unmodified lines | |||
| 655 | { | 707 | { |
| 656 | struct mv_udc *udc; | 708 | struct mv_udc *udc; |
| 657 | u32 bit_pos, direction; | 709 | u32 bit_pos, direction; |
| 658 | struct mv_ep *ep = container_of(_ep, struct mv_ep, ep); | 710 | struct mv_ep *ep; |
| 659 | unsigned int loops; | 711 | unsigned int loops; |
| 660 | 712 | ||
| 713 | if (!_ep) | ||
| 714 | return; | ||
| 715 | |||
| 716 | ep = container_of(_ep, struct mv_ep, ep); | ||
| 717 | if (!ep->desc) | ||
| 718 | return; | ||
| 719 | |||
| 661 | udc = ep->udc; | 720 | udc = ep->udc; |
| 662 | direction = ep_dir(ep); | 721 | direction = ep_dir(ep); |
| 663 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); | ||
| 664 | /* | ||
| 665 | * Flushing will halt the pipe | ||
| 666 | * Write 1 to the Flush register | ||
| 667 | */ | ||
| 668 | writel(bit_pos, &udc->op_regs->epflush); | ||
| 669 | 722 | ||
| 670 | /* Wait until flushing completed */ | 723 | if (ep->ep_num == 0) |
| 671 | loops = LOOPS(FLUSH_TIMEOUT); | 724 | bit_pos = (1 << 16) | 1; |
| 672 | while (readl(&udc->op_regs->epflush) & bit_pos) { | 725 | else if (direction == EP_DIR_OUT) |
| 673 | /* | 726 | bit_pos = 1 << ep->ep_num; |
| 674 | * ENDPTFLUSH bit should be cleared to indicate this | 727 | else |
| 675 | * operation is complete | 728 | bit_pos = 1 << (16 + ep->ep_num); |
| 676 | */ | 729 | |
| 677 | if (loops == 0) { | ||
| 678 | dev_err(&udc->dev->dev, | ||
| 679 | "TIMEOUT for ENDPTFLUSH=0x%x, bit_pos=0x%x\n", | ||
| 680 | (unsigned)readl(&udc->op_regs->epflush), | ||
| 681 | (unsigned)bit_pos); | ||
| 682 | return; | ||
| 683 | } | ||
| 684 | loops--; | ||
| 685 | udelay(LOOPS_USEC); | ||
| 686 | } | ||
| 687 | loops = LOOPS(EPSTATUS_TIMEOUT); | 730 | loops = LOOPS(EPSTATUS_TIMEOUT); |
| 688 | while (readl(&udc->op_regs->epstatus) & bit_pos) { | 731 | do { |
| 689 | unsigned int inter_loops; | 732 | unsigned int inter_loops; |
| 690 | 733 | ||
| 691 | if (loops == 0) { | 734 | if (loops == 0) { |
| @@ -700,7 +743,7 @@ static void mv_ep_fifo_flush(struct usb_ep *_ep) · 8 unmodified lines | |||
| 700 | 743 | ||
| 701 | /* Wait until flushing completed */ | 744 | /* Wait until flushing completed */ |
| 702 | inter_loops = LOOPS(FLUSH_TIMEOUT); | 745 | inter_loops = LOOPS(FLUSH_TIMEOUT); |
| 703 | while (readl(&udc->op_regs->epflush) & bit_pos) { | 746 | while (readl(&udc->op_regs->epflush)) { |
| 704 | /* | 747 | /* |
| 705 | * ENDPTFLUSH bit should be cleared to indicate this | 748 | * ENDPTFLUSH bit should be cleared to indicate this |
| 706 | * operation is complete | 749 | * operation is complete |
| @@ -717,7 +760,7 @@ static void mv_ep_fifo_flush(struct usb_ep *_ep) · 10 unmodified lines | |||
| 717 | udelay(LOOPS_USEC); | 760 | udelay(LOOPS_USEC); |
| 718 | } | 761 | } |
| 719 | loops--; | 762 | loops--; |
| 720 | } | 763 | } while (readl(&udc->op_regs->epstatus) & bit_pos); |
| 721 | } | 764 | } |
| 722 | 765 | ||
| 723 | /* queues (submits) an I/O request to an endpoint */ | 766 | /* queues (submits) an I/O request to an endpoint */ |
| @@ -987,6 +1030,22 @@ static struct usb_ep_ops mv_ep_ops = { · 263 unmodified lines | |||
| 987 | .fifo_flush = mv_ep_fifo_flush, /* flush fifo */ | 1030 | .fifo_flush = mv_ep_fifo_flush, /* flush fifo */ |
| 988 | }; | 1031 | }; |
| 989 | 1032 | ||
| 1033 | static void udc_clock_enable(struct mv_udc *udc) | ||
| 1034 | { | ||
| 1035 | unsigned int i; | ||
| 1036 | |||
| 1037 | for (i = 0; i < udc->clknum; i++) | ||
| 1038 | clk_enable(udc->clk[i]); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | static void udc_clock_disable(struct mv_udc *udc) | ||
| 1042 | { | ||
| 1043 | unsigned int i; | ||
| 1044 | |||
| 1045 | for (i = 0; i < udc->clknum; i++) | ||
| 1046 | clk_disable(udc->clk[i]); | ||
| 1047 | } | ||
| 1048 | |||
| 990 | static void udc_stop(struct mv_udc *udc) | 1049 | static void udc_stop(struct mv_udc *udc) |
| 991 | { | 1050 | { |
| 992 | u32 tmp; | 1051 | u32 tmp; |
| @@ -1075,6 +1134,40 @@ static int udc_reset(struct mv_udc *udc) · 82 unmodified lines | |||
| 1075 | return 0; | 1134 | return 0; |
| 1076 | } | 1135 | } |
| 1077 | 1136 | ||
| 1137 | static int mv_udc_enable(struct mv_udc *udc) | ||
| 1138 | { | ||
| 1139 | int retval; | ||
| 1140 | |||
| 1141 | if (udc->clock_gating == 0 || udc->active) | ||
| 1142 | return 0; | ||
| 1143 | |||
| 1144 | dev_dbg(&udc->dev->dev, "enable udc\n"); | ||
| 1145 | udc_clock_enable(udc); | ||
| 1146 | if (udc->pdata->phy_init) { | ||
| 1147 | retval = udc->pdata->phy_init(udc->phy_regs); | ||
| 1148 | if (retval) { | ||
| 1149 | dev_err(&udc->dev->dev, | ||
| 1150 | "init phy error %d\n", retval); | ||
| 1151 | udc_clock_disable(udc); | ||
| 1152 | return retval; | ||
| 1153 | } | ||
| 1154 | } | ||
| 1155 | udc->active = 1; | ||
| 1156 | |||
| 1157 | return 0; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | static void mv_udc_disable(struct mv_udc *udc) | ||
| 1161 | { | ||
| 1162 | if (udc->clock_gating && udc->active) { | ||
| 1163 | dev_dbg(&udc->dev->dev, "disable udc\n"); | ||
| 1164 | if (udc->pdata->phy_deinit) | ||
| 1165 | udc->pdata->phy_deinit(udc->phy_regs); | ||
| 1166 | udc_clock_disable(udc); | ||
| 1167 | udc->active = 0; | ||
| 1168 | } | ||
| 1169 | } | ||
| 1170 | |||
| 1078 | static int mv_udc_get_frame(struct usb_gadget *gadget) | 1171 | static int mv_udc_get_frame(struct usb_gadget *gadget) |
| 1079 | { | 1172 | { |
| 1080 | struct mv_udc *udc; | 1173 | struct mv_udc *udc; |
| @@ -1110,22 +1203,68 @@ static int mv_udc_wakeup(struct usb_gadget *gadget) · 29 unmodified lines | |||
| 1110 | return 0; | 1203 | return 0; |
| 1111 | } | 1204 | } |
| 1112 | 1205 | ||
| 1206 | static int mv_udc_vbus_session(struct usb_gadget *gadget, int is_active) | ||
| 1207 | { | ||
| 1208 | struct mv_udc *udc; | ||
| 1209 | unsigned long flags; | ||
| 1210 | int retval = 0; | ||
| 1211 | |||
| 1212 | udc = container_of(gadget, struct mv_udc, gadget); | ||
| 1213 | spin_lock_irqsave(&udc->lock, flags); | ||
| 1214 | |||
| 1215 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", | ||
| 1216 | __func__, udc->softconnect, udc->vbus_active); | ||
| 1217 | |||
| 1218 | udc->vbus_active = (is_active != 0); | ||
| 1219 | if (udc->driver && udc->softconnect && udc->vbus_active) { | ||
| 1220 | retval = mv_udc_enable(udc); | ||
| 1221 | if (retval == 0) { | ||
| 1222 | /* Clock is disabled, need re-init registers */ | ||
| 1223 | udc_reset(udc); | ||
| 1224 | ep0_reset(udc); | ||
| 1225 | udc_start(udc); | ||
| 1226 | } | ||
| 1227 | } else if (udc->driver && udc->softconnect) { | ||
| 1228 | /* stop all the transfer in queue*/ | ||
| 1229 | stop_activity(udc, udc->driver); | ||
| 1230 | udc_stop(udc); | ||
| 1231 | mv_udc_disable(udc); | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 1235 | return retval; | ||
| 1236 | } | ||
| 1237 | |||
| 1113 | static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) | 1238 | static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) |
| 1114 | { | 1239 | { |
| 1115 | struct mv_udc *udc; | 1240 | struct mv_udc *udc; |
| 1116 | unsigned long flags; | 1241 | unsigned long flags; |
| 1242 | int retval = 0; | ||
| 1117 | 1243 | ||
| 1118 | udc = container_of(gadget, struct mv_udc, gadget); | 1244 | udc = container_of(gadget, struct mv_udc, gadget); |
| 1119 | spin_lock_irqsave(&udc->lock, flags); | 1245 | spin_lock_irqsave(&udc->lock, flags); |
| 1120 | 1246 | ||
| 1247 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", | ||
| 1248 | __func__, udc->softconnect, udc->vbus_active); | ||
| 1249 | |||
| 1121 | udc->softconnect = (is_on != 0); | 1250 | udc->softconnect = (is_on != 0); |
| 1122 | if (udc->driver && udc->softconnect) | 1251 | if (udc->driver && udc->softconnect && udc->vbus_active) { |
| 1123 | udc_start(udc); | 1252 | retval = mv_udc_enable(udc); |
| 1124 | else | 1253 | if (retval == 0) { |
| 1254 | /* Clock is disabled, need re-init registers */ | ||
| 1255 | udc_reset(udc); | ||
| 1256 | ep0_reset(udc); | ||
| 1257 | udc_start(udc); | ||
| 1258 | } | ||
| 1259 | } else if (udc->driver && udc->vbus_active) { | ||
| 1260 | /* stop all the transfer in queue*/ | ||
| 1261 | stop_activity(udc, udc->driver); | ||
| 1125 | udc_stop(udc); | 1262 | udc_stop(udc); |
| 1263 | mv_udc_disable(udc); | ||
| 1264 | } | ||
| 1126 | 1265 | ||
| 1127 | spin_unlock_irqrestore(&udc->lock, flags); | 1266 | spin_unlock_irqrestore(&udc->lock, flags); |
| 1128 | return 0; | 1267 | return retval; |
| 1129 | } | 1268 | } |
| 1130 | 1269 | ||
| 1131 | static int mv_udc_start(struct usb_gadget_driver *driver, | 1270 | static int mv_udc_start(struct usb_gadget_driver *driver, |
| @@ -1140,17 +1279,15 @@ static const struct usb_gadget_ops mv_ops = { · 8 unmodified lines | |||
| 1140 | /* tries to wake up the host connected to this gadget */ | 1279 | /* tries to wake up the host connected to this gadget */ |
| 1141 | .wakeup = mv_udc_wakeup, | 1280 | .wakeup = mv_udc_wakeup, |
| 1142 | 1281 | ||
| 1282 | /* notify controller that VBUS is powered or not */ | ||
| 1283 | .vbus_session = mv_udc_vbus_session, | ||
| 1284 | |||
| 1143 | /* D+ pullup, software-controlled connect/disconnect to USB host */ | 1285 | /* D+ pullup, software-controlled connect/disconnect to USB host */ |
| 1144 | .pullup = mv_udc_pullup, | 1286 | .pullup = mv_udc_pullup, |
| 1145 | .start = mv_udc_start, | 1287 | .start = mv_udc_start, |
| 1146 | .stop = mv_udc_stop, | 1288 | .stop = mv_udc_stop, |
| 1147 | }; | 1289 | }; |
| 1148 | 1290 | ||
| 1149 | static void mv_udc_testmode(struct mv_udc *udc, u16 index, bool enter) | ||
| 1150 | { | ||
| 1151 | dev_info(&udc->dev->dev, "Test Mode is not support yet\n"); | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | static int eps_init(struct mv_udc *udc) | 1291 | static int eps_init(struct mv_udc *udc) |
| 1155 | { | 1292 | { |
| 1156 | struct mv_ep *ep; | 1293 | struct mv_ep *ep; |
| @@ -1257,7 +1394,7 @@ static int mv_udc_start(struct usb_gadget_driver *driver, · 100 unmodified lines | |||
| 1257 | 1394 | ||
| 1258 | udc->usb_state = USB_STATE_ATTACHED; | 1395 | udc->usb_state = USB_STATE_ATTACHED; |
| 1259 | udc->ep0_state = WAIT_FOR_SETUP; | 1396 | udc->ep0_state = WAIT_FOR_SETUP; |
| 1260 | udc->ep0_dir = USB_DIR_OUT; | 1397 | udc->ep0_dir = EP_DIR_OUT; |
| 1261 | 1398 | ||
| 1262 | spin_unlock_irqrestore(&udc->lock, flags); | 1399 | spin_unlock_irqrestore(&udc->lock, flags); |
| 1263 | 1400 | ||
| @@ -1269,9 +1406,13 @@ static int mv_udc_start(struct usb_gadget_driver *driver, · 5 unmodified lines | |||
| 1269 | udc->gadget.dev.driver = NULL; | 1406 | udc->gadget.dev.driver = NULL; |
| 1270 | return retval; | 1407 | return retval; |
| 1271 | } | 1408 | } |
| 1272 | udc_reset(udc); | 1409 | |
| 1273 | ep0_reset(udc); | 1410 | /* pullup is always on */ |
| 1274 | udc_start(udc); | 1411 | mv_udc_pullup(&udc->gadget, 1); |
| 1412 | |||
| 1413 | /* When boot with cable attached, there will be no vbus irq occurred */ | ||
| 1414 | if (udc->qwork) | ||
| 1415 | queue_work(udc->qwork, &udc->vbus_work); | ||
| 1275 | 1416 | ||
| 1276 | return 0; | 1417 | return 0; |
| 1277 | } | 1418 | } |
| @@ -1284,13 +1425,16 @@ static int mv_udc_stop(struct usb_gadget_driver *driver) · 6 unmodified lines | |||
| 1284 | if (!udc) | 1425 | if (!udc) |
| 1285 | return -ENODEV; | 1426 | return -ENODEV; |
| 1286 | 1427 | ||
| 1287 | udc_stop(udc); | ||
| 1288 | |||
| 1289 | spin_lock_irqsave(&udc->lock, flags); | 1428 | spin_lock_irqsave(&udc->lock, flags); |
| 1290 | 1429 | ||
| 1430 | mv_udc_enable(udc); | ||
| 1431 | udc_stop(udc); | ||
| 1432 | |||
| 1291 | /* stop all usb activities */ | 1433 | /* stop all usb activities */ |
| 1292 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1434 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
| 1293 | stop_activity(udc, driver); | 1435 | stop_activity(udc, driver); |
| 1436 | mv_udc_disable(udc); | ||
| 1437 | |||
| 1294 | spin_unlock_irqrestore(&udc->lock, flags); | 1438 | spin_unlock_irqrestore(&udc->lock, flags); |
| 1295 | 1439 | ||
| 1296 | /* unbind gadget driver */ | 1440 | /* unbind gadget driver */ |
| @@ -1301,6 +1445,31 @@ static int mv_udc_stop(struct usb_gadget_driver *driver) · 4 unmodified lines | |||
| 1301 | return 0; | 1445 | return 0; |
| 1302 | } | 1446 | } |
| 1303 | 1447 | ||
| 1448 | static void mv_set_ptc(struct mv_udc *udc, u32 mode) | ||
| 1449 | { | ||
| 1450 | u32 portsc; | ||
| 1451 | |||
| 1452 | portsc = readl(&udc->op_regs->portsc[0]); | ||
| 1453 | portsc |= mode << 16; | ||
| 1454 | writel(portsc, &udc->op_regs->portsc[0]); | ||
| 1455 | } | ||
| 1456 | |||
| 1457 | static void prime_status_complete(struct usb_ep *ep, struct usb_request *_req) | ||
| 1458 | { | ||
| 1459 | struct mv_udc *udc = the_controller; | ||
| 1460 | struct mv_req *req = container_of(_req, struct mv_req, req); | ||
| 1461 | unsigned long flags; | ||
| 1462 | |||
| 1463 | dev_info(&udc->dev->dev, "switch to test mode %d\n", req->test_mode); | ||
| 1464 | |||
| 1465 | spin_lock_irqsave(&udc->lock, flags); | ||
| 1466 | if (req->test_mode) { | ||
| 1467 | mv_set_ptc(udc, req->test_mode); | ||
| 1468 | req->test_mode = 0; | ||
| 1469 | } | ||
| 1470 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 1471 | } | ||
| 1472 | |||
| 1304 | static int | 1473 | static int |
| 1305 | udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) | 1474 | udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) |
| 1306 | { | 1475 | { |
| @@ -1310,6 +1479,7 @@ udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) · 3 unmodified lines | |||
| 1310 | 1479 | ||
| 1311 | ep = &udc->eps[0]; | 1480 | ep = &udc->eps[0]; |
| 1312 | udc->ep0_dir = direction; | 1481 | udc->ep0_dir = direction; |
| 1482 | udc->ep0_state = WAIT_FOR_OUT_STATUS; | ||
| 1313 | 1483 | ||
| 1314 | req = udc->status_req; | 1484 | req = udc->status_req; |
| 1315 | 1485 | ||
| @@ -1323,9 +1493,21 @@ udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) · 7 unmodified lines | |||
| 1323 | req->ep = ep; | 1493 | req->ep = ep; |
| 1324 | req->req.status = -EINPROGRESS; | 1494 | req->req.status = -EINPROGRESS; |
| 1325 | req->req.actual = 0; | 1495 | req->req.actual = 0; |
| 1326 | req->req.complete = NULL; | 1496 | if (udc->test_mode) { |
| 1497 | req->req.complete = prime_status_complete; | ||
| 1498 | req->test_mode = udc->test_mode; | ||
| 1499 | udc->test_mode = 0; | ||
| 1500 | } else | ||
| 1501 | req->req.complete = NULL; | ||
| 1327 | req->dtd_count = 0; | 1502 | req->dtd_count = 0; |
| 1328 | 1503 | ||
| 1504 | if (req->req.dma == DMA_ADDR_INVALID) { | ||
| 1505 | req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, | ||
| 1506 | req->req.buf, req->req.length, | ||
| 1507 | ep_dir(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 1508 | req->mapped = 1; | ||
| 1509 | } | ||
| 1510 | |||
| 1329 | /* prime the data phase */ | 1511 | /* prime the data phase */ |
| 1330 | if (!req_to_dtd(req)) | 1512 | if (!req_to_dtd(req)) |
| 1331 | retval = queue_dtd(ep, req); | 1513 | retval = queue_dtd(ep, req); |
| @@ -1346,6 +1528,17 @@ out: · 14 unmodified lines | |||
| 1346 | return retval; | 1528 | return retval; |
| 1347 | } | 1529 | } |
| 1348 | 1530 | ||
| 1531 | static void mv_udc_testmode(struct mv_udc *udc, u16 index) | ||
| 1532 | { | ||
| 1533 | if (index <= TEST_FORCE_EN) { | ||
| 1534 | udc->test_mode = index; | ||
| 1535 | if (udc_prime_status(udc, EP_DIR_IN, 0, true)) | ||
| 1536 | ep0_stall(udc); | ||
| 1537 | } else | ||
| 1538 | dev_err(&udc->dev->dev, | ||
| 1539 | "This test mode(%d) is not supported\n", index); | ||
| 1540 | } | ||
| 1541 | |||
| 1349 | static void ch9setaddress(struct mv_udc *udc, struct usb_ctrlrequest *setup) | 1542 | static void ch9setaddress(struct mv_udc *udc, struct usb_ctrlrequest *setup) |
| 1350 | { | 1543 | { |
| 1351 | udc->dev_addr = (u8)setup->wValue; | 1544 | udc->dev_addr = (u8)setup->wValue; |
| @@ -1360,7 +1553,7 @@ static void ch9setaddress(struct mv_udc *udc, struct usb_ctrlrequest *setup) · 8 unmodified lines | |||
| 1360 | static void ch9getstatus(struct mv_udc *udc, u8 ep_num, | 1553 | static void ch9getstatus(struct mv_udc *udc, u8 ep_num, |
| 1361 | struct usb_ctrlrequest *setup) | 1554 | struct usb_ctrlrequest *setup) |
| 1362 | { | 1555 | { |
| 1363 | u16 status; | 1556 | u16 status = 0; |
| 1364 | int retval; | 1557 | int retval; |
| 1365 | 1558 | ||
| 1366 | if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) | 1559 | if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) |
| @@ -1388,6 +1581,8 @@ static void ch9getstatus(struct mv_udc *udc, u8 ep_num, · 21 unmodified lines | |||
| 1388 | retval = udc_prime_status(udc, EP_DIR_IN, status, false); | 1581 | retval = udc_prime_status(udc, EP_DIR_IN, status, false); |
| 1389 | if (retval) | 1582 | if (retval) |
| 1390 | ep0_stall(udc); | 1583 | ep0_stall(udc); |
| 1584 | else | ||
| 1585 | udc->ep0_state = DATA_STATE_XMIT; | ||
| 1391 | } | 1586 | } |
| 1392 | 1587 | ||
| 1393 | static void ch9clearfeature(struct mv_udc *udc, struct usb_ctrlrequest *setup) | 1588 | static void ch9clearfeature(struct mv_udc *udc, struct usb_ctrlrequest *setup) |
| @@ -1402,9 +1597,6 @@ static void ch9clearfeature(struct mv_udc *udc, struct usb_ctrlrequest *setup) · 8 unmodified lines | |||
| 1402 | case USB_DEVICE_REMOTE_WAKEUP: | 1597 | case USB_DEVICE_REMOTE_WAKEUP: |
| 1403 | udc->remote_wakeup = 0; | 1598 | udc->remote_wakeup = 0; |
| 1404 | break; | 1599 | break; |
| 1405 | case USB_DEVICE_TEST_MODE: | ||
| 1406 | mv_udc_testmode(udc, 0, false); | ||
| 1407 | break; | ||
| 1408 | default: | 1600 | default: |
| 1409 | goto out; | 1601 | goto out; |
| 1410 | } | 1602 | } |
| @@ -1433,8 +1625,6 @@ static void ch9clearfeature(struct mv_udc *udc, struct usb_ctrlrequest *setup) · 22 unmodified lines | |||
| 1433 | 1625 | ||
| 1434 | if (udc_prime_status(udc, EP_DIR_IN, 0, true)) | 1626 | if (udc_prime_status(udc, EP_DIR_IN, 0, true)) |
| 1435 | ep0_stall(udc); | 1627 | ep0_stall(udc); |
| 1436 | else | ||
| 1437 | udc->ep0_state = DATA_STATE_XMIT; | ||
| 1438 | out: | 1628 | out: |
| 1439 | return; | 1629 | return; |
| 1440 | } | 1630 | } |
| @@ -1452,16 +1642,16 @@ static void ch9setfeature(struct mv_udc *udc, struct usb_ctrlrequest *setup) · 11 unmodified lines | |||
| 1452 | break; | 1642 | break; |
| 1453 | case USB_DEVICE_TEST_MODE: | 1643 | case USB_DEVICE_TEST_MODE: |
| 1454 | if (setup->wIndex & 0xFF | 1644 | if (setup->wIndex & 0xFF |
| 1455 | && udc->gadget.speed != USB_SPEED_HIGH) | 1645 | || udc->gadget.speed != USB_SPEED_HIGH) |
| 1456 | goto out; | 1646 | ep0_stall(udc); |
| 1457 | if (udc->usb_state == USB_STATE_CONFIGURED | 1647 | |
| 1458 | || udc->usb_state == USB_STATE_ADDRESS | 1648 | if (udc->usb_state != USB_STATE_CONFIGURED |
| 1459 | || udc->usb_state == USB_STATE_DEFAULT) | 1649 | && udc->usb_state != USB_STATE_ADDRESS |
| 1460 | mv_udc_testmode(udc, | 1650 | && udc->usb_state != USB_STATE_DEFAULT) |
| 1461 | setup->wIndex & 0xFF00, true); | 1651 | ep0_stall(udc); |
| 1462 | else | 1652 | |
| 1463 | goto out; | 1653 | mv_udc_testmode(udc, (setup->wIndex >> 8)); |
| 1464 | break; | 1654 | goto out; |
| 1465 | default: | 1655 | default: |
| 1466 | goto out; | 1656 | goto out; |
| 1467 | } | 1657 | } |
| @@ -1599,8 +1789,7 @@ static void get_setup_data(struct mv_udc *udc, u8 ep_num, u8 *buffer_ptr) · 131 unmodified lines | |||
| 1599 | dqh = &udc->ep_dqh[ep_num * 2 + EP_DIR_OUT]; | 1789 | dqh = &udc->ep_dqh[ep_num * 2 + EP_DIR_OUT]; |
| 1600 | 1790 | ||
| 1601 | /* Clear bit in ENDPTSETUPSTAT */ | 1791 | /* Clear bit in ENDPTSETUPSTAT */ |
| 1602 | temp = readl(&udc->op_regs->epsetupstat); | 1792 | writel((1 << ep_num), &udc->op_regs->epsetupstat); |
| 1603 | writel(temp | (1 << ep_num), &udc->op_regs->epsetupstat); | ||
| 1604 | 1793 | ||
| 1605 | /* while a hazard exists when setup package arrives */ | 1794 | /* while a hazard exists when setup package arrives */ |
| 1606 | do { | 1795 | do { |
| @@ -1871,23 +2060,57 @@ static irqreturn_t mv_udc_irq(int irq, void *dev) · 264 unmodified lines | |||
| 1871 | return IRQ_HANDLED; | 2060 | return IRQ_HANDLED; |
| 1872 | } | 2061 | } |
| 1873 | 2062 | ||
| 2063 | static irqreturn_t mv_udc_vbus_irq(int irq, void *dev) | ||
| 2064 | { | ||
| 2065 | struct mv_udc *udc = (struct mv_udc *)dev; | ||
| 2066 | |||
| 2067 | /* polling VBUS and init phy may cause too much time*/ | ||
| 2068 | if (udc->qwork) | ||
| 2069 | queue_work(udc->qwork, &udc->vbus_work); | ||
| 2070 | |||
| 2071 | return IRQ_HANDLED; | ||
| 2072 | } | ||
| 2073 | |||
| 2074 | static void mv_udc_vbus_work(struct work_struct *work) | ||
| 2075 | { | ||
| 2076 | struct mv_udc *udc; | ||
| 2077 | unsigned int vbus; | ||
| 2078 | |||
| 2079 | udc = container_of(work, struct mv_udc, vbus_work); | ||
| 2080 | if (!udc->pdata->vbus) | ||
| 2081 | return; | ||
| 2082 | |||
| 2083 | vbus = udc->pdata->vbus->poll(); | ||
| 2084 | dev_info(&udc->dev->dev, "vbus is %d\n", vbus); | ||
| 2085 | |||
| 2086 | if (vbus == VBUS_HIGH) | ||
| 2087 | mv_udc_vbus_session(&udc->gadget, 1); | ||
| 2088 | else if (vbus == VBUS_LOW) | ||
| 2089 | mv_udc_vbus_session(&udc->gadget, 0); | ||
| 2090 | } | ||
| 2091 | |||
| 1874 | /* release device structure */ | 2092 | /* release device structure */ |
| 1875 | static void gadget_release(struct device *_dev) | 2093 | static void gadget_release(struct device *_dev) |
| 1876 | { | 2094 | { |
| 1877 | struct mv_udc *udc = the_controller; | 2095 | struct mv_udc *udc = the_controller; |
| 1878 | 2096 | ||
| 1879 | complete(udc->done); | 2097 | complete(udc->done); |
| 1880 | kfree(udc); | ||
| 1881 | } | 2098 | } |
| 1882 | 2099 | ||
| 1883 | static int mv_udc_remove(struct platform_device *dev) | 2100 | static int __devexit mv_udc_remove(struct platform_device *dev) |
| 1884 | { | 2101 | { |
| 1885 | struct mv_udc *udc = the_controller; | 2102 | struct mv_udc *udc = the_controller; |
| 1886 | DECLARE_COMPLETION(done); | 2103 | int clk_i; |
| 1887 | 2104 | ||
| 1888 | usb_del_gadget_udc(&udc->gadget); | 2105 | usb_del_gadget_udc(&udc->gadget); |
| 1889 | 2106 | ||
| 1890 | udc->done = &done; | 2107 | if (udc->qwork) { |
| 2108 | flush_workqueue(udc->qwork); | ||
| 2109 | destroy_workqueue(udc->qwork); | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | if (udc->pdata && udc->pdata->vbus && udc->clock_gating) | ||
| 2113 | free_irq(udc->pdata->vbus->irq, &dev->dev); | ||
| 1891 | 2114 | ||
| 1892 | /* free memory allocated in probe */ | 2115 | /* free memory allocated in probe */ |
| 1893 | if (udc->dtd_pool) | 2116 | if (udc->dtd_pool) |
| @@ -1902,6 +2125,8 @@ static int mv_udc_remove(struct platform_device *dev) · 8 unmodified lines | |||
| 1902 | if (udc->irq) | 2125 | if (udc->irq) |
| 1903 | free_irq(udc->irq, &dev->dev); | 2126 | free_irq(udc->irq, &dev->dev); |
| 1904 | 2127 | ||
| 2128 | mv_udc_disable(udc); | ||
| 2129 | |||
| 1905 | if (udc->cap_regs) | 2130 | if (udc->cap_regs) |
| 1906 | iounmap(udc->cap_regs); | 2131 | iounmap(udc->cap_regs); |
| 1907 | udc->cap_regs = NULL; | 2132 | udc->cap_regs = NULL; |
| @@ -1915,45 +2140,62 @@ static int mv_udc_remove(struct platform_device *dev) · 7 unmodified lines | |||
| 1915 | kfree(udc->status_req); | 2140 | kfree(udc->status_req); |
| 1916 | } | 2141 | } |
| 1917 | 2142 | ||
| 2143 | for (clk_i = 0; clk_i <= udc->clknum; clk_i++) | ||
| 2144 | clk_put(udc->clk[clk_i]); | ||
| 2145 | |||
| 1918 | device_unregister(&udc->gadget.dev); | 2146 | device_unregister(&udc->gadget.dev); |
| 1919 | 2147 | ||
| 1920 | /* free dev, wait for the release() finished */ | 2148 | /* free dev, wait for the release() finished */ |
| 1921 | wait_for_completion(&done); | 2149 | wait_for_completion(udc->done); |
| 2150 | kfree(udc); | ||
| 1922 | 2151 | ||
| 1923 | the_controller = NULL; | 2152 | the_controller = NULL; |
| 1924 | 2153 | ||
| 1925 | return 0; | 2154 | return 0; |
| 1926 | } | 2155 | } |
| 1927 | 2156 | ||
| 1928 | int mv_udc_probe(struct platform_device *dev) | 2157 | static int __devinit mv_udc_probe(struct platform_device *dev) |
| 1929 | { | 2158 | { |
| 2159 | struct mv_usb_platform_data *pdata = dev->dev.platform_data; | ||
| 1930 | struct mv_udc *udc; | 2160 | struct mv_udc *udc; |
| 1931 | int retval = 0; | 2161 | int retval = 0; |
| 2162 | int clk_i = 0; | ||
| 1932 | struct resource *r; | 2163 | struct resource *r; |
| 1933 | size_t size; | 2164 | size_t size; |
| 1934 | 2165 | ||
| 1935 | udc = kzalloc(sizeof *udc, GFP_KERNEL); | 2166 | if (pdata == NULL) { |
| 2167 | dev_err(&dev->dev, "missing platform_data\n"); | ||
| 2168 | return -ENODEV; | ||
| 2169 | } | ||
| 2170 | |||
| 2171 | size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum; | ||
| 2172 | udc = kzalloc(size, GFP_KERNEL); | ||
| 1936 | if (udc == NULL) { | 2173 | if (udc == NULL) { |
| 1937 | dev_err(&dev->dev, "failed to allocate memory for udc\n"); | 2174 | dev_err(&dev->dev, "failed to allocate memory for udc\n"); |
| 1938 | retval = -ENOMEM; | 2175 | return -ENOMEM; |
| 1939 | goto error; | ||
| 1940 | } | 2176 | } |
| 1941 | 2177 | ||
| 2178 | the_controller = udc; | ||
| 2179 | udc->done = &release_done; | ||
| 2180 | udc->pdata = dev->dev.platform_data; | ||
| 1942 | spin_lock_init(&udc->lock); | 2181 | spin_lock_init(&udc->lock); |
| 1943 | 2182 | ||
| 1944 | udc->dev = dev; | 2183 | udc->dev = dev; |
| 1945 | 2184 | ||
| 1946 | udc->clk = clk_get(&dev->dev, "U2OCLK"); | 2185 | udc->clknum = pdata->clknum; |
| 1947 | if (IS_ERR(udc->clk)) { | 2186 | for (clk_i = 0; clk_i < udc->clknum; clk_i++) { |
| 1948 | retval = PTR_ERR(udc->clk); | 2187 | udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]); |
| 1949 | goto error; | 2188 | if (IS_ERR(udc->clk[clk_i])) { |
| 2189 | retval = PTR_ERR(udc->clk[clk_i]); | ||
| 2190 | goto err_put_clk; | ||
| 2191 | } | ||
| 1950 | } | 2192 | } |
| 1951 | 2193 | ||
| 1952 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "u2o"); | 2194 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "capregs"); |
| 1953 | if (r == NULL) { | 2195 | if (r == NULL) { |
| 1954 | dev_err(&dev->dev, "no I/O memory resource defined\n"); | 2196 | dev_err(&dev->dev, "no I/O memory resource defined\n"); |
| 1955 | retval = -ENODEV; | 2197 | retval = -ENODEV; |
| 1956 | goto error; | 2198 | goto err_put_clk; |
| 1957 | } | 2199 | } |
| 1958 | 2200 | ||
| 1959 | udc->cap_regs = (struct mv_cap_regs __iomem *) | 2201 | udc->cap_regs = (struct mv_cap_regs __iomem *) |
| @@ -1961,29 +2203,31 @@ int mv_udc_probe(struct platform_device *dev) · 1 unmodified line | |||
| 1961 | if (udc->cap_regs == NULL) { | 2203 | if (udc->cap_regs == NULL) { |
| 1962 | dev_err(&dev->dev, "failed to map I/O memory\n"); | 2204 | dev_err(&dev->dev, "failed to map I/O memory\n"); |
| 1963 | retval = -EBUSY; | 2205 | retval = -EBUSY; |
| 1964 | goto error; | 2206 | goto err_put_clk; |
| 1965 | } | 2207 | } |
| 1966 | 2208 | ||
| 1967 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "u2ophy"); | 2209 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "phyregs"); |
| 1968 | if (r == NULL) { | 2210 | if (r == NULL) { |
| 1969 | dev_err(&dev->dev, "no phy I/O memory resource defined\n"); | 2211 | dev_err(&dev->dev, "no phy I/O memory resource defined\n"); |
| 1970 | retval = -ENODEV; | 2212 | retval = -ENODEV; |
| 1971 | goto error; | 2213 | goto err_iounmap_capreg; |
| 1972 | } | 2214 | } |
| 1973 | 2215 | ||
| 1974 | udc->phy_regs = (unsigned int)ioremap(r->start, resource_size(r)); | 2216 | udc->phy_regs = (unsigned int)ioremap(r->start, resource_size(r)); |
| 1975 | if (udc->phy_regs == 0) { | 2217 | if (udc->phy_regs == 0) { |
| 1976 | dev_err(&dev->dev, "failed to map phy I/O memory\n"); | 2218 | dev_err(&dev->dev, "failed to map phy I/O memory\n"); |
| 1977 | retval = -EBUSY; | 2219 | retval = -EBUSY; |
| 1978 | goto error; | 2220 | goto err_iounmap_capreg; |
| 1979 | } | 2221 | } |
| 1980 | 2222 | ||
| 1981 | /* we will acces controller register, so enable the clk */ | 2223 | /* we will acces controller register, so enable the clk */ |
| 1982 | clk_enable(udc->clk); | 2224 | udc_clock_enable(udc); |
| 1983 | retval = mv_udc_phy_init(udc->phy_regs); | 2225 | if (pdata->phy_init) { |
| 1984 | if (retval) { | 2226 | retval = pdata->phy_init(udc->phy_regs); |
| 1985 | dev_err(&dev->dev, "phy initialization error %d\n", retval); | 2227 | if (retval) { |
| 1986 | goto error; | 2228 | dev_err(&dev->dev, "phy init error %d\n", retval); |
| 2229 | goto err_iounmap_phyreg; | ||
| 2230 | } | ||
| 1987 | } | 2231 | } |
| 1988 | 2232 | ||
| 1989 | udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs | 2233 | udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs |
| @@ -1991,6 +2235,13 @@ int mv_udc_probe(struct platform_device *dev) · 1 unmodified line | |||
| 1991 | & CAPLENGTH_MASK)); | 2235 | & CAPLENGTH_MASK)); |
| 1992 | udc->max_eps = readl(&udc->cap_regs->dccparams) & DCCPARAMS_DEN_MASK; | 2236 | udc->max_eps = readl(&udc->cap_regs->dccparams) & DCCPARAMS_DEN_MASK; |
| 1993 | 2237 | ||
| 2238 | /* | ||
| 2239 | * some platform will use usb to download image, it may not disconnect | ||
| 2240 | * usb gadget before loading kernel. So first stop udc here. | ||
| 2241 | */ | ||
| 2242 | udc_stop(udc); | ||
| 2243 | writel(0xFFFFFFFF, &udc->op_regs->usbsts); | ||
| 2244 | |||
| 1994 | size = udc->max_eps * sizeof(struct mv_dqh) *2; | 2245 | size = udc->max_eps * sizeof(struct mv_dqh) *2; |
| 1995 | size = (size + DQH_ALIGNMENT - 1) & ~(DQH_ALIGNMENT - 1); | 2246 | size = (size + DQH_ALIGNMENT - 1) & ~(DQH_ALIGNMENT - 1); |
| 1996 | udc->ep_dqh = dma_alloc_coherent(&dev->dev, size, | 2247 | udc->ep_dqh = dma_alloc_coherent(&dev->dev, size, |
| @@ -1999,7 +2250,7 @@ int mv_udc_probe(struct platform_device *dev) · 2 unmodified lines | |||
| 1999 | if (udc->ep_dqh == NULL) { | 2250 | if (udc->ep_dqh == NULL) { |
| 2000 | dev_err(&dev->dev, "allocate dQH memory failed\n"); | 2251 | dev_err(&dev->dev, "allocate dQH memory failed\n"); |
| 2001 | retval = -ENOMEM; | 2252 | retval = -ENOMEM; |
| 2002 | goto error; | 2253 | goto err_disable_clock; |
| 2003 | } | 2254 | } |
| 2004 | udc->ep_dqh_size = size; | 2255 | udc->ep_dqh_size = size; |
| 2005 | 2256 | ||
| @@ -2012,7 +2263,7 @@ int mv_udc_probe(struct platform_device *dev) · 6 unmodified lines | |||
| 2012 | 2263 | ||
| 2013 | if (!udc->dtd_pool) { | 2264 | if (!udc->dtd_pool) { |
| 2014 | retval = -ENOMEM; | 2265 | retval = -ENOMEM; |
| 2015 | goto error; | 2266 | goto err_free_dma; |
| 2016 | } | 2267 | } |
| 2017 | 2268 | ||
| 2018 | size = udc->max_eps * sizeof(struct mv_ep) *2; | 2269 | size = udc->max_eps * sizeof(struct mv_ep) *2; |
| @@ -2020,7 +2271,7 @@ int mv_udc_probe(struct platform_device *dev) · 1 unmodified line | |||
| 2020 | if (udc->eps == NULL) { | 2271 | if (udc->eps == NULL) { |
| 2021 | dev_err(&dev->dev, "allocate ep memory failed\n"); | 2272 | dev_err(&dev->dev, "allocate ep memory failed\n"); |
| 2022 | retval = -ENOMEM; | 2273 | retval = -ENOMEM; |
| 2023 | goto error; | 2274 | goto err_destroy_dma; |
| 2024 | } | 2275 | } |
| 2025 | 2276 | ||
| 2026 | /* initialize ep0 status request structure */ | 2277 | /* initialize ep0 status request structure */ |
| @@ -2028,13 +2279,13 @@ int mv_udc_probe(struct platform_device *dev) · 1 unmodified line | |||
| 2028 | if (!udc->status_req) { | 2279 | if (!udc->status_req) { |
| 2029 | dev_err(&dev->dev, "allocate status_req memory failed\n"); | 2280 | dev_err(&dev->dev, "allocate status_req memory failed\n"); |
| 2030 | retval = -ENOMEM; | 2281 | retval = -ENOMEM; |
| 2031 | goto error; | 2282 | goto err_free_eps; |
| 2032 | } | 2283 | } |
| 2033 | INIT_LIST_HEAD(&udc->status_req->queue); | 2284 | INIT_LIST_HEAD(&udc->status_req->queue); |
| 2034 | 2285 | ||
| 2035 | /* allocate a small amount of memory to get valid address */ | 2286 | /* allocate a small amount of memory to get valid address */ |
| 2036 | udc->status_req->req.buf = kzalloc(8, GFP_KERNEL); | 2287 | udc->status_req->req.buf = kzalloc(8, GFP_KERNEL); |
| 2037 | udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf); | 2288 | udc->status_req->req.dma = DMA_ADDR_INVALID; |
| 2038 | 2289 | ||
| 2039 | udc->resume_state = USB_STATE_NOTATTACHED; | 2290 | udc->resume_state = USB_STATE_NOTATTACHED; |
| 2040 | udc->usb_state = USB_STATE_POWERED; | 2291 | udc->usb_state = USB_STATE_POWERED; |
| @@ -2045,15 +2296,15 @@ int mv_udc_probe(struct platform_device *dev) · 4 unmodified lines | |||
| 2045 | if (r == NULL) { | 2296 | if (r == NULL) { |
| 2046 | dev_err(&dev->dev, "no IRQ resource defined\n"); | 2297 | dev_err(&dev->dev, "no IRQ resource defined\n"); |
| 2047 | retval = -ENODEV; | 2298 | retval = -ENODEV; |
| 2048 | goto error; | 2299 | goto err_free_status_req; |
| 2049 | } | 2300 | } |
| 2050 | udc->irq = r->start; | 2301 | udc->irq = r->start; |
| 2051 | if (request_irq(udc->irq, mv_udc_irq, | 2302 | if (request_irq(udc->irq, mv_udc_irq, |
| 2052 | IRQF_DISABLED | IRQF_SHARED, driver_name, udc)) { | 2303 | IRQF_SHARED, driver_name, udc)) { |
| 2053 | dev_err(&dev->dev, "Request irq %d for UDC failed\n", | 2304 | dev_err(&dev->dev, "Request irq %d for UDC failed\n", |
| 2054 | udc->irq); | 2305 | udc->irq); |
| 2055 | retval = -ENODEV; | 2306 | retval = -ENODEV; |
| 2056 | goto error; | 2307 | goto err_free_status_req; |
| 2057 | } | 2308 | } |
| 2058 | 2309 | ||
| 2059 | /* initialize gadget structure */ | 2310 | /* initialize gadget structure */ |
| @@ -2072,18 +2323,82 @@ int mv_udc_probe(struct platform_device *dev) · 12 unmodified lines | |||
| 2072 | 2323 | ||
| 2073 | retval = device_register(&udc->gadget.dev); | 2324 | retval = device_register(&udc->gadget.dev); |
| 2074 | if (retval) | 2325 | if (retval) |
| 2075 | goto error; | 2326 | goto err_free_irq; |
| 2076 | 2327 | ||
| 2077 | eps_init(udc); | 2328 | eps_init(udc); |
| 2078 | 2329 | ||
| 2079 | the_controller = udc; | 2330 | /* VBUS detect: we can disable/enable clock on demand.*/ |
| 2331 | if (pdata->vbus) { | ||
| 2332 | udc->clock_gating = 1; | ||
| 2333 | retval = request_threaded_irq(pdata->vbus->irq, NULL, | ||
| 2334 | mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); | ||
| 2335 | if (retval) { | ||
| 2336 | dev_info(&dev->dev, | ||
| 2337 | "Can not request irq for VBUS, " | ||
| 2338 | "disable clock gating\n"); | ||
| 2339 | udc->clock_gating = 0; | ||
| 2340 | } | ||
| 2341 | |||
| 2342 | udc->qwork = create_singlethread_workqueue("mv_udc_queue"); | ||
| 2343 | if (!udc->qwork) { | ||
| 2344 | dev_err(&dev->dev, "cannot create workqueue\n"); | ||
| 2345 | retval = -ENOMEM; | ||
| 2346 | goto err_unregister; | ||
| 2347 | } | ||
| 2348 | |||
| 2349 | INIT_WORK(&udc->vbus_work, mv_udc_vbus_work); | ||
| 2350 | } | ||
| 2351 | |||
| 2352 | /* | ||
| 2353 | * When clock gating is supported, we can disable clk and phy. | ||
| 2354 | * If not, it means that VBUS detection is not supported, we | ||
| 2355 | * have to enable vbus active all the time to let controller work. | ||
| 2356 | */ | ||
| 2357 | if (udc->clock_gating) { | ||
| 2358 | if (udc->pdata->phy_deinit) | ||
| 2359 | udc->pdata->phy_deinit(udc->phy_regs); | ||
| 2360 | udc_clock_disable(udc); | ||
| 2361 | } else | ||
| 2362 | udc->vbus_active = 1; | ||
| 2080 | 2363 | ||
| 2081 | retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); | 2364 | retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); |
| 2082 | if (!retval) | 2365 | if (retval) |
| 2083 | return retval; | 2366 | goto err_unregister; |
| 2084 | error: | 2367 | |
| 2085 | if (udc) | 2368 | dev_info(&dev->dev, "successful probe UDC device %s clock gating.\n", |
| 2086 | mv_udc_remove(udc->dev); | 2369 | udc->clock_gating ? "with" : "without"); |
| 2370 | |||
| 2371 | return 0; | ||
| 2372 | |||
| 2373 | err_unregister: | ||
| 2374 | if (udc->pdata && udc->pdata->vbus && udc->clock_gating) | ||
| 2375 | free_irq(pdata->vbus->irq, &dev->dev); | ||
| 2376 | device_unregister(&udc->gadget.dev); | ||
| 2377 | err_free_irq: | ||
| 2378 | free_irq(udc->irq, &dev->dev); | ||
| 2379 | err_free_status_req: | ||
| 2380 | kfree(udc->status_req->req.buf); | ||
| 2381 | kfree(udc->status_req); | ||
| 2382 | err_free_eps: | ||
| 2383 | kfree(udc->eps); | ||
| 2384 | err_destroy_dma: | ||
| 2385 | dma_pool_destroy(udc->dtd_pool); | ||
| 2386 | err_free_dma: | ||
| 2387 | dma_free_coherent(&dev->dev, udc->ep_dqh_size, | ||
| 2388 | udc->ep_dqh, udc->ep_dqh_dma); | ||
| 2389 | err_disable_clock: | ||
| 2390 | if (udc->pdata->phy_deinit) | ||
| 2391 | udc->pdata->phy_deinit(udc->phy_regs); | ||
| 2392 | udc_clock_disable(udc); | ||
| 2393 | err_iounmap_phyreg: | ||
| 2394 | iounmap((void *)udc->phy_regs); | ||
| 2395 | err_iounmap_capreg: | ||
| 2396 | iounmap(udc->cap_regs); | ||
| 2397 | err_put_clk: | ||
| 2398 | for (clk_i--; clk_i >= 0; clk_i--) | ||
| 2399 | clk_put(udc->clk[clk_i]); | ||
| 2400 | the_controller = NULL; | ||
| 2401 | kfree(udc); | ||
| 2087 | return retval; | 2402 | return retval; |
| 2088 | } | 2403 | } |
| 2089 | 2404 | ||
| @@ -2102,11 +2417,16 @@ static int mv_udc_resume(struct device *_dev) · 12 unmodified lines | |||
| 2102 | struct mv_udc *udc = the_controller; | 2417 | struct mv_udc *udc = the_controller; |
| 2103 | int retval; | 2418 | int retval; |
| 2104 | 2419 | ||
| 2105 | retval = mv_udc_phy_init(udc->phy_regs); | 2420 | if (udc->pdata->phy_init) { |
| 2106 | if (retval) { | 2421 | retval = udc->pdata->phy_init(udc->phy_regs); |
| 2107 | dev_err(_dev, "phy initialization error %d\n", retval); | 2422 | if (retval) { |
| 2108 | return retval; | 2423 | dev_err(&udc->dev->dev, |
| 2424 | "init phy error %d when resume back\n", | ||
| 2425 | retval); | ||
| 2426 | return retval; | ||
| 2427 | } | ||
| 2109 | } | 2428 | } |
| 2429 | |||
| 2110 | udc_reset(udc); | 2430 | udc_reset(udc); |
| 2111 | ep0_reset(udc); | 2431 | ep0_reset(udc); |
| 2112 | udc_start(udc); | 2432 | udc_start(udc); |
| @@ -2120,9 +2440,21 @@ static const struct dev_pm_ops mv_udc_pm_ops = { · 7 unmodified lines | |||
| 2120 | }; | 2440 | }; |
| 2121 | #endif | 2441 | #endif |
| 2122 | 2442 | ||
| 2443 | static void mv_udc_shutdown(struct platform_device *dev) | ||
| 2444 | { | ||
| 2445 | struct mv_udc *udc = the_controller; | ||
| 2446 | u32 mode; | ||
| 2447 | |||
| 2448 | /* reset controller mode to IDLE */ | ||
| 2449 | mode = readl(&udc->op_regs->usbmode); | ||
| 2450 | mode &= ~3; | ||
| 2451 | writel(mode, &udc->op_regs->usbmode); | ||
| 2452 | } | ||
| 2453 | |||
| 2123 | static struct platform_driver udc_driver = { | 2454 | static struct platform_driver udc_driver = { |
| 2124 | .probe = mv_udc_probe, | 2455 | .probe = mv_udc_probe, |
| 2125 | .remove = __exit_p(mv_udc_remove), | 2456 | .remove = __exit_p(mv_udc_remove), |
| 2457 | .shutdown = mv_udc_shutdown, | ||
| 2126 | .driver = { | 2458 | .driver = { |
| 2127 | .owner = THIS_MODULE, | 2459 | .owner = THIS_MODULE, |
| 2128 | .name = "pxa-u2o", | 2460 | .name = "pxa-u2o", |
| @@ -1,214 +0,0 @@ | |||
| 1 | #include <linux/delay.h> | ||
| 2 | #include <linux/timer.h> | ||
| 3 | #include <linux/io.h> | ||
| 4 | #include <linux/errno.h> | ||
| 5 | |||
| 6 | #include <mach/cputype.h> | ||
| 7 | |||
| 8 | #ifdef CONFIG_ARCH_MMP | ||
| 9 | |||
| 10 | #define UTMI_REVISION 0x0 | ||
| 11 | #define UTMI_CTRL 0x4 | ||
| 12 | #define UTMI_PLL 0x8 | ||
| 13 | #define UTMI_TX 0xc | ||
| 14 | #define UTMI_RX 0x10 | ||
| 15 | #define UTMI_IVREF 0x14 | ||
| 16 | #define UTMI_T0 0x18 | ||
| 17 | #define UTMI_T1 0x1c | ||
| 18 | #define UTMI_T2 0x20 | ||
| 19 | #define UTMI_T3 0x24 | ||
| 20 | #define UTMI_T4 0x28 | ||
| 21 | #define UTMI_T5 0x2c | ||
| 22 | #define UTMI_RESERVE 0x30 | ||
| 23 | #define UTMI_USB_INT 0x34 | ||
| 24 | #define UTMI_DBG_CTL 0x38 | ||
| 25 | #define UTMI_OTG_ADDON 0x3c | ||
| 26 | |||
| 27 | /* For UTMICTRL Register */ | ||
| 28 | #define UTMI_CTRL_USB_CLK_EN (1 << 31) | ||
| 29 | /* pxa168 */ | ||
| 30 | #define UTMI_CTRL_SUSPEND_SET1 (1 << 30) | ||
| 31 | #define UTMI_CTRL_SUSPEND_SET2 (1 << 29) | ||
| 32 | #define UTMI_CTRL_RXBUF_PDWN (1 << 24) | ||
| 33 | #define UTMI_CTRL_TXBUF_PDWN (1 << 11) | ||
| 34 | |||
| 35 | #define UTMI_CTRL_INPKT_DELAY_SHIFT 30 | ||
| 36 | #define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT 28 | ||
| 37 | #define UTMI_CTRL_PU_REF_SHIFT 20 | ||
| 38 | #define UTMI_CTRL_ARC_PULLDN_SHIFT 12 | ||
| 39 | #define UTMI_CTRL_PLL_PWR_UP_SHIFT 1 | ||
| 40 | #define UTMI_CTRL_PWR_UP_SHIFT 0 | ||
| 41 | /* For UTMI_PLL Register */ | ||
| 42 | #define UTMI_PLL_CLK_BLK_EN_SHIFT 24 | ||
| 43 | #define UTMI_PLL_FBDIV_SHIFT 4 | ||
| 44 | #define UTMI_PLL_REFDIV_SHIFT 0 | ||
| 45 | #define UTMI_PLL_FBDIV_MASK 0x00000FF0 | ||
| 46 | #define UTMI_PLL_REFDIV_MASK 0x0000000F | ||
| 47 | #define UTMI_PLL_ICP_MASK 0x00007000 | ||
| 48 | #define UTMI_PLL_KVCO_MASK 0x00031000 | ||
| 49 | #define UTMI_PLL_PLLCALI12_SHIFT 29 | ||
| 50 | #define UTMI_PLL_PLLCALI12_MASK (0x3 << 29) | ||
| 51 | #define UTMI_PLL_PLLVDD18_SHIFT 27 | ||
| 52 | #define UTMI_PLL_PLLVDD18_MASK (0x3 << 27) | ||
| 53 | #define UTMI_PLL_PLLVDD12_SHIFT 25 | ||
| 54 | #define UTMI_PLL_PLLVDD12_MASK (0x3 << 25) | ||
| 55 | #define UTMI_PLL_KVCO_SHIFT 15 | ||
| 56 | #define UTMI_PLL_ICP_SHIFT 12 | ||
| 57 | /* For UTMI_TX Register */ | ||
| 58 | #define UTMI_TX_REG_EXT_FS_RCAL_SHIFT 27 | ||
| 59 | #define UTMI_TX_REG_EXT_FS_RCAL_MASK (0xf << 27) | ||
| 60 | #define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK 26 | ||
| 61 | #define UTMI_TX_REG_EXT_FS_RCAL_EN (0x1 << 26) | ||
| 62 | #define UTMI_TX_LOW_VDD_EN_SHIFT 11 | ||
| 63 | #define UTMI_TX_IMPCAL_VTH_SHIFT 14 | ||
| 64 | #define UTMI_TX_IMPCAL_VTH_MASK (0x7 << 14) | ||
| 65 | #define UTMI_TX_CK60_PHSEL_SHIFT 17 | ||
| 66 | #define UTMI_TX_CK60_PHSEL_MASK (0xf << 17) | ||
| 67 | #define UTMI_TX_TXVDD12_SHIFT 22 | ||
| 68 | #define UTMI_TX_TXVDD12_MASK (0x3 << 22) | ||
| 69 | #define UTMI_TX_AMP_SHIFT 0 | ||
| 70 | #define UTMI_TX_AMP_MASK (0x7 << 0) | ||
| 71 | /* For UTMI_RX Register */ | ||
| 72 | #define UTMI_RX_SQ_THRESH_SHIFT 4 | ||
| 73 | #define UTMI_RX_SQ_THRESH_MASK (0xf << 4) | ||
| 74 | #define UTMI_REG_SQ_LENGTH_SHIFT 15 | ||
| 75 | #define UTMI_REG_SQ_LENGTH_MASK (0x3 << 15) | ||
| 76 | |||
| 77 | #define REG_RCAL_START 0x00001000 | ||
| 78 | #define VCOCAL_START 0x00200000 | ||
| 79 | #define KVCO_EXT 0x00400000 | ||
| 80 | #define PLL_READY 0x00800000 | ||
| 81 | #define CLK_BLK_EN 0x01000000 | ||
| 82 | #endif | ||
| 83 | |||
| 84 | static unsigned int u2o_read(unsigned int base, unsigned int offset) | ||
| 85 | { | ||
| 86 | return readl(base + offset); | ||
| 87 | } | ||
| 88 | |||
| 89 | static void u2o_set(unsigned int base, unsigned int offset, unsigned int value) | ||
| 90 | { | ||
| 91 | unsigned int reg; | ||
| 92 | |||
| 93 | reg = readl(base + offset); | ||
| 94 | reg |= value; | ||
| 95 | writel(reg, base + offset); | ||
| 96 | readl(base + offset); | ||
| 97 | } | ||
| 98 | |||
| 99 | static void u2o_clear(unsigned int base, unsigned int offset, | ||
| 100 | unsigned int value) | ||
| 101 | { | ||
| 102 | unsigned int reg; | ||
| 103 | |||
| 104 | reg = readl(base + offset); | ||
| 105 | reg &= ~value; | ||
| 106 | writel(reg, base + offset); | ||
| 107 | readl(base + offset); | ||
| 108 | } | ||
| 109 | |||
| 110 | static void u2o_write(unsigned int base, unsigned int offset, | ||
| 111 | unsigned int value) | ||
| 112 | { | ||
| 113 | writel(value, base + offset); | ||
| 114 | readl(base + offset); | ||
| 115 | } | ||
| 116 | |||
| 117 | #ifdef CONFIG_ARCH_MMP | ||
| 118 | int mv_udc_phy_init(unsigned int base) | ||
| 119 | { | ||
| 120 | unsigned long timeout; | ||
| 121 | |||
| 122 | /* Initialize the USB PHY power */ | ||
| 123 | if (cpu_is_pxa910()) { | ||
| 124 | u2o_set(base, UTMI_CTRL, (1 << UTMI_CTRL_INPKT_DELAY_SOF_SHIFT) | ||
| 125 | | (1 << UTMI_CTRL_PU_REF_SHIFT)); | ||
| 126 | } | ||
| 127 | |||
| 128 | u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PLL_PWR_UP_SHIFT); | ||
| 129 | u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PWR_UP_SHIFT); | ||
| 130 | |||
| 131 | /* UTMI_PLL settings */ | ||
| 132 | u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK | ||
| 133 | | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK | ||
| 134 | | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK | ||
| 135 | | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK); | ||
| 136 | |||
| 137 | u2o_set(base, UTMI_PLL, (0xee << UTMI_PLL_FBDIV_SHIFT) | ||
| 138 | | (0xb << UTMI_PLL_REFDIV_SHIFT) | ||
| 139 | | (3 << UTMI_PLL_PLLVDD18_SHIFT) | ||
| 140 | | (3 << UTMI_PLL_PLLVDD12_SHIFT) | ||
| 141 | | (3 << UTMI_PLL_PLLCALI12_SHIFT) | ||
| 142 | | (1 << UTMI_PLL_ICP_SHIFT) | (3 << UTMI_PLL_KVCO_SHIFT)); | ||
| 143 | |||
| 144 | /* UTMI_TX */ | ||
| 145 | u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK | ||
| 146 | | UTMI_TX_TXVDD12_MASK | ||
| 147 | | UTMI_TX_CK60_PHSEL_MASK | UTMI_TX_IMPCAL_VTH_MASK | ||
| 148 | | UTMI_TX_REG_EXT_FS_RCAL_MASK | UTMI_TX_AMP_MASK); | ||
| 149 | u2o_set(base, UTMI_TX, (3 << UTMI_TX_TXVDD12_SHIFT) | ||
| 150 | | (4 << UTMI_TX_CK60_PHSEL_SHIFT) | ||
| 151 | | (4 << UTMI_TX_IMPCAL_VTH_SHIFT) | ||
| 152 | | (8 << UTMI_TX_REG_EXT_FS_RCAL_SHIFT) | ||
| 153 | | (3 << UTMI_TX_AMP_SHIFT)); | ||
| 154 | |||
| 155 | /* UTMI_RX */ | ||
| 156 | u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK | ||
| 157 | | UTMI_REG_SQ_LENGTH_MASK); | ||
| 158 | if (cpu_is_pxa168()) | ||
| 159 | u2o_set(base, UTMI_RX, (7 << UTMI_RX_SQ_THRESH_SHIFT) | ||
| 160 | | (2 << UTMI_REG_SQ_LENGTH_SHIFT)); | ||
| 161 | else | ||
| 162 | u2o_set(base, UTMI_RX, (0x7 << UTMI_RX_SQ_THRESH_SHIFT) | ||
| 163 | | (2 << UTMI_REG_SQ_LENGTH_SHIFT)); | ||
| 164 | |||
| 165 | /* UTMI_IVREF */ | ||
| 166 | if (cpu_is_pxa168()) | ||
| 167 | /* | ||
| 168 | * fixing Microsoft Altair board interface with NEC hub issue - | ||
| 169 | * Set UTMI_IVREF from 0x4a3 to 0x4bf | ||
| 170 | */ | ||
| 171 | u2o_write(base, UTMI_IVREF, 0x4bf); | ||
| 172 | |||
| 173 | /* calibrate */ | ||
| 174 | timeout = jiffies + 100; | ||
| 175 | while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) { | ||
| 176 | if (time_after(jiffies, timeout)) | ||
| 177 | return -ETIME; | ||
| 178 | cpu_relax(); | ||
| 179 | } | ||
| 180 | |||
| 181 | /* toggle VCOCAL_START bit of UTMI_PLL */ | ||
| 182 | udelay(200); | ||
| 183 | u2o_set(base, UTMI_PLL, VCOCAL_START); | ||
| 184 | udelay(40); | ||
| 185 | u2o_clear(base, UTMI_PLL, VCOCAL_START); | ||
| 186 | |||
| 187 | /* toggle REG_RCAL_START bit of UTMI_TX */ | ||
| 188 | udelay(200); | ||
| 189 | u2o_set(base, UTMI_TX, REG_RCAL_START); | ||
| 190 | udelay(40); | ||
| 191 | u2o_clear(base, UTMI_TX, REG_RCAL_START); | ||
| 192 | udelay(200); | ||
| 193 | |||
| 194 | /* make sure phy is ready */ | ||
| 195 | timeout = jiffies + 100; | ||
| 196 | while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) { | ||
| 197 | if (time_after(jiffies, timeout)) | ||
| 198 | return -ETIME; | ||
| 199 | cpu_relax(); | ||
| 200 | } | ||
| 201 | |||
| 202 | if (cpu_is_pxa168()) { | ||
| 203 | u2o_set(base, UTMI_RESERVE, 1 << 5); | ||
| 204 | /* Turn on UTMI PHY OTG extension */ | ||
| 205 | u2o_write(base, UTMI_OTG_ADDON, 1); | ||
| 206 | } | ||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | #else | ||
| 210 | int mv_udc_phy_init(unsigned int base) | ||
| 211 | { | ||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | #endif | ||
| @@ -14,15 +14,6 @@ · 13 unmodified lines | |||
| 14 | * it under the terms of the GNU General Public License as published by | 14 | * it under the terms of the GNU General Public License as published by |
| 15 | * the Free Software Foundation; either version 2 of the License, or | 15 | * the Free Software Foundation; either version 2 of the License, or |
| 16 | * (at your option) any later version. | 16 | * (at your option) any later version. |
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program; if not, write to the Free Software | ||
| 25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 26 | */ | 17 | */ |
| 27 | 18 | ||
| 28 | /* #define DEBUG */ | 19 | /* #define DEBUG */ |
| @@ -10,12 +10,6 @@ · 9 unmodified lines | |||
| 10 | * | 10 | * |
| 11 | * This source code is offered for use in the public domain. You may | 11 | * This source code is offered for use in the public domain. You may |
| 12 | * use, modify or distribute it freely. | 12 | * use, modify or distribute it freely. |
| 13 | * | ||
| 14 | * This code is distributed in the hope that it will be useful but | ||
| 15 | * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY | ||
| 16 | * DISCLAIMED. This includes but is not limited to warranties of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 18 | * | ||
| 19 | */ | 13 | */ |
| 20 | 14 | ||
| 21 | #ifndef _LINUX_NDIS_H | 15 | #ifndef _LINUX_NDIS_H |
| @@ -204,7 +204,7 @@ net2272_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) · 203 unmodified lines | |||
| 204 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | 204 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) |
| 205 | return -ESHUTDOWN; | 205 | return -ESHUTDOWN; |
| 206 | 206 | ||
| 207 | max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff; | 207 | max = usb_endpoint_maxp(desc) & 0x1fff; |
| 208 | 208 | ||
| 209 | spin_lock_irqsave(&dev->lock, flags); | 209 | spin_lock_irqsave(&dev->lock, flags); |
| 210 | _ep->maxpacket = max & 0x7fff; | 210 | _ep->maxpacket = max & 0x7fff; |
| @@ -1172,17 +1172,18 @@ net2272_pullup(struct usb_gadget *_gadget, int is_on) · 961 unmodified lines | |||
| 1172 | return 0; | 1172 | return 0; |
| 1173 | } | 1173 | } |
| 1174 | 1174 | ||
| 1175 | static int net2272_start(struct usb_gadget_driver *driver, | 1175 | static int net2272_start(struct usb_gadget *_gadget, |
| 1176 | int (*bind)(struct usb_gadget *)); | 1176 | struct usb_gadget_driver *driver); |
| 1177 | static int net2272_stop(struct usb_gadget_driver *driver); | 1177 | static int net2272_stop(struct usb_gadget *_gadget, |
| 1178 | struct usb_gadget_driver *driver); | ||
| 1178 | 1179 | ||
| 1179 | static const struct usb_gadget_ops net2272_ops = { | 1180 | static const struct usb_gadget_ops net2272_ops = { |
| 1180 | .get_frame = net2272_get_frame, | 1181 | .get_frame = net2272_get_frame, |
| 1181 | .wakeup = net2272_wakeup, | 1182 | .wakeup = net2272_wakeup, |
| 1182 | .set_selfpowered = net2272_set_selfpowered, | 1183 | .set_selfpowered = net2272_set_selfpowered, |
| 1183 | .pullup = net2272_pullup, | 1184 | .pullup = net2272_pullup, |
| 1184 | .start = net2272_start, | 1185 | .udc_start = net2272_start, |
| 1185 | .stop = net2272_stop, | 1186 | .udc_stop = net2272_stop, |
| 1186 | }; | 1187 | }; |
| 1187 | 1188 | ||
| 1188 | /*---------------------------------------------------------------------------*/ | 1189 | /*---------------------------------------------------------------------------*/ |
| @@ -1356,8 +1357,6 @@ net2272_set_fifo_mode(struct net2272 *dev, int mode) · 167 unmodified lines | |||
| 1356 | 1357 | ||
| 1357 | /*---------------------------------------------------------------------------*/ | 1358 | /*---------------------------------------------------------------------------*/ |
| 1358 | 1359 | ||
| 1359 | static struct net2272 *the_controller; | ||
| 1360 | |||
| 1361 | static void | 1360 | static void |
| 1362 | net2272_usb_reset(struct net2272 *dev) | 1361 | net2272_usb_reset(struct net2272 *dev) |
| 1363 | { | 1362 | { |
| @@ -1453,20 +1452,17 @@ net2272_ep0_start(struct net2272 *dev) · 89 unmodified lines | |||
| 1453 | * disconnect is reported. then a host may connect again, or | 1452 | * disconnect is reported. then a host may connect again, or |
| 1454 | * the driver might get unbound. | 1453 | * the driver might get unbound. |
| 1455 | */ | 1454 | */ |
| 1456 | static int net2272_start(struct usb_gadget_driver *driver, | 1455 | static int net2272_start(struct usb_gadget *_gadget, |
| 1457 | int (*bind)(struct usb_gadget *)) | 1456 | struct usb_gadget_driver *driver) |
| 1458 | { | 1457 | { |
| 1459 | struct net2272 *dev = the_controller; | 1458 | struct net2272 *dev; |
| 1460 | int ret; | ||
| 1461 | unsigned i; | 1459 | unsigned i; |
| 1462 | 1460 | ||
| 1463 | if (!driver || !bind || !driver->unbind || !driver->setup || | 1461 | if (!driver || !driver->unbind || !driver->setup || |
| 1464 | driver->speed != USB_SPEED_HIGH) | 1462 | driver->speed != USB_SPEED_HIGH) |
| 1465 | return -EINVAL; | 1463 | return -EINVAL; |
| 1466 | if (!dev) | 1464 | |
| 1467 | return -ENODEV; | 1465 | dev = container_of(_gadget, struct net2272, gadget); |
| 1468 | if (dev->driver) | ||
| 1469 | return -EBUSY; | ||
| 1470 | 1466 | ||
| 1471 | for (i = 0; i < 4; ++i) | 1467 | for (i = 0; i < 4; ++i) |
| 1472 | dev->ep[i].irqs = 0; | 1468 | dev->ep[i].irqs = 0; |
| @@ -1475,14 +1471,6 @@ static int net2272_start(struct usb_gadget_driver *driver, · 2 unmodified lines | |||
| 1475 | driver->driver.bus = NULL; | 1471 | driver->driver.bus = NULL; |
| 1476 | dev->driver = driver; | 1472 | dev->driver = driver; |
| 1477 | dev->gadget.dev.driver = &driver->driver; | 1473 | dev->gadget.dev.driver = &driver->driver; |
| 1478 | ret = bind(&dev->gadget); | ||
| 1479 | if (ret) { | ||
| 1480 | dev_dbg(dev->dev, "bind to driver %s --> %d\n", | ||
| 1481 | driver->driver.name, ret); | ||
| 1482 | dev->driver = NULL; | ||
| 1483 | dev->gadget.dev.driver = NULL; | ||
| 1484 | return ret; | ||
| 1485 | } | ||
| 1486 | 1474 | ||
| 1487 | /* ... then enable host detection and ep0; and we're ready | 1475 | /* ... then enable host detection and ep0; and we're ready |
| 1488 | * for set_configuration as well as eventual disconnect. | 1476 | * for set_configuration as well as eventual disconnect. |
| @@ -1510,33 +1498,21 @@ stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver) · 21 unmodified lines | |||
| 1510 | for (i = 0; i < 4; ++i) | 1498 | for (i = 0; i < 4; ++i) |
| 1511 | net2272_dequeue_all(&dev->ep[i]); | 1499 | net2272_dequeue_all(&dev->ep[i]); |
| 1512 | 1500 | ||
| 1513 | /* report disconnect; the driver is already quiesced */ | ||
| 1514 | if (driver) { | ||
| 1515 | spin_unlock(&dev->lock); | ||
| 1516 | driver->disconnect(&dev->gadget); | ||
| 1517 | spin_lock(&dev->lock); | ||
| 1518 | |||
| 1519 | } | ||
| 1520 | net2272_usb_reinit(dev); | 1501 | net2272_usb_reinit(dev); |
| 1521 | } | 1502 | } |
| 1522 | 1503 | ||
| 1523 | static int net2272_stop(struct usb_gadget_driver *driver) | 1504 | static int net2272_stop(struct usb_gadget *_gadget, |
| 1505 | struct usb_gadget_driver *driver) | ||
| 1524 | { | 1506 | { |
| 1525 | struct net2272 *dev = the_controller; | 1507 | struct net2272 *dev; |
| 1526 | unsigned long flags; | 1508 | unsigned long flags; |
| 1527 | 1509 | ||
| 1528 | if (!dev) | 1510 | dev = container_of(_gadget, struct net2272, gadget); |
| 1529 | return -ENODEV; | ||
| 1530 | if (!driver || driver != dev->driver) | ||
| 1531 | return -EINVAL; | ||
| 1532 | 1511 | ||
| 1533 | spin_lock_irqsave(&dev->lock, flags); | 1512 | spin_lock_irqsave(&dev->lock, flags); |
| 1534 | stop_activity(dev, driver); | 1513 | stop_activity(dev, driver); |
| 1535 | spin_unlock_irqrestore(&dev->lock, flags); | 1514 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1536 | 1515 | ||
| 1537 | net2272_pullup(&dev->gadget, 0); | ||
| 1538 | |||
| 1539 | driver->unbind(&dev->gadget); | ||
| 1540 | dev->gadget.dev.driver = NULL; | 1516 | dev->gadget.dev.driver = NULL; |
| 1541 | dev->driver = NULL; | 1517 | dev->driver = NULL; |
| 1542 | 1518 | ||
| @@ -1764,8 +1740,8 @@ net2272_handle_stat0_irqs(struct net2272 *dev, u8 stat) · 221 unmodified lines | |||
| 1764 | dev->gadget.speed = USB_SPEED_HIGH; | 1740 | dev->gadget.speed = USB_SPEED_HIGH; |
| 1765 | else | 1741 | else |
| 1766 | dev->gadget.speed = USB_SPEED_FULL; | 1742 | dev->gadget.speed = USB_SPEED_FULL; |
| 1767 | dev_dbg(dev->dev, "%s speed\n", | 1743 | dev_dbg(dev->dev, "%s\n", |
| 1768 | (dev->gadget.speed == USB_SPEED_HIGH) ? "high" : "full"); | 1744 | usb_speed_string(dev->gadget.speed)); |
| 1769 | } | 1745 | } |
| 1770 | 1746 | ||
| 1771 | ep = &dev->ep[0]; | 1747 | ep = &dev->ep[0]; |
| @@ -2238,7 +2214,6 @@ net2272_remove(struct net2272 *dev) · 466 unmodified lines | |||
| 2238 | device_remove_file(dev->dev, &dev_attr_registers); | 2214 | device_remove_file(dev->dev, &dev_attr_registers); |
| 2239 | 2215 | ||
| 2240 | dev_info(dev->dev, "unbind\n"); | 2216 | dev_info(dev->dev, "unbind\n"); |
| 2241 | the_controller = NULL; | ||
| 2242 | } | 2217 | } |
| 2243 | 2218 | ||
| 2244 | static struct net2272 * __devinit | 2219 | static struct net2272 * __devinit |
| @@ -2246,11 +2221,6 @@ net2272_probe_init(struct device *dev, unsigned int irq) · 1 unmodified line | |||
| 2246 | { | 2221 | { |
| 2247 | struct net2272 *ret; | 2222 | struct net2272 *ret; |
| 2248 | 2223 | ||
| 2249 | if (the_controller) { | ||
| 2250 | dev_warn(dev, "ignoring\n"); | ||
| 2251 | return ERR_PTR(-EBUSY); | ||
| 2252 | } | ||
| 2253 | |||
| 2254 | if (!irq) { | 2224 | if (!irq) { |
| 2255 | dev_dbg(dev, "No IRQ!\n"); | 2225 | dev_dbg(dev, "No IRQ!\n"); |
| 2256 | return ERR_PTR(-ENODEV); | 2226 | return ERR_PTR(-ENODEV); |
| @@ -2307,8 +2277,6 @@ net2272_probe_fin(struct net2272 *dev, unsigned int irqflags) · 50 unmodified lines | |||
| 2307 | dma_mode_string()); | 2277 | dma_mode_string()); |
| 2308 | dev_info(dev->dev, "version: %s\n", driver_vers); | 2278 | dev_info(dev->dev, "version: %s\n", driver_vers); |
| 2309 | 2279 | ||
| 2310 | the_controller = dev; | ||
| 2311 | |||
| 2312 | ret = device_register(&dev->gadget.dev); | 2280 | ret = device_register(&dev->gadget.dev); |
| 2313 | if (ret) | 2281 | if (ret) |
| 2314 | goto err_irq; | 2282 | goto err_irq; |
| @@ -2684,8 +2652,6 @@ net2272_plat_probe(struct platform_device *pdev) · 369 unmodified lines | |||
| 2684 | dev_info(&pdev->dev, "running in 16-bit, %sbyte swap local bus mode\n", | 2652 | dev_info(&pdev->dev, "running in 16-bit, %sbyte swap local bus mode\n", |
| 2685 | (net2272_read(dev, LOCCTL) & (1 << BYTE_SWAP)) ? "" : "no "); | 2653 | (net2272_read(dev, LOCCTL) & (1 << BYTE_SWAP)) ? "" : "no "); |
| 2686 | 2654 | ||
| 2687 | the_controller = dev; | ||
| 2688 | |||
| 2689 | return 0; | 2655 | return 0; |
| 2690 | 2656 | ||
| 2691 | err_io: | 2657 | err_io: |
| @@ -33,15 +33,6 @@ · 32 unmodified lines | |||
| 33 | * it under the terms of the GNU General Public License as published by | 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 | 34 | * the Free Software Foundation; either version 2 of the License, or |
| 35 | * (at your option) any later version. | 35 | * (at your option) any later version. |
| 36 | * | ||
| 37 | * This program is distributed in the hope that it will be useful, | ||
| 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 40 | * GNU General Public License for more details. | ||
| 41 | * | ||
| 42 | * You should have received a copy of the GNU General Public License | ||
| 43 | * along with this program; if not, write to the Free Software | ||
| 44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 45 | */ | 36 | */ |
| 46 | 37 | ||
| 47 | #undef DEBUG /* messages on error and most fault paths */ | 38 | #undef DEBUG /* messages on error and most fault paths */ |
| @@ -169,7 +160,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) · 121 unmodified lines | |||
| 169 | return -EDOM; | 160 | return -EDOM; |
| 170 | 161 | ||
| 171 | /* sanity check ep-e/ep-f since their fifos are small */ | 162 | /* sanity check ep-e/ep-f since their fifos are small */ |
| 172 | max = le16_to_cpu (desc->wMaxPacketSize) & 0x1fff; | 163 | max = usb_endpoint_maxp (desc) & 0x1fff; |
| 173 | if (ep->num > 4 && max > 64) | 164 | if (ep->num > 4 && max > 64) |
| 174 | return -ERANGE; | 165 | return -ERANGE; |
| 175 | 166 | ||
| @@ -1410,17 +1401,18 @@ static int net2280_pullup(struct usb_gadget *_gadget, int is_on) · 1234 unmodified lines | |||
| 1410 | return 0; | 1401 | return 0; |
| 1411 | } | 1402 | } |
| 1412 | 1403 | ||
| 1413 | static int net2280_start(struct usb_gadget_driver *driver, | 1404 | static int net2280_start(struct usb_gadget *_gadget, |
| 1414 | int (*bind)(struct usb_gadget *)); | 1405 | struct usb_gadget_driver *driver); |
| 1415 | static int net2280_stop(struct usb_gadget_driver *driver); | 1406 | static int net2280_stop(struct usb_gadget *_gadget, |
| 1407 | struct usb_gadget_driver *driver); | ||
| 1416 | 1408 | ||
| 1417 | static const struct usb_gadget_ops net2280_ops = { | 1409 | static const struct usb_gadget_ops net2280_ops = { |
| 1418 | .get_frame = net2280_get_frame, | 1410 | .get_frame = net2280_get_frame, |
| 1419 | .wakeup = net2280_wakeup, | 1411 | .wakeup = net2280_wakeup, |
| 1420 | .set_selfpowered = net2280_set_selfpowered, | 1412 | .set_selfpowered = net2280_set_selfpowered, |
| 1421 | .pullup = net2280_pullup, | 1413 | .pullup = net2280_pullup, |
| 1422 | .start = net2280_start, | 1414 | .udc_start = net2280_start, |
| 1423 | .stop = net2280_stop, | 1415 | .udc_stop = net2280_stop, |
| 1424 | }; | 1416 | }; |
| 1425 | 1417 | ||
| 1426 | /*-------------------------------------------------------------------------*/ | 1418 | /*-------------------------------------------------------------------------*/ |
| @@ -1640,7 +1632,7 @@ show_queues (struct device *_dev, struct device_attribute *attr, char *buf) · 213 unmodified lines | |||
| 1640 | default: | 1632 | default: |
| 1641 | val = "iso"; break; | 1633 | val = "iso"; break; |
| 1642 | }; val; }), | 1634 | }; val; }), |
| 1643 | le16_to_cpu (d->wMaxPacketSize) & 0x1fff, | 1635 | usb_endpoint_maxp (d) & 0x1fff, |
| 1644 | ep->dma ? "dma" : "pio", ep->fifo_size | 1636 | ep->dma ? "dma" : "pio", ep->fifo_size |
| 1645 | ); | 1637 | ); |
| 1646 | } else /* ep0 should only have one transfer queued */ | 1638 | } else /* ep0 should only have one transfer queued */ |
| @@ -1753,8 +1745,6 @@ static void set_fifo_mode (struct net2280 *dev, int mode) · 106 unmodified lines | |||
| 1753 | * perhaps to bind specific drivers to specific devices. | 1745 | * perhaps to bind specific drivers to specific devices. |
| 1754 | */ | 1746 | */ |
| 1755 | 1747 | ||
| 1756 | static struct net2280 *the_controller; | ||
| 1757 | |||
| 1758 | static void usb_reset (struct net2280 *dev) | 1748 | static void usb_reset (struct net2280 *dev) |
| 1759 | { | 1749 | { |
| 1760 | u32 tmp; | 1750 | u32 tmp; |
| @@ -1880,10 +1870,10 @@ static void ep0_start (struct net2280 *dev) · 119 unmodified lines | |||
| 1880 | * disconnect is reported. then a host may connect again, or | 1870 | * disconnect is reported. then a host may connect again, or |
| 1881 | * the driver might get unbound. | 1871 | * the driver might get unbound. |
| 1882 | */ | 1872 | */ |
| 1883 | static int net2280_start(struct usb_gadget_driver *driver, | 1873 | static int net2280_start(struct usb_gadget *_gadget, |
| 1884 | int (*bind)(struct usb_gadget *)) | 1874 | struct usb_gadget_driver *driver) |
| 1885 | { | 1875 | { |
| 1886 | struct net2280 *dev = the_controller; | 1876 | struct net2280 *dev; |
| 1887 | int retval; | 1877 | int retval; |
| 1888 | unsigned i; | 1878 | unsigned i; |
| 1889 | 1879 | ||
| @@ -1891,14 +1881,11 @@ static int net2280_start(struct usb_gadget_driver *driver, · 1 unmodified line | |||
| 1891 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) | 1881 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) |
| 1892 | * "must not be used in normal operation" | 1882 | * "must not be used in normal operation" |
| 1893 | */ | 1883 | */ |
| 1894 | if (!driver | 1884 | if (!driver || driver->speed != USB_SPEED_HIGH |
| 1895 | || driver->speed != USB_SPEED_HIGH | 1885 | || !driver->setup) |
| 1896 | || !bind || !driver->setup) | ||
| 1897 | return -EINVAL; | 1886 | return -EINVAL; |
| 1898 | if (!dev) | 1887 | |
| 1899 | return -ENODEV; | 1888 | dev = container_of (_gadget, struct net2280, gadget); |
| 1900 | if (dev->driver) | ||
| 1901 | return -EBUSY; | ||
| 1902 | 1889 | ||
| 1903 | for (i = 0; i < 7; i++) | 1890 | for (i = 0; i < 7; i++) |
| 1904 | dev->ep [i].irqs = 0; | 1891 | dev->ep [i].irqs = 0; |
| @@ -1908,14 +1895,6 @@ static int net2280_start(struct usb_gadget_driver *driver, · 3 unmodified lines | |||
| 1908 | driver->driver.bus = NULL; | 1895 | driver->driver.bus = NULL; |
| 1909 | dev->driver = driver; | 1896 | dev->driver = driver; |
| 1910 | dev->gadget.dev.driver = &driver->driver; | 1897 | dev->gadget.dev.driver = &driver->driver; |
| 1911 | retval = bind(&dev->gadget); | ||
| 1912 | if (retval) { | ||
| 1913 | DEBUG (dev, "bind to driver %s --> %d\n", | ||
| 1914 | driver->driver.name, retval); | ||
| 1915 | dev->driver = NULL; | ||
| 1916 | dev->gadget.dev.driver = NULL; | ||
| 1917 | return retval; | ||
| 1918 | } | ||
| 1919 | 1898 | ||
| 1920 | retval = device_create_file (&dev->pdev->dev, &dev_attr_function); | 1899 | retval = device_create_file (&dev->pdev->dev, &dev_attr_function); |
| 1921 | if (retval) goto err_unbind; | 1900 | if (retval) goto err_unbind; |
| @@ -1961,33 +1940,21 @@ stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver) · 39 unmodified lines | |||
| 1961 | for (i = 0; i < 7; i++) | 1940 | for (i = 0; i < 7; i++) |
| 1962 | nuke (&dev->ep [i]); | 1941 | nuke (&dev->ep [i]); |
| 1963 | 1942 | ||
| 1964 | /* report disconnect; the driver is already quiesced */ | ||
| 1965 | if (driver) { | ||
| 1966 | spin_unlock (&dev->lock); | ||
| 1967 | driver->disconnect (&dev->gadget); | ||
| 1968 | spin_lock (&dev->lock); | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | usb_reinit (dev); | 1943 | usb_reinit (dev); |
| 1972 | } | 1944 | } |
| 1973 | 1945 | ||
| 1974 | static int net2280_stop(struct usb_gadget_driver *driver) | 1946 | static int net2280_stop(struct usb_gadget *_gadget, |
| 1947 | struct usb_gadget_driver *driver) | ||
| 1975 | { | 1948 | { |
| 1976 | struct net2280 *dev = the_controller; | 1949 | struct net2280 *dev; |
| 1977 | unsigned long flags; | 1950 | unsigned long flags; |
| 1978 | 1951 | ||
| 1979 | if (!dev) | 1952 | dev = container_of (_gadget, struct net2280, gadget); |
| 1980 | return -ENODEV; | ||
| 1981 | if (!driver || driver != dev->driver || !driver->unbind) | ||
| 1982 | return -EINVAL; | ||
| 1983 | 1953 | ||
| 1984 | spin_lock_irqsave (&dev->lock, flags); | 1954 | spin_lock_irqsave (&dev->lock, flags); |
| 1985 | stop_activity (dev, driver); | 1955 | stop_activity (dev, driver); |
| 1986 | spin_unlock_irqrestore (&dev->lock, flags); | 1956 | spin_unlock_irqrestore (&dev->lock, flags); |
| 1987 | 1957 | ||
| 1988 | net2280_pullup (&dev->gadget, 0); | ||
| 1989 | |||
| 1990 | driver->unbind (&dev->gadget); | ||
| 1991 | dev->gadget.dev.driver = NULL; | 1958 | dev->gadget.dev.driver = NULL; |
| 1992 | dev->driver = NULL; | 1959 | dev->driver = NULL; |
| 1993 | 1960 | ||
| @@ -2266,9 +2233,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) · 272 unmodified lines | |||
| 2266 | else | 2233 | else |
| 2267 | dev->gadget.speed = USB_SPEED_FULL; | 2234 | dev->gadget.speed = USB_SPEED_FULL; |
| 2268 | net2280_led_speed (dev, dev->gadget.speed); | 2235 | net2280_led_speed (dev, dev->gadget.speed); |
| 2269 | DEBUG (dev, "%s speed\n", | 2236 | DEBUG(dev, "%s\n", usb_speed_string(dev->gadget.speed)); |
| 2270 | (dev->gadget.speed == USB_SPEED_HIGH) | ||
| 2271 | ? "high" : "full"); | ||
| 2272 | } | 2237 | } |
| 2273 | 2238 | ||
| 2274 | ep = &dev->ep [0]; | 2239 | ep = &dev->ep [0]; |
| @@ -2709,8 +2674,6 @@ static void net2280_remove (struct pci_dev *pdev) · 434 unmodified lines | |||
| 2709 | pci_set_drvdata (pdev, NULL); | 2674 | pci_set_drvdata (pdev, NULL); |
| 2710 | 2675 | ||
| 2711 | INFO (dev, "unbind\n"); | 2676 | INFO (dev, "unbind\n"); |
| 2712 | |||
| 2713 | the_controller = NULL; | ||
| 2714 | } | 2677 | } |
| 2715 | 2678 | ||
| 2716 | /* wrap this driver around the specified device, but | 2679 | /* wrap this driver around the specified device, but |
| @@ -2724,14 +2687,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) · 7 unmodified lines | |||
| 2724 | void __iomem *base = NULL; | 2687 | void __iomem *base = NULL; |
| 2725 | int retval, i; | 2688 | int retval, i; |
| 2726 | 2689 | ||
| 2727 | /* if you want to support more than one controller in a system, | ||
| 2728 | * usb_gadget_driver_{register,unregister}() must change. | ||
| 2729 | */ | ||
| 2730 | if (the_controller) { | ||
| 2731 | dev_warn (&pdev->dev, "ignoring\n"); | ||
| 2732 | return -EBUSY; | ||
| 2733 | } | ||
| 2734 | |||
| 2735 | /* alloc, and start init */ | 2690 | /* alloc, and start init */ |
| 2736 | dev = kzalloc (sizeof *dev, GFP_KERNEL); | 2691 | dev = kzalloc (sizeof *dev, GFP_KERNEL); |
| 2737 | if (dev == NULL){ | 2692 | if (dev == NULL){ |
| @@ -2858,8 +2813,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) · 120 unmodified lines | |||
| 2858 | use_dma | 2813 | use_dma |
| 2859 | ? (use_dma_chaining ? "chaining" : "enabled") | 2814 | ? (use_dma_chaining ? "chaining" : "enabled") |
| 2860 | : "disabled"); | 2815 | : "disabled"); |
| 2861 | the_controller = dev; | ||
| 2862 | |||
| 2863 | retval = device_register (&dev->gadget.dev); | 2816 | retval = device_register (&dev->gadget.dev); |
| 2864 | if (retval) goto done; | 2817 | if (retval) goto done; |
| 2865 | retval = device_create_file (&pdev->dev, &dev_attr_registers); | 2818 | retval = device_create_file (&pdev->dev, &dev_attr_registers); |
| @@ -11,15 +11,6 @@ · 10 unmodified lines | |||
| 11 | * it under the terms of the GNU General Public License as published by | 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 | 12 | * the Free Software Foundation; either version 2 of the License, or |
| 13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 23 | */ | 14 | */ |
| 24 | 15 | ||
| 25 | #include <linux/usb/net2280.h> | 16 | #include <linux/usb/net2280.h> |
| @@ -10,15 +10,6 @@ · 9 unmodified lines | |||
| 10 | * it under the terms of the GNU General Public License as published by | 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 | 11 | * the Free Software Foundation; either version 2 of the License, or |
| 12 | * (at your option) any later version. | 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 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | */ | 13 | */ |
| 23 | 14 | ||
| 24 | #undef DEBUG | 15 | #undef DEBUG |
| @@ -166,15 +157,14 @@ static int omap_ep_enable(struct usb_ep *_ep, · 141 unmodified lines | |||
| 166 | if (!_ep || !desc || ep->desc | 157 | if (!_ep || !desc || ep->desc |
| 167 | || desc->bDescriptorType != USB_DT_ENDPOINT | 158 | || desc->bDescriptorType != USB_DT_ENDPOINT |
| 168 | || ep->bEndpointAddress != desc->bEndpointAddress | 159 | || ep->bEndpointAddress != desc->bEndpointAddress |
| 169 | || ep->maxpacket < le16_to_cpu | 160 | || ep->maxpacket < usb_endpoint_maxp(desc)) { |
| 170 | (desc->wMaxPacketSize)) { | ||
| 171 | DBG("%s, bad ep or descriptor\n", __func__); | 161 | DBG("%s, bad ep or descriptor\n", __func__); |
| 172 | return -EINVAL; | 162 | return -EINVAL; |
| 173 | } | 163 | } |
| 174 | maxp = le16_to_cpu (desc->wMaxPacketSize); | 164 | maxp = usb_endpoint_maxp(desc); |
| 175 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK | 165 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK |
| 176 | && maxp != ep->maxpacket) | 166 | && maxp != ep->maxpacket) |
| 177 | || le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket | 167 | || usb_endpoint_maxp(desc) > ep->maxpacket |
| 178 | || !desc->wMaxPacketSize) { | 168 | || !desc->wMaxPacketSize) { |
| 179 | DBG("%s, bad %s maxpacket\n", __func__, _ep->name); | 169 | DBG("%s, bad %s maxpacket\n", __func__, _ep->name); |
| 180 | return -ERANGE; | 170 | return -ERANGE; |
| @@ -2968,7 +2958,7 @@ known: · 2787 unmodified lines | |||
| 2968 | } | 2958 | } |
| 2969 | #ifdef USE_ISO | 2959 | #ifdef USE_ISO |
| 2970 | status = request_irq(pdev->resource[3].start, omap_udc_iso_irq, | 2960 | status = request_irq(pdev->resource[3].start, omap_udc_iso_irq, |
| 2971 | IRQF_DISABLED, "omap_udc iso", udc); | 2961 | 0, "omap_udc iso", udc); |
| 2972 | if (status != 0) { | 2962 | if (status != 0) { |
| 2973 | ERR("can't get irq %d, err %d\n", | 2963 | ERR("can't get irq %d, err %d\n", |
| 2974 | (int) pdev->resource[3].start, status); | 2964 | (int) pdev->resource[3].start, status); |
| @@ -4,15 +4,6 @@ · 3 unmodified lines | |||
| 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation; version 2 of the License. | 6 | * the Free Software Foundation; version 2 of the License. |
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | */ | 7 | */ |
| 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 18 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| @@ -947,7 +938,7 @@ static void pch_udc_ep_enable(struct pch_udc_ep *ep, · 928 unmodified lines | |||
| 947 | else | 938 | else |
| 948 | buff_size = UDC_EPOUT_BUFF_SIZE; | 939 | buff_size = UDC_EPOUT_BUFF_SIZE; |
| 949 | pch_udc_ep_set_bufsz(ep, buff_size, ep->in); | 940 | pch_udc_ep_set_bufsz(ep, buff_size, ep->in); |
| 950 | pch_udc_ep_set_maxpkt(ep, le16_to_cpu(desc->wMaxPacketSize)); | 941 | pch_udc_ep_set_maxpkt(ep, usb_endpoint_maxp(desc)); |
| 951 | pch_udc_ep_set_nak(ep); | 942 | pch_udc_ep_set_nak(ep); |
| 952 | pch_udc_ep_fifo_flush(ep, ep->in); | 943 | pch_udc_ep_fifo_flush(ep, ep->in); |
| 953 | /* Configure the endpoint */ | 944 | /* Configure the endpoint */ |
| @@ -957,7 +948,7 @@ static void pch_udc_ep_enable(struct pch_udc_ep *ep, · 3 unmodified lines | |||
| 957 | (cfg->cur_cfg << UDC_CSR_NE_CFG_SHIFT) | | 948 | (cfg->cur_cfg << UDC_CSR_NE_CFG_SHIFT) | |
| 958 | (cfg->cur_intf << UDC_CSR_NE_INTF_SHIFT) | | 949 | (cfg->cur_intf << UDC_CSR_NE_INTF_SHIFT) | |
| 959 | (cfg->cur_alt << UDC_CSR_NE_ALT_SHIFT) | | 950 | (cfg->cur_alt << UDC_CSR_NE_ALT_SHIFT) | |
| 960 | le16_to_cpu(desc->wMaxPacketSize) << UDC_CSR_NE_MAX_PKT_SHIFT; | 951 | usb_endpoint_maxp(desc) << UDC_CSR_NE_MAX_PKT_SHIFT; |
| 961 | 952 | ||
| 962 | if (ep->in) | 953 | if (ep->in) |
| 963 | pch_udc_write_csr(ep->dev, val, UDC_EPIN_IDX(ep->num)); | 954 | pch_udc_write_csr(ep->dev, val, UDC_EPIN_IDX(ep->num)); |
| @@ -1466,7 +1457,7 @@ static int pch_udc_pcd_ep_enable(struct usb_ep *usbep, · 502 unmodified lines | |||
| 1466 | ep->desc = desc; | 1457 | ep->desc = desc; |
| 1467 | ep->halted = 0; | 1458 | ep->halted = 0; |
| 1468 | pch_udc_ep_enable(ep, &ep->dev->cfg_data, desc); | 1459 | pch_udc_ep_enable(ep, &ep->dev->cfg_data, desc); |
| 1469 | ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 1460 | ep->ep.maxpacket = usb_endpoint_maxp(desc); |
| 1470 | pch_udc_enable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num)); | 1461 | pch_udc_enable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num)); |
| 1471 | spin_unlock_irqrestore(&dev->lock, iflags); | 1462 | spin_unlock_irqrestore(&dev->lock, iflags); |
| 1472 | return 0; | 1463 | return 0; |
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| @@ -971,23 +962,15 @@ printer_set_config(struct printer_dev *dev, unsigned number) · 948 unmodified lines | |||
| 971 | usb_gadget_vbus_draw(dev->gadget, | 962 | usb_gadget_vbus_draw(dev->gadget, |
| 972 | dev->gadget->is_otg ? 8 : 100); | 963 | dev->gadget->is_otg ? 8 : 100); |
| 973 | } else { | 964 | } else { |
| 974 | char *speed; | ||
| 975 | unsigned power; | 965 | unsigned power; |
| 976 | 966 | ||
| 977 | power = 2 * config_desc.bMaxPower; | 967 | power = 2 * config_desc.bMaxPower; |
| 978 | usb_gadget_vbus_draw(dev->gadget, power); | 968 | usb_gadget_vbus_draw(dev->gadget, power); |
| 979 | 969 | ||
| 980 | switch (gadget->speed) { | ||
| 981 | case USB_SPEED_FULL: speed = "full"; break; | ||
| 982 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
| 983 | case USB_SPEED_HIGH: speed = "high"; break; | ||
| 984 | #endif | ||
| 985 | default: speed = "?"; break; | ||
| 986 | } | ||
| 987 | |||
| 988 | dev->config = number; | 970 | dev->config = number; |
| 989 | INFO(dev, "%s speed config #%d: %d mA, %s\n", | 971 | INFO(dev, "%s config #%d: %d mA, %s\n", |
| 990 | speed, number, power, driver_desc); | 972 | usb_speed_string(gadget->speed), |
| 973 | number, power, driver_desc); | ||
| 991 | } | 974 | } |
| 992 | return result; | 975 | return result; |
| 993 | } | 976 | } |
| @@ -1611,7 +1594,7 @@ cleanup(void) · 617 unmodified lines | |||
| 1611 | if (status) | 1594 | if (status) |
| 1612 | ERROR(dev, "usb_gadget_unregister_driver %x\n", status); | 1595 | ERROR(dev, "usb_gadget_unregister_driver %x\n", status); |
| 1613 | 1596 | ||
| 1614 | unregister_chrdev_region(g_printer_devno, 2); | 1597 | unregister_chrdev_region(g_printer_devno, 1); |
| 1615 | class_destroy(usb_gadget_class); | 1598 | class_destroy(usb_gadget_class); |
| 1616 | mutex_unlock(&usb_printer_gadget.lock_printer_io); | 1599 | mutex_unlock(&usb_printer_gadget.lock_printer_io); |
| 1617 | } | 1600 | } |
| @@ -11,16 +11,6 @@ · 10 unmodified lines | |||
| 11 | * it under the terms of the GNU General Public License as published by | 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 | 12 | * the Free Software Foundation; either version 2 of the License, or |
| 13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 23 | * | ||
| 24 | */ | 14 | */ |
| 25 | 15 | ||
| 26 | /* #define VERBOSE_DEBUG */ | 16 | /* #define VERBOSE_DEBUG */ |
| @@ -232,8 +222,7 @@ static int pxa25x_ep_enable (struct usb_ep *_ep, · 205 unmodified lines | |||
| 232 | if (!_ep || !desc || ep->desc || _ep->name == ep0name | 222 | if (!_ep || !desc || ep->desc || _ep->name == ep0name |
| 233 | || desc->bDescriptorType != USB_DT_ENDPOINT | 223 | || desc->bDescriptorType != USB_DT_ENDPOINT |
| 234 | || ep->bEndpointAddress != desc->bEndpointAddress | 224 | || ep->bEndpointAddress != desc->bEndpointAddress |
| 235 | || ep->fifo_size < le16_to_cpu | 225 | || ep->fifo_size < usb_endpoint_maxp (desc)) { |
| 236 | (desc->wMaxPacketSize)) { | ||
| 237 | DMSG("%s, bad ep or descriptor\n", __func__); | 226 | DMSG("%s, bad ep or descriptor\n", __func__); |
| 238 | return -EINVAL; | 227 | return -EINVAL; |
| 239 | } | 228 | } |
| @@ -248,7 +237,7 @@ static int pxa25x_ep_enable (struct usb_ep *_ep, · 8 unmodified lines | |||
| 248 | 237 | ||
| 249 | /* hardware _could_ do smaller, but driver doesn't */ | 238 | /* hardware _could_ do smaller, but driver doesn't */ |
| 250 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK | 239 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK |
| 251 | && le16_to_cpu (desc->wMaxPacketSize) | 240 | && usb_endpoint_maxp (desc) |
| 252 | != BULK_FIFO_SIZE) | 241 | != BULK_FIFO_SIZE) |
| 253 | || !desc->wMaxPacketSize) { | 242 | || !desc->wMaxPacketSize) { |
| 254 | DMSG("%s, bad %s maxpacket\n", __func__, _ep->name); | 243 | DMSG("%s, bad %s maxpacket\n", __func__, _ep->name); |
| @@ -264,7 +253,7 @@ static int pxa25x_ep_enable (struct usb_ep *_ep, · 9 unmodified lines | |||
| 264 | ep->desc = desc; | 253 | ep->desc = desc; |
| 265 | ep->stopped = 0; | 254 | ep->stopped = 0; |
| 266 | ep->pio_irqs = 0; | 255 | ep->pio_irqs = 0; |
| 267 | ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize); | 256 | ep->ep.maxpacket = usb_endpoint_maxp (desc); |
| 268 | 257 | ||
| 269 | /* flush fifo (mostly for OUT buffers) */ | 258 | /* flush fifo (mostly for OUT buffers) */ |
| 270 | pxa25x_ep_fifo_flush (_ep); | 259 | pxa25x_ep_fifo_flush (_ep); |
| @@ -401,7 +390,7 @@ write_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) · 130 unmodified lines | |||
| 401 | { | 390 | { |
| 402 | unsigned max; | 391 | unsigned max; |
| 403 | 392 | ||
| 404 | max = le16_to_cpu(ep->desc->wMaxPacketSize); | 393 | max = usb_endpoint_maxp(ep->desc); |
| 405 | do { | 394 | do { |
| 406 | unsigned count; | 395 | unsigned count; |
| 407 | int is_last, is_short; | 396 | int is_last, is_short; |
| @@ -671,8 +660,7 @@ pxa25x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) · 263 unmodified lines | |||
| 671 | * we can report per-packet status. that also helps with dma. | 660 | * we can report per-packet status. that also helps with dma. |
| 672 | */ | 661 | */ |
| 673 | if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC | 662 | if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC |
| 674 | && req->req.length > le16_to_cpu | 663 | && req->req.length > usb_endpoint_maxp (ep->desc))) |
| 675 | (ep->desc->wMaxPacketSize))) | ||
| 676 | return -EMSGSIZE; | 664 | return -EMSGSIZE; |
| 677 | 665 | ||
| 678 | DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n", | 666 | DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n", |
| @@ -1105,7 +1093,7 @@ udc_seq_show(struct seq_file *m, void *_d) · 426 unmodified lines | |||
| 1105 | tmp = *dev->ep [i].reg_udccs; | 1093 | tmp = *dev->ep [i].reg_udccs; |
| 1106 | seq_printf(m, | 1094 | seq_printf(m, |
| 1107 | "%s max %d %s udccs %02x irqs %lu\n", | 1095 | "%s max %d %s udccs %02x irqs %lu\n", |
| 1108 | ep->ep.name, le16_to_cpu(desc->wMaxPacketSize), | 1096 | ep->ep.name, usb_endpoint_maxp(desc), |
| 1109 | "pio", tmp, ep->pio_irqs); | 1097 | "pio", tmp, ep->pio_irqs); |
| 1110 | /* TODO translate all five groups of udccs bits! */ | 1098 | /* TODO translate all five groups of udccs bits! */ |
| 1111 | 1099 | ||
| @@ -2202,7 +2190,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) · 1090 unmodified lines | |||
| 2202 | 2190 | ||
| 2203 | /* irq setup after old hardware state is cleaned up */ | 2191 | /* irq setup after old hardware state is cleaned up */ |
| 2204 | retval = request_irq(irq, pxa25x_udc_irq, | 2192 | retval = request_irq(irq, pxa25x_udc_irq, |
| 2205 | IRQF_DISABLED, driver_name, dev); | 2193 | 0, driver_name, dev); |
| 2206 | if (retval != 0) { | 2194 | if (retval != 0) { |
| 2207 | pr_err("%s: can't get irq %d, err %d\n", | 2195 | pr_err("%s: can't get irq %d, err %d\n", |
| 2208 | driver_name, irq, retval); | 2196 | driver_name, irq, retval); |
| @@ -2214,7 +2202,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 2214 | if (machine_is_lubbock()) { | 2202 | if (machine_is_lubbock()) { |
| 2215 | retval = request_irq(LUBBOCK_USB_DISC_IRQ, | 2203 | retval = request_irq(LUBBOCK_USB_DISC_IRQ, |
| 2216 | lubbock_vbus_irq, | 2204 | lubbock_vbus_irq, |
| 2217 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 2205 | IRQF_SAMPLE_RANDOM, |
| 2218 | driver_name, dev); | 2206 | driver_name, dev); |
| 2219 | if (retval != 0) { | 2207 | if (retval != 0) { |
| 2220 | pr_err("%s: can't get irq %i, err %d\n", | 2208 | pr_err("%s: can't get irq %i, err %d\n", |
| @@ -2223,7 +2211,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 2223 | } | 2211 | } |
| 2224 | retval = request_irq(LUBBOCK_USB_IRQ, | 2212 | retval = request_irq(LUBBOCK_USB_IRQ, |
| 2225 | lubbock_vbus_irq, | 2213 | lubbock_vbus_irq, |
| 2226 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 2214 | IRQF_SAMPLE_RANDOM, |
| 2227 | driver_name, dev); | 2215 | driver_name, dev); |
| 2228 | if (retval != 0) { | 2216 | if (retval != 0) { |
| 2229 | pr_err("%s: can't get irq %i, err %d\n", | 2217 | pr_err("%s: can't get irq %i, err %d\n", |
| @@ -9,15 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | 12 | */ |
| 22 | 13 | ||
| 23 | #ifndef __LINUX_USB_GADGET_PXA25X_H | 14 | #ifndef __LINUX_USB_GADGET_PXA25X_H |
| @@ -161,8 +152,6 @@ static struct pxa25x_udc *the_controller; · 137 unmodified lines | |||
| 161 | 152 | ||
| 162 | #ifdef DEBUG | 153 | #ifdef DEBUG |
| 163 | 154 | ||
| 164 | static int is_vbus_present(void); | ||
| 165 | |||
| 166 | static const char *state_name[] = { | 155 | static const char *state_name[] = { |
| 167 | "EP0_IDLE", | 156 | "EP0_IDLE", |
| 168 | "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", | 157 | "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", |
| @@ -214,8 +203,7 @@ dump_state(struct pxa25x_udc *dev) · 45 unmodified lines | |||
| 214 | u32 tmp; | 203 | u32 tmp; |
| 215 | unsigned i; | 204 | unsigned i; |
| 216 | 205 | ||
| 217 | DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", | 206 | DMSG("%s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", |
| 218 | is_vbus_present() ? "host " : "disconnected", | ||
| 219 | state_name[dev->ep0state], | 207 | state_name[dev->ep0state], |
| 220 | UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); | 208 | UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); |
| 221 | dump_udccr("udccr"); | 209 | dump_udccr("udccr"); |
| @@ -232,9 +220,6 @@ dump_state(struct pxa25x_udc *dev) · 10 unmodified lines | |||
| 232 | } else | 220 | } else |
| 233 | DMSG("ep0 driver '%s'\n", dev->driver->driver.name); | 221 | DMSG("ep0 driver '%s'\n", dev->driver->driver.name); |
| 234 | 222 | ||
| 235 | if (!is_vbus_present()) | ||
| 236 | return; | ||
| 237 | |||
| 238 | dump_udccs0 ("udccs0"); | 223 | dump_udccs0 ("udccs0"); |
| 239 | DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n", | 224 | DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n", |
| 240 | dev->stats.write.bytes, dev->stats.write.ops, | 225 | dev->stats.write.bytes, dev->stats.write.ops, |
| @@ -8,16 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | * | ||
| 21 | */ | 11 | */ |
| 22 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 23 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| @@ -1439,7 +1429,7 @@ static int pxa_ep_enable(struct usb_ep *_ep, · 1415 unmodified lines | |||
| 1439 | return -EINVAL; | 1429 | return -EINVAL; |
| 1440 | } | 1430 | } |
| 1441 | 1431 | ||
| 1442 | if (ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) { | 1432 | if (ep->fifo_size < usb_endpoint_maxp(desc)) { |
| 1443 | ep_err(ep, "bad maxpacket\n"); | 1433 | ep_err(ep, "bad maxpacket\n"); |
| 1444 | return -ERANGE; | 1434 | return -ERANGE; |
| 1445 | } | 1435 | } |
| @@ -9,15 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | 12 | */ |
| 22 | 13 | ||
| 23 | #ifndef __LINUX_USB_GADGET_PXA27X_H | 14 | #ifndef __LINUX_USB_GADGET_PXA27X_H |
| @@ -8,16 +8,6 @@ · 7 unmodified lines | |||
| 8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; version 2 of the License. | 10 | * the Free Software Foundation; version 2 of the License. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | * | ||
| 21 | */ | 11 | */ |
| 22 | 12 | ||
| 23 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| @@ -28,13 +18,14 @@ · 4 unmodified lines | |||
| 28 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
| 29 | #include <linux/err.h> | 19 | #include <linux/err.h> |
| 30 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/dma-mapping.h> | ||
| 31 | 22 | ||
| 32 | #include <linux/usb/ch9.h> | 23 | #include <linux/usb/ch9.h> |
| 33 | #include <linux/usb/gadget.h> | 24 | #include <linux/usb/gadget.h> |
| 34 | 25 | ||
| 35 | #include "r8a66597-udc.h" | 26 | #include "r8a66597-udc.h" |
| 36 | 27 | ||
| 37 | #define DRIVER_VERSION "2009-08-18" | 28 | #define DRIVER_VERSION "2011-09-26" |
| 38 | 29 | ||
| 39 | static const char udc_name[] = "r8a66597_udc"; | 30 | static const char udc_name[] = "r8a66597_udc"; |
| 40 | static const char *r8a66597_ep_name[] = { | 31 | static const char *r8a66597_ep_name[] = { |
| @@ -115,13 +106,15 @@ static inline u16 control_reg_get_pid(struct r8a66597 *r8a66597, u16 pipenum) · 74 unmodified lines | |||
| 115 | u16 pid = 0; | 106 | u16 pid = 0; |
| 116 | unsigned long offset; | 107 | unsigned long offset; |
| 117 | 108 | ||
| 118 | if (pipenum == 0) | 109 | if (pipenum == 0) { |
| 119 | pid = r8a66597_read(r8a66597, DCPCTR) & PID; | 110 | pid = r8a66597_read(r8a66597, DCPCTR) & PID; |
| 120 | else if (pipenum < R8A66597_MAX_NUM_PIPE) { | 111 | } else if (pipenum < R8A66597_MAX_NUM_PIPE) { |
| 121 | offset = get_pipectr_addr(pipenum); | 112 | offset = get_pipectr_addr(pipenum); |
| 122 | pid = r8a66597_read(r8a66597, offset) & PID; | 113 | pid = r8a66597_read(r8a66597, offset) & PID; |
| 123 | } else | 114 | } else { |
| 124 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | 115 | dev_err(r8a66597_to_dev(r8a66597), "unexpect pipe num (%d)\n", |
| 116 | pipenum); | ||
| 117 | } | ||
| 125 | 118 | ||
| 126 | return pid; | 119 | return pid; |
| 127 | } | 120 | } |
| @@ -131,13 +124,15 @@ static inline void control_reg_set_pid(struct r8a66597 *r8a66597, u16 pipenum, · 3 unmodified lines | |||
| 131 | { | 124 | { |
| 132 | unsigned long offset; | 125 | unsigned long offset; |
| 133 | 126 | ||
| 134 | if (pipenum == 0) | 127 | if (pipenum == 0) { |
| 135 | r8a66597_mdfy(r8a66597, pid, PID, DCPCTR); | 128 | r8a66597_mdfy(r8a66597, pid, PID, DCPCTR); |
| 136 | else if (pipenum < R8A66597_MAX_NUM_PIPE) { | 129 | } else if (pipenum < R8A66597_MAX_NUM_PIPE) { |
| 137 | offset = get_pipectr_addr(pipenum); | 130 | offset = get_pipectr_addr(pipenum); |
| 138 | r8a66597_mdfy(r8a66597, pid, PID, offset); | 131 | r8a66597_mdfy(r8a66597, pid, PID, offset); |
| 139 | } else | 132 | } else { |
| 140 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | 133 | dev_err(r8a66597_to_dev(r8a66597), "unexpect pipe num (%d)\n", |
| 134 | pipenum); | ||
| 135 | } | ||
| 141 | } | 136 | } |
| 142 | 137 | ||
| 143 | static inline void pipe_start(struct r8a66597 *r8a66597, u16 pipenum) | 138 | static inline void pipe_start(struct r8a66597 *r8a66597, u16 pipenum) |
| @@ -160,13 +155,15 @@ static inline u16 control_reg_get(struct r8a66597 *r8a66597, u16 pipenum) · 16 unmodified lines | |||
| 160 | u16 ret = 0; | 155 | u16 ret = 0; |
| 161 | unsigned long offset; | 156 | unsigned long offset; |
| 162 | 157 | ||
| 163 | if (pipenum == 0) | 158 | if (pipenum == 0) { |
| 164 | ret = r8a66597_read(r8a66597, DCPCTR); | 159 | ret = r8a66597_read(r8a66597, DCPCTR); |
| 165 | else if (pipenum < R8A66597_MAX_NUM_PIPE) { | 160 | } else if (pipenum < R8A66597_MAX_NUM_PIPE) { |
| 166 | offset = get_pipectr_addr(pipenum); | 161 | offset = get_pipectr_addr(pipenum); |
| 167 | ret = r8a66597_read(r8a66597, offset); | 162 | ret = r8a66597_read(r8a66597, offset); |
| 168 | } else | 163 | } else { |
| 169 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | 164 | dev_err(r8a66597_to_dev(r8a66597), "unexpect pipe num (%d)\n", |
| 165 | pipenum); | ||
| 166 | } | ||
| 170 | 167 | ||
| 171 | return ret; | 168 | return ret; |
| 172 | } | 169 | } |
| @@ -177,13 +174,63 @@ static inline void control_reg_sqclr(struct r8a66597 *r8a66597, u16 pipenum) · 4 unmodified lines | |||
| 177 | 174 | ||
| 178 | pipe_stop(r8a66597, pipenum); | 175 | pipe_stop(r8a66597, pipenum); |
| 179 | 176 | ||
| 180 | if (pipenum == 0) | 177 | if (pipenum == 0) { |
| 181 | r8a66597_bset(r8a66597, SQCLR, DCPCTR); | 178 | r8a66597_bset(r8a66597, SQCLR, DCPCTR); |
| 182 | else if (pipenum < R8A66597_MAX_NUM_PIPE) { | 179 | } else if (pipenum < R8A66597_MAX_NUM_PIPE) { |
| 183 | offset = get_pipectr_addr(pipenum); | 180 | offset = get_pipectr_addr(pipenum); |
| 184 | r8a66597_bset(r8a66597, SQCLR, offset); | 181 | r8a66597_bset(r8a66597, SQCLR, offset); |
| 185 | } else | 182 | } else { |
| 186 | printk(KERN_ERR "unexpect pipe num(%d)\n", pipenum); | 183 | dev_err(r8a66597_to_dev(r8a66597), "unexpect pipe num (%d)\n", |
| 184 | pipenum); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | static void control_reg_sqset(struct r8a66597 *r8a66597, u16 pipenum) | ||
| 189 | { | ||
| 190 | unsigned long offset; | ||
| 191 | |||
| 192 | pipe_stop(r8a66597, pipenum); | ||
| 193 | |||
| 194 | if (pipenum == 0) { | ||
| 195 | r8a66597_bset(r8a66597, SQSET, DCPCTR); | ||
| 196 | } else if (pipenum < R8A66597_MAX_NUM_PIPE) { | ||
| 197 | offset = get_pipectr_addr(pipenum); | ||
| 198 | r8a66597_bset(r8a66597, SQSET, offset); | ||
| 199 | } else { | ||
| 200 | dev_err(r8a66597_to_dev(r8a66597), | ||
| 201 | "unexpect pipe num(%d)\n", pipenum); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | static u16 control_reg_sqmon(struct r8a66597 *r8a66597, u16 pipenum) | ||
| 206 | { | ||
| 207 | unsigned long offset; | ||
| 208 | |||
| 209 | if (pipenum == 0) { | ||
| 210 | return r8a66597_read(r8a66597, DCPCTR) & SQMON; | ||
| 211 | } else if (pipenum < R8A66597_MAX_NUM_PIPE) { | ||
| 212 | offset = get_pipectr_addr(pipenum); | ||
| 213 | return r8a66597_read(r8a66597, offset) & SQMON; | ||
| 214 | } else { | ||
| 215 | dev_err(r8a66597_to_dev(r8a66597), | ||
| 216 | "unexpect pipe num(%d)\n", pipenum); | ||
| 217 | } | ||
| 218 | |||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 222 | static u16 save_usb_toggle(struct r8a66597 *r8a66597, u16 pipenum) | ||
| 223 | { | ||
| 224 | return control_reg_sqmon(r8a66597, pipenum); | ||
| 225 | } | ||
| 226 | |||
| 227 | static void restore_usb_toggle(struct r8a66597 *r8a66597, u16 pipenum, | ||
| 228 | u16 toggle) | ||
| 229 | { | ||
| 230 | if (toggle) | ||
| 231 | control_reg_sqset(r8a66597, pipenum); | ||
| 232 | else | ||
| 233 | control_reg_sqclr(r8a66597, pipenum); | ||
| 187 | } | 234 | } |
| 188 | 235 | ||
| 189 | static inline int get_buffer_size(struct r8a66597 *r8a66597, u16 pipenum) | 236 | static inline int get_buffer_size(struct r8a66597 *r8a66597, u16 pipenum) |
| @@ -222,18 +269,51 @@ static inline unsigned short mbw_value(struct r8a66597 *r8a66597) · 32 unmodified lines | |||
| 222 | return MBW_16; | 269 | return MBW_16; |
| 223 | } | 270 | } |
| 224 | 271 | ||
| 272 | static void r8a66597_change_curpipe(struct r8a66597 *r8a66597, u16 pipenum, | ||
| 273 | u16 isel, u16 fifosel) | ||
| 274 | { | ||
| 275 | u16 tmp, mask, loop; | ||
| 276 | int i = 0; | ||
| 277 | |||
| 278 | if (!pipenum) { | ||
| 279 | mask = ISEL | CURPIPE; | ||
| 280 | loop = isel; | ||
| 281 | } else { | ||
| 282 | mask = CURPIPE; | ||
| 283 | loop = pipenum; | ||
| 284 | } | ||
| 285 | r8a66597_mdfy(r8a66597, loop, mask, fifosel); | ||
| 286 | |||
| 287 | do { | ||
| 288 | tmp = r8a66597_read(r8a66597, fifosel); | ||
| 289 | if (i++ > 1000000) { | ||
| 290 | dev_err(r8a66597_to_dev(r8a66597), | ||
| 291 | "r8a66597: register%x, loop %x " | ||
| 292 | "is timeout\n", fifosel, loop); | ||
| 293 | break; | ||
| 294 | } | ||
| 295 | ndelay(1); | ||
| 296 | } while ((tmp & mask) != loop); | ||
| 297 | } | ||
| 298 | |||
| 225 | static inline void pipe_change(struct r8a66597 *r8a66597, u16 pipenum) | 299 | static inline void pipe_change(struct r8a66597 *r8a66597, u16 pipenum) |
| 226 | { | 300 | { |
| 227 | struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum]; | 301 | struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum]; |
| 228 | 302 | ||
| 229 | if (ep->use_dma) | 303 | if (ep->use_dma) |
| 230 | return; | 304 | r8a66597_bclr(r8a66597, DREQE, ep->fifosel); |
| 231 | 305 | ||
| 232 | r8a66597_mdfy(r8a66597, pipenum, CURPIPE, ep->fifosel); | 306 | r8a66597_mdfy(r8a66597, pipenum, CURPIPE, ep->fifosel); |
| 233 | 307 | ||
| 234 | ndelay(450); | 308 | ndelay(450); |
| 235 | 309 | ||
| 236 | r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel); | 310 | if (r8a66597_is_sudmac(r8a66597) && ep->use_dma) |
| 311 | r8a66597_bclr(r8a66597, mbw_value(r8a66597), ep->fifosel); | ||
| 312 | else | ||
| 313 | r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel); | ||
| 314 | |||
| 315 | if (ep->use_dma) | ||
| 316 | r8a66597_bset(r8a66597, DREQE, ep->fifosel); | ||
| 237 | } | 317 | } |
| 238 | 318 | ||
| 239 | static int pipe_buffer_setting(struct r8a66597 *r8a66597, | 319 | static int pipe_buffer_setting(struct r8a66597 *r8a66597, |
| @@ -297,17 +377,18 @@ static void pipe_buffer_release(struct r8a66597 *r8a66597, · 57 unmodified lines | |||
| 297 | if (info->pipe == 0) | 377 | if (info->pipe == 0) |
| 298 | return; | 378 | return; |
| 299 | 379 | ||
| 300 | if (is_bulk_pipe(info->pipe)) | 380 | if (is_bulk_pipe(info->pipe)) { |
| 301 | r8a66597->bulk--; | 381 | r8a66597->bulk--; |
| 302 | else if (is_interrupt_pipe(info->pipe)) | 382 | } else if (is_interrupt_pipe(info->pipe)) { |
| 303 | r8a66597->interrupt--; | 383 | r8a66597->interrupt--; |
| 304 | else if (is_isoc_pipe(info->pipe)) { | 384 | } else if (is_isoc_pipe(info->pipe)) { |
| 305 | r8a66597->isochronous--; | 385 | r8a66597->isochronous--; |
| 306 | if (info->type == R8A66597_BULK) | 386 | if (info->type == R8A66597_BULK) |
| 307 | r8a66597->bulk--; | 387 | r8a66597->bulk--; |
| 308 | } else | 388 | } else { |
| 309 | printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", | 389 | dev_err(r8a66597_to_dev(r8a66597), |
| 310 | info->pipe); | 390 | "ep_release: unexpect pipenum (%d)\n", info->pipe); |
| 391 | } | ||
| 311 | } | 392 | } |
| 312 | 393 | ||
| 313 | static void pipe_initialize(struct r8a66597_ep *ep) | 394 | static void pipe_initialize(struct r8a66597_ep *ep) |
| @@ -337,11 +418,17 @@ static void r8a66597_ep_setting(struct r8a66597 *r8a66597, · 23 unmodified lines | |||
| 337 | ep->fifoaddr = CFIFO; | 418 | ep->fifoaddr = CFIFO; |
| 338 | ep->fifosel = CFIFOSEL; | 419 | ep->fifosel = CFIFOSEL; |
| 339 | ep->fifoctr = CFIFOCTR; | 420 | ep->fifoctr = CFIFOCTR; |
| 340 | ep->fifotrn = 0; | ||
| 341 | 421 | ||
| 342 | ep->pipectr = get_pipectr_addr(pipenum); | 422 | ep->pipectr = get_pipectr_addr(pipenum); |
| 423 | if (is_bulk_pipe(pipenum) || is_isoc_pipe(pipenum)) { | ||
| 424 | ep->pipetre = get_pipetre_addr(pipenum); | ||
| 425 | ep->pipetrn = get_pipetrn_addr(pipenum); | ||
| 426 | } else { | ||
| 427 | ep->pipetre = 0; | ||
| 428 | ep->pipetrn = 0; | ||
| 429 | } | ||
| 343 | ep->pipenum = pipenum; | 430 | ep->pipenum = pipenum; |
| 344 | ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 431 | ep->ep.maxpacket = usb_endpoint_maxp(desc); |
| 345 | r8a66597->pipenum2ep[pipenum] = ep; | 432 | r8a66597->pipenum2ep[pipenum] = ep; |
| 346 | r8a66597->epaddr2ep[desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK] | 433 | r8a66597->epaddr2ep[desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK] |
| 347 | = ep; | 434 | = ep; |
| @@ -381,7 +468,8 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, · 33 unmodified lines | |||
| 381 | case USB_ENDPOINT_XFER_BULK: | 468 | case USB_ENDPOINT_XFER_BULK: |
| 382 | if (r8a66597->bulk >= R8A66597_MAX_NUM_BULK) { | 469 | if (r8a66597->bulk >= R8A66597_MAX_NUM_BULK) { |
| 383 | if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) { | 470 | if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) { |
| 384 | printk(KERN_ERR "bulk pipe is insufficient\n"); | 471 | dev_err(r8a66597_to_dev(r8a66597), |
| 472 | "bulk pipe is insufficient\n"); | ||
| 385 | return -ENODEV; | 473 | return -ENODEV; |
| 386 | } else { | 474 | } else { |
| 387 | info.pipe = R8A66597_BASE_PIPENUM_ISOC | 475 | info.pipe = R8A66597_BASE_PIPENUM_ISOC |
| @@ -397,7 +485,8 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, · 9 unmodified lines | |||
| 397 | break; | 485 | break; |
| 398 | case USB_ENDPOINT_XFER_INT: | 486 | case USB_ENDPOINT_XFER_INT: |
| 399 | if (r8a66597->interrupt >= R8A66597_MAX_NUM_INT) { | 487 | if (r8a66597->interrupt >= R8A66597_MAX_NUM_INT) { |
| 400 | printk(KERN_ERR "interrupt pipe is insufficient\n"); | 488 | dev_err(r8a66597_to_dev(r8a66597), |
| 489 | "interrupt pipe is insufficient\n"); | ||
| 401 | return -ENODEV; | 490 | return -ENODEV; |
| 402 | } | 491 | } |
| 403 | info.pipe = R8A66597_BASE_PIPENUM_INT + r8a66597->interrupt; | 492 | info.pipe = R8A66597_BASE_PIPENUM_INT + r8a66597->interrupt; |
| @@ -406,7 +495,8 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, · 2 unmodified lines | |||
| 406 | break; | 495 | break; |
| 407 | case USB_ENDPOINT_XFER_ISOC: | 496 | case USB_ENDPOINT_XFER_ISOC: |
| 408 | if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) { | 497 | if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) { |
| 409 | printk(KERN_ERR "isochronous pipe is insufficient\n"); | 498 | dev_err(r8a66597_to_dev(r8a66597), |
| 499 | "isochronous pipe is insufficient\n"); | ||
| 410 | return -ENODEV; | 500 | return -ENODEV; |
| 411 | } | 501 | } |
| 412 | info.pipe = R8A66597_BASE_PIPENUM_ISOC + r8a66597->isochronous; | 502 | info.pipe = R8A66597_BASE_PIPENUM_ISOC + r8a66597->isochronous; |
| @@ -414,13 +504,13 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, · 1 unmodified line | |||
| 414 | counter = &r8a66597->isochronous; | 504 | counter = &r8a66597->isochronous; |
| 415 | break; | 505 | break; |
| 416 | default: | 506 | default: |
| 417 | printk(KERN_ERR "unexpect xfer type\n"); | 507 | dev_err(r8a66597_to_dev(r8a66597), "unexpect xfer type\n"); |
| 418 | return -EINVAL; | 508 | return -EINVAL; |
| 419 | } | 509 | } |
| 420 | ep->type = info.type; | 510 | ep->type = info.type; |
| 421 | 511 | ||
| 422 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 512 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; |
| 423 | info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 513 | info.maxpacket = usb_endpoint_maxp(desc); |
| 424 | info.interval = desc->bInterval; | 514 | info.interval = desc->bInterval; |
| 425 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 515 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
| 426 | info.dir_in = 1; | 516 | info.dir_in = 1; |
| @@ -429,7 +519,8 @@ static int alloc_pipe_config(struct r8a66597_ep *ep, · 2 unmodified lines | |||
| 429 | 519 | ||
| 430 | ret = pipe_buffer_setting(r8a66597, &info); | 520 | ret = pipe_buffer_setting(r8a66597, &info); |
| 431 | if (ret < 0) { | 521 | if (ret < 0) { |
| 432 | printk(KERN_ERR "pipe_buffer_setting fail\n"); | 522 | dev_err(r8a66597_to_dev(r8a66597), |
| 523 | "pipe_buffer_setting fail\n"); | ||
| 433 | return ret; | 524 | return ret; |
| 434 | } | 525 | } |
| 435 | 526 | ||
| @@ -495,6 +586,124 @@ static void start_ep0_write(struct r8a66597_ep *ep, · 59 unmodified lines | |||
| 495 | } | 586 | } |
| 496 | } | 587 | } |
| 497 | 588 | ||
| 589 | static void disable_fifosel(struct r8a66597 *r8a66597, u16 pipenum, | ||
| 590 | u16 fifosel) | ||
| 591 | { | ||
| 592 | u16 tmp; | ||
| 593 | |||
| 594 | tmp = r8a66597_read(r8a66597, fifosel) & CURPIPE; | ||
| 595 | if (tmp == pipenum) | ||
| 596 | r8a66597_change_curpipe(r8a66597, 0, 0, fifosel); | ||
| 597 | } | ||
| 598 | |||
| 599 | static void change_bfre_mode(struct r8a66597 *r8a66597, u16 pipenum, | ||
| 600 | int enable) | ||
| 601 | { | ||
| 602 | struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum]; | ||
| 603 | u16 tmp, toggle; | ||
| 604 | |||
| 605 | /* check current BFRE bit */ | ||
| 606 | r8a66597_write(r8a66597, pipenum, PIPESEL); | ||
| 607 | tmp = r8a66597_read(r8a66597, PIPECFG) & R8A66597_BFRE; | ||
| 608 | if ((enable && tmp) || (!enable && !tmp)) | ||
| 609 | return; | ||
| 610 | |||
| 611 | /* change BFRE bit */ | ||
| 612 | pipe_stop(r8a66597, pipenum); | ||
| 613 | disable_fifosel(r8a66597, pipenum, CFIFOSEL); | ||
| 614 | disable_fifosel(r8a66597, pipenum, D0FIFOSEL); | ||
| 615 | disable_fifosel(r8a66597, pipenum, D1FIFOSEL); | ||
| 616 | |||
| 617 | toggle = save_usb_toggle(r8a66597, pipenum); | ||
| 618 | |||
| 619 | r8a66597_write(r8a66597, pipenum, PIPESEL); | ||
| 620 | if (enable) | ||
| 621 | r8a66597_bset(r8a66597, R8A66597_BFRE, PIPECFG); | ||
| 622 | else | ||
| 623 | r8a66597_bclr(r8a66597, R8A66597_BFRE, PIPECFG); | ||
| 624 | |||
| 625 | /* initialize for internal BFRE flag */ | ||
| 626 | r8a66597_bset(r8a66597, ACLRM, ep->pipectr); | ||
| 627 | r8a66597_bclr(r8a66597, ACLRM, ep->pipectr); | ||
| 628 | |||
| 629 | restore_usb_toggle(r8a66597, pipenum, toggle); | ||
| 630 | } | ||
| 631 | |||
| 632 | static int sudmac_alloc_channel(struct r8a66597 *r8a66597, | ||
| 633 | struct r8a66597_ep *ep, | ||
| 634 | struct r8a66597_request *req) | ||
| 635 | { | ||
| 636 | struct r8a66597_dma *dma; | ||
| 637 | |||
| 638 | if (!r8a66597_is_sudmac(r8a66597)) | ||
| 639 | return -ENODEV; | ||
| 640 | |||
| 641 | /* Check transfer type */ | ||
| 642 | if (!is_bulk_pipe(ep->pipenum)) | ||
| 643 | return -EIO; | ||
| 644 | |||
| 645 | if (r8a66597->dma.used) | ||
| 646 | return -EBUSY; | ||
| 647 | |||
| 648 | /* set SUDMAC parameters */ | ||
| 649 | dma = &r8a66597->dma; | ||
| 650 | dma->used = 1; | ||
| 651 | if (ep->desc->bEndpointAddress & USB_DIR_IN) { | ||
| 652 | dma->dir = 1; | ||
| 653 | } else { | ||
| 654 | dma->dir = 0; | ||
| 655 | change_bfre_mode(r8a66597, ep->pipenum, 1); | ||
| 656 | } | ||
| 657 | |||
| 658 | /* set r8a66597_ep paramters */ | ||
| 659 | ep->use_dma = 1; | ||
| 660 | ep->dma = dma; | ||
| 661 | ep->fifoaddr = D0FIFO; | ||
| 662 | ep->fifosel = D0FIFOSEL; | ||
| 663 | ep->fifoctr = D0FIFOCTR; | ||
| 664 | |||
| 665 | /* dma mapping */ | ||
| 666 | req->req.dma = dma_map_single(r8a66597_to_dev(ep->r8a66597), | ||
| 667 | req->req.buf, req->req.length, | ||
| 668 | dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 669 | |||
| 670 | return 0; | ||
| 671 | } | ||
| 672 | |||
| 673 | static void sudmac_free_channel(struct r8a66597 *r8a66597, | ||
| 674 | struct r8a66597_ep *ep, | ||
| 675 | struct r8a66597_request *req) | ||
| 676 | { | ||
| 677 | if (!r8a66597_is_sudmac(r8a66597)) | ||
| 678 | return; | ||
| 679 | |||
| 680 | dma_unmap_single(r8a66597_to_dev(ep->r8a66597), | ||
| 681 | req->req.dma, req->req.length, | ||
| 682 | ep->dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 683 | |||
| 684 | r8a66597_bclr(r8a66597, DREQE, ep->fifosel); | ||
| 685 | r8a66597_change_curpipe(r8a66597, 0, 0, ep->fifosel); | ||
| 686 | |||
| 687 | ep->dma->used = 0; | ||
| 688 | ep->use_dma = 0; | ||
| 689 | ep->fifoaddr = CFIFO; | ||
| 690 | ep->fifosel = CFIFOSEL; | ||
| 691 | ep->fifoctr = CFIFOCTR; | ||
| 692 | } | ||
| 693 | |||
| 694 | static void sudmac_start(struct r8a66597 *r8a66597, struct r8a66597_ep *ep, | ||
| 695 | struct r8a66597_request *req) | ||
| 696 | { | ||
| 697 | BUG_ON(req->req.length == 0); | ||
| 698 | |||
| 699 | r8a66597_sudmac_write(r8a66597, LBA_WAIT, CH0CFG); | ||
| 700 | r8a66597_sudmac_write(r8a66597, req->req.dma, CH0BA); | ||
| 701 | r8a66597_sudmac_write(r8a66597, req->req.length, CH0BBC); | ||
| 702 | r8a66597_sudmac_write(r8a66597, CH0ENDE, DINTCTRL); | ||
| 703 | |||
| 704 | r8a66597_sudmac_write(r8a66597, DEN, CH0DEN); | ||
| 705 | } | ||
| 706 | |||
| 498 | static void start_packet_write(struct r8a66597_ep *ep, | 707 | static void start_packet_write(struct r8a66597_ep *ep, |
| 499 | struct r8a66597_request *req) | 708 | struct r8a66597_request *req) |
| 500 | { | 709 | { |
| @@ -505,11 +714,29 @@ static void start_packet_write(struct r8a66597_ep *ep, · 4 unmodified lines | |||
| 505 | disable_irq_empty(r8a66597, ep->pipenum); | 714 | disable_irq_empty(r8a66597, ep->pipenum); |
| 506 | pipe_start(r8a66597, ep->pipenum); | 715 | pipe_start(r8a66597, ep->pipenum); |
| 507 | 716 | ||
| 508 | tmp = r8a66597_read(r8a66597, ep->fifoctr); | 717 | if (req->req.length == 0) { |
| 509 | if (unlikely((tmp & FRDY) == 0)) | 718 | transfer_complete(ep, req, 0); |
| 510 | pipe_irq_enable(r8a66597, ep->pipenum); | 719 | } else { |
| 511 | else | 720 | r8a66597_write(r8a66597, ~(1 << ep->pipenum), BRDYSTS); |
| 512 | irq_packet_write(ep, req); | 721 | if (sudmac_alloc_channel(r8a66597, ep, req) < 0) { |
| 722 | /* PIO mode */ | ||
| 723 | pipe_change(r8a66597, ep->pipenum); | ||
| 724 | disable_irq_empty(r8a66597, ep->pipenum); | ||
| 725 | pipe_start(r8a66597, ep->pipenum); | ||
| 726 | tmp = r8a66597_read(r8a66597, ep->fifoctr); | ||
| 727 | if (unlikely((tmp & FRDY) == 0)) | ||
| 728 | pipe_irq_enable(r8a66597, ep->pipenum); | ||
| 729 | else | ||
| 730 | irq_packet_write(ep, req); | ||
| 731 | } else { | ||
| 732 | /* DMA mode */ | ||
| 733 | pipe_change(r8a66597, ep->pipenum); | ||
| 734 | disable_irq_nrdy(r8a66597, ep->pipenum); | ||
| 735 | pipe_start(r8a66597, ep->pipenum); | ||
| 736 | enable_irq_nrdy(r8a66597, ep->pipenum); | ||
| 737 | sudmac_start(r8a66597, ep, req); | ||
| 738 | } | ||
| 739 | } | ||
| 513 | } | 740 | } |
| 514 | 741 | ||
| 515 | static void start_packet_read(struct r8a66597_ep *ep, | 742 | static void start_packet_read(struct r8a66597_ep *ep, |
| @@ -524,17 +751,26 @@ static void start_packet_read(struct r8a66597_ep *ep, · 8 unmodified lines | |||
| 524 | pipe_start(r8a66597, pipenum); | 751 | pipe_start(r8a66597, pipenum); |
| 525 | pipe_irq_enable(r8a66597, pipenum); | 752 | pipe_irq_enable(r8a66597, pipenum); |
| 526 | } else { | 753 | } else { |
| 527 | if (ep->use_dma) { | 754 | pipe_stop(r8a66597, pipenum); |
| 528 | r8a66597_bset(r8a66597, TRCLR, ep->fifosel); | 755 | if (ep->pipetre) { |
| 529 | pipe_change(r8a66597, pipenum); | 756 | enable_irq_nrdy(r8a66597, pipenum); |
| 530 | r8a66597_bset(r8a66597, TRENB, ep->fifosel); | 757 | r8a66597_write(r8a66597, TRCLR, ep->pipetre); |
| 531 | r8a66597_write(r8a66597, | 758 | r8a66597_write(r8a66597, |
| 532 | (req->req.length + ep->ep.maxpacket - 1) | 759 | DIV_ROUND_UP(req->req.length, ep->ep.maxpacket), |
| 533 | / ep->ep.maxpacket, | 760 | ep->pipetrn); |
| 534 | ep->fifotrn); | 761 | r8a66597_bset(r8a66597, TRENB, ep->pipetre); |
| 762 | } | ||
| 763 | |||
| 764 | if (sudmac_alloc_channel(r8a66597, ep, req) < 0) { | ||
| 765 | /* PIO mode */ | ||
| 766 | change_bfre_mode(r8a66597, ep->pipenum, 0); | ||
| 767 | pipe_start(r8a66597, pipenum); /* trigger once */ | ||
| 768 | pipe_irq_enable(r8a66597, pipenum); | ||
| 769 | } else { | ||
| 770 | pipe_change(r8a66597, pipenum); | ||
| 771 | sudmac_start(r8a66597, ep, req); | ||
| 772 | pipe_start(r8a66597, pipenum); /* trigger once */ | ||
| 535 | } | 773 | } |
| 536 | pipe_start(r8a66597, pipenum); /* trigger once */ | ||
| 537 | pipe_irq_enable(r8a66597, pipenum); | ||
| 538 | } | 774 | } |
| 539 | } | 775 | } |
| 540 | 776 | ||
| @@ -564,7 +800,8 @@ static void start_ep0(struct r8a66597_ep *ep, struct r8a66597_request *req) · 23 unmodified lines | |||
| 564 | control_end(ep->r8a66597, 0); | 800 | control_end(ep->r8a66597, 0); |
| 565 | break; | 801 | break; |
| 566 | default: | 802 | default: |
| 567 | printk(KERN_ERR "start_ep0: unexpect ctsq(%x)\n", ctsq); | 803 | dev_err(r8a66597_to_dev(ep->r8a66597), |
| 804 | "start_ep0: unexpect ctsq(%x)\n", ctsq); | ||
| 568 | break; | 805 | break; |
| 569 | } | 806 | } |
| 570 | } | 807 | } |
| @@ -690,6 +927,9 @@ __acquires(r8a66597->lock) · 119 unmodified lines | |||
| 690 | if (!list_empty(&ep->queue)) | 927 | if (!list_empty(&ep->queue)) |
| 691 | restart = 1; | 928 | restart = 1; |
| 692 | 929 | ||
| 930 | if (ep->use_dma) | ||
| 931 | sudmac_free_channel(ep->r8a66597, ep, req); | ||
| 932 | |||
| 693 | spin_unlock(&ep->r8a66597->lock); | 933 | spin_unlock(&ep->r8a66597->lock); |
| 694 | req->req.complete(&ep->ep, &req->req); | 934 | req->req.complete(&ep->ep, &req->req); |
| 695 | spin_lock(&ep->r8a66597->lock); | 935 | spin_lock(&ep->r8a66597->lock); |
| @@ -718,7 +958,8 @@ static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req) · 22 unmodified lines | |||
| 718 | do { | 958 | do { |
| 719 | tmp = r8a66597_read(r8a66597, ep->fifoctr); | 959 | tmp = r8a66597_read(r8a66597, ep->fifoctr); |
| 720 | if (i++ > 100000) { | 960 | if (i++ > 100000) { |
| 721 | printk(KERN_ERR "pipe0 is busy. maybe cpu i/o bus" | 961 | dev_err(r8a66597_to_dev(r8a66597), |
| 962 | "pipe0 is busy. maybe cpu i/o bus " | ||
| 722 | "conflict. please power off this controller."); | 963 | "conflict. please power off this controller."); |
| 723 | return; | 964 | return; |
| 724 | } | 965 | } |
| @@ -733,7 +974,7 @@ static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req) · 8 unmodified lines | |||
| 733 | /* write fifo */ | 974 | /* write fifo */ |
| 734 | if (req->req.buf) { | 975 | if (req->req.buf) { |
| 735 | if (size > 0) | 976 | if (size > 0) |
| 736 | r8a66597_write_fifo(r8a66597, ep->fifoaddr, buf, size); | 977 | r8a66597_write_fifo(r8a66597, ep, buf, size); |
| 737 | if ((size == 0) || ((size % ep->ep.maxpacket) != 0)) | 978 | if ((size == 0) || ((size % ep->ep.maxpacket) != 0)) |
| 738 | r8a66597_bset(r8a66597, BVAL, ep->fifoctr); | 979 | r8a66597_bset(r8a66597, BVAL, ep->fifoctr); |
| 739 | } | 980 | } |
| @@ -769,7 +1010,8 @@ static void irq_packet_write(struct r8a66597_ep *ep, · 29 unmodified lines | |||
| 769 | if (unlikely((tmp & FRDY) == 0)) { | 1010 | if (unlikely((tmp & FRDY) == 0)) { |
| 770 | pipe_stop(r8a66597, pipenum); | 1011 | pipe_stop(r8a66597, pipenum); |
| 771 | pipe_irq_disable(r8a66597, pipenum); | 1012 | pipe_irq_disable(r8a66597, pipenum); |
| 772 | printk(KERN_ERR "write fifo not ready. pipnum=%d\n", pipenum); | 1013 | dev_err(r8a66597_to_dev(r8a66597), |
| 1014 | "write fifo not ready. pipnum=%d\n", pipenum); | ||
| 773 | return; | 1015 | return; |
| 774 | } | 1016 | } |
| 775 | 1017 | ||
| @@ -780,7 +1022,7 @@ static void irq_packet_write(struct r8a66597_ep *ep, · 4 unmodified lines | |||
| 780 | 1022 | ||
| 781 | /* write fifo */ | 1023 | /* write fifo */ |
| 782 | if (req->req.buf) { | 1024 | if (req->req.buf) { |
| 783 | r8a66597_write_fifo(r8a66597, ep->fifoaddr, buf, size); | 1025 | r8a66597_write_fifo(r8a66597, ep, buf, size); |
| 784 | if ((size == 0) | 1026 | if ((size == 0) |
| 785 | || ((size % ep->ep.maxpacket) != 0) | 1027 | || ((size % ep->ep.maxpacket) != 0) |
| 786 | || ((bufsize != ep->ep.maxpacket) | 1028 | || ((bufsize != ep->ep.maxpacket) |
| @@ -819,7 +1061,7 @@ static void irq_packet_read(struct r8a66597_ep *ep, · 32 unmodified lines | |||
| 819 | req->req.status = -EPIPE; | 1061 | req->req.status = -EPIPE; |
| 820 | pipe_stop(r8a66597, pipenum); | 1062 | pipe_stop(r8a66597, pipenum); |
| 821 | pipe_irq_disable(r8a66597, pipenum); | 1063 | pipe_irq_disable(r8a66597, pipenum); |
| 822 | printk(KERN_ERR "read fifo not ready"); | 1064 | dev_err(r8a66597_to_dev(r8a66597), "read fifo not ready"); |
| 823 | return; | 1065 | return; |
| 824 | } | 1066 | } |
| 825 | 1067 | ||
| @@ -1095,7 +1337,7 @@ static void r8a66597_update_usb_speed(struct r8a66597 *r8a66597) · 269 unmodified lines | |||
| 1095 | break; | 1337 | break; |
| 1096 | default: | 1338 | default: |
| 1097 | r8a66597->gadget.speed = USB_SPEED_UNKNOWN; | 1339 | r8a66597->gadget.speed = USB_SPEED_UNKNOWN; |
| 1098 | printk(KERN_ERR "USB speed unknown\n"); | 1340 | dev_err(r8a66597_to_dev(r8a66597), "USB speed unknown\n"); |
| 1099 | } | 1341 | } |
| 1100 | } | 1342 | } |
| 1101 | 1343 | ||
| @@ -1158,11 +1400,71 @@ __acquires(r8a66597->lock) · 56 unmodified lines | |||
| 1158 | control_end(r8a66597, 0); | 1400 | control_end(r8a66597, 0); |
| 1159 | break; | 1401 | break; |
| 1160 | default: | 1402 | default: |
| 1161 | printk(KERN_ERR "ctrl_stage: unexpect ctsq(%x)\n", ctsq); | 1403 | dev_err(r8a66597_to_dev(r8a66597), |
| 1404 | "ctrl_stage: unexpect ctsq(%x)\n", ctsq); | ||
| 1162 | break; | 1405 | break; |
| 1163 | } | 1406 | } |
| 1164 | } | 1407 | } |
| 1165 | 1408 | ||
| 1409 | static void sudmac_finish(struct r8a66597 *r8a66597, struct r8a66597_ep *ep) | ||
| 1410 | { | ||
| 1411 | u16 pipenum; | ||
| 1412 | struct r8a66597_request *req; | ||
| 1413 | u32 len; | ||
| 1414 | int i = 0; | ||
| 1415 | |||
| 1416 | pipenum = ep->pipenum; | ||
| 1417 | pipe_change(r8a66597, pipenum); | ||
| 1418 | |||
| 1419 | while (!(r8a66597_read(r8a66597, ep->fifoctr) & FRDY)) { | ||
| 1420 | udelay(1); | ||
| 1421 | if (unlikely(i++ >= 10000)) { /* timeout = 10 msec */ | ||
| 1422 | dev_err(r8a66597_to_dev(r8a66597), | ||
| 1423 | "%s: FRDY was not set (%d)\n", | ||
| 1424 | __func__, pipenum); | ||
| 1425 | return; | ||
| 1426 | } | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | r8a66597_bset(r8a66597, BCLR, ep->fifoctr); | ||
| 1430 | req = get_request_from_ep(ep); | ||
| 1431 | |||
| 1432 | /* prepare parameters */ | ||
| 1433 | len = r8a66597_sudmac_read(r8a66597, CH0CBC); | ||
| 1434 | req->req.actual += len; | ||
| 1435 | |||
| 1436 | /* clear */ | ||
| 1437 | r8a66597_sudmac_write(r8a66597, CH0STCLR, DSTSCLR); | ||
| 1438 | |||
| 1439 | /* check transfer finish */ | ||
| 1440 | if ((!req->req.zero && (req->req.actual == req->req.length)) | ||
| 1441 | || (len % ep->ep.maxpacket)) { | ||
| 1442 | if (ep->dma->dir) { | ||
| 1443 | disable_irq_ready(r8a66597, pipenum); | ||
| 1444 | enable_irq_empty(r8a66597, pipenum); | ||
| 1445 | } else { | ||
| 1446 | /* Clear the interrupt flag for next transfer */ | ||
| 1447 | r8a66597_write(r8a66597, ~(1 << pipenum), BRDYSTS); | ||
| 1448 | transfer_complete(ep, req, 0); | ||
| 1449 | } | ||
| 1450 | } | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | static void r8a66597_sudmac_irq(struct r8a66597 *r8a66597) | ||
| 1454 | { | ||
| 1455 | u32 irqsts; | ||
| 1456 | struct r8a66597_ep *ep; | ||
| 1457 | u16 pipenum; | ||
| 1458 | |||
| 1459 | irqsts = r8a66597_sudmac_read(r8a66597, DINTSTS); | ||
| 1460 | if (irqsts & CH0ENDS) { | ||
| 1461 | r8a66597_sudmac_write(r8a66597, CH0ENDC, DINTSTSCLR); | ||
| 1462 | pipenum = (r8a66597_read(r8a66597, D0FIFOSEL) & CURPIPE); | ||
| 1463 | ep = r8a66597->pipenum2ep[pipenum]; | ||
| 1464 | sudmac_finish(r8a66597, ep); | ||
| 1465 | } | ||
| 1466 | } | ||
| 1467 | |||
| 1166 | static irqreturn_t r8a66597_irq(int irq, void *_r8a66597) | 1468 | static irqreturn_t r8a66597_irq(int irq, void *_r8a66597) |
| 1167 | { | 1469 | { |
| 1168 | struct r8a66597 *r8a66597 = _r8a66597; | 1470 | struct r8a66597 *r8a66597 = _r8a66597; |
| @@ -1173,6 +1475,9 @@ static irqreturn_t r8a66597_irq(int irq, void *_r8a66597) · 4 unmodified lines | |||
| 1173 | u16 savepipe; | 1475 | u16 savepipe; |
| 1174 | u16 mask0; | 1476 | u16 mask0; |
| 1175 | 1477 | ||
| 1478 | if (r8a66597_is_sudmac(r8a66597)) | ||
| 1479 | r8a66597_sudmac_irq(r8a66597); | ||
| 1480 | |||
| 1176 | spin_lock(&r8a66597->lock); | 1481 | spin_lock(&r8a66597->lock); |
| 1177 | 1482 | ||
| 1178 | intsts0 = r8a66597_read(r8a66597, INTSTS0); | 1483 | intsts0 = r8a66597_read(r8a66597, INTSTS0); |
| @@ -1433,23 +1738,18 @@ static struct usb_ep_ops r8a66597_ep_ops = { · 254 unmodified lines | |||
| 1433 | }; | 1738 | }; |
| 1434 | 1739 | ||
| 1435 | /*-------------------------------------------------------------------------*/ | 1740 | /*-------------------------------------------------------------------------*/ |
| 1436 | static struct r8a66597 *the_controller; | 1741 | static int r8a66597_start(struct usb_gadget *gadget, |
| 1437 | 1742 | struct usb_gadget_driver *driver) | |
| 1438 | static int r8a66597_start(struct usb_gadget_driver *driver, | ||
| 1439 | int (*bind)(struct usb_gadget *)) | ||
| 1440 | { | 1743 | { |
| 1441 | struct r8a66597 *r8a66597 = the_controller; | 1744 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); |
| 1442 | int retval; | 1745 | int retval; |
| 1443 | 1746 | ||
| 1444 | if (!driver | 1747 | if (!driver |
| 1445 | || driver->speed != USB_SPEED_HIGH | 1748 | || driver->speed != USB_SPEED_HIGH |
| 1446 | || !bind | ||
| 1447 | || !driver->setup) | 1749 | || !driver->setup) |
| 1448 | return -EINVAL; | 1750 | return -EINVAL; |
| 1449 | if (!r8a66597) | 1751 | if (!r8a66597) |
| 1450 | return -ENODEV; | 1752 | return -ENODEV; |
| 1451 | if (r8a66597->driver) | ||
| 1452 | return -EBUSY; | ||
| 1453 | 1753 | ||
| 1454 | /* hook up the driver */ | 1754 | /* hook up the driver */ |
| 1455 | driver->driver.bus = NULL; | 1755 | driver->driver.bus = NULL; |
| @@ -1458,14 +1758,8 @@ static int r8a66597_start(struct usb_gadget_driver *driver, · 2 unmodified lines | |||
| 1458 | 1758 | ||
| 1459 | retval = device_add(&r8a66597->gadget.dev); | 1759 | retval = device_add(&r8a66597->gadget.dev); |
| 1460 | if (retval) { | 1760 | if (retval) { |
| 1461 | printk(KERN_ERR "device_add error (%d)\n", retval); | 1761 | dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n", |
| 1462 | goto error; | 1762 | retval); |
| 1463 | } | ||
| 1464 | |||
| 1465 | retval = bind(&r8a66597->gadget); | ||
| 1466 | if (retval) { | ||
| 1467 | printk(KERN_ERR "bind to driver error (%d)\n", retval); | ||
| 1468 | device_del(&r8a66597->gadget.dev); | ||
| 1469 | goto error; | 1763 | goto error; |
| 1470 | } | 1764 | } |
| 1471 | 1765 | ||
| @@ -1489,23 +1783,17 @@ error: · 17 unmodified lines | |||
| 1489 | return retval; | 1783 | return retval; |
| 1490 | } | 1784 | } |
| 1491 | 1785 | ||
| 1492 | static int r8a66597_stop(struct usb_gadget_driver *driver) | 1786 | static int r8a66597_stop(struct usb_gadget *gadget, |
| 1787 | struct usb_gadget_driver *driver) | ||
| 1493 | { | 1788 | { |
| 1494 | struct r8a66597 *r8a66597 = the_controller; | 1789 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); |
| 1495 | unsigned long flags; | 1790 | unsigned long flags; |
| 1496 | 1791 | ||
| 1497 | if (driver != r8a66597->driver || !driver->unbind) | ||
| 1498 | return -EINVAL; | ||
| 1499 | |||
| 1500 | spin_lock_irqsave(&r8a66597->lock, flags); | 1792 | spin_lock_irqsave(&r8a66597->lock, flags); |
| 1501 | if (r8a66597->gadget.speed != USB_SPEED_UNKNOWN) | ||
| 1502 | r8a66597_usb_disconnect(r8a66597); | ||
| 1503 | r8a66597_bclr(r8a66597, VBSE, INTENB0); | 1793 | r8a66597_bclr(r8a66597, VBSE, INTENB0); |
| 1504 | disable_controller(r8a66597); | 1794 | disable_controller(r8a66597); |
| 1505 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1795 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
| 1506 | 1796 | ||
| 1507 | driver->unbind(&r8a66597->gadget); | ||
| 1508 | |||
| 1509 | device_del(&r8a66597->gadget.dev); | 1797 | device_del(&r8a66597->gadget.dev); |
| 1510 | r8a66597->driver = NULL; | 1798 | r8a66597->driver = NULL; |
| 1511 | return 0; | 1799 | return 0; |
| @@ -1535,8 +1823,8 @@ static int r8a66597_pullup(struct usb_gadget *gadget, int is_on) · 23 unmodified lines | |||
| 1535 | 1823 | ||
| 1536 | static struct usb_gadget_ops r8a66597_gadget_ops = { | 1824 | static struct usb_gadget_ops r8a66597_gadget_ops = { |
| 1537 | .get_frame = r8a66597_get_frame, | 1825 | .get_frame = r8a66597_get_frame, |
| 1538 | .start = r8a66597_start, | 1826 | .udc_start = r8a66597_start, |
| 1539 | .stop = r8a66597_stop, | 1827 | .udc_stop = r8a66597_stop, |
| 1540 | .pullup = r8a66597_pullup, | 1828 | .pullup = r8a66597_pullup, |
| 1541 | }; | 1829 | }; |
| 1542 | 1830 | ||
| @@ -1547,6 +1835,8 @@ static int __exit r8a66597_remove(struct platform_device *pdev) · 4 unmodified lines | |||
| 1547 | usb_del_gadget_udc(&r8a66597->gadget); | 1835 | usb_del_gadget_udc(&r8a66597->gadget); |
| 1548 | del_timer_sync(&r8a66597->timer); | 1836 | del_timer_sync(&r8a66597->timer); |
| 1549 | iounmap(r8a66597->reg); | 1837 | iounmap(r8a66597->reg); |
| 1838 | if (r8a66597->pdata->sudmac) | ||
| 1839 | iounmap(r8a66597->sudmac_reg); | ||
| 1550 | free_irq(platform_get_irq(pdev, 0), r8a66597); | 1840 | free_irq(platform_get_irq(pdev, 0), r8a66597); |
| 1551 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); | 1841 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); |
| 1552 | #ifdef CONFIG_HAVE_CLK | 1842 | #ifdef CONFIG_HAVE_CLK |
| @@ -1563,6 +1853,26 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r) · 10 unmodified lines | |||
| 1563 | { | 1853 | { |
| 1564 | } | 1854 | } |
| 1565 | 1855 | ||
| 1856 | static int __init r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, | ||
| 1857 | struct platform_device *pdev) | ||
| 1858 | { | ||
| 1859 | struct resource *res; | ||
| 1860 | |||
| 1861 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); | ||
| 1862 | if (!res) { | ||
| 1863 | dev_err(&pdev->dev, "platform_get_resource error(sudmac).\n"); | ||
| 1864 | return -ENODEV; | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | r8a66597->sudmac_reg = ioremap(res->start, resource_size(res)); | ||
| 1868 | if (r8a66597->sudmac_reg == NULL) { | ||
| 1869 | dev_err(&pdev->dev, "ioremap error(sudmac).\n"); | ||
| 1870 | return -ENOMEM; | ||
| 1871 | } | ||
| 1872 | |||
| 1873 | return 0; | ||
| 1874 | } | ||
| 1875 | |||
| 1566 | static int __init r8a66597_probe(struct platform_device *pdev) | 1876 | static int __init r8a66597_probe(struct platform_device *pdev) |
| 1567 | { | 1877 | { |
| 1568 | #ifdef CONFIG_HAVE_CLK | 1878 | #ifdef CONFIG_HAVE_CLK |
| @@ -1579,7 +1889,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 1579 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1889 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1580 | if (!res) { | 1890 | if (!res) { |
| 1581 | ret = -ENODEV; | 1891 | ret = -ENODEV; |
| 1582 | printk(KERN_ERR "platform_get_resource error.\n"); | 1892 | dev_err(&pdev->dev, "platform_get_resource error.\n"); |
| 1583 | goto clean_up; | 1893 | goto clean_up; |
| 1584 | } | 1894 | } |
| 1585 | 1895 | ||
| @@ -1589,14 +1899,14 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 1589 | 1899 | ||
| 1590 | if (irq < 0) { | 1900 | if (irq < 0) { |
| 1591 | ret = -ENODEV; | 1901 | ret = -ENODEV; |
| 1592 | printk(KERN_ERR "platform_get_irq error.\n"); | 1902 | dev_err(&pdev->dev, "platform_get_irq error.\n"); |
| 1593 | goto clean_up; | 1903 | goto clean_up; |
| 1594 | } | 1904 | } |
| 1595 | 1905 | ||
| 1596 | reg = ioremap(res->start, resource_size(res)); | 1906 | reg = ioremap(res->start, resource_size(res)); |
| 1597 | if (reg == NULL) { | 1907 | if (reg == NULL) { |
| 1598 | ret = -ENOMEM; | 1908 | ret = -ENOMEM; |
| 1599 | printk(KERN_ERR "ioremap error.\n"); | 1909 | dev_err(&pdev->dev, "ioremap error.\n"); |
| 1600 | goto clean_up; | 1910 | goto clean_up; |
| 1601 | } | 1911 | } |
| 1602 | 1912 | ||
| @@ -1604,7 +1914,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 1604 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); | 1914 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); |
| 1605 | if (r8a66597 == NULL) { | 1915 | if (r8a66597 == NULL) { |
| 1606 | ret = -ENOMEM; | 1916 | ret = -ENOMEM; |
| 1607 | printk(KERN_ERR "kzalloc error\n"); | 1917 | dev_err(&pdev->dev, "kzalloc error\n"); |
| 1608 | goto clean_up; | 1918 | goto clean_up; |
| 1609 | } | 1919 | } |
| 1610 | 1920 | ||
| @@ -1640,13 +1950,18 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 29 unmodified lines | |||
| 1640 | clk_enable(r8a66597->clk); | 1950 | clk_enable(r8a66597->clk); |
| 1641 | } | 1951 | } |
| 1642 | #endif | 1952 | #endif |
| 1953 | if (r8a66597->pdata->sudmac) { | ||
| 1954 | ret = r8a66597_sudmac_ioremap(r8a66597, pdev); | ||
| 1955 | if (ret < 0) | ||
| 1956 | goto clean_up2; | ||
| 1957 | } | ||
| 1643 | 1958 | ||
| 1644 | disable_controller(r8a66597); /* make sure controller is disabled */ | 1959 | disable_controller(r8a66597); /* make sure controller is disabled */ |
| 1645 | 1960 | ||
| 1646 | ret = request_irq(irq, r8a66597_irq, IRQF_DISABLED | IRQF_SHARED, | 1961 | ret = request_irq(irq, r8a66597_irq, IRQF_SHARED, |
| 1647 | udc_name, r8a66597); | 1962 | udc_name, r8a66597); |
| 1648 | if (ret < 0) { | 1963 | if (ret < 0) { |
| 1649 | printk(KERN_ERR "request_irq error (%d)\n", ret); | 1964 | dev_err(&pdev->dev, "request_irq error (%d)\n", ret); |
| 1650 | goto clean_up2; | 1965 | goto clean_up2; |
| 1651 | } | 1966 | } |
| 1652 | 1967 | ||
| @@ -1672,13 +1987,10 @@ static int __init r8a66597_probe(struct platform_device *pdev) · 19 unmodified lines | |||
| 1672 | r8a66597->ep[0].fifoaddr = CFIFO; | 1987 | r8a66597->ep[0].fifoaddr = CFIFO; |
| 1673 | r8a66597->ep[0].fifosel = CFIFOSEL; | 1988 | r8a66597->ep[0].fifosel = CFIFOSEL; |
| 1674 | r8a66597->ep[0].fifoctr = CFIFOCTR; | 1989 | r8a66597->ep[0].fifoctr = CFIFOCTR; |
| 1675 | r8a66597->ep[0].fifotrn = 0; | ||
| 1676 | r8a66597->ep[0].pipectr = get_pipectr_addr(0); | 1990 | r8a66597->ep[0].pipectr = get_pipectr_addr(0); |
| 1677 | r8a66597->pipenum2ep[0] = &r8a66597->ep[0]; | 1991 | r8a66597->pipenum2ep[0] = &r8a66597->ep[0]; |
| 1678 | r8a66597->epaddr2ep[0] = &r8a66597->ep[0]; | 1992 | r8a66597->epaddr2ep[0] = &r8a66597->ep[0]; |
| 1679 | 1993 | ||
| 1680 | the_controller = r8a66597; | ||
| 1681 | |||
| 1682 | r8a66597->ep0_req = r8a66597_alloc_request(&r8a66597->ep[0].ep, | 1994 | r8a66597->ep0_req = r8a66597_alloc_request(&r8a66597->ep[0].ep, |
| 1683 | GFP_KERNEL); | 1995 | GFP_KERNEL); |
| 1684 | if (r8a66597->ep0_req == NULL) | 1996 | if (r8a66597->ep0_req == NULL) |
| @@ -1705,6 +2017,8 @@ clean_up2: · 20 unmodified lines | |||
| 1705 | #endif | 2017 | #endif |
| 1706 | clean_up: | 2018 | clean_up: |
| 1707 | if (r8a66597) { | 2019 | if (r8a66597) { |
| 2020 | if (r8a66597->sudmac_reg) | ||
| 2021 | iounmap(r8a66597->sudmac_reg); | ||
| 1708 | if (r8a66597->ep0_req) | 2022 | if (r8a66597->ep0_req) |
| 1709 | r8a66597_free_request(&r8a66597->ep[0].ep, | 2023 | r8a66597_free_request(&r8a66597->ep[0].ep, |
| 1710 | r8a66597->ep0_req); | 2024 | r8a66597->ep0_req); |
| @@ -8,16 +8,6 @@ · 7 unmodified lines | |||
| 8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; version 2 of the License. | 10 | * the Free Software Foundation; version 2 of the License. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | * | ||
| 21 | */ | 11 | */ |
| 22 | 12 | ||
| 23 | #ifndef __R8A66597_H__ | 13 | #ifndef __R8A66597_H__ |
| @@ -53,6 +43,7 @@ · 29 unmodified lines | |||
| 53 | ((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \ | 43 | ((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \ |
| 54 | (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC))) | 44 | (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC))) |
| 55 | 45 | ||
| 46 | #define r8a66597_is_sudmac(r8a66597) (r8a66597->pdata->sudmac) | ||
| 56 | struct r8a66597_pipe_info { | 47 | struct r8a66597_pipe_info { |
| 57 | u16 pipe; | 48 | u16 pipe; |
| 58 | u16 epnum; | 49 | u16 epnum; |
| @@ -70,6 +61,7 @@ struct r8a66597_request { · 11 unmodified lines | |||
| 70 | struct r8a66597_ep { | 61 | struct r8a66597_ep { |
| 71 | struct usb_ep ep; | 62 | struct usb_ep ep; |
| 72 | struct r8a66597 *r8a66597; | 63 | struct r8a66597 *r8a66597; |
| 64 | struct r8a66597_dma *dma; | ||
| 73 | 65 | ||
| 74 | struct list_head queue; | 66 | struct list_head queue; |
| 75 | unsigned busy:1; | 67 | unsigned busy:1; |
| @@ -85,13 +77,20 @@ struct r8a66597_ep { · 9 unmodified lines | |||
| 85 | unsigned char fifoaddr; | 77 | unsigned char fifoaddr; |
| 86 | unsigned char fifosel; | 78 | unsigned char fifosel; |
| 87 | unsigned char fifoctr; | 79 | unsigned char fifoctr; |
| 88 | unsigned char fifotrn; | ||
| 89 | unsigned char pipectr; | 80 | unsigned char pipectr; |
| 81 | unsigned char pipetre; | ||
| 82 | unsigned char pipetrn; | ||
| 83 | }; | ||
| 84 | |||
| 85 | struct r8a66597_dma { | ||
| 86 | unsigned used:1; | ||
| 87 | unsigned dir:1; /* 1 = IN(write), 0 = OUT(read) */ | ||
| 90 | }; | 88 | }; |
| 91 | 89 | ||
| 92 | struct r8a66597 { | 90 | struct r8a66597 { |
| 93 | spinlock_t lock; | 91 | spinlock_t lock; |
| 94 | void __iomem *reg; | 92 | void __iomem *reg; |
| 93 | void __iomem *sudmac_reg; | ||
| 95 | 94 | ||
| 96 | #ifdef CONFIG_HAVE_CLK | 95 | #ifdef CONFIG_HAVE_CLK |
| 97 | struct clk *clk; | 96 | struct clk *clk; |
| @@ -104,6 +103,7 @@ struct r8a66597 { · 6 unmodified lines | |||
| 104 | struct r8a66597_ep ep[R8A66597_MAX_NUM_PIPE]; | 103 | struct r8a66597_ep ep[R8A66597_MAX_NUM_PIPE]; |
| 105 | struct r8a66597_ep *pipenum2ep[R8A66597_MAX_NUM_PIPE]; | 104 | struct r8a66597_ep *pipenum2ep[R8A66597_MAX_NUM_PIPE]; |
| 106 | struct r8a66597_ep *epaddr2ep[16]; | 105 | struct r8a66597_ep *epaddr2ep[16]; |
| 106 | struct r8a66597_dma dma; | ||
| 107 | 107 | ||
| 108 | struct timer_list timer; | 108 | struct timer_list timer; |
| 109 | struct usb_request *ep0_req; /* for internal request */ | 109 | struct usb_request *ep0_req; /* for internal request */ |
| @@ -124,6 +124,7 @@ struct r8a66597 { · 14 unmodified lines | |||
| 124 | #define gadget_to_r8a66597(_gadget) \ | 124 | #define gadget_to_r8a66597(_gadget) \ |
| 125 | container_of(_gadget, struct r8a66597, gadget) | 125 | container_of(_gadget, struct r8a66597, gadget) |
| 126 | #define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget) | 126 | #define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget) |
| 127 | #define r8a66597_to_dev(r8a66597) (r8a66597->gadget.dev.parent) | ||
| 127 | 128 | ||
| 128 | static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) | 129 | static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) |
| 129 | { | 130 | { |
| @@ -182,12 +183,27 @@ static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, · 52 unmodified lines | |||
| 182 | iowrite16(val, r8a66597->reg + offset); | 183 | iowrite16(val, r8a66597->reg + offset); |
| 183 | } | 184 | } |
| 184 | 185 | ||
| 186 | static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, | ||
| 187 | u16 val, u16 pat, unsigned long offset) | ||
| 188 | { | ||
| 189 | u16 tmp; | ||
| 190 | tmp = r8a66597_read(r8a66597, offset); | ||
| 191 | tmp = tmp & (~pat); | ||
| 192 | tmp = tmp | val; | ||
| 193 | r8a66597_write(r8a66597, tmp, offset); | ||
| 194 | } | ||
| 195 | |||
| 196 | #define r8a66597_bclr(r8a66597, val, offset) \ | ||
| 197 | r8a66597_mdfy(r8a66597, 0, val, offset) | ||
| 198 | #define r8a66597_bset(r8a66597, val, offset) \ | ||
| 199 | r8a66597_mdfy(r8a66597, val, 0, offset) | ||
| 200 | |||
| 185 | static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, | 201 | static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, |
| 186 | unsigned long offset, | 202 | struct r8a66597_ep *ep, |
| 187 | unsigned char *buf, | 203 | unsigned char *buf, |
| 188 | int len) | 204 | int len) |
| 189 | { | 205 | { |
| 190 | void __iomem *fifoaddr = r8a66597->reg + offset; | 206 | void __iomem *fifoaddr = r8a66597->reg + ep->fifoaddr; |
| 191 | int adj = 0; | 207 | int adj = 0; |
| 192 | int i; | 208 | int i; |
| 193 | 209 | ||
| @@ -215,18 +231,12 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, · 21 unmodified lines | |||
| 215 | adj = 0x01; /* 16-bit wide */ | 231 | adj = 0x01; /* 16-bit wide */ |
| 216 | } | 232 | } |
| 217 | 233 | ||
| 234 | if (r8a66597->pdata->wr0_shorted_to_wr1) | ||
| 235 | r8a66597_bclr(r8a66597, MBW_16, ep->fifosel); | ||
| 218 | for (i = 0; i < len; i++) | 236 | for (i = 0; i < len; i++) |
| 219 | iowrite8(buf[i], fifoaddr + adj - (i & adj)); | 237 | iowrite8(buf[i], fifoaddr + adj - (i & adj)); |
| 220 | } | 238 | if (r8a66597->pdata->wr0_shorted_to_wr1) |
| 221 | 239 | r8a66597_bclr(r8a66597, MBW_16, ep->fifosel); | |
| 222 | static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, | ||
| 223 | u16 val, u16 pat, unsigned long offset) | ||
| 224 | { | ||
| 225 | u16 tmp; | ||
| 226 | tmp = r8a66597_read(r8a66597, offset); | ||
| 227 | tmp = tmp & (~pat); | ||
| 228 | tmp = tmp | val; | ||
| 229 | r8a66597_write(r8a66597, tmp, offset); | ||
| 230 | } | 240 | } |
| 231 | 241 | ||
| 232 | static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata) | 242 | static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata) |
| @@ -251,12 +261,21 @@ static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata) · 18 unmodified lines | |||
| 251 | return clock; | 261 | return clock; |
| 252 | } | 262 | } |
| 253 | 263 | ||
| 254 | #define r8a66597_bclr(r8a66597, val, offset) \ | 264 | static inline u32 r8a66597_sudmac_read(struct r8a66597 *r8a66597, |
| 255 | r8a66597_mdfy(r8a66597, 0, val, offset) | 265 | unsigned long offset) |
| 256 | #define r8a66597_bset(r8a66597, val, offset) \ | 266 | { |
| 257 | r8a66597_mdfy(r8a66597, val, 0, offset) | 267 | return ioread32(r8a66597->sudmac_reg + offset); |
| 268 | } | ||
| 269 | |||
| 270 | static inline void r8a66597_sudmac_write(struct r8a66597 *r8a66597, u32 val, | ||
| 271 | unsigned long offset) | ||
| 272 | { | ||
| 273 | iowrite32(val, r8a66597->sudmac_reg + offset); | ||
| 274 | } | ||
| 258 | 275 | ||
| 259 | #define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2) | 276 | #define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2) |
| 277 | #define get_pipetre_addr(pipenum) (PIPE1TRE + (pipenum - 1) * 4) | ||
| 278 | #define get_pipetrn_addr(pipenum) (PIPE1TRN + (pipenum - 1) * 4) | ||
| 260 | 279 | ||
| 261 | #define enable_irq_ready(r8a66597, pipenum) \ | 280 | #define enable_irq_ready(r8a66597, pipenum) \ |
| 262 | enable_pipe_irq(r8a66597, pipenum, BRDYENB) | 281 | enable_pipe_irq(r8a66597, pipenum, BRDYENB) |
| @@ -1951,30 +1951,26 @@ static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) · 1950 unmodified lines | |||
| 1951 | case S3C_DSTS_EnumSpd_FS: | 1951 | case S3C_DSTS_EnumSpd_FS: |
| 1952 | case S3C_DSTS_EnumSpd_FS48: | 1952 | case S3C_DSTS_EnumSpd_FS48: |
| 1953 | hsotg->gadget.speed = USB_SPEED_FULL; | 1953 | hsotg->gadget.speed = USB_SPEED_FULL; |
| 1954 | dev_info(hsotg->dev, "new device is full-speed\n"); | ||
| 1955 | |||
| 1956 | ep0_mps = EP0_MPS_LIMIT; | 1954 | ep0_mps = EP0_MPS_LIMIT; |
| 1957 | ep_mps = 64; | 1955 | ep_mps = 64; |
| 1958 | break; | 1956 | break; |
| 1959 | 1957 | ||
| 1960 | case S3C_DSTS_EnumSpd_HS: | 1958 | case S3C_DSTS_EnumSpd_HS: |
| 1961 | dev_info(hsotg->dev, "new device is high-speed\n"); | ||
| 1962 | hsotg->gadget.speed = USB_SPEED_HIGH; | 1959 | hsotg->gadget.speed = USB_SPEED_HIGH; |
| 1963 | |||
| 1964 | ep0_mps = EP0_MPS_LIMIT; | 1960 | ep0_mps = EP0_MPS_LIMIT; |
| 1965 | ep_mps = 512; | 1961 | ep_mps = 512; |
| 1966 | break; | 1962 | break; |
| 1967 | 1963 | ||
| 1968 | case S3C_DSTS_EnumSpd_LS: | 1964 | case S3C_DSTS_EnumSpd_LS: |
| 1969 | hsotg->gadget.speed = USB_SPEED_LOW; | 1965 | hsotg->gadget.speed = USB_SPEED_LOW; |
| 1970 | dev_info(hsotg->dev, "new device is low-speed\n"); | ||
| 1971 | |||
| 1972 | /* note, we don't actually support LS in this driver at the | 1966 | /* note, we don't actually support LS in this driver at the |
| 1973 | * moment, and the documentation seems to imply that it isn't | 1967 | * moment, and the documentation seems to imply that it isn't |
| 1974 | * supported by the PHYs on some of the devices. | 1968 | * supported by the PHYs on some of the devices. |
| 1975 | */ | 1969 | */ |
| 1976 | break; | 1970 | break; |
| 1977 | } | 1971 | } |
| 1972 | dev_info(hsotg->dev, "new device is %s\n", | ||
| 1973 | usb_speed_string(hsotg->gadget.speed)); | ||
| 1978 | 1974 | ||
| 1979 | /* we should now know the maximum packet size for an | 1975 | /* we should now know the maximum packet size for an |
| 1980 | * endpoint, so set the endpoints to a default value. */ | 1976 | * endpoint, so set the endpoints to a default value. */ |
| @@ -2297,7 +2293,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, · 316 unmodified lines | |||
| 2297 | return -EINVAL; | 2293 | return -EINVAL; |
| 2298 | } | 2294 | } |
| 2299 | 2295 | ||
| 2300 | mps = le16_to_cpu(desc->wMaxPacketSize); | 2296 | mps = usb_endpoint_maxp(desc); |
| 2301 | 2297 | ||
| 2302 | /* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */ | 2298 | /* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */ |
| 2303 | 2299 | ||
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
| 27 | #include <linux/usb/ch9.h> | 27 | #include <linux/usb/ch9.h> |
| 28 | #include <linux/usb/gadget.h> | 28 | #include <linux/usb/gadget.h> |
| 29 | #include <linux/usb/otg.h> | ||
| 29 | #include <linux/prefetch.h> | 30 | #include <linux/prefetch.h> |
| 30 | 31 | ||
| 31 | #include <mach/regs-s3c2443-clock.h> | 32 | #include <mach/regs-s3c2443-clock.h> |
| @@ -137,6 +138,7 @@ struct s3c_hsudc { · 105 unmodified lines | |||
| 137 | struct usb_gadget_driver *driver; | 138 | struct usb_gadget_driver *driver; |
| 138 | struct device *dev; | 139 | struct device *dev; |
| 139 | struct s3c24xx_hsudc_platdata *pd; | 140 | struct s3c24xx_hsudc_platdata *pd; |
| 141 | struct otg_transceiver *transceiver; | ||
| 140 | spinlock_t lock; | 142 | spinlock_t lock; |
| 141 | void __iomem *regs; | 143 | void __iomem *regs; |
| 142 | struct resource *mem_rsrc; | 144 | struct resource *mem_rsrc; |
| @@ -759,11 +761,11 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep, · 616 unmodified lines | |||
| 759 | if (!_ep || !desc || hsep->desc || _ep->name == ep0name | 761 | if (!_ep || !desc || hsep->desc || _ep->name == ep0name |
| 760 | || desc->bDescriptorType != USB_DT_ENDPOINT | 762 | || desc->bDescriptorType != USB_DT_ENDPOINT |
| 761 | || hsep->bEndpointAddress != desc->bEndpointAddress | 763 | || hsep->bEndpointAddress != desc->bEndpointAddress |
| 762 | || ep_maxpacket(hsep) < le16_to_cpu(desc->wMaxPacketSize)) | 764 | || ep_maxpacket(hsep) < usb_endpoint_maxp(desc)) |
| 763 | return -EINVAL; | 765 | return -EINVAL; |
| 764 | 766 | ||
| 765 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK | 767 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK |
| 766 | && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(hsep)) | 768 | && usb_endpoint_maxp(desc) != ep_maxpacket(hsep)) |
| 767 | || !desc->wMaxPacketSize) | 769 | || !desc->wMaxPacketSize) |
| 768 | return -ERANGE; | 770 | return -ERANGE; |
| 769 | 771 | ||
| @@ -779,7 +781,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep, · 9 unmodified lines | |||
| 779 | 781 | ||
| 780 | hsep->stopped = hsep->wedge = 0; | 782 | hsep->stopped = hsep->wedge = 0; |
| 781 | hsep->desc = desc; | 783 | hsep->desc = desc; |
| 782 | hsep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 784 | hsep->ep.maxpacket = usb_endpoint_maxp(desc); |
| 783 | 785 | ||
| 784 | s3c_hsudc_set_halt(_ep, 0); | 786 | s3c_hsudc_set_halt(_ep, 0); |
| 785 | __set_bit(ep_index(hsep), hsudc->regs + S3C_EIER); | 787 | __set_bit(ep_index(hsep), hsudc->regs + S3C_EIER); |
| @@ -1171,6 +1173,22 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, · 385 unmodified lines | |||
| 1171 | return ret; | 1173 | return ret; |
| 1172 | } | 1174 | } |
| 1173 | 1175 | ||
| 1176 | /* connect to bus through transceiver */ | ||
| 1177 | if (hsudc->transceiver) { | ||
| 1178 | ret = otg_set_peripheral(hsudc->transceiver, &hsudc->gadget); | ||
| 1179 | if (ret) { | ||
| 1180 | dev_err(hsudc->dev, "%s: can't bind to transceiver\n", | ||
| 1181 | hsudc->gadget.name); | ||
| 1182 | driver->unbind(&hsudc->gadget); | ||
| 1183 | |||
| 1184 | device_del(&hsudc->gadget.dev); | ||
| 1185 | |||
| 1186 | hsudc->driver = NULL; | ||
| 1187 | hsudc->gadget.dev.driver = NULL; | ||
| 1188 | return ret; | ||
| 1189 | } | ||
| 1190 | } | ||
| 1191 | |||
| 1174 | enable_irq(hsudc->irq); | 1192 | enable_irq(hsudc->irq); |
| 1175 | dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); | 1193 | dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); |
| 1176 | 1194 | ||
| @@ -1201,6 +1219,9 @@ static int s3c_hsudc_stop(struct usb_gadget_driver *driver) · 24 unmodified lines | |||
| 1201 | s3c_hsudc_stop_activity(hsudc, driver); | 1219 | s3c_hsudc_stop_activity(hsudc, driver); |
| 1202 | spin_unlock_irqrestore(&hsudc->lock, flags); | 1220 | spin_unlock_irqrestore(&hsudc->lock, flags); |
| 1203 | 1221 | ||
| 1222 | if (hsudc->transceiver) | ||
| 1223 | (void) otg_set_peripheral(hsudc->transceiver, NULL); | ||
| 1224 | |||
| 1204 | driver->unbind(&hsudc->gadget); | 1225 | driver->unbind(&hsudc->gadget); |
| 1205 | device_del(&hsudc->gadget.dev); | 1226 | device_del(&hsudc->gadget.dev); |
| 1206 | disable_irq(hsudc->irq); | 1227 | disable_irq(hsudc->irq); |
| @@ -1220,10 +1241,24 @@ static int s3c_hsudc_gadget_getframe(struct usb_gadget *gadget) · 13 unmodified lines | |||
| 1220 | return s3c_hsudc_read_frameno(to_hsudc(gadget)); | 1241 | return s3c_hsudc_read_frameno(to_hsudc(gadget)); |
| 1221 | } | 1242 | } |
| 1222 | 1243 | ||
| 1244 | static int s3c_hsudc_vbus_draw(struct usb_gadget *gadget, unsigned mA) | ||
| 1245 | { | ||
| 1246 | struct s3c_hsudc *hsudc = the_controller; | ||
| 1247 | |||
| 1248 | if (!hsudc) | ||
| 1249 | return -ENODEV; | ||
| 1250 | |||
| 1251 | if (hsudc->transceiver) | ||
| 1252 | return otg_set_power(hsudc->transceiver, mA); | ||
| 1253 | |||
| 1254 | return -EOPNOTSUPP; | ||
| 1255 | } | ||
| 1256 | |||
| 1223 | static struct usb_gadget_ops s3c_hsudc_gadget_ops = { | 1257 | static struct usb_gadget_ops s3c_hsudc_gadget_ops = { |
| 1224 | .get_frame = s3c_hsudc_gadget_getframe, | 1258 | .get_frame = s3c_hsudc_gadget_getframe, |
| 1225 | .start = s3c_hsudc_start, | 1259 | .start = s3c_hsudc_start, |
| 1226 | .stop = s3c_hsudc_stop, | 1260 | .stop = s3c_hsudc_stop, |
| 1261 | .vbus_draw = s3c_hsudc_vbus_draw, | ||
| 1227 | }; | 1262 | }; |
| 1228 | 1263 | ||
| 1229 | static int s3c_hsudc_probe(struct platform_device *pdev) | 1264 | static int s3c_hsudc_probe(struct platform_device *pdev) |
| @@ -1247,6 +1282,8 @@ static int s3c_hsudc_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 1247 | hsudc->dev = dev; | 1282 | hsudc->dev = dev; |
| 1248 | hsudc->pd = pdev->dev.platform_data; | 1283 | hsudc->pd = pdev->dev.platform_data; |
| 1249 | 1284 | ||
| 1285 | hsudc->transceiver = otg_get_transceiver(); | ||
| 1286 | |||
| 1250 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1287 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1251 | if (!res) { | 1288 | if (!res) { |
| 1252 | dev_err(dev, "unable to obtain driver resource data\n"); | 1289 | dev_err(dev, "unable to obtain driver resource data\n"); |
| @@ -1269,19 +1306,6 @@ static int s3c_hsudc_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 1269 | goto err_remap; | 1306 | goto err_remap; |
| 1270 | } | 1307 | } |
| 1271 | 1308 | ||
| 1272 | ret = platform_get_irq(pdev, 0); | ||
| 1273 | if (ret < 0) { | ||
| 1274 | dev_err(dev, "unable to obtain IRQ number\n"); | ||
| 1275 | goto err_irq; | ||
| 1276 | } | ||
| 1277 | hsudc->irq = ret; | ||
| 1278 | |||
| 1279 | ret = request_irq(hsudc->irq, s3c_hsudc_irq, 0, driver_name, hsudc); | ||
| 1280 | if (ret < 0) { | ||
| 1281 | dev_err(dev, "irq request failed\n"); | ||
| 1282 | goto err_irq; | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | spin_lock_init(&hsudc->lock); | 1309 | spin_lock_init(&hsudc->lock); |
| 1286 | 1310 | ||
| 1287 | device_initialize(&hsudc->gadget.dev); | 1311 | device_initialize(&hsudc->gadget.dev); |
| @@ -1299,6 +1323,19 @@ static int s3c_hsudc_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 1299 | 1323 | ||
| 1300 | s3c_hsudc_setup_ep(hsudc); | 1324 | s3c_hsudc_setup_ep(hsudc); |
| 1301 | 1325 | ||
| 1326 | ret = platform_get_irq(pdev, 0); | ||
| 1327 | if (ret < 0) { | ||
| 1328 | dev_err(dev, "unable to obtain IRQ number\n"); | ||
| 1329 | goto err_irq; | ||
| 1330 | } | ||
| 1331 | hsudc->irq = ret; | ||
| 1332 | |||
| 1333 | ret = request_irq(hsudc->irq, s3c_hsudc_irq, 0, driver_name, hsudc); | ||
| 1334 | if (ret < 0) { | ||
| 1335 | dev_err(dev, "irq request failed\n"); | ||
| 1336 | goto err_irq; | ||
| 1337 | } | ||
| 1338 | |||
| 1302 | hsudc->uclk = clk_get(&pdev->dev, "usb-device"); | 1339 | hsudc->uclk = clk_get(&pdev->dev, "usb-device"); |
| 1303 | if (IS_ERR(hsudc->uclk)) { | 1340 | if (IS_ERR(hsudc->uclk)) { |
| 1304 | dev_err(dev, "failed to find usb-device clock source\n"); | 1341 | dev_err(dev, "failed to find usb-device clock source\n"); |
| @@ -10,16 +10,6 @@ · 9 unmodified lines | |||
| 10 | * it under the terms of the GNU General Public License as published by | 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 | 11 | * the Free Software Foundation; either version 2 of the License, or |
| 12 | * (at your option) any later version. | 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 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | * | ||
| 23 | */ | 13 | */ |
| 24 | 14 | ||
| 25 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| @@ -1082,7 +1072,7 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep, · 1056 unmodified lines | |||
| 1082 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | 1072 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) |
| 1083 | return -ESHUTDOWN; | 1073 | return -ESHUTDOWN; |
| 1084 | 1074 | ||
| 1085 | max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff; | 1075 | max = usb_endpoint_maxp(desc) & 0x1fff; |
| 1086 | 1076 | ||
| 1087 | local_irq_save (flags); | 1077 | local_irq_save (flags); |
| 1088 | _ep->maxpacket = max & 0x7ff; | 1078 | _ep->maxpacket = max & 0x7ff; |
| @@ -1903,7 +1893,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) · 814 unmodified lines | |||
| 1903 | 1893 | ||
| 1904 | /* irq setup after old hardware state is cleaned up */ | 1894 | /* irq setup after old hardware state is cleaned up */ |
| 1905 | retval = request_irq(IRQ_USBD, s3c2410_udc_irq, | 1895 | retval = request_irq(IRQ_USBD, s3c2410_udc_irq, |
| 1906 | IRQF_DISABLED, gadget_name, udc); | 1896 | 0, gadget_name, udc); |
| 1907 | 1897 | ||
| 1908 | if (retval != 0) { | 1898 | if (retval != 0) { |
| 1909 | dev_err(dev, "cannot get irq %i, err %d\n", IRQ_USBD, retval); | 1899 | dev_err(dev, "cannot get irq %i, err %d\n", IRQ_USBD, retval); |
| @@ -1927,7 +1917,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 1927 | } | 1917 | } |
| 1928 | 1918 | ||
| 1929 | retval = request_irq(irq, s3c2410_udc_vbus_irq, | 1919 | retval = request_irq(irq, s3c2410_udc_vbus_irq, |
| 1930 | IRQF_DISABLED | IRQF_TRIGGER_RISING | 1920 | IRQF_TRIGGER_RISING |
| 1931 | | IRQF_TRIGGER_FALLING | IRQF_SHARED, | 1921 | | IRQF_TRIGGER_FALLING | IRQF_SHARED, |
| 1932 | gadget_name, udc); | 1922 | gadget_name, udc); |
| 1933 | 1923 | ||
| @@ -9,16 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | * | ||
| 22 | */ | 12 | */ |
| 23 | 13 | ||
| 24 | #ifndef _S3C2410_UDC_H | 14 | #ifndef _S3C2410_UDC_H |
| @@ -9,15 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | 12 | */ |
| 22 | 13 | ||
| 23 | 14 | ||
| @@ -52,6 +43,12 @@ · 28 unmodified lines | |||
| 52 | * characters rather then a pointer to void. | 43 | * characters rather then a pointer to void. |
| 53 | */ | 44 | */ |
| 54 | 45 | ||
| 46 | /* | ||
| 47 | * When USB_GADGET_DEBUG_FILES is defined the module param num_buffers | ||
| 48 | * sets the number of pipeline buffers (length of the fsg_buffhd array). | ||
| 49 | * The valid range of num_buffers is: num >= 2 && num <= 4. | ||
| 50 | */ | ||
| 51 | |||
| 55 | 52 | ||
| 56 | #include <linux/usb/storage.h> | 53 | #include <linux/usb/storage.h> |
| 57 | #include <scsi/scsi.h> | 54 | #include <scsi/scsi.h> |
| @@ -247,6 +244,8 @@ struct fsg_lun { · 189 unmodified lines | |||
| 247 | u32 sense_data_info; | 244 | u32 sense_data_info; |
| 248 | u32 unit_attention_data; | 245 | u32 unit_attention_data; |
| 249 | 246 | ||
| 247 | unsigned int blkbits; /* Bits of logical block size of bound block device */ | ||
| 248 | unsigned int blksize; /* logical block size of bound block device */ | ||
| 250 | struct device dev; | 249 | struct device dev; |
| 251 | }; | 250 | }; |
| 252 | 251 | ||
| @@ -262,8 +261,31 @@ static struct fsg_lun *fsg_lun_from_dev(struct device *dev) · 9 unmodified lines | |||
| 262 | #define EP0_BUFSIZE 256 | 261 | #define EP0_BUFSIZE 256 |
| 263 | #define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */ | 262 | #define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */ |
| 264 | 263 | ||
| 265 | /* Number of buffers we will use. 2 is enough for double-buffering */ | 264 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
| 266 | #define FSG_NUM_BUFFERS 2 | 265 | |
| 266 | static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; | ||
| 267 | module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO); | ||
| 268 | MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers"); | ||
| 269 | |||
| 270 | #else | ||
| 271 | |||
| 272 | /* | ||
| 273 | * Number of buffers we will use. | ||
| 274 | * 2 is usually enough for good buffering pipeline | ||
| 275 | */ | ||
| 276 | #define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS | ||
| 277 | |||
| 278 | #endif /* CONFIG_USB_DEBUG */ | ||
| 279 | |||
| 280 | /* check if fsg_num_buffers is within a valid range */ | ||
| 281 | static inline int fsg_num_buffers_validate(void) | ||
| 282 | { | ||
| 283 | if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4) | ||
| 284 | return 0; | ||
| 285 | pr_err("fsg_num_buffers %u is out of range (%d to %d)\n", | ||
| 286 | fsg_num_buffers, 2 ,4); | ||
| 287 | return -EINVAL; | ||
| 288 | } | ||
| 267 | 289 | ||
| 268 | /* Default size of buffer length. */ | 290 | /* Default size of buffer length. */ |
| 269 | #define FSG_BUFLEN ((u32)16384) | 291 | #define FSG_BUFLEN ((u32)16384) |
| @@ -493,12 +515,128 @@ static struct usb_descriptor_header *fsg_hs_function[] = { · 223 unmodified lines | |||
| 493 | NULL, | 515 | NULL, |
| 494 | }; | 516 | }; |
| 495 | 517 | ||
| 518 | static struct usb_endpoint_descriptor | ||
| 519 | fsg_ss_bulk_in_desc = { | ||
| 520 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 521 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 522 | |||
| 523 | /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ | ||
| 524 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 525 | .wMaxPacketSize = cpu_to_le16(1024), | ||
| 526 | }; | ||
| 527 | |||
| 528 | static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { | ||
| 529 | .bLength = sizeof(fsg_ss_bulk_in_comp_desc), | ||
| 530 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
| 531 | |||
| 532 | /*.bMaxBurst = DYNAMIC, */ | ||
| 533 | }; | ||
| 534 | |||
| 535 | static struct usb_endpoint_descriptor | ||
| 536 | fsg_ss_bulk_out_desc = { | ||
| 537 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 538 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 539 | |||
| 540 | /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ | ||
| 541 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 542 | .wMaxPacketSize = cpu_to_le16(1024), | ||
| 543 | }; | ||
| 544 | |||
| 545 | static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { | ||
| 546 | .bLength = sizeof(fsg_ss_bulk_in_comp_desc), | ||
| 547 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
| 548 | |||
| 549 | /*.bMaxBurst = DYNAMIC, */ | ||
| 550 | }; | ||
| 551 | |||
| 552 | #ifndef FSG_NO_INTR_EP | ||
| 553 | |||
| 554 | static struct usb_endpoint_descriptor | ||
| 555 | fsg_ss_intr_in_desc = { | ||
| 556 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 557 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 558 | |||
| 559 | /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ | ||
| 560 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
| 561 | .wMaxPacketSize = cpu_to_le16(2), | ||
| 562 | .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */ | ||
| 563 | }; | ||
| 564 | |||
| 565 | static struct usb_ss_ep_comp_descriptor fsg_ss_intr_in_comp_desc = { | ||
| 566 | .bLength = sizeof(fsg_ss_bulk_in_comp_desc), | ||
| 567 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
| 568 | |||
| 569 | .wBytesPerInterval = cpu_to_le16(2), | ||
| 570 | }; | ||
| 571 | |||
| 572 | #ifndef FSG_NO_OTG | ||
| 573 | # define FSG_SS_FUNCTION_PRE_EP_ENTRIES 2 | ||
| 574 | #else | ||
| 575 | # define FSG_SS_FUNCTION_PRE_EP_ENTRIES 1 | ||
| 576 | #endif | ||
| 577 | |||
| 578 | #endif | ||
| 579 | |||
| 580 | static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = { | ||
| 581 | .bLength = USB_DT_USB_EXT_CAP_SIZE, | ||
| 582 | .bDescriptorType = USB_DT_DEVICE_CAPABILITY, | ||
| 583 | .bDevCapabilityType = USB_CAP_TYPE_EXT, | ||
| 584 | |||
| 585 | .bmAttributes = cpu_to_le32(USB_LPM_SUPPORT), | ||
| 586 | }; | ||
| 587 | |||
| 588 | static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = { | ||
| 589 | .bLength = USB_DT_USB_SS_CAP_SIZE, | ||
| 590 | .bDescriptorType = USB_DT_DEVICE_CAPABILITY, | ||
| 591 | .bDevCapabilityType = USB_SS_CAP_TYPE, | ||
| 592 | |||
| 593 | /* .bmAttributes = LTM is not supported yet */ | ||
| 594 | |||
| 595 | .wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION | ||
| 596 | | USB_FULL_SPEED_OPERATION | ||
| 597 | | USB_HIGH_SPEED_OPERATION | ||
| 598 | | USB_5GBPS_OPERATION), | ||
| 599 | .bFunctionalitySupport = USB_LOW_SPEED_OPERATION, | ||
| 600 | .bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT, | ||
| 601 | .bU2DevExitLat = USB_DEFAULT_U2_DEV_EXIT_LAT, | ||
| 602 | }; | ||
| 603 | |||
| 604 | static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = { | ||
| 605 | .bLength = USB_DT_BOS_SIZE, | ||
| 606 | .bDescriptorType = USB_DT_BOS, | ||
| 607 | |||
| 608 | .wTotalLength = USB_DT_BOS_SIZE | ||
| 609 | + USB_DT_USB_EXT_CAP_SIZE | ||
| 610 | + USB_DT_USB_SS_CAP_SIZE, | ||
| 611 | |||
| 612 | .bNumDeviceCaps = 2, | ||
| 613 | }; | ||
| 614 | |||
| 615 | static struct usb_descriptor_header *fsg_ss_function[] = { | ||
| 616 | #ifndef FSG_NO_OTG | ||
| 617 | (struct usb_descriptor_header *) &fsg_otg_desc, | ||
| 618 | #endif | ||
| 619 | (struct usb_descriptor_header *) &fsg_intf_desc, | ||
| 620 | (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc, | ||
| 621 | (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc, | ||
| 622 | (struct usb_descriptor_header *) &fsg_ss_bulk_out_desc, | ||
| 623 | (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc, | ||
| 624 | #ifndef FSG_NO_INTR_EP | ||
| 625 | (struct usb_descriptor_header *) &fsg_ss_intr_in_desc, | ||
| 626 | (struct usb_descriptor_header *) &fsg_ss_intr_in_comp_desc, | ||
| 627 | #endif | ||
| 628 | NULL, | ||
| 629 | }; | ||
| 630 | |||
| 496 | /* Maxpacket and other transfer characteristics vary by speed. */ | 631 | /* Maxpacket and other transfer characteristics vary by speed. */ |
| 497 | static __maybe_unused struct usb_endpoint_descriptor * | 632 | static __maybe_unused struct usb_endpoint_descriptor * |
| 498 | fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, | 633 | fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, |
| 499 | struct usb_endpoint_descriptor *hs) | 634 | struct usb_endpoint_descriptor *hs, |
| 635 | struct usb_endpoint_descriptor *ss) | ||
| 500 | { | 636 | { |
| 501 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | 637 | if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) |
| 638 | return ss; | ||
| 639 | else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
| 502 | return hs; | 640 | return hs; |
| 503 | return fs; | 641 | return fs; |
| 504 | } | 642 | } |
| @@ -580,13 +718,24 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) · 75 unmodified lines | |||
| 580 | rc = (int) size; | 718 | rc = (int) size; |
| 581 | goto out; | 719 | goto out; |
| 582 | } | 720 | } |
| 583 | num_sectors = size >> 9; /* File size in 512-byte blocks */ | 721 | |
| 722 | if (curlun->cdrom) { | ||
| 723 | curlun->blksize = 2048; | ||
| 724 | curlun->blkbits = 11; | ||
| 725 | } else if (inode->i_bdev) { | ||
| 726 | curlun->blksize = bdev_logical_block_size(inode->i_bdev); | ||
| 727 | curlun->blkbits = blksize_bits(curlun->blksize); | ||
| 728 | } else { | ||
| 729 | curlun->blksize = 512; | ||
| 730 | curlun->blkbits = 9; | ||
| 731 | } | ||
| 732 | |||
| 733 | num_sectors = size >> curlun->blkbits; /* File size in logic-block-size blocks */ | ||
| 584 | min_sectors = 1; | 734 | min_sectors = 1; |
| 585 | if (curlun->cdrom) { | 735 | if (curlun->cdrom) { |
| 586 | num_sectors &= ~3; /* Reduce to a multiple of 2048 */ | 736 | min_sectors = 300; /* Smallest track is 300 frames */ |
| 587 | min_sectors = 300*4; /* Smallest track is 300 frames */ | 737 | if (num_sectors >= 256*60*75) { |
| 588 | if (num_sectors >= 256*60*75*4) { | 738 | num_sectors = 256*60*75 - 1; |
| 589 | num_sectors = (256*60*75 - 1) * 4; | ||
| 590 | LINFO(curlun, "file too big: %s\n", filename); | 739 | LINFO(curlun, "file too big: %s\n", filename); |
| 591 | LINFO(curlun, "using only first %d blocks\n", | 740 | LINFO(curlun, "using only first %d blocks\n", |
| 592 | (int) num_sectors); | 741 | (int) num_sectors); |
| @@ -9,15 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | 12 | */ |
| 22 | 13 | ||
| 23 | /* #define VERBOSE_DEBUG */ | 14 | /* #define VERBOSE_DEBUG */ |
| @@ -9,15 +9,6 @@ · 8 unmodified lines | |||
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | 12 | */ |
| 22 | 13 | ||
| 23 | #ifndef __U_ETHER_H | 14 | #ifndef __U_ETHER_H |
| @@ -552,9 +552,8 @@ recycle: · 551 unmodified lines | |||
| 552 | /* Push from tty to ldisc; without low_latency set this is handled by | 552 | /* Push from tty to ldisc; without low_latency set this is handled by |
| 553 | * a workqueue, so we won't get callbacks and can hold port_lock | 553 | * a workqueue, so we won't get callbacks and can hold port_lock |
| 554 | */ | 554 | */ |
| 555 | if (tty && do_push) { | 555 | if (tty && do_push) |
| 556 | tty_flip_buffer_push(tty); | 556 | tty_flip_buffer_push(tty); |
| 557 | } | ||
| 558 | 557 | ||
| 559 | 558 | ||
| 560 | /* We want our data queue to become empty ASAP, keeping data | 559 | /* We want our data queue to become empty ASAP, keeping data |
| @@ -356,7 +356,7 @@ static DEVICE_ATTR(srp, S_IWUSR, NULL, usb_udc_srp_store); · 355 unmodified lines | |||
| 356 | static ssize_t usb_udc_softconn_store(struct device *dev, | 356 | static ssize_t usb_udc_softconn_store(struct device *dev, |
| 357 | struct device_attribute *attr, const char *buf, size_t n) | 357 | struct device_attribute *attr, const char *buf, size_t n) |
| 358 | { | 358 | { |
| 359 | struct usb_udc *udc = dev_get_drvdata(dev); | 359 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); |
| 360 | 360 | ||
| 361 | if (sysfs_streq(buf, "connect")) { | 361 | if (sysfs_streq(buf, "connect")) { |
| 362 | usb_gadget_connect(udc->gadget); | 362 | usb_gadget_connect(udc->gadget); |
| @@ -375,23 +375,8 @@ static ssize_t usb_udc_speed_show(struct device *dev, · 12 unmodified lines | |||
| 375 | struct device_attribute *attr, char *buf) | 375 | struct device_attribute *attr, char *buf) |
| 376 | { | 376 | { |
| 377 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); | 377 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); |
| 378 | struct usb_gadget *gadget = udc->gadget; | 378 | return snprintf(buf, PAGE_SIZE, "%s\n", |
| 379 | 379 | usb_speed_string(udc->gadget->speed)); | |
| 380 | switch (gadget->speed) { | ||
| 381 | case USB_SPEED_LOW: | ||
| 382 | return snprintf(buf, PAGE_SIZE, "low-speed\n"); | ||
| 383 | case USB_SPEED_FULL: | ||
| 384 | return snprintf(buf, PAGE_SIZE, "full-speed\n"); | ||
| 385 | case USB_SPEED_HIGH: | ||
| 386 | return snprintf(buf, PAGE_SIZE, "high-speed\n"); | ||
| 387 | case USB_SPEED_WIRELESS: | ||
| 388 | return snprintf(buf, PAGE_SIZE, "wireless\n"); | ||
| 389 | case USB_SPEED_SUPER: | ||
| 390 | return snprintf(buf, PAGE_SIZE, "super-speed\n"); | ||
| 391 | case USB_SPEED_UNKNOWN: /* FALLTHROUGH */ | ||
| 392 | default: | ||
| 393 | return snprintf(buf, PAGE_SIZE, "UNKNOWN\n"); | ||
| 394 | } | ||
| 395 | } | 380 | } |
| 396 | static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); | 381 | static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); |
| 397 | 382 | ||
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | */ | 11 | */ |
| 13 | 12 | ||
| 14 | #ifndef _UVC_GADGET_H_ | 13 | #ifndef _UVC_GADGET_H_ |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | */ | 11 | */ |
| 13 | 12 | ||
| 14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | */ | 11 | */ |
| 13 | 12 | ||
| 14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | */ | 11 | */ |
| 13 | 12 | ||
| 14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| @@ -8,8 +8,8 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | */ | 11 | */ |
| 12 | |||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
| 15 | #include <linux/usb/video.h> | 15 | #include <linux/usb/video.h> |
| @@ -8,15 +8,6 @@ · 7 unmodified lines | |||
| 8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | 11 | */ |
| 21 | 12 | ||
| 22 | 13 | ||
| @@ -19,7 +19,7 @@ config USB_C67X00_HCD · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | config USB_XHCI_HCD | 20 | config USB_XHCI_HCD |
| 21 | tristate "xHCI HCD (USB 3.0) support (EXPERIMENTAL)" | 21 | tristate "xHCI HCD (USB 3.0) support (EXPERIMENTAL)" |
| 22 | depends on USB && PCI && EXPERIMENTAL | 22 | depends on USB && USB_ARCH_HAS_XHCI && EXPERIMENTAL |
| 23 | ---help--- | 23 | ---help--- |
| 24 | The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0 | 24 | The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0 |
| 25 | "SuperSpeed" host controller hardware. | 25 | "SuperSpeed" host controller hardware. |
| @@ -515,6 +515,19 @@ config USB_R8A66597_HCD · 489 unmodified lines | |||
| 515 | To compile this driver as a module, choose M here: the | 515 | To compile this driver as a module, choose M here: the |
| 516 | module will be called r8a66597-hcd. | 516 | module will be called r8a66597-hcd. |
| 517 | 517 | ||
| 518 | config USB_RENESAS_USBHS_HCD | ||
| 519 | tristate "Renesas USBHS HCD support" | ||
| 520 | depends on USB | ||
| 521 | depends on USB_RENESAS_USBHS | ||
| 522 | help | ||
| 523 | The Renesas USBHS is a USB 2.0 host and peripheral controller. | ||
| 524 | |||
| 525 | Enable this option if your board has this chip, and you want | ||
| 526 | to use it as a host controller. If unsure, say N. | ||
| 527 | |||
| 528 | To compile this driver as a module, choose M here: the | ||
| 529 | module will be called renesas-usbhs. | ||
| 530 | |||
| 518 | config USB_WHCI_HCD | 531 | config USB_WHCI_HCD |
| 519 | tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)" | 532 | tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)" |
| 520 | depends on EXPERIMENTAL | 533 | depends on EXPERIMENTAL |
| @@ -544,11 +557,11 @@ config USB_HWA_HCD · 23 unmodified lines | |||
| 544 | will be called "hwa-hc". | 557 | will be called "hwa-hc". |
| 545 | 558 | ||
| 546 | config USB_IMX21_HCD | 559 | config USB_IMX21_HCD |
| 547 | tristate "iMX21 HCD support" | 560 | tristate "i.MX21 HCD support" |
| 548 | depends on USB && ARM && MACH_MX21 | 561 | depends on USB && ARM && ARCH_MXC |
| 549 | help | 562 | help |
| 550 | This driver enables support for the on-chip USB host in the | 563 | This driver enables support for the on-chip USB host in the |
| 551 | iMX21 processor. | 564 | i.MX21 processor. |
| 552 | 565 | ||
| 553 | To compile this driver as a module, choose M here: the | 566 | To compile this driver as a module, choose M here: the |
| 554 | module will be called "imx21-hcd". | 567 | module will be called "imx21-hcd". |
| @@ -578,3 +591,10 @@ config USB_OCTEON_OHCI · 23 unmodified lines | |||
| 578 | config USB_OCTEON2_COMMON | 591 | config USB_OCTEON2_COMMON |
| 579 | bool | 592 | bool |
| 580 | default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI | 593 | default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI |
| 594 | |||
| 595 | config USB_PXA168_EHCI | ||
| 596 | bool "Marvell PXA168 on-chip EHCI HCD support" | ||
| 597 | depends on USB_EHCI_HCD && ARCH_MMP | ||
| 598 | help | ||
| 599 | Enable support for Marvell PXA168 SoC's on-chip EHCI | ||
| 600 | host controller | ||
| @@ -11,8 +11,9 @@ fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o | 12 | fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o |
| 13 | 13 | ||
| 14 | xhci-hcd-y := xhci.o xhci-mem.o xhci-pci.o | 14 | xhci-hcd-y := xhci.o xhci-mem.o |
| 15 | xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o | 15 | xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o |
| 16 | xhci-hcd-$(CONFIG_PCI) += xhci-pci.o | ||
| 16 | 17 | ||
| 17 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ | 18 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ |
| 18 | 19 | ||
| @@ -163,7 +163,7 @@ static int ehci_ath79_probe(struct platform_device *pdev) · 162 unmodified lines | |||
| 163 | goto err_release_region; | 163 | goto err_release_region; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 166 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 167 | if (ret) | 167 | if (ret) |
| 168 | goto err_iounmap; | 168 | goto err_iounmap; |
| 169 | 169 | ||
| @@ -181,7 +181,7 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) · 180 unmodified lines | |||
| 181 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 181 | ehci->hcs_params = readl(&ehci->caps->hcs_params); |
| 182 | 182 | ||
| 183 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | 183 | ret = usb_add_hcd(hcd, pdev->resource[1].start, |
| 184 | IRQF_DISABLED | IRQF_SHARED); | 184 | IRQF_SHARED); |
| 185 | if (ret == 0) { | 185 | if (ret == 0) { |
| 186 | platform_set_drvdata(pdev, hcd); | 186 | platform_set_drvdata(pdev, hcd); |
| 187 | return ret; | 187 | return ret; |
| @@ -293,7 +293,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev) · 105 unmodified lines | |||
| 293 | /* here we "know" root ports should always stay powered */ | 293 | /* here we "know" root ports should always stay powered */ |
| 294 | ehci_port_power(ehci, 1); | 294 | ehci_port_power(ehci, 1); |
| 295 | 295 | ||
| 296 | hcd->state = HC_STATE_SUSPENDED; | 296 | ehci->rh_state = EHCI_RH_SUSPENDED; |
| 297 | 297 | ||
| 298 | return 0; | 298 | return 0; |
| 299 | } | 299 | } |
| @@ -697,6 +697,19 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) · 696 unmodified lines | |||
| 697 | } | 697 | } |
| 698 | #undef DBG_SCHED_LIMIT | 698 | #undef DBG_SCHED_LIMIT |
| 699 | 699 | ||
| 700 | static const char *rh_state_string(struct ehci_hcd *ehci) | ||
| 701 | { | ||
| 702 | switch (ehci->rh_state) { | ||
| 703 | case EHCI_RH_HALTED: | ||
| 704 | return "halted"; | ||
| 705 | case EHCI_RH_SUSPENDED: | ||
| 706 | return "suspended"; | ||
| 707 | case EHCI_RH_RUNNING: | ||
| 708 | return "running"; | ||
| 709 | } | ||
| 710 | return "?"; | ||
| 711 | } | ||
| 712 | |||
| 700 | static ssize_t fill_registers_buffer(struct debug_buffer *buf) | 713 | static ssize_t fill_registers_buffer(struct debug_buffer *buf) |
| 701 | { | 714 | { |
| 702 | struct usb_hcd *hcd; | 715 | struct usb_hcd *hcd; |
| @@ -730,11 +743,11 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) · 27 unmodified lines | |||
| 730 | temp = scnprintf (next, size, | 743 | temp = scnprintf (next, size, |
| 731 | "bus %s, device %s\n" | 744 | "bus %s, device %s\n" |
| 732 | "%s\n" | 745 | "%s\n" |
| 733 | "EHCI %x.%02x, hcd state %d\n", | 746 | "EHCI %x.%02x, rh state %s\n", |
| 734 | hcd->self.controller->bus->name, | 747 | hcd->self.controller->bus->name, |
| 735 | dev_name(hcd->self.controller), | 748 | dev_name(hcd->self.controller), |
| 736 | hcd->product_desc, | 749 | hcd->product_desc, |
| 737 | i >> 8, i & 0x0ff, hcd->state); | 750 | i >> 8, i & 0x0ff, rh_state_string(ehci)); |
| 738 | size -= temp; | 751 | size -= temp; |
| 739 | next += temp; | 752 | next += temp; |
| 740 | 753 | ||
| @@ -808,7 +821,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) · 67 unmodified lines | |||
| 808 | next += temp; | 821 | next += temp; |
| 809 | 822 | ||
| 810 | temp = scnprintf (next, size, "uframe %04x\n", | 823 | temp = scnprintf (next, size, "uframe %04x\n", |
| 811 | ehci_readl(ehci, &ehci->regs->frame_index)); | 824 | ehci_read_frame_index(ehci)); |
| 812 | size -= temp; | 825 | size -= temp; |
| 813 | next += temp; | 826 | next += temp; |
| 814 | 827 | ||
| @@ -134,7 +134,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, · 133 unmodified lines | |||
| 134 | 134 | ||
| 135 | /* Don't need to set host mode here. It will be done by tdi_reset() */ | 135 | /* Don't need to set host mode here. It will be done by tdi_reset() */ |
| 136 | 136 | ||
| 137 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 137 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 138 | if (retval != 0) | 138 | if (retval != 0) |
| 139 | goto err4; | 139 | goto err4; |
| 140 | 140 | ||
| @@ -392,7 +392,7 @@ static int ehci_fsl_mpc512x_drv_suspend(struct device *dev) · 251 unmodified lines | |||
| 392 | 392 | ||
| 393 | dev_dbg(dev, "suspending...\n"); | 393 | dev_dbg(dev, "suspending...\n"); |
| 394 | 394 | ||
| 395 | hcd->state = HC_STATE_SUSPENDED; | 395 | ehci->rh_state = EHCI_RH_SUSPENDED; |
| 396 | dev->power.power_state = PMSG_SUSPEND; | 396 | dev->power.power_state = PMSG_SUSPEND; |
| 397 | 397 | ||
| 398 | /* ignore non-host interrupts */ | 398 | /* ignore non-host interrupts */ |
| @@ -481,7 +481,7 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev) · 82 unmodified lines | |||
| 481 | ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]); | 481 | ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]); |
| 482 | 482 | ||
| 483 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 483 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
| 484 | hcd->state = HC_STATE_RUNNING; | 484 | ehci->rh_state = EHCI_RH_RUNNING; |
| 485 | dev->power.power_state = PMSG_ON; | 485 | dev->power.power_state = PMSG_ON; |
| 486 | 486 | ||
| 487 | tmp = ehci_readl(ehci, &ehci->regs->command); | 487 | tmp = ehci_readl(ehci, &ehci->regs->command); |
| @@ -95,7 +95,7 @@ static const char hcd_name [] = "ehci_hcd"; · 94 unmodified lines | |||
| 95 | #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ | 95 | #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ |
| 96 | #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ | 96 | #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ |
| 97 | #define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1) | 97 | #define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1) |
| 98 | /* 200-ms async qh unlink delay */ | 98 | /* 5-ms async qh unlink delay */ |
| 99 | 99 | ||
| 100 | /* Initial IRQ latency: faster than hw default */ | 100 | /* Initial IRQ latency: faster than hw default */ |
| 101 | static int log2_irq_thresh = 0; // 0 to 6 | 101 | static int log2_irq_thresh = 0; // 0 to 6 |
| @@ -238,7 +238,7 @@ static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, · 136 unmodified lines | |||
| 238 | error = handshake(ehci, ptr, mask, done, usec); | 238 | error = handshake(ehci, ptr, mask, done, usec); |
| 239 | if (error) { | 239 | if (error) { |
| 240 | ehci_halt(ehci); | 240 | ehci_halt(ehci); |
| 241 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 241 | ehci->rh_state = EHCI_RH_HALTED; |
| 242 | ehci_err(ehci, "force halt; handshake %p %08x %08x -> %d\n", | 242 | ehci_err(ehci, "force halt; handshake %p %08x %08x -> %d\n", |
| 243 | ptr, mask, done, error); | 243 | ptr, mask, done, error); |
| 244 | } | 244 | } |
| @@ -278,7 +278,7 @@ static int ehci_reset (struct ehci_hcd *ehci) · 33 unmodified lines | |||
| 278 | command |= CMD_RESET; | 278 | command |= CMD_RESET; |
| 279 | dbg_cmd (ehci, "reset", command); | 279 | dbg_cmd (ehci, "reset", command); |
| 280 | ehci_writel(ehci, command, &ehci->regs->command); | 280 | ehci_writel(ehci, command, &ehci->regs->command); |
| 281 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 281 | ehci->rh_state = EHCI_RH_HALTED; |
| 282 | ehci->next_statechange = jiffies; | 282 | ehci->next_statechange = jiffies; |
| 283 | retval = handshake (ehci, &ehci->regs->command, | 283 | retval = handshake (ehci, &ehci->regs->command, |
| 284 | CMD_RESET, 0, 250 * 1000); | 284 | CMD_RESET, 0, 250 * 1000); |
| @@ -307,7 +307,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci) · 22 unmodified lines | |||
| 307 | u32 temp; | 307 | u32 temp; |
| 308 | 308 | ||
| 309 | #ifdef DEBUG | 309 | #ifdef DEBUG |
| 310 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 310 | if (ehci->rh_state != EHCI_RH_RUNNING) |
| 311 | BUG (); | 311 | BUG (); |
| 312 | #endif | 312 | #endif |
| 313 | 313 | ||
| @@ -356,7 +356,7 @@ static void ehci_iaa_watchdog(unsigned long param) · 42 unmodified lines | |||
| 356 | */ | 356 | */ |
| 357 | if (ehci->reclaim | 357 | if (ehci->reclaim |
| 358 | && !timer_pending(&ehci->iaa_watchdog) | 358 | && !timer_pending(&ehci->iaa_watchdog) |
| 359 | && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 359 | && ehci->rh_state == EHCI_RH_RUNNING) { |
| 360 | u32 cmd, status; | 360 | u32 cmd, status; |
| 361 | 361 | ||
| 362 | /* If we get here, IAA is *REALLY* late. It's barely | 362 | /* If we get here, IAA is *REALLY* late. It's barely |
| @@ -496,7 +496,7 @@ static void ehci_work (struct ehci_hcd *ehci) · 133 unmodified lines | |||
| 496 | * misplace IRQs, and should let us run completely without IRQs. | 496 | * misplace IRQs, and should let us run completely without IRQs. |
| 497 | * such lossage has been observed on both VT6202 and VT8235. | 497 | * such lossage has been observed on both VT6202 and VT8235. |
| 498 | */ | 498 | */ |
| 499 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && | 499 | if (ehci->rh_state == EHCI_RH_RUNNING && |
| 500 | (ehci->async->qh_next.ptr != NULL || | 500 | (ehci->async->qh_next.ptr != NULL || |
| 501 | ehci->periodic_sched != 0)) | 501 | ehci->periodic_sched != 0)) |
| 502 | timer_action (ehci, TIMER_IO_WATCHDOG); | 502 | timer_action (ehci, TIMER_IO_WATCHDOG); |
| @@ -516,7 +516,7 @@ static void ehci_stop (struct usb_hcd *hcd) · 13 unmodified lines | |||
| 516 | del_timer_sync(&ehci->iaa_watchdog); | 516 | del_timer_sync(&ehci->iaa_watchdog); |
| 517 | 517 | ||
| 518 | spin_lock_irq(&ehci->lock); | 518 | spin_lock_irq(&ehci->lock); |
| 519 | if (HC_IS_RUNNING (hcd->state)) | 519 | if (ehci->rh_state == EHCI_RH_RUNNING) |
| 520 | ehci_quiesce (ehci); | 520 | ehci_quiesce (ehci); |
| 521 | 521 | ||
| 522 | ehci_silence_controller(ehci); | 522 | ehci_silence_controller(ehci); |
| @@ -741,7 +741,7 @@ static int ehci_run (struct usb_hcd *hcd) · 218 unmodified lines | |||
| 741 | * be started before the port switching actions could complete. | 741 | * be started before the port switching actions could complete. |
| 742 | */ | 742 | */ |
| 743 | down_write(&ehci_cf_port_reset_rwsem); | 743 | down_write(&ehci_cf_port_reset_rwsem); |
| 744 | hcd->state = HC_STATE_RUNNING; | 744 | ehci->rh_state = EHCI_RH_RUNNING; |
| 745 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); | 745 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
| 746 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ | 746 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
| 747 | msleep(5); | 747 | msleep(5); |
| @@ -768,6 +768,35 @@ static int ehci_run (struct usb_hcd *hcd) · 20 unmodified lines | |||
| 768 | return 0; | 768 | return 0; |
| 769 | } | 769 | } |
| 770 | 770 | ||
| 771 | static int __maybe_unused ehci_setup (struct usb_hcd *hcd) | ||
| 772 | { | ||
| 773 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 774 | int retval; | ||
| 775 | |||
| 776 | ehci->regs = (void __iomem *)ehci->caps + | ||
| 777 | HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
| 778 | dbg_hcs_params(ehci, "reset"); | ||
| 779 | dbg_hcc_params(ehci, "reset"); | ||
| 780 | |||
| 781 | /* cache this readonly data; minimize chip reads */ | ||
| 782 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
| 783 | |||
| 784 | ehci->sbrn = HCD_USB2; | ||
| 785 | |||
| 786 | retval = ehci_halt(ehci); | ||
| 787 | if (retval) | ||
| 788 | return retval; | ||
| 789 | |||
| 790 | /* data structure init */ | ||
| 791 | retval = ehci_init(hcd); | ||
| 792 | if (retval) | ||
| 793 | return retval; | ||
| 794 | |||
| 795 | ehci_reset(ehci); | ||
| 796 | |||
| 797 | return 0; | ||
| 798 | } | ||
| 799 | |||
| 771 | /*-------------------------------------------------------------------------*/ | 800 | /*-------------------------------------------------------------------------*/ |
| 772 | 801 | ||
| 773 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) | 802 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
| @@ -788,7 +817,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) · 14 unmodified lines | |||
| 788 | 817 | ||
| 789 | /* Shared IRQ? */ | 818 | /* Shared IRQ? */ |
| 790 | masked_status = status & INTR_MASK; | 819 | masked_status = status & INTR_MASK; |
| 791 | if (!masked_status || unlikely(hcd->state == HC_STATE_HALT)) { | 820 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { |
| 792 | spin_unlock(&ehci->lock); | 821 | spin_unlock(&ehci->lock); |
| 793 | return IRQ_NONE; | 822 | return IRQ_NONE; |
| 794 | } | 823 | } |
| @@ -952,7 +981,7 @@ static int ehci_urb_enqueue ( · 157 unmodified lines | |||
| 952 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 981 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
| 953 | { | 982 | { |
| 954 | /* failfast */ | 983 | /* failfast */ |
| 955 | if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim) | 984 | if (ehci->rh_state != EHCI_RH_RUNNING && ehci->reclaim) |
| 956 | end_unlink_async(ehci); | 985 | end_unlink_async(ehci); |
| 957 | 986 | ||
| 958 | /* If the QH isn't linked then there's nothing we can do | 987 | /* If the QH isn't linked then there's nothing we can do |
| @@ -1079,7 +1108,7 @@ rescan: · 120 unmodified lines | |||
| 1079 | goto idle_timeout; | 1108 | goto idle_timeout; |
| 1080 | } | 1109 | } |
| 1081 | 1110 | ||
| 1082 | if (!HC_IS_RUNNING (hcd->state)) | 1111 | if (ehci->rh_state != EHCI_RH_RUNNING) |
| 1083 | qh->qh_state = QH_STATE_IDLE; | 1112 | qh->qh_state = QH_STATE_IDLE; |
| 1084 | switch (qh->qh_state) { | 1113 | switch (qh->qh_state) { |
| 1085 | case QH_STATE_LINKED: | 1114 | case QH_STATE_LINKED: |
| @@ -1166,8 +1195,7 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) · 80 unmodified lines | |||
| 1166 | static int ehci_get_frame (struct usb_hcd *hcd) | 1195 | static int ehci_get_frame (struct usb_hcd *hcd) |
| 1167 | { | 1196 | { |
| 1168 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 1197 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
| 1169 | return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) % | 1198 | return (ehci_read_frame_index(ehci) >> 3) % ehci->periodic_size; |
| 1170 | ehci->periodic_size; | ||
| 1171 | } | 1199 | } |
| 1172 | 1200 | ||
| 1173 | /*-------------------------------------------------------------------------*/ | 1201 | /*-------------------------------------------------------------------------*/ |
| @@ -1291,6 +1319,16 @@ MODULE_LICENSE ("GPL"); · 117 unmodified lines | |||
| 1291 | #define PLATFORM_DRIVER ehci_grlib_driver | 1319 | #define PLATFORM_DRIVER ehci_grlib_driver |
| 1292 | #endif | 1320 | #endif |
| 1293 | 1321 | ||
| 1322 | #ifdef CONFIG_USB_PXA168_EHCI | ||
| 1323 | #include "ehci-pxa168.c" | ||
| 1324 | #define PLATFORM_DRIVER ehci_pxa168_driver | ||
| 1325 | #endif | ||
| 1326 | |||
| 1327 | #ifdef CONFIG_NLM_XLR | ||
| 1328 | #include "ehci-xls.c" | ||
| 1329 | #define PLATFORM_DRIVER ehci_xls_driver | ||
| 1330 | #endif | ||
| 1331 | |||
| 1294 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ | 1332 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ |
| 1295 | !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ | 1333 | !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ |
| 1296 | !defined(XILINX_OF_PLATFORM_DRIVER) | 1334 | !defined(XILINX_OF_PLATFORM_DRIVER) |
| @@ -236,10 +236,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) · 235 unmodified lines | |||
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | /* stop schedules, clean any completed work */ | 238 | /* stop schedules, clean any completed work */ |
| 239 | if (HC_IS_RUNNING(hcd->state)) { | 239 | if (ehci->rh_state == EHCI_RH_RUNNING) |
| 240 | ehci_quiesce (ehci); | 240 | ehci_quiesce (ehci); |
| 241 | hcd->state = HC_STATE_QUIESCING; | ||
| 242 | } | ||
| 243 | ehci->command = ehci_readl(ehci, &ehci->regs->command); | 241 | ehci->command = ehci_readl(ehci, &ehci->regs->command); |
| 244 | ehci_work(ehci); | 242 | ehci_work(ehci); |
| 245 | 243 | ||
| @@ -313,7 +311,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) · 67 unmodified lines | |||
| 313 | 311 | ||
| 314 | /* turn off now-idle HC */ | 312 | /* turn off now-idle HC */ |
| 315 | ehci_halt (ehci); | 313 | ehci_halt (ehci); |
| 316 | hcd->state = HC_STATE_SUSPENDED; | 314 | ehci->rh_state = EHCI_RH_SUSPENDED; |
| 317 | 315 | ||
| 318 | if (ehci->reclaim) | 316 | if (ehci->reclaim) |
| 319 | end_unlink_async(ehci); | 317 | end_unlink_async(ehci); |
| @@ -382,6 +380,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) · 62 unmodified lines | |||
| 382 | 380 | ||
| 383 | /* restore CMD_RUN, framelist size, and irq threshold */ | 381 | /* restore CMD_RUN, framelist size, and irq threshold */ |
| 384 | ehci_writel(ehci, ehci->command, &ehci->regs->command); | 382 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
| 383 | ehci->rh_state = EHCI_RH_RUNNING; | ||
| 385 | 384 | ||
| 386 | /* Some controller/firmware combinations need a delay during which | 385 | /* Some controller/firmware combinations need a delay during which |
| 387 | * they set up the port statuses. See Bugzilla #8190. */ | 386 | * they set up the port statuses. See Bugzilla #8190. */ |
| @@ -451,7 +450,6 @@ static int ehci_bus_resume (struct usb_hcd *hcd) · 63 unmodified lines | |||
| 451 | } | 450 | } |
| 452 | 451 | ||
| 453 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); | 452 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); |
| 454 | hcd->state = HC_STATE_RUNNING; | ||
| 455 | 453 | ||
| 456 | /* Now we can safely re-enable irqs */ | 454 | /* Now we can safely re-enable irqs */ |
| 457 | ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); | 455 | ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); |
| @@ -563,7 +561,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) · 105 unmodified lines | |||
| 563 | u32 ppcd = 0; | 561 | u32 ppcd = 0; |
| 564 | 562 | ||
| 565 | /* if !USB_SUSPEND, root hub timers won't get shut down ... */ | 563 | /* if !USB_SUSPEND, root hub timers won't get shut down ... */ |
| 566 | if (!HC_IS_RUNNING(hcd->state)) | 564 | if (ehci->rh_state != EHCI_RH_RUNNING) |
| 567 | return 0; | 565 | return 0; |
| 568 | 566 | ||
| 569 | /* init status to no-changes */ | 567 | /* init status to no-changes */ |
| @@ -236,7 +236,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) · 235 unmodified lines | |||
| 236 | priv->hcd = hcd; | 236 | priv->hcd = hcd; |
| 237 | platform_set_drvdata(pdev, priv); | 237 | platform_set_drvdata(pdev, priv); |
| 238 | 238 | ||
| 239 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 239 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 240 | if (ret) | 240 | if (ret) |
| 241 | goto err_add; | 241 | goto err_add; |
| 242 | 242 | ||
| @@ -155,7 +155,7 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev) · 154 unmodified lines | |||
| 155 | /* cache this readonly data; minimize chip reads */ | 155 | /* cache this readonly data; minimize chip reads */ |
| 156 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 156 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
| 157 | 157 | ||
| 158 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 158 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 159 | if (ret) { | 159 | if (ret) { |
| 160 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); | 160 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); |
| 161 | goto err3; | 161 | goto err3; |
| @@ -228,7 +228,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) · 227 unmodified lines | |||
| 228 | /* cache this readonly data; minimize chip reads */ | 228 | /* cache this readonly data; minimize chip reads */ |
| 229 | omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); | 229 | omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); |
| 230 | 230 | ||
| 231 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 231 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 232 | if (ret) { | 232 | if (ret) { |
| 233 | dev_err(dev, "failed to add hcd with err %d\n", ret); | 233 | dev_err(dev, "failed to add hcd with err %d\n", ret); |
| 234 | goto err_add_hcd; | 234 | goto err_add_hcd; |
| @@ -277,7 +277,7 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev) · 276 unmodified lines | |||
| 277 | printk(KERN_WARNING "Orion ehci -USB phy version isn't supported.\n"); | 277 | printk(KERN_WARNING "Orion ehci -USB phy version isn't supported.\n"); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED); | 280 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 281 | if (err) | 281 | if (err) |
| 282 | goto err4; | 282 | goto err4; |
| 283 | 283 | ||
| @@ -224,6 +224,11 @@ static int ehci_pci_setup(struct usb_hcd *hcd) · 223 unmodified lines | |||
| 224 | pci_dev_put(p_smbus); | 224 | pci_dev_put(p_smbus); |
| 225 | } | 225 | } |
| 226 | break; | 226 | break; |
| 227 | case PCI_VENDOR_ID_NETMOS: | ||
| 228 | /* MosChip frame-index-register bug */ | ||
| 229 | ehci_info(ehci, "applying MosChip frame-index workaround\n"); | ||
| 230 | ehci->frame_index_bug = 1; | ||
| 231 | break; | ||
| 227 | } | 232 | } |
| 228 | 233 | ||
| 229 | /* optional debug port, normally in the first BAR */ | 234 | /* optional debug port, normally in the first BAR */ |
| @@ -439,7 +444,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) · 209 unmodified lines | |||
| 439 | /* here we "know" root ports should always stay powered */ | 444 | /* here we "know" root ports should always stay powered */ |
| 440 | ehci_port_power(ehci, 1); | 445 | ehci_port_power(ehci, 1); |
| 441 | 446 | ||
| 442 | hcd->state = HC_STATE_SUSPENDED; | 447 | ehci->rh_state = EHCI_RH_SUSPENDED; |
| 443 | return 0; | 448 | return 0; |
| 444 | } | 449 | } |
| 445 | #endif | 450 | #endif |
| @@ -167,7 +167,7 @@ static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) · 166 unmodified lines | |||
| 167 | 167 | ||
| 168 | ps3_system_bus_set_drvdata(dev, hcd); | 168 | ps3_system_bus_set_drvdata(dev, hcd); |
| 169 | 169 | ||
| 170 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | 170 | result = usb_add_hcd(hcd, virq, 0); |
| 171 | 171 | ||
| 172 | if (result) { | 172 | if (result) { |
| 173 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", | 173 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", |
| @@ -0,0 +1,363 @@ | |||
| 1 | /* | ||
| 2 | * drivers/usb/host/ehci-pxa168.c | ||
| 3 | * | ||
| 4 | * Tanmay Upadhyay <tanmay.upadhyay@einfochips.com> | ||
| 5 | * | ||
| 6 | * Based on drivers/usb/host/ehci-orion.c | ||
| 7 | * | ||
| 8 | * This file is licensed under the terms of the GNU General Public | ||
| 9 | * License version 2. This program is licensed "as is" without any | ||
| 10 | * warranty of any kind, whether express or implied. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/clk.h> | ||
| 17 | #include <mach/pxa168.h> | ||
| 18 | |||
| 19 | #define USB_PHY_CTRL_REG 0x4 | ||
| 20 | #define USB_PHY_PLL_REG 0x8 | ||
| 21 | #define USB_PHY_TX_REG 0xc | ||
| 22 | |||
| 23 | #define FBDIV_SHIFT 4 | ||
| 24 | |||
| 25 | #define ICP_SHIFT 12 | ||
| 26 | #define ICP_15 2 | ||
| 27 | #define ICP_20 3 | ||
| 28 | #define ICP_25 4 | ||
| 29 | |||
| 30 | #define KVCO_SHIFT 15 | ||
| 31 | |||
| 32 | #define PLLCALI12_SHIFT 25 | ||
| 33 | #define CALI12_VDD 0 | ||
| 34 | #define CALI12_09 1 | ||
| 35 | #define CALI12_10 2 | ||
| 36 | #define CALI12_11 3 | ||
| 37 | |||
| 38 | #define PLLVDD12_SHIFT 27 | ||
| 39 | #define VDD12_VDD 0 | ||
| 40 | #define VDD12_10 1 | ||
| 41 | #define VDD12_11 2 | ||
| 42 | #define VDD12_12 3 | ||
| 43 | |||
| 44 | #define PLLVDD18_SHIFT 29 | ||
| 45 | #define VDD18_19 0 | ||
| 46 | #define VDD18_20 1 | ||
| 47 | #define VDD18_21 2 | ||
| 48 | #define VDD18_22 3 | ||
| 49 | |||
| 50 | |||
| 51 | #define PLL_READY (1 << 23) | ||
| 52 | #define VCOCAL_START (1 << 21) | ||
| 53 | #define REG_RCAL_START (1 << 12) | ||
| 54 | |||
| 55 | struct pxa168_usb_drv_data { | ||
| 56 | struct ehci_hcd ehci; | ||
| 57 | struct clk *pxa168_usb_clk; | ||
| 58 | struct resource *usb_phy_res; | ||
| 59 | void __iomem *usb_phy_reg_base; | ||
| 60 | }; | ||
| 61 | |||
| 62 | static int ehci_pxa168_setup(struct usb_hcd *hcd) | ||
| 63 | { | ||
| 64 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 65 | int retval; | ||
| 66 | |||
| 67 | ehci_reset(ehci); | ||
| 68 | retval = ehci_halt(ehci); | ||
| 69 | if (retval) | ||
| 70 | return retval; | ||
| 71 | |||
| 72 | /* | ||
| 73 | * data structure init | ||
| 74 | */ | ||
| 75 | retval = ehci_init(hcd); | ||
| 76 | if (retval) | ||
| 77 | return retval; | ||
| 78 | |||
| 79 | hcd->has_tt = 1; | ||
| 80 | |||
| 81 | ehci_port_power(ehci, 0); | ||
| 82 | |||
| 83 | return retval; | ||
| 84 | } | ||
| 85 | |||
| 86 | static const struct hc_driver ehci_pxa168_hc_driver = { | ||
| 87 | .description = hcd_name, | ||
| 88 | .product_desc = "Marvell PXA168 EHCI", | ||
| 89 | .hcd_priv_size = sizeof(struct pxa168_usb_drv_data), | ||
| 90 | |||
| 91 | /* | ||
| 92 | * generic hardware linkage | ||
| 93 | */ | ||
| 94 | .irq = ehci_irq, | ||
| 95 | .flags = HCD_MEMORY | HCD_USB2, | ||
| 96 | |||
| 97 | /* | ||
| 98 | * basic lifecycle operations | ||
| 99 | */ | ||
| 100 | .reset = ehci_pxa168_setup, | ||
| 101 | .start = ehci_run, | ||
| 102 | .stop = ehci_stop, | ||
| 103 | .shutdown = ehci_shutdown, | ||
| 104 | |||
| 105 | /* | ||
| 106 | * managing i/o requests and associated device resources | ||
| 107 | */ | ||
| 108 | .urb_enqueue = ehci_urb_enqueue, | ||
| 109 | .urb_dequeue = ehci_urb_dequeue, | ||
| 110 | .endpoint_disable = ehci_endpoint_disable, | ||
| 111 | .endpoint_reset = ehci_endpoint_reset, | ||
| 112 | |||
| 113 | /* | ||
| 114 | * scheduling support | ||
| 115 | */ | ||
| 116 | .get_frame_number = ehci_get_frame, | ||
| 117 | |||
| 118 | /* | ||
| 119 | * root hub support | ||
| 120 | */ | ||
| 121 | .hub_status_data = ehci_hub_status_data, | ||
| 122 | .hub_control = ehci_hub_control, | ||
| 123 | .bus_suspend = ehci_bus_suspend, | ||
| 124 | .bus_resume = ehci_bus_resume, | ||
| 125 | .relinquish_port = ehci_relinquish_port, | ||
| 126 | .port_handed_over = ehci_port_handed_over, | ||
| 127 | |||
| 128 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 129 | }; | ||
| 130 | |||
| 131 | static int pxa168_usb_phy_init(struct platform_device *pdev) | ||
| 132 | { | ||
| 133 | struct resource *res; | ||
| 134 | void __iomem *usb_phy_reg_base; | ||
| 135 | struct pxa168_usb_pdata *pdata; | ||
| 136 | struct pxa168_usb_drv_data *drv_data; | ||
| 137 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
| 138 | unsigned long reg_val; | ||
| 139 | int pll_retry_cont = 10000, err = 0; | ||
| 140 | |||
| 141 | drv_data = (struct pxa168_usb_drv_data *)hcd->hcd_priv; | ||
| 142 | pdata = (struct pxa168_usb_pdata *)pdev->dev.platform_data; | ||
| 143 | |||
| 144 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 145 | if (!res) { | ||
| 146 | dev_err(&pdev->dev, | ||
| 147 | "Found HC with no PHY register addr. Check %s setup!\n", | ||
| 148 | dev_name(&pdev->dev)); | ||
| 149 | return -ENODEV; | ||
| 150 | } | ||
| 151 | |||
| 152 | if (!request_mem_region(res->start, resource_size(res), | ||
| 153 | ehci_pxa168_hc_driver.description)) { | ||
| 154 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
| 155 | return -EBUSY; | ||
| 156 | } | ||
| 157 | |||
| 158 | usb_phy_reg_base = ioremap(res->start, resource_size(res)); | ||
| 159 | if (usb_phy_reg_base == NULL) { | ||
| 160 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
| 161 | err = -EFAULT; | ||
| 162 | goto err1; | ||
| 163 | } | ||
| 164 | drv_data->usb_phy_reg_base = usb_phy_reg_base; | ||
| 165 | drv_data->usb_phy_res = res; | ||
| 166 | |||
| 167 | /* If someone wants to init USB phy in board specific way */ | ||
| 168 | if (pdata && pdata->phy_init) | ||
| 169 | return pdata->phy_init(usb_phy_reg_base); | ||
| 170 | |||
| 171 | /* Power up the PHY and PLL */ | ||
| 172 | writel(readl(usb_phy_reg_base + USB_PHY_CTRL_REG) | 0x3, | ||
| 173 | usb_phy_reg_base + USB_PHY_CTRL_REG); | ||
| 174 | |||
| 175 | /* Configure PHY PLL */ | ||
| 176 | reg_val = readl(usb_phy_reg_base + USB_PHY_PLL_REG) & ~(0x7e03ffff); | ||
| 177 | reg_val |= (VDD18_22 << PLLVDD18_SHIFT | VDD12_12 << PLLVDD12_SHIFT | | ||
| 178 | CALI12_11 << PLLCALI12_SHIFT | 3 << KVCO_SHIFT | | ||
| 179 | ICP_15 << ICP_SHIFT | 0xee << FBDIV_SHIFT | 0xb); | ||
| 180 | writel(reg_val, usb_phy_reg_base + USB_PHY_PLL_REG); | ||
| 181 | |||
| 182 | /* Make sure PHY PLL is ready */ | ||
| 183 | while (!(readl(usb_phy_reg_base + USB_PHY_PLL_REG) & PLL_READY)) { | ||
| 184 | if (!(pll_retry_cont--)) { | ||
| 185 | dev_dbg(&pdev->dev, "USB PHY PLL not ready\n"); | ||
| 186 | err = -EIO; | ||
| 187 | goto err2; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | /* Toggle VCOCAL_START bit of U2PLL for PLL calibration */ | ||
| 192 | udelay(200); | ||
| 193 | writel(readl(usb_phy_reg_base + USB_PHY_PLL_REG) | VCOCAL_START, | ||
| 194 | usb_phy_reg_base + USB_PHY_PLL_REG); | ||
| 195 | udelay(40); | ||
| 196 | writel(readl(usb_phy_reg_base + USB_PHY_PLL_REG) & ~VCOCAL_START, | ||
| 197 | usb_phy_reg_base + USB_PHY_PLL_REG); | ||
| 198 | |||
| 199 | /* Toggle REG_RCAL_START bit of U2PTX for impedance calibration */ | ||
| 200 | udelay(400); | ||
| 201 | writel(readl(usb_phy_reg_base + USB_PHY_TX_REG) | REG_RCAL_START, | ||
| 202 | usb_phy_reg_base + USB_PHY_TX_REG); | ||
| 203 | udelay(40); | ||
| 204 | writel(readl(usb_phy_reg_base + USB_PHY_TX_REG) & ~REG_RCAL_START, | ||
| 205 | usb_phy_reg_base + USB_PHY_TX_REG); | ||
| 206 | |||
| 207 | /* Make sure PHY PLL is ready again */ | ||
| 208 | pll_retry_cont = 0; | ||
| 209 | while (!(readl(usb_phy_reg_base + USB_PHY_PLL_REG) & PLL_READY)) { | ||
| 210 | if (!(pll_retry_cont--)) { | ||
| 211 | dev_dbg(&pdev->dev, "USB PHY PLL not ready\n"); | ||
| 212 | err = -EIO; | ||
| 213 | goto err2; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | return 0; | ||
| 218 | err2: | ||
| 219 | iounmap(usb_phy_reg_base); | ||
| 220 | err1: | ||
| 221 | release_mem_region(res->start, resource_size(res)); | ||
| 222 | return err; | ||
| 223 | } | ||
| 224 | |||
| 225 | static int __devinit ehci_pxa168_drv_probe(struct platform_device *pdev) | ||
| 226 | { | ||
| 227 | struct resource *res; | ||
| 228 | struct usb_hcd *hcd; | ||
| 229 | struct ehci_hcd *ehci; | ||
| 230 | struct pxa168_usb_drv_data *drv_data; | ||
| 231 | void __iomem *regs; | ||
| 232 | int irq, err = 0; | ||
| 233 | |||
| 234 | if (usb_disabled()) | ||
| 235 | return -ENODEV; | ||
| 236 | |||
| 237 | pr_debug("Initializing pxa168-SoC USB Host Controller\n"); | ||
| 238 | |||
| 239 | irq = platform_get_irq(pdev, 0); | ||
| 240 | if (irq <= 0) { | ||
| 241 | dev_err(&pdev->dev, | ||
| 242 | "Found HC with no IRQ. Check %s setup!\n", | ||
| 243 | dev_name(&pdev->dev)); | ||
| 244 | err = -ENODEV; | ||
| 245 | goto err1; | ||
| 246 | } | ||
| 247 | |||
| 248 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 249 | if (!res) { | ||
| 250 | dev_err(&pdev->dev, | ||
| 251 | "Found HC with no register addr. Check %s setup!\n", | ||
| 252 | dev_name(&pdev->dev)); | ||
| 253 | err = -ENODEV; | ||
| 254 | goto err1; | ||
| 255 | } | ||
| 256 | |||
| 257 | if (!request_mem_region(res->start, resource_size(res), | ||
| 258 | ehci_pxa168_hc_driver.description)) { | ||
| 259 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
| 260 | err = -EBUSY; | ||
| 261 | goto err1; | ||
| 262 | } | ||
| 263 | |||
| 264 | regs = ioremap(res->start, resource_size(res)); | ||
| 265 | if (regs == NULL) { | ||
| 266 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
| 267 | err = -EFAULT; | ||
| 268 | goto err2; | ||
| 269 | } | ||
| 270 | |||
| 271 | hcd = usb_create_hcd(&ehci_pxa168_hc_driver, | ||
| 272 | &pdev->dev, dev_name(&pdev->dev)); | ||
| 273 | if (!hcd) { | ||
| 274 | err = -ENOMEM; | ||
| 275 | goto err3; | ||
| 276 | } | ||
| 277 | |||
| 278 | drv_data = (struct pxa168_usb_drv_data *)hcd->hcd_priv; | ||
| 279 | |||
| 280 | /* Enable USB clock */ | ||
| 281 | drv_data->pxa168_usb_clk = clk_get(&pdev->dev, "PXA168-USBCLK"); | ||
| 282 | if (IS_ERR(drv_data->pxa168_usb_clk)) { | ||
| 283 | dev_err(&pdev->dev, "Couldn't get USB clock\n"); | ||
| 284 | err = PTR_ERR(drv_data->pxa168_usb_clk); | ||
| 285 | goto err4; | ||
| 286 | } | ||
| 287 | clk_enable(drv_data->pxa168_usb_clk); | ||
| 288 | |||
| 289 | err = pxa168_usb_phy_init(pdev); | ||
| 290 | if (err) { | ||
| 291 | dev_err(&pdev->dev, "USB PHY initialization failed\n"); | ||
| 292 | goto err5; | ||
| 293 | } | ||
| 294 | |||
| 295 | hcd->rsrc_start = res->start; | ||
| 296 | hcd->rsrc_len = resource_size(res); | ||
| 297 | hcd->regs = regs; | ||
| 298 | |||
| 299 | ehci = hcd_to_ehci(hcd); | ||
| 300 | ehci->caps = hcd->regs + 0x100; | ||
| 301 | ehci->regs = hcd->regs + 0x100 + | ||
| 302 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
| 303 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
| 304 | hcd->has_tt = 1; | ||
| 305 | ehci->sbrn = 0x20; | ||
| 306 | |||
| 307 | err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED); | ||
| 308 | if (err) | ||
| 309 | goto err5; | ||
| 310 | |||
| 311 | return 0; | ||
| 312 | |||
| 313 | err5: | ||
| 314 | clk_disable(drv_data->pxa168_usb_clk); | ||
| 315 | clk_put(drv_data->pxa168_usb_clk); | ||
| 316 | err4: | ||
| 317 | usb_put_hcd(hcd); | ||
| 318 | err3: | ||
| 319 | iounmap(regs); | ||
| 320 | err2: | ||
| 321 | release_mem_region(res->start, resource_size(res)); | ||
| 322 | err1: | ||
| 323 | dev_err(&pdev->dev, "init %s fail, %d\n", | ||
| 324 | dev_name(&pdev->dev), err); | ||
| 325 | |||
| 326 | return err; | ||
| 327 | } | ||
| 328 | |||
| 329 | static int __exit ehci_pxa168_drv_remove(struct platform_device *pdev) | ||
| 330 | { | ||
| 331 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
| 332 | struct pxa168_usb_drv_data *drv_data = | ||
| 333 | (struct pxa168_usb_drv_data *)hcd->hcd_priv; | ||
| 334 | |||
| 335 | usb_remove_hcd(hcd); | ||
| 336 | |||
| 337 | /* Power down PHY & PLL */ | ||
| 338 | writel(readl(drv_data->usb_phy_reg_base + USB_PHY_CTRL_REG) & (~0x3), | ||
| 339 | drv_data->usb_phy_reg_base + USB_PHY_CTRL_REG); | ||
| 340 | |||
| 341 | clk_disable(drv_data->pxa168_usb_clk); | ||
| 342 | clk_put(drv_data->pxa168_usb_clk); | ||
| 343 | |||
| 344 | iounmap(hcd->regs); | ||
| 345 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 346 | |||
| 347 | iounmap(drv_data->usb_phy_reg_base); | ||
| 348 | release_mem_region(drv_data->usb_phy_res->start, | ||
| 349 | resource_size(drv_data->usb_phy_res)); | ||
| 350 | |||
| 351 | usb_put_hcd(hcd); | ||
| 352 | |||
| 353 | return 0; | ||
| 354 | } | ||
| 355 | |||
| 356 | MODULE_ALIAS("platform:pxa168-ehci"); | ||
| 357 | |||
| 358 | static struct platform_driver ehci_pxa168_driver = { | ||
| 359 | .probe = ehci_pxa168_drv_probe, | ||
| 360 | .remove = __exit_p(ehci_pxa168_drv_remove), | ||
| 361 | .shutdown = usb_hcd_platform_shutdown, | ||
| 362 | .driver.name = "pxa168-ehci", | ||
| 363 | }; | ||
| @@ -111,8 +111,6 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) · 110 unmodified lines | |||
| 111 | } | 111 | } |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ | ||
| 115 | wmb (); | ||
| 116 | hw->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); | 114 | hw->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); |
| 117 | } | 115 | } |
| 118 | 116 | ||
| @@ -153,7 +151,7 @@ static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd, · 34 unmodified lines | |||
| 153 | spin_lock_irqsave(&ehci->lock, flags); | 151 | spin_lock_irqsave(&ehci->lock, flags); |
| 154 | qh->clearing_tt = 0; | 152 | qh->clearing_tt = 0; |
| 155 | if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list) | 153 | if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list) |
| 156 | && HC_IS_RUNNING(hcd->state)) | 154 | && ehci->rh_state == EHCI_RH_RUNNING) |
| 157 | qh_link_async(ehci, qh); | 155 | qh_link_async(ehci, qh); |
| 158 | spin_unlock_irqrestore(&ehci->lock, flags); | 156 | spin_unlock_irqrestore(&ehci->lock, flags); |
| 159 | } | 157 | } |
| @@ -425,7 +423,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) · 265 unmodified lines | |||
| 425 | 423 | ||
| 426 | /* stop scanning when we reach qtds the hc is using */ | 424 | /* stop scanning when we reach qtds the hc is using */ |
| 427 | } else if (likely (!stopped | 425 | } else if (likely (!stopped |
| 428 | && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) { | 426 | && ehci->rh_state == EHCI_RH_RUNNING)) { |
| 429 | break; | 427 | break; |
| 430 | 428 | ||
| 431 | /* scan the whole queue for unlinks whenever it stops */ | 429 | /* scan the whole queue for unlinks whenever it stops */ |
| @@ -433,7 +431,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) · 1 unmodified line | |||
| 433 | stopped = 1; | 431 | stopped = 1; |
| 434 | 432 | ||
| 435 | /* cancel everything if we halt, suspend, etc */ | 433 | /* cancel everything if we halt, suspend, etc */ |
| 436 | if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) | 434 | if (ehci->rh_state != EHCI_RH_RUNNING) |
| 437 | last_status = -ESHUTDOWN; | 435 | last_status = -ESHUTDOWN; |
| 438 | 436 | ||
| 439 | /* this qtd is active; skip it unless a previous qtd | 437 | /* this qtd is active; skip it unless a previous qtd |
| @@ -724,7 +722,8 @@ qh_urb_transaction ( · 284 unmodified lines | |||
| 724 | 722 | ||
| 725 | /* | 723 | /* |
| 726 | * control requests may need a terminating data "status" ack; | 724 | * control requests may need a terminating data "status" ack; |
| 727 | * bulk ones may need a terminating short packet (zero length). | 725 | * other OUT ones may need a terminating short packet |
| 726 | * (zero length). | ||
| 728 | */ | 727 | */ |
| 729 | if (likely (urb->transfer_buffer_length != 0)) { | 728 | if (likely (urb->transfer_buffer_length != 0)) { |
| 730 | int one_more = 0; | 729 | int one_more = 0; |
| @@ -733,7 +732,7 @@ qh_urb_transaction ( · 2 unmodified lines | |||
| 733 | one_more = 1; | 732 | one_more = 1; |
| 734 | token ^= 0x0100; /* "in" <--> "out" */ | 733 | token ^= 0x0100; /* "in" <--> "out" */ |
| 735 | token |= QTD_TOGGLE; /* force DATA1 */ | 734 | token |= QTD_TOGGLE; /* force DATA1 */ |
| 736 | } else if (usb_pipebulk (urb->pipe) | 735 | } else if (usb_pipeout(urb->pipe) |
| 737 | && (urb->transfer_flags & URB_ZERO_PACKET) | 736 | && (urb->transfer_flags & URB_ZERO_PACKET) |
| 738 | && !(urb->transfer_buffer_length % maxpacket)) { | 737 | && !(urb->transfer_buffer_length % maxpacket)) { |
| 739 | one_more = 1; | 738 | one_more = 1; |
| @@ -977,9 +976,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) · 237 unmodified lines | |||
| 977 | /* in case a clear of CMD_ASE didn't take yet */ | 976 | /* in case a clear of CMD_ASE didn't take yet */ |
| 978 | (void)handshake(ehci, &ehci->regs->status, | 977 | (void)handshake(ehci, &ehci->regs->status, |
| 979 | STS_ASS, 0, 150); | 978 | STS_ASS, 0, 150); |
| 980 | cmd |= CMD_ASE | CMD_RUN; | 979 | cmd |= CMD_ASE; |
| 981 | ehci_writel(ehci, cmd, &ehci->regs->command); | 980 | ehci_writel(ehci, cmd, &ehci->regs->command); |
| 982 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | ||
| 983 | /* posted write need not be known to HC yet ... */ | 981 | /* posted write need not be known to HC yet ... */ |
| 984 | } | 982 | } |
| 985 | } | 983 | } |
| @@ -1058,7 +1056,7 @@ static struct ehci_qh *qh_append_tds ( · 72 unmodified lines | |||
| 1058 | */ | 1056 | */ |
| 1059 | token = qtd->hw_token; | 1057 | token = qtd->hw_token; |
| 1060 | qtd->hw_token = HALT_BIT(ehci); | 1058 | qtd->hw_token = HALT_BIT(ehci); |
| 1061 | wmb (); | 1059 | |
| 1062 | dummy = qh->dummy; | 1060 | dummy = qh->dummy; |
| 1063 | 1061 | ||
| 1064 | dma = dummy->qtd_dma; | 1062 | dma = dummy->qtd_dma; |
| @@ -1168,14 +1166,13 @@ static void end_unlink_async (struct ehci_hcd *ehci) · 103 unmodified lines | |||
| 1168 | 1166 | ||
| 1169 | qh_completions (ehci, qh); | 1167 | qh_completions (ehci, qh); |
| 1170 | 1168 | ||
| 1171 | if (!list_empty (&qh->qtd_list) | 1169 | if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) { |
| 1172 | && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | ||
| 1173 | qh_link_async (ehci, qh); | 1170 | qh_link_async (ehci, qh); |
| 1174 | else { | 1171 | } else { |
| 1175 | /* it's not free to turn the async schedule on/off; leave it | 1172 | /* it's not free to turn the async schedule on/off; leave it |
| 1176 | * active but idle for a while once it empties. | 1173 | * active but idle for a while once it empties. |
| 1177 | */ | 1174 | */ |
| 1178 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) | 1175 | if (ehci->rh_state == EHCI_RH_RUNNING |
| 1179 | && ehci->async->qh_next.qh == NULL) | 1176 | && ehci->async->qh_next.qh == NULL) |
| 1180 | timer_action (ehci, TIMER_ASYNC_OFF); | 1177 | timer_action (ehci, TIMER_ASYNC_OFF); |
| 1181 | } | 1178 | } |
| @@ -1211,7 +1208,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) · 29 unmodified lines | |||
| 1211 | /* stop async schedule right now? */ | 1208 | /* stop async schedule right now? */ |
| 1212 | if (unlikely (qh == ehci->async)) { | 1209 | if (unlikely (qh == ehci->async)) { |
| 1213 | /* can't get here without STS_ASS set */ | 1210 | /* can't get here without STS_ASS set */ |
| 1214 | if (ehci_to_hcd(ehci)->state != HC_STATE_HALT | 1211 | if (ehci->rh_state != EHCI_RH_HALTED |
| 1215 | && !ehci->reclaim) { | 1212 | && !ehci->reclaim) { |
| 1216 | /* ... and CMD_IAAD clear */ | 1213 | /* ... and CMD_IAAD clear */ |
| 1217 | ehci_writel(ehci, cmd & ~CMD_ASE, | 1214 | ehci_writel(ehci, cmd & ~CMD_ASE, |
| @@ -1237,7 +1234,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) · 19 unmodified lines | |||
| 1237 | wmb (); | 1234 | wmb (); |
| 1238 | 1235 | ||
| 1239 | /* If the controller isn't running, we don't have to wait for it */ | 1236 | /* If the controller isn't running, we don't have to wait for it */ |
| 1240 | if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) { | 1237 | if (unlikely(ehci->rh_state != EHCI_RH_RUNNING)) { |
| 1241 | /* if (unlikely (qh->reclaim != 0)) | 1238 | /* if (unlikely (qh->reclaim != 0)) |
| 1242 | * this will recurse, probably not much | 1239 | * this will recurse, probably not much |
| 1243 | */ | 1240 | */ |
| @@ -1260,7 +1257,7 @@ static void scan_async (struct ehci_hcd *ehci) · 16 unmodified lines | |||
| 1260 | enum ehci_timer_action action = TIMER_IO_WATCHDOG; | 1257 | enum ehci_timer_action action = TIMER_IO_WATCHDOG; |
| 1261 | 1258 | ||
| 1262 | timer_action_done (ehci, TIMER_ASYNC_SHRINK); | 1259 | timer_action_done (ehci, TIMER_ASYNC_SHRINK); |
| 1263 | stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state); | 1260 | stopped = (ehci->rh_state != EHCI_RH_RUNNING); |
| 1264 | 1261 | ||
| 1265 | ehci->qh_scan_next = ehci->async->qh_next.qh; | 1262 | ehci->qh_scan_next = ehci->async->qh_next.qh; |
| 1266 | while (ehci->qh_scan_next) { | 1263 | while (ehci->qh_scan_next) { |
| @@ -136,7 +136,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev) · 135 unmodified lines | |||
| 136 | /* cache this readonly data; minimize chip reads */ | 136 | /* cache this readonly data; minimize chip reads */ |
| 137 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 137 | ehci->hcs_params = readl(&ehci->caps->hcs_params); |
| 138 | 138 | ||
| 139 | err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 139 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 140 | if (err) { | 140 | if (err) { |
| 141 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); | 141 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); |
| 142 | goto fail; | 142 | goto fail; |
| @@ -270,7 +270,7 @@ static int s5p_ehci_resume(struct device *dev) · 127 unmodified lines | |||
| 270 | /* here we "know" root ports should always stay powered */ | 270 | /* here we "know" root ports should always stay powered */ |
| 271 | ehci_port_power(ehci, 1); | 271 | ehci_port_power(ehci, 1); |
| 272 | 272 | ||
| 273 | hcd->state = HC_STATE_SUSPENDED; | 273 | ehci->rh_state = EHCI_RH_SUSPENDED; |
| 274 | 274 | ||
| 275 | return 0; | 275 | return 0; |
| 276 | } | 276 | } |
| @@ -36,6 +36,27 @@ · 35 unmodified lines | |||
| 36 | 36 | ||
| 37 | static int ehci_get_frame (struct usb_hcd *hcd); | 37 | static int ehci_get_frame (struct usb_hcd *hcd); |
| 38 | 38 | ||
| 39 | #ifdef CONFIG_PCI | ||
| 40 | |||
| 41 | static unsigned ehci_read_frame_index(struct ehci_hcd *ehci) | ||
| 42 | { | ||
| 43 | unsigned uf; | ||
| 44 | |||
| 45 | /* | ||
| 46 | * The MosChip MCS9990 controller updates its microframe counter | ||
| 47 | * a little before the frame counter, and occasionally we will read | ||
| 48 | * the invalid intermediate value. Avoid problems by checking the | ||
| 49 | * microframe number (the low-order 3 bits); if they are 0 then | ||
| 50 | * re-read the register to get the correct value. | ||
| 51 | */ | ||
| 52 | uf = ehci_readl(ehci, &ehci->regs->frame_index); | ||
| 53 | if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0))) | ||
| 54 | uf = ehci_readl(ehci, &ehci->regs->frame_index); | ||
| 55 | return uf; | ||
| 56 | } | ||
| 57 | |||
| 58 | #endif | ||
| 59 | |||
| 39 | /*-------------------------------------------------------------------------*/ | 60 | /*-------------------------------------------------------------------------*/ |
| 40 | 61 | ||
| 41 | /* | 62 | /* |
| @@ -479,10 +500,9 @@ static int enable_periodic (struct ehci_hcd *ehci) · 437 unmodified lines | |||
| 479 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; | 500 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; |
| 480 | ehci_writel(ehci, cmd, &ehci->regs->command); | 501 | ehci_writel(ehci, cmd, &ehci->regs->command); |
| 481 | /* posted write ... PSS happens later */ | 502 | /* posted write ... PSS happens later */ |
| 482 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | ||
| 483 | 503 | ||
| 484 | /* make sure ehci_work scans these */ | 504 | /* make sure ehci_work scans these */ |
| 485 | ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) | 505 | ehci->next_uframe = ehci_read_frame_index(ehci) |
| 486 | % (ehci->periodic_size << 3); | 506 | % (ehci->periodic_size << 3); |
| 487 | if (unlikely(ehci->broken_periodic)) | 507 | if (unlikely(ehci->broken_periodic)) |
| 488 | ehci->last_periodic_enable = ktime_get_real(); | 508 | ehci->last_periodic_enable = ktime_get_real(); |
| @@ -677,7 +697,7 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) · 188 unmodified lines | |||
| 677 | 697 | ||
| 678 | /* reschedule QH iff another request is queued */ | 698 | /* reschedule QH iff another request is queued */ |
| 679 | if (!list_empty(&qh->qtd_list) && | 699 | if (!list_empty(&qh->qtd_list) && |
| 680 | HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 700 | ehci->rh_state == EHCI_RH_RUNNING) { |
| 681 | rc = qh_schedule(ehci, qh); | 701 | rc = qh_schedule(ehci, qh); |
| 682 | 702 | ||
| 683 | /* An error here likely indicates handshake failure | 703 | /* An error here likely indicates handshake failure |
| @@ -1409,7 +1429,7 @@ iso_stream_schedule ( · 725 unmodified lines | |||
| 1409 | goto fail; | 1429 | goto fail; |
| 1410 | } | 1430 | } |
| 1411 | 1431 | ||
| 1412 | now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1); | 1432 | now = ehci_read_frame_index(ehci) & (mod - 1); |
| 1413 | 1433 | ||
| 1414 | /* Typical case: reuse current schedule, stream is still active. | 1434 | /* Typical case: reuse current schedule, stream is still active. |
| 1415 | * Hopefully there are no gaps from the host falling behind | 1435 | * Hopefully there are no gaps from the host falling behind |
| @@ -2275,8 +2295,8 @@ scan_periodic (struct ehci_hcd *ehci) · 859 unmodified lines | |||
| 2275 | * Touches as few pages as possible: cache-friendly. | 2295 | * Touches as few pages as possible: cache-friendly. |
| 2276 | */ | 2296 | */ |
| 2277 | now_uframe = ehci->next_uframe; | 2297 | now_uframe = ehci->next_uframe; |
| 2278 | if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 2298 | if (ehci->rh_state == EHCI_RH_RUNNING) { |
| 2279 | clock = ehci_readl(ehci, &ehci->regs->frame_index); | 2299 | clock = ehci_read_frame_index(ehci); |
| 2280 | clock_frame = (clock >> 3) & (ehci->periodic_size - 1); | 2300 | clock_frame = (clock >> 3) & (ehci->periodic_size - 1); |
| 2281 | } else { | 2301 | } else { |
| 2282 | clock = now_uframe + mod - 1; | 2302 | clock = now_uframe + mod - 1; |
| @@ -2310,7 +2330,7 @@ restart: · 27 unmodified lines | |||
| 2310 | union ehci_shadow temp; | 2330 | union ehci_shadow temp; |
| 2311 | int live; | 2331 | int live; |
| 2312 | 2332 | ||
| 2313 | live = HC_IS_RUNNING (ehci_to_hcd(ehci)->state); | 2333 | live = (ehci->rh_state == EHCI_RH_RUNNING); |
| 2314 | switch (hc32_to_cpu(ehci, type)) { | 2334 | switch (hc32_to_cpu(ehci, type)) { |
| 2315 | case Q_TYPE_QH: | 2335 | case Q_TYPE_QH: |
| 2316 | /* handle any completions */ | 2336 | /* handle any completions */ |
| @@ -2435,7 +2455,7 @@ restart: · 118 unmodified lines | |||
| 2435 | * We can't advance our scan without collecting the ISO | 2455 | * We can't advance our scan without collecting the ISO |
| 2436 | * transfers that are still pending in this frame. | 2456 | * transfers that are still pending in this frame. |
| 2437 | */ | 2457 | */ |
| 2438 | if (incomplete && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 2458 | if (incomplete && ehci->rh_state == EHCI_RH_RUNNING) { |
| 2439 | ehci->next_uframe = now_uframe; | 2459 | ehci->next_uframe = now_uframe; |
| 2440 | break; | 2460 | break; |
| 2441 | } | 2461 | } |
| @@ -2451,12 +2471,11 @@ restart: · 9 unmodified lines | |||
| 2451 | if (now_uframe == clock) { | 2471 | if (now_uframe == clock) { |
| 2452 | unsigned now; | 2472 | unsigned now; |
| 2453 | 2473 | ||
| 2454 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) | 2474 | if (ehci->rh_state != EHCI_RH_RUNNING |
| 2455 | || ehci->periodic_sched == 0) | 2475 | || ehci->periodic_sched == 0) |
| 2456 | break; | 2476 | break; |
| 2457 | ehci->next_uframe = now_uframe; | 2477 | ehci->next_uframe = now_uframe; |
| 2458 | now = ehci_readl(ehci, &ehci->regs->frame_index) & | 2478 | now = ehci_read_frame_index(ehci) & (mod - 1); |
| 2459 | (mod - 1); | ||
| 2460 | if (now_uframe == now) | 2479 | if (now_uframe == now) |
| 2461 | break; | 2480 | break; |
| 2462 | 2481 | ||
| @@ -168,7 +168,7 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) · 167 unmodified lines | |||
| 168 | clk_enable(priv->fclk); | 168 | clk_enable(priv->fclk); |
| 169 | clk_enable(priv->iclk); | 169 | clk_enable(priv->iclk); |
| 170 | 170 | ||
| 171 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 171 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 172 | if (ret != 0) { | 172 | if (ret != 0) { |
| 173 | dev_err(&pdev->dev, "Failed to add hcd"); | 173 | dev_err(&pdev->dev, "Failed to add hcd"); |
| 174 | goto fail_add_hcd; | 174 | goto fail_add_hcd; |
| @@ -154,7 +154,7 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) · 153 unmodified lines | |||
| 154 | ehci->clk = usbh_clk; | 154 | ehci->clk = usbh_clk; |
| 155 | 155 | ||
| 156 | spear_start_ehci(ehci); | 156 | spear_start_ehci(ehci); |
| 157 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED); | 157 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 158 | if (retval) | 158 | if (retval) |
| 159 | goto fail_add_hcd; | 159 | goto fail_add_hcd; |
| 160 | 160 | ||
| @@ -674,7 +674,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) · 673 unmodified lines | |||
| 674 | } | 674 | } |
| 675 | #endif | 675 | #endif |
| 676 | 676 | ||
| 677 | err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 677 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 678 | if (err) { | 678 | if (err) { |
| 679 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); | 679 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); |
| 680 | goto fail; | 680 | goto fail; |
| @@ -133,7 +133,7 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev) · 132 unmodified lines | |||
| 133 | ehci_port_power(ehci, 1); | 133 | ehci_port_power(ehci, 1); |
| 134 | 134 | ||
| 135 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | 135 | ret = usb_add_hcd(hcd, pdev->resource[1].start, |
| 136 | IRQF_DISABLED | IRQF_SHARED); | 136 | IRQF_SHARED); |
| 137 | if (ret == 0) { | 137 | if (ret == 0) { |
| 138 | platform_set_drvdata(pdev, hcd); | 138 | platform_set_drvdata(pdev, hcd); |
| 139 | return ret; | 139 | return ret; |
| @@ -0,0 +1,161 @@ | |||
| 1 | /* | ||
| 2 | * EHCI HCD for Netlogic XLS processors. | ||
| 3 | * | ||
| 4 | * (C) Copyright 2011 Netlogic Microsystems Inc. | ||
| 5 | * | ||
| 6 | * Based on various ehci-*.c drivers | ||
| 7 | * | ||
| 8 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 9 | * License. See the file COPYING in the main directory of this archive for | ||
| 10 | * more details. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/platform_device.h> | ||
| 14 | |||
| 15 | static int ehci_xls_setup(struct usb_hcd *hcd) | ||
| 16 | { | ||
| 17 | int retval; | ||
| 18 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 19 | |||
| 20 | ehci->caps = hcd->regs; | ||
| 21 | ehci->regs = hcd->regs + | ||
| 22 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
| 23 | dbg_hcs_params(ehci, "reset"); | ||
| 24 | dbg_hcc_params(ehci, "reset"); | ||
| 25 | |||
| 26 | /* cache this readonly data; minimize chip reads */ | ||
| 27 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
| 28 | |||
| 29 | retval = ehci_halt(ehci); | ||
| 30 | if (retval) | ||
| 31 | return retval; | ||
| 32 | |||
| 33 | /* data structure init */ | ||
| 34 | retval = ehci_init(hcd); | ||
| 35 | if (retval) | ||
| 36 | return retval; | ||
| 37 | |||
| 38 | ehci_reset(ehci); | ||
| 39 | |||
| 40 | return retval; | ||
| 41 | } | ||
| 42 | |||
| 43 | int ehci_xls_probe_internal(const struct hc_driver *driver, | ||
| 44 | struct platform_device *pdev) | ||
| 45 | { | ||
| 46 | struct usb_hcd *hcd; | ||
| 47 | struct resource *res; | ||
| 48 | int retval, irq; | ||
| 49 | |||
| 50 | /* Get our IRQ from an earlier registered Platform Resource */ | ||
| 51 | irq = platform_get_irq(pdev, 0); | ||
| 52 | if (irq < 0) { | ||
| 53 | dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", | ||
| 54 | dev_name(&pdev->dev)); | ||
| 55 | return -ENODEV; | ||
| 56 | } | ||
| 57 | |||
| 58 | /* Get our Memory Handle */ | ||
| 59 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 60 | if (!res) { | ||
| 61 | dev_err(&pdev->dev, "Error: MMIO Handle %s setup!\n", | ||
| 62 | dev_name(&pdev->dev)); | ||
| 63 | return -ENODEV; | ||
| 64 | } | ||
| 65 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | ||
| 66 | if (!hcd) { | ||
| 67 | retval = -ENOMEM; | ||
| 68 | goto err1; | ||
| 69 | } | ||
| 70 | |||
| 71 | hcd->rsrc_start = res->start; | ||
| 72 | hcd->rsrc_len = res->end - res->start + 1; | ||
| 73 | |||
| 74 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
| 75 | driver->description)) { | ||
| 76 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
| 77 | retval = -EBUSY; | ||
| 78 | goto err2; | ||
| 79 | } | ||
| 80 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
| 81 | |||
| 82 | if (hcd->regs == NULL) { | ||
| 83 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
| 84 | retval = -EFAULT; | ||
| 85 | goto err3; | ||
| 86 | } | ||
| 87 | |||
| 88 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
| 89 | if (retval != 0) | ||
| 90 | goto err4; | ||
| 91 | return retval; | ||
| 92 | |||
| 93 | err4: | ||
| 94 | iounmap(hcd->regs); | ||
| 95 | err3: | ||
| 96 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 97 | err2: | ||
| 98 | usb_put_hcd(hcd); | ||
| 99 | err1: | ||
| 100 | dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), | ||
| 101 | retval); | ||
| 102 | return retval; | ||
| 103 | } | ||
| 104 | |||
| 105 | static struct hc_driver ehci_xls_hc_driver = { | ||
| 106 | .description = hcd_name, | ||
| 107 | .product_desc = "XLS EHCI Host Controller", | ||
| 108 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
| 109 | .irq = ehci_irq, | ||
| 110 | .flags = HCD_USB2 | HCD_MEMORY, | ||
| 111 | .reset = ehci_xls_setup, | ||
| 112 | .start = ehci_run, | ||
| 113 | .stop = ehci_stop, | ||
| 114 | .shutdown = ehci_shutdown, | ||
| 115 | |||
| 116 | .urb_enqueue = ehci_urb_enqueue, | ||
| 117 | .urb_dequeue = ehci_urb_dequeue, | ||
| 118 | .endpoint_disable = ehci_endpoint_disable, | ||
| 119 | .endpoint_reset = ehci_endpoint_reset, | ||
| 120 | |||
| 121 | .get_frame_number = ehci_get_frame, | ||
| 122 | |||
| 123 | .hub_status_data = ehci_hub_status_data, | ||
| 124 | .hub_control = ehci_hub_control, | ||
| 125 | .bus_suspend = ehci_bus_suspend, | ||
| 126 | .bus_resume = ehci_bus_resume, | ||
| 127 | .relinquish_port = ehci_relinquish_port, | ||
| 128 | .port_handed_over = ehci_port_handed_over, | ||
| 129 | |||
| 130 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int ehci_xls_probe(struct platform_device *pdev) | ||
| 134 | { | ||
| 135 | if (usb_disabled()) | ||
| 136 | return -ENODEV; | ||
| 137 | |||
| 138 | return ehci_xls_probe_internal(&ehci_xls_hc_driver, pdev); | ||
| 139 | } | ||
| 140 | |||
| 141 | static int ehci_xls_remove(struct platform_device *pdev) | ||
| 142 | { | ||
| 143 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
| 144 | |||
| 145 | usb_remove_hcd(hcd); | ||
| 146 | iounmap(hcd->regs); | ||
| 147 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 148 | usb_put_hcd(hcd); | ||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | MODULE_ALIAS("ehci-xls"); | ||
| 153 | |||
| 154 | static struct platform_driver ehci_xls_driver = { | ||
| 155 | .probe = ehci_xls_probe, | ||
| 156 | .remove = ehci_xls_remove, | ||
| 157 | .shutdown = usb_hcd_platform_shutdown, | ||
| 158 | .driver = { | ||
| 159 | .name = "ehci-xls", | ||
| 160 | }, | ||
| 161 | }; | ||
| @@ -62,6 +62,12 @@ struct ehci_stats { · 61 unmodified lines | |||
| 62 | 62 | ||
| 63 | #define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */ | 63 | #define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */ |
| 64 | 64 | ||
| 65 | enum ehci_rh_state { | ||
| 66 | EHCI_RH_HALTED, | ||
| 67 | EHCI_RH_SUSPENDED, | ||
| 68 | EHCI_RH_RUNNING | ||
| 69 | }; | ||
| 70 | |||
| 65 | struct ehci_hcd { /* one per controller */ | 71 | struct ehci_hcd { /* one per controller */ |
| 66 | /* glue to PCI and HCD framework */ | 72 | /* glue to PCI and HCD framework */ |
| 67 | struct ehci_caps __iomem *caps; | 73 | struct ehci_caps __iomem *caps; |
| @@ -70,6 +76,7 @@ struct ehci_hcd { /* one per controller */ · 2 unmodified lines | |||
| 70 | 76 | ||
| 71 | __u32 hcs_params; /* cached register copy */ | 77 | __u32 hcs_params; /* cached register copy */ |
| 72 | spinlock_t lock; | 78 | spinlock_t lock; |
| 79 | enum ehci_rh_state rh_state; | ||
| 73 | 80 | ||
| 74 | /* async schedule support */ | 81 | /* async schedule support */ |
| 75 | struct ehci_qh *async; | 82 | struct ehci_qh *async; |
| @@ -139,6 +146,7 @@ struct ehci_hcd { /* one per controller */ · 63 unmodified lines | |||
| 139 | unsigned fs_i_thresh:1; /* Intel iso scheduling */ | 146 | unsigned fs_i_thresh:1; /* Intel iso scheduling */ |
| 140 | unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ | 147 | unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ |
| 141 | unsigned has_synopsys_hc_bug:1; /* Synopsys HC */ | 148 | unsigned has_synopsys_hc_bug:1; /* Synopsys HC */ |
| 149 | unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ | ||
| 142 | 150 | ||
| 143 | /* required for usb32 quirk */ | 151 | /* required for usb32 quirk */ |
| 144 | #define OHCI_CTRL_HCFS (3 << 6) | 152 | #define OHCI_CTRL_HCFS (3 << 6) |
| @@ -740,6 +748,22 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) · 595 unmodified lines | |||
| 740 | 748 | ||
| 741 | /*-------------------------------------------------------------------------*/ | 749 | /*-------------------------------------------------------------------------*/ |
| 742 | 750 | ||
| 751 | #ifdef CONFIG_PCI | ||
| 752 | |||
| 753 | /* For working around the MosChip frame-index-register bug */ | ||
| 754 | static unsigned ehci_read_frame_index(struct ehci_hcd *ehci); | ||
| 755 | |||
| 756 | #else | ||
| 757 | |||
| 758 | static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci) | ||
| 759 | { | ||
| 760 | return ehci_readl(ehci, &ehci->regs->frame_index); | ||
| 761 | } | ||
| 762 | |||
| 763 | #endif | ||
| 764 | |||
| 765 | /*-------------------------------------------------------------------------*/ | ||
| 766 | |||
| 743 | #ifndef DEBUG | 767 | #ifndef DEBUG |
| 744 | #define STUB_DEBUG_FILES | 768 | #define STUB_DEBUG_FILES |
| 745 | #endif /* DEBUG */ | 769 | #endif /* DEBUG */ |
| @@ -621,12 +621,15 @@ static int __devinit of_fhci_probe(struct platform_device *ofdev) · 620 unmodified lines | |||
| 621 | goto err_pram; | 621 | goto err_pram; |
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | pram_addr = cpm_muram_alloc_fixed(iprop[2], FHCI_PRAM_SIZE); | 624 | pram_addr = cpm_muram_alloc(FHCI_PRAM_SIZE, 64); |
| 625 | if (IS_ERR_VALUE(pram_addr)) { | 625 | if (IS_ERR_VALUE(pram_addr)) { |
| 626 | dev_err(dev, "failed to allocate usb pram\n"); | 626 | dev_err(dev, "failed to allocate usb pram\n"); |
| 627 | ret = -ENOMEM; | 627 | ret = -ENOMEM; |
| 628 | goto err_pram; | 628 | goto err_pram; |
| 629 | } | 629 | } |
| 630 | |||
| 631 | qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, QE_CR_SUBBLOCK_USB, | ||
| 632 | QE_CR_PROTOCOL_UNSPECIFIED, pram_addr); | ||
| 630 | fhci->pram = cpm_muram_addr(pram_addr); | 633 | fhci->pram = cpm_muram_addr(pram_addr); |
| 631 | 634 | ||
| 632 | /* GPIOs and pins */ | 635 | /* GPIOs and pins */ |
| @@ -686,7 +689,7 @@ static int __devinit of_fhci_probe(struct platform_device *ofdev) · 53 unmodified lines | |||
| 686 | } | 689 | } |
| 687 | 690 | ||
| 688 | ret = request_irq(fhci->timer->irq, fhci_frame_limit_timer_irq, | 691 | ret = request_irq(fhci->timer->irq, fhci_frame_limit_timer_irq, |
| 689 | IRQF_DISABLED, "qe timer (usb)", hcd); | 692 | 0, "qe timer (usb)", hcd); |
| 690 | if (ret) { | 693 | if (ret) { |
| 691 | dev_err(dev, "failed to request timer irq"); | 694 | dev_err(dev, "failed to request timer irq"); |
| 692 | goto err_timer_irq; | 695 | goto err_timer_irq; |
| @@ -745,7 +748,7 @@ static int __devinit of_fhci_probe(struct platform_device *ofdev) · 52 unmodified lines | |||
| 745 | out_be16(&fhci->regs->usb_event, 0xffff); | 748 | out_be16(&fhci->regs->usb_event, 0xffff); |
| 746 | out_be16(&fhci->regs->usb_mask, 0); | 749 | out_be16(&fhci->regs->usb_mask, 0); |
| 747 | 750 | ||
| 748 | ret = usb_add_hcd(hcd, usb_irq, IRQF_DISABLED); | 751 | ret = usb_add_hcd(hcd, usb_irq, 0); |
| 749 | if (ret < 0) | 752 | if (ret < 0) |
| 750 | goto err_add_hcd; | 753 | goto err_add_hcd; |
| 751 | 754 | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Freescale QUICC Engine USB Host Controller Driver | 2 | * Freescale QUICC Engine USB Host Controller Driver |
| 3 | * | 3 | * |
| 4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | 4 | * Copyright (c) Freescale Semicondutor, Inc. 2006, 2011. |
| 5 | * Shlomi Gridish <gridish@freescale.com> | 5 | * Shlomi Gridish <gridish@freescale.com> |
| 6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | 6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> |
| 7 | * Copyright (c) Logic Product Development, Inc. 2007 | 7 | * Copyright (c) Logic Product Development, Inc. 2007 |
| @@ -810,9 +810,11 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb) · 802 unmodified lines | |||
| 810 | ed->dev_addr = usb_pipedevice(urb->pipe); | 810 | ed->dev_addr = usb_pipedevice(urb->pipe); |
| 811 | ed->max_pkt_size = usb_maxpacket(urb->dev, urb->pipe, | 811 | ed->max_pkt_size = usb_maxpacket(urb->dev, urb->pipe, |
| 812 | usb_pipeout(urb->pipe)); | 812 | usb_pipeout(urb->pipe)); |
| 813 | /* setup stage */ | ||
| 813 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP, | 814 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP, |
| 814 | USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true); | 815 | USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true); |
| 815 | 816 | ||
| 817 | /* data stage */ | ||
| 816 | if (data_len > 0) { | 818 | if (data_len > 0) { |
| 817 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | 819 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, |
| 818 | usb_pipeout(urb->pipe) ? FHCI_TA_OUT : | 820 | usb_pipeout(urb->pipe) ? FHCI_TA_OUT : |
| @@ -820,9 +822,18 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb) · 1 unmodified line | |||
| 820 | USB_TD_TOGGLE_DATA1, data, data_len, 0, 0, | 822 | USB_TD_TOGGLE_DATA1, data, data_len, 0, 0, |
| 821 | true); | 823 | true); |
| 822 | } | 824 | } |
| 823 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | 825 | |
| 824 | usb_pipeout(urb->pipe) ? FHCI_TA_IN : FHCI_TA_OUT, | 826 | /* status stage */ |
| 825 | USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); | 827 | if (data_len > 0) |
| 828 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||
| 829 | (usb_pipeout(urb->pipe) ? FHCI_TA_IN : | ||
| 830 | FHCI_TA_OUT), | ||
| 831 | USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); | ||
| 832 | else | ||
| 833 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||
| 834 | FHCI_TA_IN, | ||
| 835 | USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); | ||
| 836 | |||
| 826 | urb_state = US_CTRL_SETUP; | 837 | urb_state = US_CTRL_SETUP; |
| 827 | break; | 838 | break; |
| 828 | case FHCI_TF_ISO: | 839 | case FHCI_TF_ISO: |
| @@ -1891,7 +1891,7 @@ static int imx21_probe(struct platform_device *pdev) · 1890 unmodified lines | |||
| 1891 | dev_info(imx21->dev, "Hardware HC revision: 0x%02X\n", | 1891 | dev_info(imx21->dev, "Hardware HC revision: 0x%02X\n", |
| 1892 | (readl(imx21->regs + USBOTG_HWMODE) >> 16) & 0xFF); | 1892 | (readl(imx21->regs + USBOTG_HWMODE) >> 16) & 0xFF); |
| 1893 | 1893 | ||
| 1894 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 1894 | ret = usb_add_hcd(hcd, irq, 0); |
| 1895 | if (ret != 0) { | 1895 | if (ret != 0) { |
| 1896 | dev_err(imx21->dev, "usb_add_hcd() returned %d\n", ret); | 1896 | dev_err(imx21->dev, "usb_add_hcd() returned %d\n", ret); |
| 1897 | goto failed_add_hcd; | 1897 | goto failed_add_hcd; |
| @@ -1639,7 +1639,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev) · 1638 unmodified lines | |||
| 1639 | goto err6; | 1639 | goto err6; |
| 1640 | } | 1640 | } |
| 1641 | 1641 | ||
| 1642 | ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED); | 1642 | ret = usb_add_hcd(hcd, irq, irqflags); |
| 1643 | if (ret) | 1643 | if (ret) |
| 1644 | goto err6; | 1644 | goto err6; |
| 1645 | 1645 | ||
| @@ -2358,7 +2358,7 @@ static int isp1362_hc_reset(struct usb_hcd *hcd) · 2357 unmodified lines | |||
| 2358 | unsigned long flags; | 2358 | unsigned long flags; |
| 2359 | int clkrdy = 0; | 2359 | int clkrdy = 0; |
| 2360 | 2360 | ||
| 2361 | pr_info("%s:\n", __func__); | 2361 | pr_debug("%s:\n", __func__); |
| 2362 | 2362 | ||
| 2363 | if (isp1362_hcd->board && isp1362_hcd->board->reset) { | 2363 | if (isp1362_hcd->board && isp1362_hcd->board->reset) { |
| 2364 | isp1362_hcd->board->reset(hcd->self.controller, 1); | 2364 | isp1362_hcd->board->reset(hcd->self.controller, 1); |
| @@ -2395,7 +2395,7 @@ static void isp1362_hc_stop(struct usb_hcd *hcd) · 30 unmodified lines | |||
| 2395 | unsigned long flags; | 2395 | unsigned long flags; |
| 2396 | u32 tmp; | 2396 | u32 tmp; |
| 2397 | 2397 | ||
| 2398 | pr_info("%s:\n", __func__); | 2398 | pr_debug("%s:\n", __func__); |
| 2399 | 2399 | ||
| 2400 | del_timer_sync(&hcd->rh_timer); | 2400 | del_timer_sync(&hcd->rh_timer); |
| 2401 | 2401 | ||
| @@ -2523,7 +2523,7 @@ static int isp1362_hc_start(struct usb_hcd *hcd) · 121 unmodified lines | |||
| 2523 | u16 chipid; | 2523 | u16 chipid; |
| 2524 | unsigned long flags; | 2524 | unsigned long flags; |
| 2525 | 2525 | ||
| 2526 | pr_info("%s:\n", __func__); | 2526 | pr_debug("%s:\n", __func__); |
| 2527 | 2527 | ||
| 2528 | spin_lock_irqsave(&isp1362_hcd->lock, flags); | 2528 | spin_lock_irqsave(&isp1362_hcd->lock, flags); |
| 2529 | chipid = isp1362_read_reg16(isp1362_hcd, HCCHIPID); | 2529 | chipid = isp1362_read_reg16(isp1362_hcd, HCCHIPID); |
| @@ -2773,7 +2773,7 @@ static int __devinit isp1362_probe(struct platform_device *pdev) · 243 unmodified lines | |||
| 2773 | if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL) | 2773 | if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL) |
| 2774 | irq_flags |= IRQF_TRIGGER_LOW; | 2774 | irq_flags |= IRQF_TRIGGER_LOW; |
| 2775 | 2775 | ||
| 2776 | retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_DISABLED | IRQF_SHARED); | 2776 | retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_SHARED); |
| 2777 | if (retval != 0) | 2777 | if (retval != 0) |
| 2778 | goto err6; | 2778 | goto err6; |
| 2779 | pr_info("%s, irq %d\n", hcd->product_desc, irq); | 2779 | pr_info("%s, irq %d\n", hcd->product_desc, irq); |
| @@ -21,8 +21,10 @@ · 20 unmodified lines | |||
| 21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
| 22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
| 23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| 24 | #include <linux/timer.h> | ||
| 24 | #include <asm/unaligned.h> | 25 | #include <asm/unaligned.h> |
| 25 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
| 27 | #include <linux/gpio.h> | ||
| 26 | 28 | ||
| 27 | #include "isp1760-hcd.h" | 29 | #include "isp1760-hcd.h" |
| 28 | 30 | ||
| @@ -39,7 +41,6 @@ struct isp1760_hcd { · 10 unmodified lines | |||
| 39 | int int_done_map; | 41 | int int_done_map; |
| 40 | struct memory_chunk memory_pool[BLOCKS]; | 42 | struct memory_chunk memory_pool[BLOCKS]; |
| 41 | struct list_head controlqhs, bulkqhs, interruptqhs; | 43 | struct list_head controlqhs, bulkqhs, interruptqhs; |
| 42 | int active_ptds; | ||
| 43 | 44 | ||
| 44 | /* periodic schedule support */ | 45 | /* periodic schedule support */ |
| 45 | #define DEFAULT_I_TDPS 1024 | 46 | #define DEFAULT_I_TDPS 1024 |
| @@ -48,6 +49,8 @@ struct isp1760_hcd { · 2 unmodified lines | |||
| 48 | unsigned long reset_done; | 49 | unsigned long reset_done; |
| 49 | unsigned long next_statechange; | 50 | unsigned long next_statechange; |
| 50 | unsigned int devflags; | 51 | unsigned int devflags; |
| 52 | |||
| 53 | int rst_gpio; | ||
| 51 | }; | 54 | }; |
| 52 | 55 | ||
| 53 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) | 56 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) |
| @@ -114,6 +117,7 @@ struct isp1760_qh { · 60 unmodified lines | |||
| 114 | u32 toggle; | 117 | u32 toggle; |
| 115 | u32 ping; | 118 | u32 ping; |
| 116 | int slot; | 119 | int slot; |
| 120 | int tt_buffer_dirty; /* See USB2.0 spec section 11.17.5 */ | ||
| 117 | }; | 121 | }; |
| 118 | 122 | ||
| 119 | struct urb_listitem { | 123 | struct urb_listitem { |
| @@ -432,6 +436,18 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) · 312 unmodified lines | |||
| 432 | int result; | 436 | int result; |
| 433 | u32 scratch, hwmode; | 437 | u32 scratch, hwmode; |
| 434 | 438 | ||
| 439 | /* low-level chip reset */ | ||
| 440 | if (gpio_is_valid(priv->rst_gpio)) { | ||
| 441 | unsigned int rst_lvl; | ||
| 442 | |||
| 443 | rst_lvl = (priv->devflags & | ||
| 444 | ISP1760_FLAG_RESET_ACTIVE_HIGH) ? 1 : 0; | ||
| 445 | |||
| 446 | gpio_set_value(priv->rst_gpio, rst_lvl); | ||
| 447 | mdelay(50); | ||
| 448 | gpio_set_value(priv->rst_gpio, !rst_lvl); | ||
| 449 | } | ||
| 450 | |||
| 435 | /* Setup HW Mode Control: This assumes a level active-low interrupt */ | 451 | /* Setup HW Mode Control: This assumes a level active-low interrupt */ |
| 436 | hwmode = HW_DATA_BUS_32BIT; | 452 | hwmode = HW_DATA_BUS_32BIT; |
| 437 | 453 | ||
| @@ -489,10 +505,6 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) · 51 unmodified lines | |||
| 489 | 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ? | 505 | 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ? |
| 490 | "analog" : "digital"); | 506 | "analog" : "digital"); |
| 491 | 507 | ||
| 492 | /* This is weird: at the first plug-in of a device there seems to be | ||
| 493 | one packet queued that never gets returned? */ | ||
| 494 | priv->active_ptds = -1; | ||
| 495 | |||
| 496 | /* ATL reset */ | 508 | /* ATL reset */ |
| 497 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); | 509 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); |
| 498 | mdelay(10); | 510 | mdelay(10); |
| @@ -514,83 +526,6 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) · 15 unmodified lines | |||
| 514 | return priv_init(hcd); | 526 | return priv_init(hcd); |
| 515 | } | 527 | } |
| 516 | 528 | ||
| 517 | static void isp1760_init_maps(struct usb_hcd *hcd) | ||
| 518 | { | ||
| 519 | /*set last maps, for iso its only 1, else 32 tds bitmap*/ | ||
| 520 | reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000); | ||
| 521 | reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000); | ||
| 522 | reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001); | ||
| 523 | |||
| 524 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); | ||
| 525 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, 0xffffffff); | ||
| 526 | reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, 0xffffffff); | ||
| 527 | |||
| 528 | reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, | ||
| 529 | ATL_BUF_FILL | INT_BUF_FILL); | ||
| 530 | } | ||
| 531 | |||
| 532 | static void isp1760_enable_interrupts(struct usb_hcd *hcd) | ||
| 533 | { | ||
| 534 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0); | ||
| 535 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0xffffffff); | ||
| 536 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0); | ||
| 537 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0xffffffff); | ||
| 538 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0); | ||
| 539 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff); | ||
| 540 | /* step 23 passed */ | ||
| 541 | } | ||
| 542 | |||
| 543 | static int isp1760_run(struct usb_hcd *hcd) | ||
| 544 | { | ||
| 545 | int retval; | ||
| 546 | u32 temp; | ||
| 547 | u32 command; | ||
| 548 | u32 chipid; | ||
| 549 | |||
| 550 | hcd->uses_new_polling = 1; | ||
| 551 | |||
| 552 | hcd->state = HC_STATE_RUNNING; | ||
| 553 | isp1760_enable_interrupts(hcd); | ||
| 554 | temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); | ||
| 555 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN); | ||
| 556 | |||
| 557 | command = reg_read32(hcd->regs, HC_USBCMD); | ||
| 558 | command &= ~(CMD_LRESET|CMD_RESET); | ||
| 559 | command |= CMD_RUN; | ||
| 560 | reg_write32(hcd->regs, HC_USBCMD, command); | ||
| 561 | |||
| 562 | retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000); | ||
| 563 | if (retval) | ||
| 564 | return retval; | ||
| 565 | |||
| 566 | /* | ||
| 567 | * XXX | ||
| 568 | * Spec says to write FLAG_CF as last config action, priv code grabs | ||
| 569 | * the semaphore while doing so. | ||
| 570 | */ | ||
| 571 | down_write(&ehci_cf_port_reset_rwsem); | ||
| 572 | reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF); | ||
| 573 | |||
| 574 | retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000); | ||
| 575 | up_write(&ehci_cf_port_reset_rwsem); | ||
| 576 | if (retval) | ||
| 577 | return retval; | ||
| 578 | |||
| 579 | chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); | ||
| 580 | dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n", | ||
| 581 | chipid & 0xffff, chipid >> 16); | ||
| 582 | |||
| 583 | /* PTD Register Init Part 2, Step 28 */ | ||
| 584 | /* enable INTs */ | ||
| 585 | isp1760_init_maps(hcd); | ||
| 586 | |||
| 587 | /* GRR this is run-once init(), being done every time the HC starts. | ||
| 588 | * So long as they're part of class devices, we can't do it init() | ||
| 589 | * since the class device isn't created that early. | ||
| 590 | */ | ||
| 591 | return 0; | ||
| 592 | } | ||
| 593 | |||
| 594 | static u32 base_to_chip(u32 base) | 529 | static u32 base_to_chip(u32 base) |
| 595 | { | 530 | { |
| 596 | return ((base - 0x400) >> 3); | 531 | return ((base - 0x400) >> 3); |
| @@ -813,28 +748,29 @@ static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot, · 216 unmodified lines | |||
| 813 | WARN_ON(slots[slot].qh); | 748 | WARN_ON(slots[slot].qh); |
| 814 | WARN_ON(qtd->status != QTD_PAYLOAD_ALLOC); | 749 | WARN_ON(qtd->status != QTD_PAYLOAD_ALLOC); |
| 815 | 750 | ||
| 816 | slots[slot].qtd = qtd; | ||
| 817 | slots[slot].qh = qh; | ||
| 818 | qh->slot = slot; | ||
| 819 | qtd->status = QTD_XFER_STARTED; /* Set this before writing ptd, since | ||
| 820 | interrupt routine may preempt and expects this value. */ | ||
| 821 | ptd_write(hcd->regs, ptd_offset, slot, ptd); | ||
| 822 | priv->active_ptds++; | ||
| 823 | |||
| 824 | /* Make sure done map has not triggered from some unlinked transfer */ | 751 | /* Make sure done map has not triggered from some unlinked transfer */ |
| 825 | if (ptd_offset == ATL_PTD_OFFSET) { | 752 | if (ptd_offset == ATL_PTD_OFFSET) { |
| 826 | priv->atl_done_map |= reg_read32(hcd->regs, | 753 | priv->atl_done_map |= reg_read32(hcd->regs, |
| 827 | HC_ATL_PTD_DONEMAP_REG); | 754 | HC_ATL_PTD_DONEMAP_REG); |
| 828 | priv->atl_done_map &= ~(1 << qh->slot); | 755 | priv->atl_done_map &= ~(1 << slot); |
| 756 | } else { | ||
| 757 | priv->int_done_map |= reg_read32(hcd->regs, | ||
| 758 | HC_INT_PTD_DONEMAP_REG); | ||
| 759 | priv->int_done_map &= ~(1 << slot); | ||
| 760 | } | ||
| 761 | |||
| 762 | qh->slot = slot; | ||
| 763 | qtd->status = QTD_XFER_STARTED; | ||
| 764 | slots[slot].timestamp = jiffies; | ||
| 765 | slots[slot].qtd = qtd; | ||
| 766 | slots[slot].qh = qh; | ||
| 767 | ptd_write(hcd->regs, ptd_offset, slot, ptd); | ||
| 829 | 768 | ||
| 769 | if (ptd_offset == ATL_PTD_OFFSET) { | ||
| 830 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); | 770 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); |
| 831 | skip_map &= ~(1 << qh->slot); | 771 | skip_map &= ~(1 << qh->slot); |
| 832 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); | 772 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); |
| 833 | } else { | 773 | } else { |
| 834 | priv->int_done_map |= reg_read32(hcd->regs, | ||
| 835 | HC_INT_PTD_DONEMAP_REG); | ||
| 836 | priv->int_done_map &= ~(1 << qh->slot); | ||
| 837 | |||
| 838 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); | 774 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); |
| 839 | skip_map &= ~(1 << qh->slot); | 775 | skip_map &= ~(1 << qh->slot); |
| 840 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); | 776 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); |
| @@ -858,10 +794,7 @@ static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh, · 17 unmodified lines | |||
| 858 | if (qtd->status < QTD_XFER_COMPLETE) | 794 | if (qtd->status < QTD_XFER_COMPLETE) |
| 859 | break; | 795 | break; |
| 860 | 796 | ||
| 861 | if (list_is_last(&qtd->qtd_list, &qh->qtd_list)) | 797 | last_qtd = last_qtd_of_urb(qtd, qh); |
| 862 | last_qtd = 1; | ||
| 863 | else | ||
| 864 | last_qtd = qtd->urb != qtd_next->urb; | ||
| 865 | 798 | ||
| 866 | if ((!last_qtd) && (qtd->status == QTD_RETIRE)) | 799 | if ((!last_qtd) && (qtd->status == QTD_RETIRE)) |
| 867 | qtd_next->status = QTD_RETIRE; | 800 | qtd_next->status = QTD_RETIRE; |
| @@ -902,7 +835,7 @@ static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh, · 34 unmodified lines | |||
| 902 | urb_listitem = kmem_cache_zalloc(urb_listitem_cachep, | 835 | urb_listitem = kmem_cache_zalloc(urb_listitem_cachep, |
| 903 | GFP_ATOMIC); | 836 | GFP_ATOMIC); |
| 904 | if (unlikely(!urb_listitem)) | 837 | if (unlikely(!urb_listitem)) |
| 905 | break; | 838 | break; /* Try again on next call */ |
| 906 | urb_listitem->urb = qtd->urb; | 839 | urb_listitem->urb = qtd->urb; |
| 907 | list_add_tail(&urb_listitem->urb_list, urb_list); | 840 | list_add_tail(&urb_listitem->urb_list, urb_list); |
| 908 | } | 841 | } |
| @@ -928,6 +861,10 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh) · 19 unmodified lines | |||
| 928 | return; | 861 | return; |
| 929 | } | 862 | } |
| 930 | 863 | ||
| 864 | /* Make sure this endpoint's TT buffer is clean before queueing ptds */ | ||
| 865 | if (qh->tt_buffer_dirty) | ||
| 866 | return; | ||
| 867 | |||
| 931 | if (usb_pipeint(list_entry(qh->qtd_list.next, struct isp1760_qtd, | 868 | if (usb_pipeint(list_entry(qh->qtd_list.next, struct isp1760_qtd, |
| 932 | qtd_list)->urb->pipe)) { | 869 | qtd_list)->urb->pipe)) { |
| 933 | ptd_offset = INT_PTD_OFFSET; | 870 | ptd_offset = INT_PTD_OFFSET; |
| @@ -1168,11 +1105,9 @@ static int check_atl_transfer(struct usb_hcd *hcd, struct ptd *ptd, · 234 unmodified lines | |||
| 1168 | return PTD_STATE_QTD_DONE; | 1105 | return PTD_STATE_QTD_DONE; |
| 1169 | } | 1106 | } |
| 1170 | 1107 | ||
| 1171 | static irqreturn_t isp1760_irq(struct usb_hcd *hcd) | 1108 | static void handle_done_ptds(struct usb_hcd *hcd) |
| 1172 | { | 1109 | { |
| 1173 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 1110 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
| 1174 | u32 imask; | ||
| 1175 | irqreturn_t irqret = IRQ_NONE; | ||
| 1176 | struct ptd ptd; | 1111 | struct ptd ptd; |
| 1177 | struct isp1760_qh *qh; | 1112 | struct isp1760_qh *qh; |
| 1178 | int slot; | 1113 | int slot; |
| @@ -1181,27 +1116,14 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd) · 2 unmodified lines | |||
| 1181 | u32 ptd_offset; | 1116 | u32 ptd_offset; |
| 1182 | struct isp1760_qtd *qtd; | 1117 | struct isp1760_qtd *qtd; |
| 1183 | int modified; | 1118 | int modified; |
| 1184 | static int last_active_ptds; | 1119 | int skip_map; |
| 1185 | int int_skip_map, atl_skip_map; | ||
| 1186 | |||
| 1187 | spin_lock(&priv->lock); | ||
| 1188 | |||
| 1189 | if (!(hcd->state & HC_STATE_RUNNING)) | ||
| 1190 | goto leave; | ||
| 1191 | |||
| 1192 | imask = reg_read32(hcd->regs, HC_INTERRUPT_REG); | ||
| 1193 | if (unlikely(!imask)) | ||
| 1194 | goto leave; | ||
| 1195 | reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); /* Clear */ | ||
| 1196 | 1120 | ||
| 1197 | int_skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); | 1121 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); |
| 1198 | atl_skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); | 1122 | priv->int_done_map &= ~skip_map; |
| 1199 | priv->int_done_map |= reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG); | 1123 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); |
| 1200 | priv->atl_done_map |= reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG); | 1124 | priv->atl_done_map &= ~skip_map; |
| 1201 | priv->int_done_map &= ~int_skip_map; | ||
| 1202 | priv->atl_done_map &= ~atl_skip_map; | ||
| 1203 | 1125 | ||
| 1204 | modified = priv->int_done_map | priv->atl_done_map; | 1126 | modified = priv->int_done_map || priv->atl_done_map; |
| 1205 | 1127 | ||
| 1206 | while (priv->int_done_map || priv->atl_done_map) { | 1128 | while (priv->int_done_map || priv->atl_done_map) { |
| 1207 | if (priv->int_done_map) { | 1129 | if (priv->int_done_map) { |
| @@ -1240,7 +1162,6 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd) · 32 unmodified lines | |||
| 1240 | slots[slot].qtd = NULL; | 1162 | slots[slot].qtd = NULL; |
| 1241 | qh = slots[slot].qh; | 1163 | qh = slots[slot].qh; |
| 1242 | slots[slot].qh = NULL; | 1164 | slots[slot].qh = NULL; |
| 1243 | priv->active_ptds--; | ||
| 1244 | qh->slot = -1; | 1165 | qh->slot = -1; |
| 1245 | 1166 | ||
| 1246 | WARN_ON(qtd->status != QTD_XFER_STARTED); | 1167 | WARN_ON(qtd->status != QTD_XFER_STARTED); |
| @@ -1281,6 +1202,15 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd) · 34 unmodified lines | |||
| 1281 | 1202 | ||
| 1282 | case PTD_STATE_URB_RETIRE: | 1203 | case PTD_STATE_URB_RETIRE: |
| 1283 | qtd->status = QTD_RETIRE; | 1204 | qtd->status = QTD_RETIRE; |
| 1205 | if ((qtd->urb->dev->speed != USB_SPEED_HIGH) && | ||
| 1206 | (qtd->urb->status != -EPIPE) && | ||
| 1207 | (qtd->urb->status != -EREMOTEIO)) { | ||
| 1208 | qh->tt_buffer_dirty = 1; | ||
| 1209 | if (usb_hub_clear_tt_buffer(qtd->urb)) | ||
| 1210 | /* Clear failed; let's hope things work | ||
| 1211 | anyway */ | ||
| 1212 | qh->tt_buffer_dirty = 0; | ||
| 1213 | } | ||
| 1284 | qtd = NULL; | 1214 | qtd = NULL; |
| 1285 | qh->toggle = 0; | 1215 | qh->toggle = 0; |
| 1286 | qh->ping = 0; | 1216 | qh->ping = 0; |
| @@ -1311,22 +1241,28 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd) · 24 unmodified lines | |||
| 1311 | 1241 | ||
| 1312 | if (modified) | 1242 | if (modified) |
| 1313 | schedule_ptds(hcd); | 1243 | schedule_ptds(hcd); |
| 1244 | } | ||
| 1314 | 1245 | ||
| 1315 | /* ISP1760 Errata 2 explains that interrupts may be missed (or not | 1246 | static irqreturn_t isp1760_irq(struct usb_hcd *hcd) |
| 1316 | happen?) if two USB devices are running simultaneously. Perhaps | 1247 | { |
| 1317 | this happens when a PTD is finished during interrupt handling; | 1248 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
| 1318 | enable SOF interrupts if PTDs are still scheduled when exiting this | 1249 | u32 imask; |
| 1319 | interrupt handler, just to be safe. */ | 1250 | irqreturn_t irqret = IRQ_NONE; |
| 1320 | 1251 | ||
| 1321 | if (priv->active_ptds != last_active_ptds) { | 1252 | spin_lock(&priv->lock); |
| 1322 | if (priv->active_ptds > 0) | 1253 | |
| 1323 | reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, | 1254 | if (!(hcd->state & HC_STATE_RUNNING)) |
| 1324 | INTERRUPT_ENABLE_SOT_MASK); | 1255 | goto leave; |
| 1325 | else | 1256 | |
| 1326 | reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, | 1257 | imask = reg_read32(hcd->regs, HC_INTERRUPT_REG); |
| 1327 | INTERRUPT_ENABLE_MASK); | 1258 | if (unlikely(!imask)) |
| 1328 | last_active_ptds = priv->active_ptds; | 1259 | goto leave; |
| 1329 | } | 1260 | reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); /* Clear */ |
| 1261 | |||
| 1262 | priv->int_done_map |= reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG); | ||
| 1263 | priv->atl_done_map |= reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG); | ||
| 1264 | |||
| 1265 | handle_done_ptds(hcd); | ||
| 1330 | 1266 | ||
| 1331 | irqret = IRQ_HANDLED; | 1267 | irqret = IRQ_HANDLED; |
| 1332 | leave: | 1268 | leave: |
| @@ -1335,6 +1271,138 @@ leave: · 2 unmodified lines | |||
| 1335 | return irqret; | 1271 | return irqret; |
| 1336 | } | 1272 | } |
| 1337 | 1273 | ||
| 1274 | /* | ||
| 1275 | * Workaround for problem described in chip errata 2: | ||
| 1276 | * | ||
| 1277 | * Sometimes interrupts are not generated when ATL (not INT?) completion occurs. | ||
| 1278 | * One solution suggested in the errata is to use SOF interrupts _instead_of_ | ||
| 1279 | * ATL done interrupts (the "instead of" might be important since it seems | ||
| 1280 | * enabling ATL interrupts also causes the chip to sometimes - rarely - "forget" | ||
| 1281 | * to set the PTD's done bit in addition to not generating an interrupt!). | ||
| 1282 | * | ||
| 1283 | * So if we use SOF + ATL interrupts, we sometimes get stale PTDs since their | ||
| 1284 | * done bit is not being set. This is bad - it blocks the endpoint until reboot. | ||
| 1285 | * | ||
| 1286 | * If we use SOF interrupts only, we get latency between ptd completion and the | ||
| 1287 | * actual handling. This is very noticeable in testusb runs which takes several | ||
| 1288 | * minutes longer without ATL interrupts. | ||
| 1289 | * | ||
| 1290 | * A better solution is to run the code below every SLOT_CHECK_PERIOD ms. If it | ||
| 1291 | * finds active ATL slots which are older than SLOT_TIMEOUT ms, it checks the | ||
| 1292 | * slot's ACTIVE and VALID bits. If these are not set, the ptd is considered | ||
| 1293 | * completed and its done map bit is set. | ||
| 1294 | * | ||
| 1295 | * The values of SLOT_TIMEOUT and SLOT_CHECK_PERIOD have been arbitrarily chosen | ||
| 1296 | * not to cause too much lag when this HW bug occurs, while still hopefully | ||
| 1297 | * ensuring that the check does not falsely trigger. | ||
| 1298 | */ | ||
| 1299 | #define SLOT_TIMEOUT 300 | ||
| 1300 | #define SLOT_CHECK_PERIOD 200 | ||
| 1301 | static struct timer_list errata2_timer; | ||
| 1302 | |||
| 1303 | void errata2_function(unsigned long data) | ||
| 1304 | { | ||
| 1305 | struct usb_hcd *hcd = (struct usb_hcd *) data; | ||
| 1306 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
| 1307 | int slot; | ||
| 1308 | struct ptd ptd; | ||
| 1309 | unsigned long spinflags; | ||
| 1310 | |||
| 1311 | spin_lock_irqsave(&priv->lock, spinflags); | ||
| 1312 | |||
| 1313 | for (slot = 0; slot < 32; slot++) | ||
| 1314 | if (priv->atl_slots[slot].qh && time_after(jiffies, | ||
| 1315 | priv->atl_slots[slot].timestamp + | ||
| 1316 | SLOT_TIMEOUT * HZ / 1000)) { | ||
| 1317 | ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); | ||
| 1318 | if (!FROM_DW0_VALID(ptd.dw0) && | ||
| 1319 | !FROM_DW3_ACTIVE(ptd.dw3)) | ||
| 1320 | priv->atl_done_map |= 1 << slot; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | if (priv->atl_done_map) | ||
| 1324 | handle_done_ptds(hcd); | ||
| 1325 | |||
| 1326 | spin_unlock_irqrestore(&priv->lock, spinflags); | ||
| 1327 | |||
| 1328 | errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; | ||
| 1329 | add_timer(&errata2_timer); | ||
| 1330 | } | ||
| 1331 | |||
| 1332 | static int isp1760_run(struct usb_hcd *hcd) | ||
| 1333 | { | ||
| 1334 | int retval; | ||
| 1335 | u32 temp; | ||
| 1336 | u32 command; | ||
| 1337 | u32 chipid; | ||
| 1338 | |||
| 1339 | hcd->uses_new_polling = 1; | ||
| 1340 | |||
| 1341 | hcd->state = HC_STATE_RUNNING; | ||
| 1342 | |||
| 1343 | /* Set PTD interrupt AND & OR maps */ | ||
| 1344 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0); | ||
| 1345 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0xffffffff); | ||
| 1346 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0); | ||
| 1347 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0xffffffff); | ||
| 1348 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0); | ||
| 1349 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff); | ||
| 1350 | /* step 23 passed */ | ||
| 1351 | |||
| 1352 | temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); | ||
| 1353 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN); | ||
| 1354 | |||
| 1355 | command = reg_read32(hcd->regs, HC_USBCMD); | ||
| 1356 | command &= ~(CMD_LRESET|CMD_RESET); | ||
| 1357 | command |= CMD_RUN; | ||
| 1358 | reg_write32(hcd->regs, HC_USBCMD, command); | ||
| 1359 | |||
| 1360 | retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000); | ||
| 1361 | if (retval) | ||
| 1362 | return retval; | ||
| 1363 | |||
| 1364 | /* | ||
| 1365 | * XXX | ||
| 1366 | * Spec says to write FLAG_CF as last config action, priv code grabs | ||
| 1367 | * the semaphore while doing so. | ||
| 1368 | */ | ||
| 1369 | down_write(&ehci_cf_port_reset_rwsem); | ||
| 1370 | reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF); | ||
| 1371 | |||
| 1372 | retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000); | ||
| 1373 | up_write(&ehci_cf_port_reset_rwsem); | ||
| 1374 | if (retval) | ||
| 1375 | return retval; | ||
| 1376 | |||
| 1377 | init_timer(&errata2_timer); | ||
| 1378 | errata2_timer.function = errata2_function; | ||
| 1379 | errata2_timer.data = (unsigned long) hcd; | ||
| 1380 | errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; | ||
| 1381 | add_timer(&errata2_timer); | ||
| 1382 | |||
| 1383 | chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); | ||
| 1384 | dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n", | ||
| 1385 | chipid & 0xffff, chipid >> 16); | ||
| 1386 | |||
| 1387 | /* PTD Register Init Part 2, Step 28 */ | ||
| 1388 | |||
| 1389 | /* Setup registers controlling PTD checking */ | ||
| 1390 | reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000); | ||
| 1391 | reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000); | ||
| 1392 | reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001); | ||
| 1393 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); | ||
| 1394 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, 0xffffffff); | ||
| 1395 | reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, 0xffffffff); | ||
| 1396 | reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, | ||
| 1397 | ATL_BUF_FILL | INT_BUF_FILL); | ||
| 1398 | |||
| 1399 | /* GRR this is run-once init(), being done every time the HC starts. | ||
| 1400 | * So long as they're part of class devices, we can't do it init() | ||
| 1401 | * since the class device isn't created that early. | ||
| 1402 | */ | ||
| 1403 | return 0; | ||
| 1404 | } | ||
| 1405 | |||
| 1338 | static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len) | 1406 | static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len) |
| 1339 | { | 1407 | { |
| 1340 | qtd->data_buffer = databuffer; | 1408 | qtd->data_buffer = databuffer; |
| @@ -1503,7 +1571,6 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, · 162 unmodified lines | |||
| 1503 | packetize_urb(hcd, urb, &new_qtds, mem_flags); | 1571 | packetize_urb(hcd, urb, &new_qtds, mem_flags); |
| 1504 | if (list_empty(&new_qtds)) | 1572 | if (list_empty(&new_qtds)) |
| 1505 | return -ENOMEM; | 1573 | return -ENOMEM; |
| 1506 | urb->hcpriv = NULL; /* Used to signal unlink to interrupt handler */ | ||
| 1507 | 1574 | ||
| 1508 | retval = 0; | 1575 | retval = 0; |
| 1509 | spin_lock_irqsave(&priv->lock, spinflags); | 1576 | spin_lock_irqsave(&priv->lock, spinflags); |
| @@ -1531,6 +1598,7 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, · 21 unmodified lines | |||
| 1531 | qh = qh_alloc(GFP_ATOMIC); | 1598 | qh = qh_alloc(GFP_ATOMIC); |
| 1532 | if (!qh) { | 1599 | if (!qh) { |
| 1533 | retval = -ENOMEM; | 1600 | retval = -ENOMEM; |
| 1601 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
| 1534 | goto out; | 1602 | goto out; |
| 1535 | } | 1603 | } |
| 1536 | list_add_tail(&qh->qh_list, ep_queue); | 1604 | list_add_tail(&qh->qh_list, ep_queue); |
| @@ -1570,7 +1638,41 @@ static void kill_transfer(struct usb_hcd *hcd, struct urb *urb, · 33 unmodified lines | |||
| 1570 | } | 1638 | } |
| 1571 | 1639 | ||
| 1572 | qh->slot = -1; | 1640 | qh->slot = -1; |
| 1573 | priv->active_ptds--; | 1641 | } |
| 1642 | |||
| 1643 | /* | ||
| 1644 | * Retire the qtds beginning at 'qtd' and belonging all to the same urb, killing | ||
| 1645 | * any active transfer belonging to the urb in the process. | ||
| 1646 | */ | ||
| 1647 | static void dequeue_urb_from_qtd(struct usb_hcd *hcd, struct isp1760_qh *qh, | ||
| 1648 | struct isp1760_qtd *qtd) | ||
| 1649 | { | ||
| 1650 | struct urb *urb; | ||
| 1651 | int urb_was_running; | ||
| 1652 | |||
| 1653 | urb = qtd->urb; | ||
| 1654 | urb_was_running = 0; | ||
| 1655 | list_for_each_entry_from(qtd, &qh->qtd_list, qtd_list) { | ||
| 1656 | if (qtd->urb != urb) | ||
| 1657 | break; | ||
| 1658 | |||
| 1659 | if (qtd->status >= QTD_XFER_STARTED) | ||
| 1660 | urb_was_running = 1; | ||
| 1661 | if (last_qtd_of_urb(qtd, qh) && | ||
| 1662 | (qtd->status >= QTD_XFER_COMPLETE)) | ||
| 1663 | urb_was_running = 0; | ||
| 1664 | |||
| 1665 | if (qtd->status == QTD_XFER_STARTED) | ||
| 1666 | kill_transfer(hcd, urb, qh); | ||
| 1667 | qtd->status = QTD_RETIRE; | ||
| 1668 | } | ||
| 1669 | |||
| 1670 | if ((urb->dev->speed != USB_SPEED_HIGH) && urb_was_running) { | ||
| 1671 | qh->tt_buffer_dirty = 1; | ||
| 1672 | if (usb_hub_clear_tt_buffer(urb)) | ||
| 1673 | /* Clear failed; let's hope things work anyway */ | ||
| 1674 | qh->tt_buffer_dirty = 0; | ||
| 1675 | } | ||
| 1574 | } | 1676 | } |
| 1575 | 1677 | ||
| 1576 | static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, | 1678 | static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, |
| @@ -1595,9 +1697,8 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, · 18 unmodified lines | |||
| 1595 | 1697 | ||
| 1596 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) | 1698 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) |
| 1597 | if (qtd->urb == urb) { | 1699 | if (qtd->urb == urb) { |
| 1598 | if (qtd->status == QTD_XFER_STARTED) | 1700 | dequeue_urb_from_qtd(hcd, qh, qtd); |
| 1599 | kill_transfer(hcd, urb, qh); | 1701 | break; |
| 1600 | qtd->status = QTD_RETIRE; | ||
| 1601 | } | 1702 | } |
| 1602 | 1703 | ||
| 1603 | urb->status = status; | 1704 | urb->status = status; |
| @@ -1622,12 +1723,11 @@ static void isp1760_endpoint_disable(struct usb_hcd *hcd, · 18 unmodified lines | |||
| 1622 | if (!qh) | 1723 | if (!qh) |
| 1623 | goto out; | 1724 | goto out; |
| 1624 | 1725 | ||
| 1625 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) { | 1726 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) |
| 1626 | if (qtd->status == QTD_XFER_STARTED) | 1727 | if (qtd->status != QTD_RETIRE) { |
| 1627 | kill_transfer(hcd, qtd->urb, qh); | 1728 | dequeue_urb_from_qtd(hcd, qh, qtd); |
| 1628 | qtd->status = QTD_RETIRE; | 1729 | qtd->urb->status = -ECONNRESET; |
| 1629 | qtd->urb->status = -ECONNRESET; | 1730 | } |
| 1630 | } | ||
| 1631 | 1731 | ||
| 1632 | ep->hcpriv = NULL; | 1732 | ep->hcpriv = NULL; |
| 1633 | /* Cannot free qh here since it will be parsed by schedule_ptds() */ | 1733 | /* Cannot free qh here since it will be parsed by schedule_ptds() */ |
| @@ -2021,6 +2121,8 @@ static void isp1760_stop(struct usb_hcd *hcd) · 387 unmodified lines | |||
| 2021 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 2121 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
| 2022 | u32 temp; | 2122 | u32 temp; |
| 2023 | 2123 | ||
| 2124 | del_timer(&errata2_timer); | ||
| 2125 | |||
| 2024 | isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, | 2126 | isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, |
| 2025 | NULL, 0); | 2127 | NULL, 0); |
| 2026 | mdelay(20); | 2128 | mdelay(20); |
| @@ -2048,6 +2150,23 @@ static void isp1760_shutdown(struct usb_hcd *hcd) · 21 unmodified lines | |||
| 2048 | reg_write32(hcd->regs, HC_USBCMD, command); | 2150 | reg_write32(hcd->regs, HC_USBCMD, command); |
| 2049 | } | 2151 | } |
| 2050 | 2152 | ||
| 2153 | static void isp1760_clear_tt_buffer_complete(struct usb_hcd *hcd, | ||
| 2154 | struct usb_host_endpoint *ep) | ||
| 2155 | { | ||
| 2156 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
| 2157 | struct isp1760_qh *qh = ep->hcpriv; | ||
| 2158 | unsigned long spinflags; | ||
| 2159 | |||
| 2160 | if (!qh) | ||
| 2161 | return; | ||
| 2162 | |||
| 2163 | spin_lock_irqsave(&priv->lock, spinflags); | ||
| 2164 | qh->tt_buffer_dirty = 0; | ||
| 2165 | schedule_ptds(hcd); | ||
| 2166 | spin_unlock_irqrestore(&priv->lock, spinflags); | ||
| 2167 | } | ||
| 2168 | |||
| 2169 | |||
| 2051 | static const struct hc_driver isp1760_hc_driver = { | 2170 | static const struct hc_driver isp1760_hc_driver = { |
| 2052 | .description = "isp1760-hcd", | 2171 | .description = "isp1760-hcd", |
| 2053 | .product_desc = "NXP ISP1760 USB Host Controller", | 2172 | .product_desc = "NXP ISP1760 USB Host Controller", |
| @@ -2064,6 +2183,7 @@ static const struct hc_driver isp1760_hc_driver = { · 10 unmodified lines | |||
| 2064 | .get_frame_number = isp1760_get_frame, | 2183 | .get_frame_number = isp1760_get_frame, |
| 2065 | .hub_status_data = isp1760_hub_status_data, | 2184 | .hub_status_data = isp1760_hub_status_data, |
| 2066 | .hub_control = isp1760_hub_control, | 2185 | .hub_control = isp1760_hub_control, |
| 2186 | .clear_tt_buffer_complete = isp1760_clear_tt_buffer_complete, | ||
| 2067 | }; | 2187 | }; |
| 2068 | 2188 | ||
| 2069 | int __init init_kmem_once(void) | 2189 | int __init init_kmem_once(void) |
| @@ -2102,6 +2222,7 @@ void deinit_kmem_cache(void) · 32 unmodified lines | |||
| 2102 | 2222 | ||
| 2103 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, | 2223 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, |
| 2104 | int irq, unsigned long irqflags, | 2224 | int irq, unsigned long irqflags, |
| 2225 | int rst_gpio, | ||
| 2105 | struct device *dev, const char *busname, | 2226 | struct device *dev, const char *busname, |
| 2106 | unsigned int devflags) | 2227 | unsigned int devflags) |
| 2107 | { | 2228 | { |
| @@ -2121,6 +2242,7 @@ struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, · 13 unmodified lines | |||
| 2121 | 2242 | ||
| 2122 | priv = hcd_to_priv(hcd); | 2243 | priv = hcd_to_priv(hcd); |
| 2123 | priv->devflags = devflags; | 2244 | priv->devflags = devflags; |
| 2245 | priv->rst_gpio = rst_gpio; | ||
| 2124 | init_memory(priv); | 2246 | init_memory(priv); |
| 2125 | hcd->regs = ioremap(res_start, res_len); | 2247 | hcd->regs = ioremap(res_start, res_len); |
| 2126 | if (!hcd->regs) { | 2248 | if (!hcd->regs) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | /* exports for if */ | 4 | /* exports for if */ |
| 5 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, | 5 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, |
| 6 | int irq, unsigned long irqflags, | 6 | int irq, unsigned long irqflags, |
| 7 | int rst_gpio, | ||
| 7 | struct device *dev, const char *busname, | 8 | struct device *dev, const char *busname, |
| 8 | unsigned int devflags); | 9 | unsigned int devflags); |
| 9 | int init_kmem_once(void); | 10 | int init_kmem_once(void); |
| @@ -73,7 +74,6 @@ void deinit_kmem_cache(void); · 63 unmodified lines | |||
| 73 | #define HC_EOT_INT (1 << 3) | 74 | #define HC_EOT_INT (1 << 3) |
| 74 | #define HC_SOT_INT (1 << 1) | 75 | #define HC_SOT_INT (1 << 1) |
| 75 | #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT) | 76 | #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT) |
| 76 | #define INTERRUPT_ENABLE_SOT_MASK (HC_SOT_INT) | ||
| 77 | 77 | ||
| 78 | #define HC_ISO_IRQ_MASK_OR_REG 0x318 | 78 | #define HC_ISO_IRQ_MASK_OR_REG 0x318 |
| 79 | #define HC_INT_IRQ_MASK_OR_REG 0x31C | 79 | #define HC_INT_IRQ_MASK_OR_REG 0x31C |
| @@ -107,6 +107,7 @@ struct ptd { · 27 unmodified lines | |||
| 107 | struct slotinfo { | 107 | struct slotinfo { |
| 108 | struct isp1760_qh *qh; | 108 | struct isp1760_qh *qh; |
| 109 | struct isp1760_qtd *qtd; | 109 | struct isp1760_qtd *qtd; |
| 110 | unsigned long timestamp; | ||
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 112 | 113 | ||
| @@ -126,6 +127,7 @@ typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, · 13 unmodified lines | |||
| 126 | #define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */ | 127 | #define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */ |
| 127 | #define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */ | 128 | #define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */ |
| 128 | #define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */ | 129 | #define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */ |
| 130 | #define ISP1760_FLAG_RESET_ACTIVE_HIGH 0x80000000 /* RESET GPIO active high */ | ||
| 129 | 131 | ||
| 130 | /* chip memory management */ | 132 | /* chip memory management */ |
| 131 | struct memory_chunk { | 133 | struct memory_chunk { |
| @@ -188,6 +190,7 @@ struct memory_chunk { · 56 unmodified lines | |||
| 188 | #define DW3_BABBLE_BIT (1 << 29) | 190 | #define DW3_BABBLE_BIT (1 << 29) |
| 189 | #define DW3_HALT_BIT (1 << 30) | 191 | #define DW3_HALT_BIT (1 << 30) |
| 190 | #define DW3_ACTIVE_BIT (1 << 31) | 192 | #define DW3_ACTIVE_BIT (1 << 31) |
| 193 | #define FROM_DW3_ACTIVE(x) (((x) >> 31) & 0x01) | ||
| 191 | 194 | ||
| 192 | #define INT_UNDERRUN (1 << 2) | 195 | #define INT_UNDERRUN (1 << 2) |
| 193 | #define INT_BABBLE (1 << 1) | 196 | #define INT_BABBLE (1 << 1) |
| @@ -17,19 +17,28 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #include "isp1760-hcd.h" | 18 | #include "isp1760-hcd.h" |
| 19 | 19 | ||
| 20 | #ifdef CONFIG_PPC_OF | 20 | #ifdef CONFIG_OF |
| 21 | #include <linux/slab.h> | ||
| 21 | #include <linux/of.h> | 22 | #include <linux/of.h> |
| 22 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
| 24 | #include <linux/of_address.h> | ||
| 25 | #include <linux/of_irq.h> | ||
| 26 | #include <linux/of_gpio.h> | ||
| 23 | #endif | 27 | #endif |
| 24 | 28 | ||
| 25 | #ifdef CONFIG_PCI | 29 | #ifdef CONFIG_PCI |
| 26 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
| 27 | #endif | 31 | #endif |
| 28 | 32 | ||
| 29 | #ifdef CONFIG_PPC_OF | 33 | #ifdef CONFIG_OF |
| 34 | struct isp1760 { | ||
| 35 | struct usb_hcd *hcd; | ||
| 36 | int rst_gpio; | ||
| 37 | }; | ||
| 38 | |||
| 30 | static int of_isp1760_probe(struct platform_device *dev) | 39 | static int of_isp1760_probe(struct platform_device *dev) |
| 31 | { | 40 | { |
| 32 | struct usb_hcd *hcd; | 41 | struct isp1760 *drvdata; |
| 33 | struct device_node *dp = dev->dev.of_node; | 42 | struct device_node *dp = dev->dev.of_node; |
| 34 | struct resource *res; | 43 | struct resource *res; |
| 35 | struct resource memory; | 44 | struct resource memory; |
| @@ -39,6 +48,11 @@ static int of_isp1760_probe(struct platform_device *dev) · 3 unmodified lines | |||
| 39 | int ret; | 48 | int ret; |
| 40 | const unsigned int *prop; | 49 | const unsigned int *prop; |
| 41 | unsigned int devflags = 0; | 50 | unsigned int devflags = 0; |
| 51 | enum of_gpio_flags gpio_flags; | ||
| 52 | |||
| 53 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | ||
| 54 | if (!drvdata) | ||
| 55 | return -ENOMEM; | ||
| 42 | 56 | ||
| 43 | ret = of_address_to_resource(dp, 0, &memory); | 57 | ret = of_address_to_resource(dp, 0, &memory); |
| 44 | if (ret) | 58 | if (ret) |
| @@ -78,32 +92,57 @@ static int of_isp1760_probe(struct platform_device *dev) · 33 unmodified lines | |||
| 78 | if (of_get_property(dp, "dreq-polarity", NULL) != NULL) | 92 | if (of_get_property(dp, "dreq-polarity", NULL) != NULL) |
| 79 | devflags |= ISP1760_FLAG_DREQ_POL_HIGH; | 93 | devflags |= ISP1760_FLAG_DREQ_POL_HIGH; |
| 80 | 94 | ||
| 81 | hcd = isp1760_register(memory.start, res_len, virq, | 95 | drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags); |
| 82 | IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), | 96 | if (gpio_is_valid(drvdata->rst_gpio)) { |
| 83 | devflags); | 97 | ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev)); |
| 84 | if (IS_ERR(hcd)) { | 98 | if (!ret) { |
| 85 | ret = PTR_ERR(hcd); | 99 | if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) { |
| 86 | goto release_reg; | 100 | devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH; |
| 101 | gpio_direction_output(drvdata->rst_gpio, 0); | ||
| 102 | } else { | ||
| 103 | gpio_direction_output(drvdata->rst_gpio, 1); | ||
| 104 | } | ||
| 105 | } else { | ||
| 106 | drvdata->rst_gpio = ret; | ||
| 107 | } | ||
| 87 | } | 108 | } |
| 88 | 109 | ||
| 89 | dev_set_drvdata(&dev->dev, hcd); | 110 | drvdata->hcd = isp1760_register(memory.start, res_len, virq, |
| 111 | IRQF_SHARED, drvdata->rst_gpio, | ||
| 112 | &dev->dev, dev_name(&dev->dev), | ||
| 113 | devflags); | ||
| 114 | if (IS_ERR(drvdata->hcd)) { | ||
| 115 | ret = PTR_ERR(drvdata->hcd); | ||
| 116 | goto free_gpio; | ||
| 117 | } | ||
| 118 | |||
| 119 | dev_set_drvdata(&dev->dev, drvdata); | ||
| 90 | return ret; | 120 | return ret; |
| 91 | 121 | ||
| 122 | free_gpio: | ||
| 123 | if (gpio_is_valid(drvdata->rst_gpio)) | ||
| 124 | gpio_free(drvdata->rst_gpio); | ||
| 92 | release_reg: | 125 | release_reg: |
| 93 | release_mem_region(memory.start, res_len); | 126 | release_mem_region(memory.start, res_len); |
| 127 | kfree(drvdata); | ||
| 94 | return ret; | 128 | return ret; |
| 95 | } | 129 | } |
| 96 | 130 | ||
| 97 | static int of_isp1760_remove(struct platform_device *dev) | 131 | static int of_isp1760_remove(struct platform_device *dev) |
| 98 | { | 132 | { |
| 99 | struct usb_hcd *hcd = dev_get_drvdata(&dev->dev); | 133 | struct isp1760 *drvdata = dev_get_drvdata(&dev->dev); |
| 100 | 134 | ||
| 101 | dev_set_drvdata(&dev->dev, NULL); | 135 | dev_set_drvdata(&dev->dev, NULL); |
| 102 | 136 | ||
| 103 | usb_remove_hcd(hcd); | 137 | usb_remove_hcd(drvdata->hcd); |
| 104 | iounmap(hcd->regs); | 138 | iounmap(drvdata->hcd->regs); |
| 105 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 139 | release_mem_region(drvdata->hcd->rsrc_start, drvdata->hcd->rsrc_len); |
| 106 | usb_put_hcd(hcd); | 140 | usb_put_hcd(drvdata->hcd); |
| 141 | |||
| 142 | if (gpio_is_valid(drvdata->rst_gpio)) | ||
| 143 | gpio_free(drvdata->rst_gpio); | ||
| 144 | |||
| 145 | kfree(drvdata); | ||
| 107 | return 0; | 146 | return 0; |
| 108 | } | 147 | } |
| 109 | 148 | ||
| @@ -240,7 +279,7 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev, · 130 unmodified lines | |||
| 240 | 279 | ||
| 241 | dev->dev.dma_mask = NULL; | 280 | dev->dev.dma_mask = NULL; |
| 242 | hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq, | 281 | hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq, |
| 243 | IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), | 282 | IRQF_SHARED, -ENOENT, &dev->dev, dev_name(&dev->dev), |
| 244 | devflags); | 283 | devflags); |
| 245 | if (IS_ERR(hcd)) { | 284 | if (IS_ERR(hcd)) { |
| 246 | ret_status = -ENODEV; | 285 | ret_status = -ENODEV; |
| @@ -313,7 +352,7 @@ static int __devinit isp1760_plat_probe(struct platform_device *pdev) · 66 unmodified lines | |||
| 313 | resource_size_t mem_size; | 352 | resource_size_t mem_size; |
| 314 | struct isp1760_platform_data *priv = pdev->dev.platform_data; | 353 | struct isp1760_platform_data *priv = pdev->dev.platform_data; |
| 315 | unsigned int devflags = 0; | 354 | unsigned int devflags = 0; |
| 316 | unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED; | 355 | unsigned long irqflags = IRQF_SHARED; |
| 317 | 356 | ||
| 318 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 357 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 319 | if (!mem_res) { | 358 | if (!mem_res) { |
| @@ -351,7 +390,8 @@ static int __devinit isp1760_plat_probe(struct platform_device *pdev) · 31 unmodified lines | |||
| 351 | } | 390 | } |
| 352 | 391 | ||
| 353 | hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, | 392 | hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, |
| 354 | irqflags, &pdev->dev, dev_name(&pdev->dev), devflags); | 393 | irqflags, -ENOENT, |
| 394 | &pdev->dev, dev_name(&pdev->dev), devflags); | ||
| 355 | if (IS_ERR(hcd)) { | 395 | if (IS_ERR(hcd)) { |
| 356 | pr_warning("isp1760: Failed to register the HCD device\n"); | 396 | pr_warning("isp1760: Failed to register the HCD device\n"); |
| 357 | ret = -ENODEV; | 397 | ret = -ENODEV; |
| @@ -396,7 +436,7 @@ static int __init isp1760_init(void) · 38 unmodified lines | |||
| 396 | ret = platform_driver_register(&isp1760_plat_driver); | 436 | ret = platform_driver_register(&isp1760_plat_driver); |
| 397 | if (!ret) | 437 | if (!ret) |
| 398 | any_ret = 0; | 438 | any_ret = 0; |
| 399 | #ifdef CONFIG_PPC_OF | 439 | #ifdef CONFIG_OF |
| 400 | ret = platform_driver_register(&isp1760_of_driver); | 440 | ret = platform_driver_register(&isp1760_of_driver); |
| 401 | if (!ret) | 441 | if (!ret) |
| 402 | any_ret = 0; | 442 | any_ret = 0; |
| @@ -416,7 +456,7 @@ module_init(isp1760_init); · 13 unmodified lines | |||
| 416 | static void __exit isp1760_exit(void) | 456 | static void __exit isp1760_exit(void) |
| 417 | { | 457 | { |
| 418 | platform_driver_unregister(&isp1760_plat_driver); | 458 | platform_driver_unregister(&isp1760_plat_driver); |
| 419 | #ifdef CONFIG_PPC_OF | 459 | #ifdef CONFIG_OF |
| 420 | platform_driver_unregister(&isp1760_of_driver); | 460 | platform_driver_unregister(&isp1760_of_driver); |
| 421 | #endif | 461 | #endif |
| 422 | #ifdef CONFIG_PCI | 462 | #ifdef CONFIG_PCI |
| @@ -111,7 +111,7 @@ static int ohci_ath79_probe(struct platform_device *pdev) · 110 unmodified lines | |||
| 111 | 111 | ||
| 112 | ohci_hcd_init(hcd_to_ohci(hcd)); | 112 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 113 | 113 | ||
| 114 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 114 | ret = usb_add_hcd(hcd, irq, 0); |
| 115 | if (ret) | 115 | if (ret) |
| 116 | goto err_stop_hcd; | 116 | goto err_stop_hcd; |
| 117 | 117 | ||
| @@ -218,7 +218,7 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) · 217 unmodified lines | |||
| 218 | ohci_hcd_init(hcd_to_ohci(hcd)); | 218 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 219 | 219 | ||
| 220 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | 220 | ret = usb_add_hcd(hcd, pdev->resource[1].start, |
| 221 | IRQF_DISABLED | IRQF_SHARED); | 221 | IRQF_SHARED); |
| 222 | if (ret == 0) { | 222 | if (ret == 0) { |
| 223 | platform_set_drvdata(pdev, hcd); | 223 | platform_set_drvdata(pdev, hcd); |
| 224 | return ret; | 224 | return ret; |
| @@ -344,7 +344,7 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver, · 343 unmodified lines | |||
| 344 | error = -ENODEV; | 344 | error = -ENODEV; |
| 345 | goto err4; | 345 | goto err4; |
| 346 | } | 346 | } |
| 347 | error = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 347 | error = usb_add_hcd(hcd, irq, 0); |
| 348 | if (error) | 348 | if (error) |
| 349 | goto err4; | 349 | goto err4; |
| 350 | 350 | ||
| @@ -81,7 +81,7 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver, · 80 unmodified lines | |||
| 81 | 81 | ||
| 82 | ohci_hcd_init(hcd_to_ohci(hcd)); | 82 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 83 | 83 | ||
| 84 | retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED); | 84 | retval = usb_add_hcd(hcd, pdev->resource[1].start, 0); |
| 85 | if (retval == 0) | 85 | if (retval == 0) |
| 86 | return retval; | 86 | return retval; |
| 87 | 87 | ||
| @@ -1114,6 +1114,11 @@ MODULE_LICENSE ("GPL"); · 1113 unmodified lines | |||
| 1114 | #define PLATFORM_DRIVER ohci_hcd_ath79_driver | 1114 | #define PLATFORM_DRIVER ohci_hcd_ath79_driver |
| 1115 | #endif | 1115 | #endif |
| 1116 | 1116 | ||
| 1117 | #ifdef CONFIG_NLM_XLR | ||
| 1118 | #include "ohci-xls.c" | ||
| 1119 | #define PLATFORM_DRIVER ohci_xls_driver | ||
| 1120 | #endif | ||
| 1121 | |||
| 1117 | #if !defined(PCI_DRIVER) && \ | 1122 | #if !defined(PCI_DRIVER) && \ |
| 1118 | !defined(PLATFORM_DRIVER) && \ | 1123 | !defined(PLATFORM_DRIVER) && \ |
| 1119 | !defined(OMAP1_PLATFORM_DRIVER) && \ | 1124 | !defined(OMAP1_PLATFORM_DRIVER) && \ |
| @@ -356,10 +356,7 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd) · 355 unmodified lines | |||
| 356 | msleep(20); | 356 | msleep(20); |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | /* Does the root hub have a port wakeup pending? */ | 359 | usb_hcd_resume_root_hub(hcd); |
| 360 | if (ohci_readl(ohci, &ohci->regs->intrstatus) & | ||
| 361 | (OHCI_INTR_RD | OHCI_INTR_RHSC)) | ||
| 362 | usb_hcd_resume_root_hub(hcd); | ||
| 363 | } | 360 | } |
| 364 | 361 | ||
| 365 | /* Carry out polling-, autostop-, and autoresume-related state changes */ | 362 | /* Carry out polling-, autostop-, and autoresume-related state changes */ |
| @@ -164,7 +164,7 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev) · 163 unmodified lines | |||
| 164 | 164 | ||
| 165 | ohci_hcd_init(ohci); | 165 | ohci_hcd_init(ohci); |
| 166 | 166 | ||
| 167 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 167 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 168 | if (ret) { | 168 | if (ret) { |
| 169 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); | 169 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); |
| 170 | goto err3; | 170 | goto err3; |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | |||
| 14 | * This file is licenced under the GPL. | 14 | * This file is licenced under the GPL. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/signal.h> /* IRQF_DISABLED */ | 17 | #include <linux/signal.h> |
| 18 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
| @@ -363,7 +363,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver, · 342 unmodified lines | |||
| 363 | retval = -ENXIO; | 363 | retval = -ENXIO; |
| 364 | goto err3; | 364 | goto err3; |
| 365 | } | 365 | } |
| 366 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 366 | retval = usb_add_hcd(hcd, irq, 0); |
| 367 | if (retval) | 367 | if (retval) |
| 368 | goto err3; | 368 | goto err3; |
| 369 | 369 | ||
| @@ -149,7 +149,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) · 148 unmodified lines | |||
| 149 | 149 | ||
| 150 | res = platform_get_resource_byname(pdev, | 150 | res = platform_get_resource_byname(pdev, |
| 151 | IORESOURCE_MEM, "ohci"); | 151 | IORESOURCE_MEM, "ohci"); |
| 152 | if (!ret) { | 152 | if (!res) { |
| 153 | dev_err(dev, "UHH OHCI get resource failed\n"); | 153 | dev_err(dev, "UHH OHCI get resource failed\n"); |
| 154 | return -ENOMEM; | 154 | return -ENOMEM; |
| 155 | } | 155 | } |
| @@ -180,7 +180,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) · 24 unmodified lines | |||
| 180 | 180 | ||
| 181 | ohci_hcd_init(hcd_to_ohci(hcd)); | 181 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 182 | 182 | ||
| 183 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 183 | ret = usb_add_hcd(hcd, irq, 0); |
| 184 | if (ret) { | 184 | if (ret) { |
| 185 | dev_dbg(dev, "failed to add hcd with err %d\n", ret); | 185 | dev_dbg(dev, "failed to add hcd with err %d\n", ret); |
| 186 | goto err_add_hcd; | 186 | goto err_add_hcd; |
| @@ -398,7 +398,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) · 397 unmodified lines | |||
| 398 | ohci_hcd_init(ohci); | 398 | ohci_hcd_init(ohci); |
| 399 | 399 | ||
| 400 | dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq); | 400 | dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq); |
| 401 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 401 | ret = usb_add_hcd(hcd, irq, 0); |
| 402 | if (ret == 0) | 402 | if (ret == 0) |
| 403 | return ret; | 403 | return ret; |
| 404 | 404 | ||
| @@ -107,7 +107,7 @@ int usb_hcd_pnx8550_probe (const struct hc_driver *driver, · 106 unmodified lines | |||
| 107 | 107 | ||
| 108 | ohci_hcd_init(hcd_to_ohci(hcd)); | 108 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 109 | 109 | ||
| 110 | retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); | 110 | retval = usb_add_hcd(hcd, dev->resource[1].start, 0); |
| 111 | if (retval == 0) | 111 | if (retval == 0) |
| 112 | return retval; | 112 | return retval; |
| 113 | 113 | ||
| @@ -143,7 +143,7 @@ static int __devinit ohci_hcd_ppc_of_probe(struct platform_device *op) · 142 unmodified lines | |||
| 143 | 143 | ||
| 144 | ohci_hcd_init(ohci); | 144 | ohci_hcd_init(ohci); |
| 145 | 145 | ||
| 146 | rv = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 146 | rv = usb_add_hcd(hcd, irq, 0); |
| 147 | if (rv == 0) | 147 | if (rv == 0) |
| 148 | return 0; | 148 | return 0; |
| 149 | 149 | ||
| @@ -80,7 +80,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, · 79 unmodified lines | |||
| 80 | #endif | 80 | #endif |
| 81 | ohci_hcd_init(ohci); | 81 | ohci_hcd_init(ohci); |
| 82 | 82 | ||
| 83 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 83 | retval = usb_add_hcd(hcd, irq, 0); |
| 84 | if (retval == 0) | 84 | if (retval == 0) |
| 85 | return retval; | 85 | return retval; |
| 86 | 86 | ||
| @@ -164,7 +164,7 @@ static int __devinit ps3_ohci_probe(struct ps3_system_bus_device *dev) · 163 unmodified lines | |||
| 164 | 164 | ||
| 165 | ps3_system_bus_set_drvdata(dev, hcd); | 165 | ps3_system_bus_set_drvdata(dev, hcd); |
| 166 | 166 | ||
| 167 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | 167 | result = usb_add_hcd(hcd, virq, 0); |
| 168 | 168 | ||
| 169 | if (result) { | 169 | if (result) { |
| 170 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", | 170 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", |
| @@ -359,7 +359,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device · 358 unmodified lines | |||
| 359 | 359 | ||
| 360 | ohci_hcd_init(hcd_to_ohci(hcd)); | 360 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 361 | 361 | ||
| 362 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 362 | retval = usb_add_hcd(hcd, irq, 0); |
| 363 | if (retval == 0) | 363 | if (retval == 0) |
| 364 | return retval; | 364 | return retval; |
| 365 | 365 | ||
| @@ -428,7 +428,7 @@ static struct ed *ed_get ( · 427 unmodified lines | |||
| 428 | ed->type = usb_pipetype(pipe); | 428 | ed->type = usb_pipetype(pipe); |
| 429 | 429 | ||
| 430 | info |= (ep->desc.bEndpointAddress & ~USB_DIR_IN) << 7; | 430 | info |= (ep->desc.bEndpointAddress & ~USB_DIR_IN) << 7; |
| 431 | info |= le16_to_cpu(ep->desc.wMaxPacketSize) << 16; | 431 | info |= usb_endpoint_maxp(&ep->desc) << 16; |
| 432 | if (udev->speed == USB_SPEED_LOW) | 432 | if (udev->speed == USB_SPEED_LOW) |
| 433 | info |= ED_LOWSPEED; | 433 | info |= ED_LOWSPEED; |
| 434 | /* only control transfers store pids in tds */ | 434 | /* only control transfers store pids in tds */ |
| @@ -444,7 +444,7 @@ static struct ed *ed_get ( · 9 unmodified lines | |||
| 444 | ed->load = usb_calc_bus_time ( | 444 | ed->load = usb_calc_bus_time ( |
| 445 | udev->speed, !is_out, | 445 | udev->speed, !is_out, |
| 446 | ed->type == PIPE_ISOCHRONOUS, | 446 | ed->type == PIPE_ISOCHRONOUS, |
| 447 | le16_to_cpu(ep->desc.wMaxPacketSize)) | 447 | usb_endpoint_maxp(&ep->desc)) |
| 448 | / 1000; | 448 | / 1000; |
| 449 | } | 449 | } |
| 450 | } | 450 | } |
| @@ -384,7 +384,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver, · 383 unmodified lines | |||
| 384 | 384 | ||
| 385 | ohci_hcd_init(hcd_to_ohci(hcd)); | 385 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 386 | 386 | ||
| 387 | retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); | 387 | retval = usb_add_hcd(hcd, dev->resource[1].start, 0); |
| 388 | if (retval != 0) | 388 | if (retval != 0) |
| 389 | goto err_ioremap; | 389 | goto err_ioremap; |
| 390 | 390 | ||
| @@ -143,7 +143,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, · 142 unmodified lines | |||
| 143 | sa1111_start_hc(dev); | 143 | sa1111_start_hc(dev); |
| 144 | ohci_hcd_init(hcd_to_ohci(hcd)); | 144 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 145 | 145 | ||
| 146 | retval = usb_add_hcd(hcd, dev->irq[1], IRQF_DISABLED); | 146 | retval = usb_add_hcd(hcd, dev->irq[1], 0); |
| 147 | if (retval == 0) | 147 | if (retval == 0) |
| 148 | return retval; | 148 | return retval; |
| 149 | 149 | ||
| @@ -109,7 +109,7 @@ static int ohci_hcd_sh_probe(struct platform_device *pdev) · 108 unmodified lines | |||
| 109 | hcd->regs = (void __iomem *)res->start; | 109 | hcd->regs = (void __iomem *)res->start; |
| 110 | hcd->rsrc_start = res->start; | 110 | hcd->rsrc_start = res->start; |
| 111 | hcd->rsrc_len = resource_size(res); | 111 | hcd->rsrc_len = resource_size(res); |
| 112 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 112 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 113 | if (ret != 0) { | 113 | if (ret != 0) { |
| 114 | err("Failed to add hcd"); | 114 | err("Failed to add hcd"); |
| 115 | usb_put_hcd(hcd); | 115 | usb_put_hcd(hcd); |
| @@ -165,7 +165,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) · 164 unmodified lines | |||
| 165 | 165 | ||
| 166 | ohci_hcd_init(hcd_to_ohci(hcd)); | 166 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 167 | 167 | ||
| 168 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 168 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 169 | if (retval) | 169 | if (retval) |
| 170 | goto err5; | 170 | goto err5; |
| 171 | 171 | ||
| @@ -152,7 +152,7 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) · 151 unmodified lines | |||
| 152 | spear_start_ohci(ohci_p); | 152 | spear_start_ohci(ohci_p); |
| 153 | ohci_hcd_init(hcd_to_ohci(hcd)); | 153 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 154 | 154 | ||
| 155 | retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), IRQF_DISABLED); | 155 | retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0); |
| 156 | if (retval == 0) | 156 | if (retval == 0) |
| 157 | return retval; | 157 | return retval; |
| 158 | 158 | ||
| @@ -169,7 +169,7 @@ static int ssb_ohci_attach(struct ssb_device *dev) · 168 unmodified lines | |||
| 169 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | 169 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); |
| 170 | if (!hcd->regs) | 170 | if (!hcd->regs) |
| 171 | goto err_put_hcd; | 171 | goto err_put_hcd; |
| 172 | err = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); | 172 | err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED); |
| 173 | if (err) | 173 | if (err) |
| 174 | goto err_iounmap; | 174 | goto err_iounmap; |
| 175 | 175 | ||
| @@ -244,7 +244,7 @@ static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev) · 243 unmodified lines | |||
| 244 | ohci = hcd_to_ohci(hcd); | 244 | ohci = hcd_to_ohci(hcd); |
| 245 | ohci_hcd_init(ohci); | 245 | ohci_hcd_init(ohci); |
| 246 | 246 | ||
| 247 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 247 | ret = usb_add_hcd(hcd, irq, 0); |
| 248 | if (ret) | 248 | if (ret) |
| 249 | goto err_add_hcd; | 249 | goto err_add_hcd; |
| 250 | 250 | ||
| @@ -0,0 +1,151 @@ | |||
| 1 | /* | ||
| 2 | * OHCI HCD for Netlogic XLS processors. | ||
| 3 | * | ||
| 4 | * (C) Copyright 2011 Netlogic Microsystems Inc. | ||
| 5 | * | ||
| 6 | * Based on ohci-au1xxx.c, and other Linux OHCI drivers. | ||
| 7 | * | ||
| 8 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 9 | * License. See the file COPYING in the main directory of this archive for | ||
| 10 | * more details. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/signal.h> | ||
| 15 | |||
| 16 | static int ohci_xls_probe_internal(const struct hc_driver *driver, | ||
| 17 | struct platform_device *dev) | ||
| 18 | { | ||
| 19 | struct resource *res; | ||
| 20 | struct usb_hcd *hcd; | ||
| 21 | int retval, irq; | ||
| 22 | |||
| 23 | /* Get our IRQ from an earlier registered Platform Resource */ | ||
| 24 | irq = platform_get_irq(dev, 0); | ||
| 25 | if (irq < 0) { | ||
| 26 | dev_err(&dev->dev, "Found HC with no IRQ\n"); | ||
| 27 | return -ENODEV; | ||
| 28 | } | ||
| 29 | |||
| 30 | /* Get our Memory Handle */ | ||
| 31 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
| 32 | if (!res) { | ||
| 33 | dev_err(&dev->dev, "MMIO Handle incorrect!\n"); | ||
| 34 | return -ENODEV; | ||
| 35 | } | ||
| 36 | |||
| 37 | hcd = usb_create_hcd(driver, &dev->dev, "XLS"); | ||
| 38 | if (!hcd) { | ||
| 39 | retval = -ENOMEM; | ||
| 40 | goto err1; | ||
| 41 | } | ||
| 42 | hcd->rsrc_start = res->start; | ||
| 43 | hcd->rsrc_len = res->end - res->start + 1; | ||
| 44 | |||
| 45 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
| 46 | driver->description)) { | ||
| 47 | dev_dbg(&dev->dev, "Controller already in use\n"); | ||
| 48 | retval = -EBUSY; | ||
| 49 | goto err2; | ||
| 50 | } | ||
| 51 | |||
| 52 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
| 53 | if (hcd->regs == NULL) { | ||
| 54 | dev_dbg(&dev->dev, "error mapping memory\n"); | ||
| 55 | retval = -EFAULT; | ||
| 56 | goto err3; | ||
| 57 | } | ||
| 58 | |||
| 59 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | ||
| 60 | if (retval != 0) | ||
| 61 | goto err4; | ||
| 62 | return retval; | ||
| 63 | |||
| 64 | err4: | ||
| 65 | iounmap(hcd->regs); | ||
| 66 | err3: | ||
| 67 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 68 | err2: | ||
| 69 | usb_put_hcd(hcd); | ||
| 70 | err1: | ||
| 71 | dev_err(&dev->dev, "init fail, %d\n", retval); | ||
| 72 | return retval; | ||
| 73 | } | ||
| 74 | |||
| 75 | static int ohci_xls_reset(struct usb_hcd *hcd) | ||
| 76 | { | ||
| 77 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
| 78 | |||
| 79 | ohci_hcd_init(ohci); | ||
| 80 | return ohci_init(ohci); | ||
| 81 | } | ||
| 82 | |||
| 83 | static int __devinit ohci_xls_start(struct usb_hcd *hcd) | ||
| 84 | { | ||
| 85 | struct ohci_hcd *ohci; | ||
| 86 | int ret; | ||
| 87 | |||
| 88 | ohci = hcd_to_ohci(hcd); | ||
| 89 | ret = ohci_run(ohci); | ||
| 90 | if (ret < 0) { | ||
| 91 | err("can't start %s", hcd->self.bus_name); | ||
| 92 | ohci_stop(hcd); | ||
| 93 | return ret; | ||
| 94 | } | ||
| 95 | return 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | static struct hc_driver ohci_xls_hc_driver = { | ||
| 99 | .description = hcd_name, | ||
| 100 | .product_desc = "XLS OHCI Host Controller", | ||
| 101 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
| 102 | .irq = ohci_irq, | ||
| 103 | .flags = HCD_MEMORY | HCD_USB11, | ||
| 104 | .reset = ohci_xls_reset, | ||
| 105 | .start = ohci_xls_start, | ||
| 106 | .stop = ohci_stop, | ||
| 107 | .shutdown = ohci_shutdown, | ||
| 108 | .urb_enqueue = ohci_urb_enqueue, | ||
| 109 | .urb_dequeue = ohci_urb_dequeue, | ||
| 110 | .endpoint_disable = ohci_endpoint_disable, | ||
| 111 | .get_frame_number = ohci_get_frame, | ||
| 112 | .hub_status_data = ohci_hub_status_data, | ||
| 113 | .hub_control = ohci_hub_control, | ||
| 114 | #ifdef CONFIG_PM | ||
| 115 | .bus_suspend = ohci_bus_suspend, | ||
| 116 | .bus_resume = ohci_bus_resume, | ||
| 117 | #endif | ||
| 118 | .start_port_reset = ohci_start_port_reset, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static int ohci_xls_probe(struct platform_device *dev) | ||
| 122 | { | ||
| 123 | int ret; | ||
| 124 | |||
| 125 | pr_debug("In ohci_xls_probe"); | ||
| 126 | if (usb_disabled()) | ||
| 127 | return -ENODEV; | ||
| 128 | ret = ohci_xls_probe_internal(&ohci_xls_hc_driver, dev); | ||
| 129 | return ret; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int ohci_xls_remove(struct platform_device *dev) | ||
| 133 | { | ||
| 134 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
| 135 | |||
| 136 | usb_remove_hcd(hcd); | ||
| 137 | iounmap(hcd->regs); | ||
| 138 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 139 | usb_put_hcd(hcd); | ||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | static struct platform_driver ohci_xls_driver = { | ||
| 144 | .probe = ohci_xls_probe, | ||
| 145 | .remove = ohci_xls_remove, | ||
| 146 | .shutdown = usb_hcd_platform_shutdown, | ||
| 147 | .driver = { | ||
| 148 | .name = "ohci-xls-0", | ||
| 149 | .owner = THIS_MODULE, | ||
| 150 | }, | ||
| 151 | }; | ||
| @@ -959,7 +959,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, · 958 unmodified lines | |||
| 959 | info.pipenum = get_empty_pipenum(r8a66597, ep); | 959 | info.pipenum = get_empty_pipenum(r8a66597, ep); |
| 960 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); | 960 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); |
| 961 | info.epnum = usb_endpoint_num(ep); | 961 | info.epnum = usb_endpoint_num(ep); |
| 962 | info.maxpacket = le16_to_cpu(ep->wMaxPacketSize); | 962 | info.maxpacket = usb_endpoint_maxp(ep); |
| 963 | info.type = get_r8a66597_type(usb_endpoint_type(ep)); | 963 | info.type = get_r8a66597_type(usb_endpoint_type(ep)); |
| 964 | info.bufnum = get_bufnum(info.pipenum); | 964 | info.bufnum = get_bufnum(info.pipenum); |
| 965 | info.buf_bsize = get_buf_bsize(info.pipenum); | 965 | info.buf_bsize = get_buf_bsize(info.pipenum); |
| @@ -2519,7 +2519,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) · 1553 unmodified lines | |||
| 2519 | hcd->rsrc_start = res->start; | 2519 | hcd->rsrc_start = res->start; |
| 2520 | hcd->has_tt = 1; | 2520 | hcd->has_tt = 1; |
| 2521 | 2521 | ||
| 2522 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger); | 2522 | ret = usb_add_hcd(hcd, irq, irq_trigger); |
| 2523 | if (ret != 0) { | 2523 | if (ret != 0) { |
| 2524 | dev_err(&pdev->dev, "Failed to add hcd\n"); | 2524 | dev_err(&pdev->dev, "Failed to add hcd\n"); |
| 2525 | goto clean_up3; | 2525 | goto clean_up3; |
| @@ -1729,7 +1729,7 @@ sl811h_probe(struct platform_device *dev) · 1728 unmodified lines | |||
| 1729 | * Use resource IRQ flags if set by platform device setup. | 1729 | * Use resource IRQ flags if set by platform device setup. |
| 1730 | */ | 1730 | */ |
| 1731 | irqflags |= IRQF_SHARED; | 1731 | irqflags |= IRQF_SHARED; |
| 1732 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | irqflags); | 1732 | retval = usb_add_hcd(hcd, irq, irqflags); |
| 1733 | if (retval != 0) | 1733 | if (retval != 0) |
| 1734 | goto err6; | 1734 | goto err6; |
| 1735 | 1735 | ||
| @@ -294,50 +294,50 @@ __acquires(uhci->lock) · 293 unmodified lines | |||
| 294 | * and that remote wakeups should be enabled. | 294 | * and that remote wakeups should be enabled. |
| 295 | */ | 295 | */ |
| 296 | egsm_enable = USBCMD_EGSM; | 296 | egsm_enable = USBCMD_EGSM; |
| 297 | uhci->RD_enable = 1; | ||
| 298 | int_enable = USBINTR_RESUME; | 297 | int_enable = USBINTR_RESUME; |
| 299 | wakeup_enable = 1; | 298 | wakeup_enable = 1; |
| 300 | 299 | ||
| 301 | /* In auto-stop mode wakeups must always be detected, but | 300 | /* |
| 302 | * Resume-Detect interrupts may be prohibited. (In the absence | 301 | * In auto-stop mode, we must be able to detect new connections. |
| 303 | * of CONFIG_PM, they are always disallowed.) | 302 | * The user can force us to poll by disabling remote wakeup; |
| 303 | * otherwise we will use the EGSM/RD mechanism. | ||
| 304 | */ | 304 | */ |
| 305 | if (auto_stop) { | 305 | if (auto_stop) { |
| 306 | if (!device_may_wakeup(&rhdev->dev)) | 306 | if (!device_may_wakeup(&rhdev->dev)) |
| 307 | int_enable = 0; | 307 | egsm_enable = int_enable = 0; |
| 308 | } | ||
| 308 | 309 | ||
| 309 | /* In bus-suspend mode wakeups may be disabled, but if they are | ||
| 310 | * allowed then so are Resume-Detect interrupts. | ||
| 311 | */ | ||
| 312 | } else { | ||
| 313 | #ifdef CONFIG_PM | 310 | #ifdef CONFIG_PM |
| 311 | /* | ||
| 312 | * In bus-suspend mode, we use the wakeup setting specified | ||
| 313 | * for the root hub. | ||
| 314 | */ | ||
| 315 | else { | ||
| 314 | if (!rhdev->do_remote_wakeup) | 316 | if (!rhdev->do_remote_wakeup) |
| 315 | wakeup_enable = 0; | 317 | wakeup_enable = 0; |
| 316 | #endif | ||
| 317 | } | 318 | } |
| 319 | #endif | ||
| 318 | 320 | ||
| 319 | /* EGSM causes the root hub to echo a 'K' signal (resume) out any | 321 | /* |
| 320 | * port which requests a remote wakeup. According to the USB spec, | 322 | * UHCI doesn't distinguish between wakeup requests from downstream |
| 321 | * every hub is supposed to do this. But if we are ignoring | 323 | * devices and local connect/disconnect events. There's no way to |
| 322 | * remote-wakeup requests anyway then there's no point to it. | 324 | * enable one without the other; both are controlled by EGSM. Thus |
| 323 | * We also shouldn't enable EGSM if it's broken. | 325 | * if wakeups are disallowed then EGSM must be turned off -- in which |
| 324 | */ | 326 | * case remote wakeup requests from downstream during system sleep |
| 325 | if (!wakeup_enable || global_suspend_mode_is_broken(uhci)) | 327 | * will be lost. |
| 326 | egsm_enable = 0; | 328 | * |
| 327 | 329 | * In addition, if EGSM is broken then we can't use it. Likewise, | |
| 328 | /* If we're ignoring wakeup events then there's no reason to | 330 | * if Resume-Detect interrupts are broken then we can't use them. |
| 329 | * enable Resume-Detect interrupts. We also shouldn't enable | ||
| 330 | * them if they are broken or disallowed. | ||
| 331 | * | 331 | * |
| 332 | * This logic may lead us to enabling RD but not EGSM. The UHCI | 332 | * Finally, neither EGSM nor RD is useful by itself. Without EGSM, |
| 333 | * spec foolishly says that RD works only when EGSM is on, but | 333 | * the RD status bit will never get set. Without RD, the controller |
| 334 | * there's no harm in enabling it anyway -- perhaps some chips | 334 | * won't generate interrupts to tell the system about wakeup events. |
| 335 | * will implement it! | ||
| 336 | */ | 335 | */ |
| 337 | if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) || | 336 | if (!wakeup_enable || global_suspend_mode_is_broken(uhci) || |
| 338 | !int_enable) | 337 | resume_detect_interrupts_are_broken(uhci)) |
| 339 | uhci->RD_enable = int_enable = 0; | 338 | egsm_enable = int_enable = 0; |
| 340 | 339 | ||
| 340 | uhci->RD_enable = !!int_enable; | ||
| 341 | uhci_writew(uhci, int_enable, USBINTR); | 341 | uhci_writew(uhci, int_enable, USBINTR); |
| 342 | uhci_writew(uhci, egsm_enable | USBCMD_CF, USBCMD); | 342 | uhci_writew(uhci, egsm_enable | USBCMD_CF, USBCMD); |
| 343 | mb(); | 343 | mb(); |
| @@ -364,10 +364,12 @@ __acquires(uhci->lock) · 20 unmodified lines | |||
| 364 | uhci->rh_state = new_state; | 364 | uhci->rh_state = new_state; |
| 365 | uhci->is_stopped = UHCI_IS_STOPPED; | 365 | uhci->is_stopped = UHCI_IS_STOPPED; |
| 366 | 366 | ||
| 367 | /* If interrupts don't work and remote wakeup is enabled then | 367 | /* |
| 368 | * the suspended root hub needs to be polled. | 368 | * If remote wakeup is enabled but either EGSM or RD interrupts |
| 369 | * doesn't work, then we won't get an interrupt when a wakeup event | ||
| 370 | * occurs. Thus the suspended root hub needs to be polled. | ||
| 369 | */ | 371 | */ |
| 370 | if (!int_enable && wakeup_enable) | 372 | if (wakeup_enable && (!int_enable || !egsm_enable)) |
| 371 | set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); | 373 | set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); |
| 372 | else | 374 | else |
| 373 | clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); | 375 | clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); |
| @@ -280,7 +280,7 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, · 279 unmodified lines | |||
| 280 | qh->load = usb_calc_bus_time(udev->speed, | 280 | qh->load = usb_calc_bus_time(udev->speed, |
| 281 | usb_endpoint_dir_in(&hep->desc), | 281 | usb_endpoint_dir_in(&hep->desc), |
| 282 | qh->type == USB_ENDPOINT_XFER_ISOC, | 282 | qh->type == USB_ENDPOINT_XFER_ISOC, |
| 283 | le16_to_cpu(hep->desc.wMaxPacketSize)) | 283 | usb_endpoint_maxp(&hep->desc)) |
| 284 | / 1000 + 1; | 284 | / 1000 + 1; |
| 285 | 285 | ||
| 286 | } else { /* Skeleton QH */ | 286 | } else { /* Skeleton QH */ |
| @@ -792,7 +792,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, · 505 unmodified lines | |||
| 792 | { | 792 | { |
| 793 | struct uhci_td *td; | 793 | struct uhci_td *td; |
| 794 | unsigned long destination, status; | 794 | unsigned long destination, status; |
| 795 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); | 795 | int maxsze = usb_endpoint_maxp(&qh->hep->desc); |
| 796 | int len = urb->transfer_buffer_length; | 796 | int len = urb->transfer_buffer_length; |
| 797 | dma_addr_t data = urb->transfer_dma; | 797 | dma_addr_t data = urb->transfer_dma; |
| 798 | __hc32 *plink; | 798 | __hc32 *plink; |
| @@ -918,7 +918,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, · 119 unmodified lines | |||
| 918 | { | 918 | { |
| 919 | struct uhci_td *td; | 919 | struct uhci_td *td; |
| 920 | unsigned long destination, status; | 920 | unsigned long destination, status; |
| 921 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); | 921 | int maxsze = usb_endpoint_maxp(&qh->hep->desc); |
| 922 | int len = urb->transfer_buffer_length; | 922 | int len = urb->transfer_buffer_length; |
| 923 | int this_sg_len; | 923 | int this_sg_len; |
| 924 | dma_addr_t data; | 924 | dma_addr_t data; |
| @@ -65,6 +65,12 @@ · 64 unmodified lines | |||
| 65 | /* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ | 65 | /* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ |
| 66 | #define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) | 66 | #define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) |
| 67 | 67 | ||
| 68 | /* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */ | ||
| 69 | #define XHCI_L1C (1 << 16) | ||
| 70 | |||
| 71 | /* USB 2.0 xHCI 1.0 hardware LMP capability - section 7.2.2.1.3.2 */ | ||
| 72 | #define XHCI_HLC (1 << 19) | ||
| 73 | |||
| 68 | /* command register values to disable interrupts and halt the HC */ | 74 | /* command register values to disable interrupts and halt the HC */ |
| 69 | /* start/stop HC execution - do not write unless HC is halted*/ | 75 | /* start/stop HC execution - do not write unless HC is halted*/ |
| 70 | #define XHCI_CMD_RUN (1 << 0) | 76 | #define XHCI_CMD_RUN (1 << 0) |
| @@ -28,6 +28,25 @@ · 27 unmodified lines | |||
| 28 | #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \ | 28 | #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \ |
| 29 | PORT_RC | PORT_PLC | PORT_PE) | 29 | PORT_RC | PORT_PLC | PORT_PE) |
| 30 | 30 | ||
| 31 | /* usb 1.1 root hub device descriptor */ | ||
| 32 | static u8 usb_bos_descriptor [] = { | ||
| 33 | USB_DT_BOS_SIZE, /* __u8 bLength, 5 bytes */ | ||
| 34 | USB_DT_BOS, /* __u8 bDescriptorType */ | ||
| 35 | 0x0F, 0x00, /* __le16 wTotalLength, 15 bytes */ | ||
| 36 | 0x1, /* __u8 bNumDeviceCaps */ | ||
| 37 | /* First device capability */ | ||
| 38 | USB_DT_USB_SS_CAP_SIZE, /* __u8 bLength, 10 bytes */ | ||
| 39 | USB_DT_DEVICE_CAPABILITY, /* Device Capability */ | ||
| 40 | USB_SS_CAP_TYPE, /* bDevCapabilityType, SUPERSPEED_USB */ | ||
| 41 | 0x00, /* bmAttributes, LTM off by default */ | ||
| 42 | USB_5GBPS_OPERATION, 0x00, /* wSpeedsSupported, 5Gbps only */ | ||
| 43 | 0x03, /* bFunctionalitySupport, | ||
| 44 | USB 3.0 speed only */ | ||
| 45 | 0x00, /* bU1DevExitLat, set later. */ | ||
| 46 | 0x00, 0x00 /* __le16 bU2DevExitLat, set later. */ | ||
| 47 | }; | ||
| 48 | |||
| 49 | |||
| 31 | static void xhci_common_hub_descriptor(struct xhci_hcd *xhci, | 50 | static void xhci_common_hub_descriptor(struct xhci_hcd *xhci, |
| 32 | struct usb_hub_descriptor *desc, int ports) | 51 | struct usb_hub_descriptor *desc, int ports) |
| 33 | { | 52 | { |
| @@ -232,7 +251,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, · 198 unmodified lines | |||
| 232 | continue; | 251 | continue; |
| 233 | speed = xhci->devs[i]->udev->speed; | 252 | speed = xhci->devs[i]->udev->speed; |
| 234 | if (((speed == USB_SPEED_SUPER) == (hcd->speed == HCD_USB3)) | 253 | if (((speed == USB_SPEED_SUPER) == (hcd->speed == HCD_USB3)) |
| 235 | && xhci->devs[i]->port == port) { | 254 | && xhci->devs[i]->fake_port == port) { |
| 236 | slot_id = i; | 255 | slot_id = i; |
| 237 | break; | 256 | break; |
| 238 | } | 257 | } |
| @@ -392,13 +411,39 @@ static int xhci_get_ports(struct usb_hcd *hcd, __le32 __iomem ***port_array) · 153 unmodified lines | |||
| 392 | return max_ports; | 411 | return max_ports; |
| 393 | } | 412 | } |
| 394 | 413 | ||
| 414 | void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, | ||
| 415 | int port_id, u32 link_state) | ||
| 416 | { | ||
| 417 | u32 temp; | ||
| 418 | |||
| 419 | temp = xhci_readl(xhci, port_array[port_id]); | ||
| 420 | temp = xhci_port_state_to_neutral(temp); | ||
| 421 | temp &= ~PORT_PLS_MASK; | ||
| 422 | temp |= PORT_LINK_STROBE | link_state; | ||
| 423 | xhci_writel(xhci, temp, port_array[port_id]); | ||
| 424 | } | ||
| 425 | |||
| 426 | /* Test and clear port RWC bit */ | ||
| 427 | void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, | ||
| 428 | int port_id, u32 port_bit) | ||
| 429 | { | ||
| 430 | u32 temp; | ||
| 431 | |||
| 432 | temp = xhci_readl(xhci, port_array[port_id]); | ||
| 433 | if (temp & port_bit) { | ||
| 434 | temp = xhci_port_state_to_neutral(temp); | ||
| 435 | temp |= port_bit; | ||
| 436 | xhci_writel(xhci, temp, port_array[port_id]); | ||
| 437 | } | ||
| 438 | } | ||
| 439 | |||
| 395 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 440 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |
| 396 | u16 wIndex, char *buf, u16 wLength) | 441 | u16 wIndex, char *buf, u16 wLength) |
| 397 | { | 442 | { |
| 398 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 443 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
| 399 | int max_ports; | 444 | int max_ports; |
| 400 | unsigned long flags; | 445 | unsigned long flags; |
| 401 | u32 temp, temp1, status; | 446 | u32 temp, status; |
| 402 | int retval = 0; | 447 | int retval = 0; |
| 403 | __le32 __iomem **port_array; | 448 | __le32 __iomem **port_array; |
| 404 | int slot_id; | 449 | int slot_id; |
| @@ -429,6 +474,21 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 24 unmodified lines | |||
| 429 | xhci_hub_descriptor(hcd, xhci, | 474 | xhci_hub_descriptor(hcd, xhci, |
| 430 | (struct usb_hub_descriptor *) buf); | 475 | (struct usb_hub_descriptor *) buf); |
| 431 | break; | 476 | break; |
| 477 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: | ||
| 478 | if ((wValue & 0xff00) != (USB_DT_BOS << 8)) | ||
| 479 | goto error; | ||
| 480 | |||
| 481 | if (hcd->speed != HCD_USB3) | ||
| 482 | goto error; | ||
| 483 | |||
| 484 | memcpy(buf, &usb_bos_descriptor, | ||
| 485 | USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE); | ||
| 486 | temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params3); | ||
| 487 | buf[12] = HCS_U1_LATENCY(temp); | ||
| 488 | put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]); | ||
| 489 | |||
| 490 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
| 491 | return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE; | ||
| 432 | case GetPortStatus: | 492 | case GetPortStatus: |
| 433 | if (!wIndex || wIndex > max_ports) | 493 | if (!wIndex || wIndex > max_ports) |
| 434 | goto error; | 494 | goto error; |
| @@ -472,11 +532,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 37 unmodified lines | |||
| 472 | xhci_dbg(xhci, "Resume USB2 port %d\n", | 532 | xhci_dbg(xhci, "Resume USB2 port %d\n", |
| 473 | wIndex + 1); | 533 | wIndex + 1); |
| 474 | bus_state->resume_done[wIndex] = 0; | 534 | bus_state->resume_done[wIndex] = 0; |
| 475 | temp1 = xhci_port_state_to_neutral(temp); | 535 | xhci_set_link_state(xhci, port_array, wIndex, |
| 476 | temp1 &= ~PORT_PLS_MASK; | 536 | XDEV_U0); |
| 477 | temp1 |= PORT_LINK_STROBE | XDEV_U0; | ||
| 478 | xhci_writel(xhci, temp1, port_array[wIndex]); | ||
| 479 | |||
| 480 | xhci_dbg(xhci, "set port %d resume\n", | 537 | xhci_dbg(xhci, "set port %d resume\n", |
| 481 | wIndex + 1); | 538 | wIndex + 1); |
| 482 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | 539 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, |
| @@ -551,10 +608,19 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 68 unmodified lines | |||
| 551 | switch (wValue) { | 608 | switch (wValue) { |
| 552 | case USB_PORT_FEAT_SUSPEND: | 609 | case USB_PORT_FEAT_SUSPEND: |
| 553 | temp = xhci_readl(xhci, port_array[wIndex]); | 610 | temp = xhci_readl(xhci, port_array[wIndex]); |
| 611 | if ((temp & PORT_PLS_MASK) != XDEV_U0) { | ||
| 612 | /* Resume the port to U0 first */ | ||
| 613 | xhci_set_link_state(xhci, port_array, wIndex, | ||
| 614 | XDEV_U0); | ||
| 615 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
| 616 | msleep(10); | ||
| 617 | spin_lock_irqsave(&xhci->lock, flags); | ||
| 618 | } | ||
| 554 | /* In spec software should not attempt to suspend | 619 | /* In spec software should not attempt to suspend |
| 555 | * a port unless the port reports that it is in the | 620 | * a port unless the port reports that it is in the |
| 556 | * enabled (PED = ‘1’,PLS < ‘3’) state. | 621 | * enabled (PED = ‘1’,PLS < ‘3’) state. |
| 557 | */ | 622 | */ |
| 623 | temp = xhci_readl(xhci, port_array[wIndex]); | ||
| 558 | if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) | 624 | if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) |
| 559 | || (temp & PORT_PLS_MASK) >= XDEV_U3) { | 625 | || (temp & PORT_PLS_MASK) >= XDEV_U3) { |
| 560 | xhci_warn(xhci, "USB core suspending device " | 626 | xhci_warn(xhci, "USB core suspending device " |
| @@ -573,10 +639,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 12 unmodified lines | |||
| 573 | xhci_stop_device(xhci, slot_id, 1); | 639 | xhci_stop_device(xhci, slot_id, 1); |
| 574 | spin_lock_irqsave(&xhci->lock, flags); | 640 | spin_lock_irqsave(&xhci->lock, flags); |
| 575 | 641 | ||
| 576 | temp = xhci_port_state_to_neutral(temp); | 642 | xhci_set_link_state(xhci, port_array, wIndex, XDEV_U3); |
| 577 | temp &= ~PORT_PLS_MASK; | ||
| 578 | temp |= PORT_LINK_STROBE | XDEV_U3; | ||
| 579 | xhci_writel(xhci, temp, port_array[wIndex]); | ||
| 580 | 643 | ||
| 581 | spin_unlock_irqrestore(&xhci->lock, flags); | 644 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 582 | msleep(10); /* wait device to enter */ | 645 | msleep(10); /* wait device to enter */ |
| @@ -610,10 +673,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 27 unmodified lines | |||
| 610 | } | 673 | } |
| 611 | } | 674 | } |
| 612 | 675 | ||
| 613 | temp = xhci_port_state_to_neutral(temp); | 676 | xhci_set_link_state(xhci, port_array, wIndex, |
| 614 | temp &= ~PORT_PLS_MASK; | 677 | link_state); |
| 615 | temp |= PORT_LINK_STROBE | link_state; | ||
| 616 | xhci_writel(xhci, temp, port_array[wIndex]); | ||
| 617 | 678 | ||
| 618 | spin_unlock_irqrestore(&xhci->lock, flags); | 679 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 619 | msleep(20); /* wait device to enter */ | 680 | msleep(20); /* wait device to enter */ |
| @@ -677,24 +738,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 57 unmodified lines | |||
| 677 | if ((temp & PORT_PE) == 0) | 738 | if ((temp & PORT_PE) == 0) |
| 678 | goto error; | 739 | goto error; |
| 679 | 740 | ||
| 680 | temp = xhci_port_state_to_neutral(temp); | 741 | xhci_set_link_state(xhci, port_array, wIndex, |
| 681 | temp &= ~PORT_PLS_MASK; | 742 | XDEV_RESUME); |
| 682 | temp |= PORT_LINK_STROBE | XDEV_RESUME; | 743 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 683 | xhci_writel(xhci, temp, | ||
| 684 | port_array[wIndex]); | ||
| 685 | |||
| 686 | spin_unlock_irqrestore(&xhci->lock, | ||
| 687 | flags); | ||
| 688 | msleep(20); | 744 | msleep(20); |
| 689 | spin_lock_irqsave(&xhci->lock, flags); | 745 | spin_lock_irqsave(&xhci->lock, flags); |
| 690 | 746 | xhci_set_link_state(xhci, port_array, wIndex, | |
| 691 | temp = xhci_readl(xhci, | 747 | XDEV_U0); |
| 692 | port_array[wIndex]); | ||
| 693 | temp = xhci_port_state_to_neutral(temp); | ||
| 694 | temp &= ~PORT_PLS_MASK; | ||
| 695 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
| 696 | xhci_writel(xhci, temp, | ||
| 697 | port_array[wIndex]); | ||
| 698 | } | 748 | } |
| 699 | bus_state->port_c_suspend |= 1 << wIndex; | 749 | bus_state->port_c_suspend |= 1 << wIndex; |
| 700 | 750 | ||
| @@ -910,25 +960,18 @@ int xhci_bus_resume(struct usb_hcd *hcd) · 209 unmodified lines | |||
| 910 | if (test_bit(port_index, &bus_state->bus_suspended) && | 960 | if (test_bit(port_index, &bus_state->bus_suspended) && |
| 911 | (temp & PORT_PLS_MASK)) { | 961 | (temp & PORT_PLS_MASK)) { |
| 912 | if (DEV_SUPERSPEED(temp)) { | 962 | if (DEV_SUPERSPEED(temp)) { |
| 913 | temp = xhci_port_state_to_neutral(temp); | 963 | xhci_set_link_state(xhci, port_array, |
| 914 | temp &= ~PORT_PLS_MASK; | 964 | port_index, XDEV_U0); |
| 915 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
| 916 | xhci_writel(xhci, temp, port_array[port_index]); | ||
| 917 | } else { | 965 | } else { |
| 918 | temp = xhci_port_state_to_neutral(temp); | 966 | xhci_set_link_state(xhci, port_array, |
| 919 | temp &= ~PORT_PLS_MASK; | 967 | port_index, XDEV_RESUME); |
| 920 | temp |= PORT_LINK_STROBE | XDEV_RESUME; | ||
| 921 | xhci_writel(xhci, temp, port_array[port_index]); | ||
| 922 | 968 | ||
| 923 | spin_unlock_irqrestore(&xhci->lock, flags); | 969 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 924 | msleep(20); | 970 | msleep(20); |
| 925 | spin_lock_irqsave(&xhci->lock, flags); | 971 | spin_lock_irqsave(&xhci->lock, flags); |
| 926 | 972 | ||
| 927 | temp = xhci_readl(xhci, port_array[port_index]); | 973 | xhci_set_link_state(xhci, port_array, |
| 928 | temp = xhci_port_state_to_neutral(temp); | 974 | port_index, XDEV_U0); |
| 929 | temp &= ~PORT_PLS_MASK; | ||
| 930 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
| 931 | xhci_writel(xhci, temp, port_array[port_index]); | ||
| 932 | } | 975 | } |
| 933 | /* wait for the port to enter U0 and report port link | 976 | /* wait for the port to enter U0 and report port link |
| 934 | * state change. | 977 | * state change. |
| @@ -938,12 +981,8 @@ int xhci_bus_resume(struct usb_hcd *hcd) · 3 unmodified lines | |||
| 938 | spin_lock_irqsave(&xhci->lock, flags); | 981 | spin_lock_irqsave(&xhci->lock, flags); |
| 939 | 982 | ||
| 940 | /* Clear PLC */ | 983 | /* Clear PLC */ |
| 941 | temp = xhci_readl(xhci, port_array[port_index]); | 984 | xhci_test_and_clear_bit(xhci, port_array, port_index, |
| 942 | if (temp & PORT_PLC) { | 985 | PORT_PLC); |
| 943 | temp = xhci_port_state_to_neutral(temp); | ||
| 944 | temp |= PORT_PLC; | ||
| 945 | xhci_writel(xhci, temp, port_array[port_index]); | ||
| 946 | } | ||
| 947 | 986 | ||
| 948 | slot_id = xhci_find_slot_id_by_port(hcd, | 987 | slot_id = xhci_find_slot_id_by_port(hcd, |
| 949 | xhci, port_index + 1); | 988 | xhci, port_index + 1); |
| @@ -61,8 +61,6 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, gfp_t flag · 60 unmodified lines | |||
| 61 | 61 | ||
| 62 | static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg) | 62 | static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg) |
| 63 | { | 63 | { |
| 64 | if (!seg) | ||
| 65 | return; | ||
| 66 | if (seg->trbs) { | 64 | if (seg->trbs) { |
| 67 | xhci_dbg(xhci, "Freeing DMA segment at %p (virtual) 0x%llx (DMA)\n", | 65 | xhci_dbg(xhci, "Freeing DMA segment at %p (virtual) 0x%llx (DMA)\n", |
| 68 | seg->trbs, (unsigned long long)seg->dma); | 66 | seg->trbs, (unsigned long long)seg->dma); |
| @@ -81,7 +79,7 @@ static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg) · 12 unmodified lines | |||
| 81 | * related flags, such as End TRB, Toggle Cycle, and no snoop. | 79 | * related flags, such as End TRB, Toggle Cycle, and no snoop. |
| 82 | */ | 80 | */ |
| 83 | static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, | 81 | static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, |
| 84 | struct xhci_segment *next, bool link_trbs) | 82 | struct xhci_segment *next, bool link_trbs, bool isoc) |
| 85 | { | 83 | { |
| 86 | u32 val; | 84 | u32 val; |
| 87 | 85 | ||
| @@ -97,7 +95,9 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, · 9 unmodified lines | |||
| 97 | val &= ~TRB_TYPE_BITMASK; | 95 | val &= ~TRB_TYPE_BITMASK; |
| 98 | val |= TRB_TYPE(TRB_LINK); | 96 | val |= TRB_TYPE(TRB_LINK); |
| 99 | /* Always set the chain bit with 0.95 hardware */ | 97 | /* Always set the chain bit with 0.95 hardware */ |
| 100 | if (xhci_link_trb_quirk(xhci)) | 98 | /* Set chain bit for isoc rings on AMD 0.96 host */ |
| 99 | if (xhci_link_trb_quirk(xhci) || | ||
| 100 | (isoc && (xhci->quirks & XHCI_AMD_0x96_HOST))) | ||
| 101 | val |= TRB_CHAIN; | 101 | val |= TRB_CHAIN; |
| 102 | prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); | 102 | prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); |
| 103 | } | 103 | } |
| @@ -112,18 +112,20 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) · 8 unmodified lines | |||
| 112 | struct xhci_segment *seg; | 112 | struct xhci_segment *seg; |
| 113 | struct xhci_segment *first_seg; | 113 | struct xhci_segment *first_seg; |
| 114 | 114 | ||
| 115 | if (!ring || !ring->first_seg) | 115 | if (!ring) |
| 116 | return; | 116 | return; |
| 117 | first_seg = ring->first_seg; | 117 | if (ring->first_seg) { |
| 118 | seg = first_seg->next; | 118 | first_seg = ring->first_seg; |
| 119 | xhci_dbg(xhci, "Freeing ring at %p\n", ring); | 119 | seg = first_seg->next; |
| 120 | while (seg != first_seg) { | 120 | xhci_dbg(xhci, "Freeing ring at %p\n", ring); |
| 121 | struct xhci_segment *next = seg->next; | 121 | while (seg != first_seg) { |
| 122 | xhci_segment_free(xhci, seg); | 122 | struct xhci_segment *next = seg->next; |
| 123 | seg = next; | 123 | xhci_segment_free(xhci, seg); |
| 124 | seg = next; | ||
| 125 | } | ||
| 126 | xhci_segment_free(xhci, first_seg); | ||
| 127 | ring->first_seg = NULL; | ||
| 124 | } | 128 | } |
| 125 | xhci_segment_free(xhci, first_seg); | ||
| 126 | ring->first_seg = NULL; | ||
| 127 | kfree(ring); | 129 | kfree(ring); |
| 128 | } | 130 | } |
| 129 | 131 | ||
| @@ -152,7 +154,7 @@ static void xhci_initialize_ring_info(struct xhci_ring *ring) · 22 unmodified lines | |||
| 152 | * See section 4.9.1 and figures 15 and 16. | 154 | * See section 4.9.1 and figures 15 and 16. |
| 153 | */ | 155 | */ |
| 154 | static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, | 156 | static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, |
| 155 | unsigned int num_segs, bool link_trbs, gfp_t flags) | 157 | unsigned int num_segs, bool link_trbs, bool isoc, gfp_t flags) |
| 156 | { | 158 | { |
| 157 | struct xhci_ring *ring; | 159 | struct xhci_ring *ring; |
| 158 | struct xhci_segment *prev; | 160 | struct xhci_segment *prev; |
| @@ -178,12 +180,12 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, · 19 unmodified lines | |||
| 178 | next = xhci_segment_alloc(xhci, flags); | 180 | next = xhci_segment_alloc(xhci, flags); |
| 179 | if (!next) | 181 | if (!next) |
| 180 | goto fail; | 182 | goto fail; |
| 181 | xhci_link_segments(xhci, prev, next, link_trbs); | 183 | xhci_link_segments(xhci, prev, next, link_trbs, isoc); |
| 182 | 184 | ||
| 183 | prev = next; | 185 | prev = next; |
| 184 | num_segs--; | 186 | num_segs--; |
| 185 | } | 187 | } |
| 186 | xhci_link_segments(xhci, prev, ring->first_seg, link_trbs); | 188 | xhci_link_segments(xhci, prev, ring->first_seg, link_trbs, isoc); |
| 187 | 189 | ||
| 188 | if (link_trbs) { | 190 | if (link_trbs) { |
| 189 | /* See section 4.9.2.1 and 6.4.4.1 */ | 191 | /* See section 4.9.2.1 and 6.4.4.1 */ |
| @@ -229,14 +231,14 @@ void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci, · 39 unmodified lines | |||
| 229 | * pointers to the beginning of the ring. | 231 | * pointers to the beginning of the ring. |
| 230 | */ | 232 | */ |
| 231 | static void xhci_reinit_cached_ring(struct xhci_hcd *xhci, | 233 | static void xhci_reinit_cached_ring(struct xhci_hcd *xhci, |
| 232 | struct xhci_ring *ring) | 234 | struct xhci_ring *ring, bool isoc) |
| 233 | { | 235 | { |
| 234 | struct xhci_segment *seg = ring->first_seg; | 236 | struct xhci_segment *seg = ring->first_seg; |
| 235 | do { | 237 | do { |
| 236 | memset(seg->trbs, 0, | 238 | memset(seg->trbs, 0, |
| 237 | sizeof(union xhci_trb)*TRBS_PER_SEGMENT); | 239 | sizeof(union xhci_trb)*TRBS_PER_SEGMENT); |
| 238 | /* All endpoint rings have link TRBs */ | 240 | /* All endpoint rings have link TRBs */ |
| 239 | xhci_link_segments(xhci, seg, seg->next, 1); | 241 | xhci_link_segments(xhci, seg, seg->next, 1, isoc); |
| 240 | seg = seg->next; | 242 | seg = seg->next; |
| 241 | } while (seg != ring->first_seg); | 243 | } while (seg != ring->first_seg); |
| 242 | xhci_initialize_ring_info(ring); | 244 | xhci_initialize_ring_info(ring); |
| @@ -315,7 +317,7 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci, · 72 unmodified lines | |||
| 315 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); | 317 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); |
| 316 | 318 | ||
| 317 | if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE) | 319 | if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE) |
| 318 | pci_free_consistent(pdev, | 320 | dma_free_coherent(&pdev->dev, |
| 319 | sizeof(struct xhci_stream_ctx)*num_stream_ctxs, | 321 | sizeof(struct xhci_stream_ctx)*num_stream_ctxs, |
| 320 | stream_ctx, dma); | 322 | stream_ctx, dma); |
| 321 | else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE) | 323 | else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE) |
| @@ -343,9 +345,9 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci, · 21 unmodified lines | |||
| 343 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); | 345 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); |
| 344 | 346 | ||
| 345 | if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE) | 347 | if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE) |
| 346 | return pci_alloc_consistent(pdev, | 348 | return dma_alloc_coherent(&pdev->dev, |
| 347 | sizeof(struct xhci_stream_ctx)*num_stream_ctxs, | 349 | sizeof(struct xhci_stream_ctx)*num_stream_ctxs, |
| 348 | dma); | 350 | dma, mem_flags); |
| 349 | else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE) | 351 | else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE) |
| 350 | return dma_pool_alloc(xhci->small_streams_pool, | 352 | return dma_pool_alloc(xhci->small_streams_pool, |
| 351 | mem_flags, dma); | 353 | mem_flags, dma); |
| @@ -540,7 +542,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, · 188 unmodified lines | |||
| 540 | */ | 542 | */ |
| 541 | for (cur_stream = 1; cur_stream < num_streams; cur_stream++) { | 543 | for (cur_stream = 1; cur_stream < num_streams; cur_stream++) { |
| 542 | stream_info->stream_rings[cur_stream] = | 544 | stream_info->stream_rings[cur_stream] = |
| 543 | xhci_ring_alloc(xhci, 1, true, mem_flags); | 545 | xhci_ring_alloc(xhci, 1, true, false, mem_flags); |
| 544 | cur_ring = stream_info->stream_rings[cur_stream]; | 546 | cur_ring = stream_info->stream_rings[cur_stream]; |
| 545 | if (!cur_ring) | 547 | if (!cur_ring) |
| 546 | goto cleanup_rings; | 548 | goto cleanup_rings; |
| @@ -687,11 +689,103 @@ static void xhci_init_endpoint_timer(struct xhci_hcd *xhci, · 140 unmodified lines | |||
| 687 | ep->xhci = xhci; | 689 | ep->xhci = xhci; |
| 688 | } | 690 | } |
| 689 | 691 | ||
| 690 | /* All the xhci_tds in the ring's TD list should be freed at this point */ | 692 | static void xhci_free_tt_info(struct xhci_hcd *xhci, |
| 693 | struct xhci_virt_device *virt_dev, | ||
| 694 | int slot_id) | ||
| 695 | { | ||
| 696 | struct list_head *tt; | ||
| 697 | struct list_head *tt_list_head; | ||
| 698 | struct list_head *tt_next; | ||
| 699 | struct xhci_tt_bw_info *tt_info; | ||
| 700 | |||
| 701 | /* If the device never made it past the Set Address stage, | ||
| 702 | * it may not have the real_port set correctly. | ||
| 703 | */ | ||
| 704 | if (virt_dev->real_port == 0 || | ||
| 705 | virt_dev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) { | ||
| 706 | xhci_dbg(xhci, "Bad real port.\n"); | ||
| 707 | return; | ||
| 708 | } | ||
| 709 | |||
| 710 | tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts); | ||
| 711 | if (list_empty(tt_list_head)) | ||
| 712 | return; | ||
| 713 | |||
| 714 | list_for_each(tt, tt_list_head) { | ||
| 715 | tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list); | ||
| 716 | if (tt_info->slot_id == slot_id) | ||
| 717 | break; | ||
| 718 | } | ||
| 719 | /* Cautionary measure in case the hub was disconnected before we | ||
| 720 | * stored the TT information. | ||
| 721 | */ | ||
| 722 | if (tt_info->slot_id != slot_id) | ||
| 723 | return; | ||
| 724 | |||
| 725 | tt_next = tt->next; | ||
| 726 | tt_info = list_entry(tt, struct xhci_tt_bw_info, | ||
| 727 | tt_list); | ||
| 728 | /* Multi-TT hubs will have more than one entry */ | ||
| 729 | do { | ||
| 730 | list_del(tt); | ||
| 731 | kfree(tt_info); | ||
| 732 | tt = tt_next; | ||
| 733 | if (list_empty(tt_list_head)) | ||
| 734 | break; | ||
| 735 | tt_next = tt->next; | ||
| 736 | tt_info = list_entry(tt, struct xhci_tt_bw_info, | ||
| 737 | tt_list); | ||
| 738 | } while (tt_info->slot_id == slot_id); | ||
| 739 | } | ||
| 740 | |||
| 741 | int xhci_alloc_tt_info(struct xhci_hcd *xhci, | ||
| 742 | struct xhci_virt_device *virt_dev, | ||
| 743 | struct usb_device *hdev, | ||
| 744 | struct usb_tt *tt, gfp_t mem_flags) | ||
| 745 | { | ||
| 746 | struct xhci_tt_bw_info *tt_info; | ||
| 747 | unsigned int num_ports; | ||
| 748 | int i, j; | ||
| 749 | |||
| 750 | if (!tt->multi) | ||
| 751 | num_ports = 1; | ||
| 752 | else | ||
| 753 | num_ports = hdev->maxchild; | ||
| 754 | |||
| 755 | for (i = 0; i < num_ports; i++, tt_info++) { | ||
| 756 | struct xhci_interval_bw_table *bw_table; | ||
| 757 | |||
| 758 | tt_info = kzalloc(sizeof(*tt_info), mem_flags); | ||
| 759 | if (!tt_info) | ||
| 760 | goto free_tts; | ||
| 761 | INIT_LIST_HEAD(&tt_info->tt_list); | ||
| 762 | list_add(&tt_info->tt_list, | ||
| 763 | &xhci->rh_bw[virt_dev->real_port - 1].tts); | ||
| 764 | tt_info->slot_id = virt_dev->udev->slot_id; | ||
| 765 | if (tt->multi) | ||
| 766 | tt_info->ttport = i+1; | ||
| 767 | bw_table = &tt_info->bw_table; | ||
| 768 | for (j = 0; j < XHCI_MAX_INTERVAL; j++) | ||
| 769 | INIT_LIST_HEAD(&bw_table->interval_bw[j].endpoints); | ||
| 770 | } | ||
| 771 | return 0; | ||
| 772 | |||
| 773 | free_tts: | ||
| 774 | xhci_free_tt_info(xhci, virt_dev, virt_dev->udev->slot_id); | ||
| 775 | return -ENOMEM; | ||
| 776 | } | ||
| 777 | |||
| 778 | |||
| 779 | /* All the xhci_tds in the ring's TD list should be freed at this point. | ||
| 780 | * Should be called with xhci->lock held if there is any chance the TT lists | ||
| 781 | * will be manipulated by the configure endpoint, allocate device, or update | ||
| 782 | * hub functions while this function is removing the TT entries from the list. | ||
| 783 | */ | ||
| 691 | void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) | 784 | void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) |
| 692 | { | 785 | { |
| 693 | struct xhci_virt_device *dev; | 786 | struct xhci_virt_device *dev; |
| 694 | int i; | 787 | int i; |
| 788 | int old_active_eps = 0; | ||
| 695 | 789 | ||
| 696 | /* Slot ID 0 is reserved */ | 790 | /* Slot ID 0 is reserved */ |
| 697 | if (slot_id == 0 || !xhci->devs[slot_id]) | 791 | if (slot_id == 0 || !xhci->devs[slot_id]) |
| @@ -702,13 +796,29 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) · 4 unmodified lines | |||
| 702 | if (!dev) | 796 | if (!dev) |
| 703 | return; | 797 | return; |
| 704 | 798 | ||
| 799 | if (dev->tt_info) | ||
| 800 | old_active_eps = dev->tt_info->active_eps; | ||
| 801 | |||
| 705 | for (i = 0; i < 31; ++i) { | 802 | for (i = 0; i < 31; ++i) { |
| 706 | if (dev->eps[i].ring) | 803 | if (dev->eps[i].ring) |
| 707 | xhci_ring_free(xhci, dev->eps[i].ring); | 804 | xhci_ring_free(xhci, dev->eps[i].ring); |
| 708 | if (dev->eps[i].stream_info) | 805 | if (dev->eps[i].stream_info) |
| 709 | xhci_free_stream_info(xhci, | 806 | xhci_free_stream_info(xhci, |
| 710 | dev->eps[i].stream_info); | 807 | dev->eps[i].stream_info); |
| 808 | /* Endpoints on the TT/root port lists should have been removed | ||
| 809 | * when usb_disable_device() was called for the device. | ||
| 810 | * We can't drop them anyway, because the udev might have gone | ||
| 811 | * away by this point, and we can't tell what speed it was. | ||
| 812 | */ | ||
| 813 | if (!list_empty(&dev->eps[i].bw_endpoint_list)) | ||
| 814 | xhci_warn(xhci, "Slot %u endpoint %u " | ||
| 815 | "not removed from BW list!\n", | ||
| 816 | slot_id, i); | ||
| 711 | } | 817 | } |
| 818 | /* If this is a hub, free the TT(s) from the TT list */ | ||
| 819 | xhci_free_tt_info(xhci, dev, slot_id); | ||
| 820 | /* If necessary, update the number of active TTs on this root port */ | ||
| 821 | xhci_update_tt_active_eps(xhci, dev, old_active_eps); | ||
| 712 | 822 | ||
| 713 | if (dev->ring_cache) { | 823 | if (dev->ring_cache) { |
| 714 | for (i = 0; i < dev->num_rings_cached; i++) | 824 | for (i = 0; i < dev->num_rings_cached; i++) |
| @@ -762,10 +872,11 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, · 47 unmodified lines | |||
| 762 | for (i = 0; i < 31; i++) { | 872 | for (i = 0; i < 31; i++) { |
| 763 | xhci_init_endpoint_timer(xhci, &dev->eps[i]); | 873 | xhci_init_endpoint_timer(xhci, &dev->eps[i]); |
| 764 | INIT_LIST_HEAD(&dev->eps[i].cancelled_td_list); | 874 | INIT_LIST_HEAD(&dev->eps[i].cancelled_td_list); |
| 875 | INIT_LIST_HEAD(&dev->eps[i].bw_endpoint_list); | ||
| 765 | } | 876 | } |
| 766 | 877 | ||
| 767 | /* Allocate endpoint 0 ring */ | 878 | /* Allocate endpoint 0 ring */ |
| 768 | dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, flags); | 879 | dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, false, flags); |
| 769 | if (!dev->eps[0].ring) | 880 | if (!dev->eps[0].ring) |
| 770 | goto fail; | 881 | goto fail; |
| 771 | 882 | ||
| @@ -921,9 +1032,40 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud · 149 unmodified lines | |||
| 921 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; | 1032 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; |
| 922 | top_dev = top_dev->parent) | 1033 | top_dev = top_dev->parent) |
| 923 | /* Found device below root hub */; | 1034 | /* Found device below root hub */; |
| 924 | dev->port = top_dev->portnum; | 1035 | dev->fake_port = top_dev->portnum; |
| 1036 | dev->real_port = port_num; | ||
| 925 | xhci_dbg(xhci, "Set root hub portnum to %d\n", port_num); | 1037 | xhci_dbg(xhci, "Set root hub portnum to %d\n", port_num); |
| 926 | xhci_dbg(xhci, "Set fake root hub portnum to %d\n", dev->port); | 1038 | xhci_dbg(xhci, "Set fake root hub portnum to %d\n", dev->fake_port); |
| 1039 | |||
| 1040 | /* Find the right bandwidth table that this device will be a part of. | ||
| 1041 | * If this is a full speed device attached directly to a root port (or a | ||
| 1042 | * decendent of one), it counts as a primary bandwidth domain, not a | ||
| 1043 | * secondary bandwidth domain under a TT. An xhci_tt_info structure | ||
| 1044 | * will never be created for the HS root hub. | ||
| 1045 | */ | ||
| 1046 | if (!udev->tt || !udev->tt->hub->parent) { | ||
| 1047 | dev->bw_table = &xhci->rh_bw[port_num - 1].bw_table; | ||
| 1048 | } else { | ||
| 1049 | struct xhci_root_port_bw_info *rh_bw; | ||
| 1050 | struct xhci_tt_bw_info *tt_bw; | ||
| 1051 | |||
| 1052 | rh_bw = &xhci->rh_bw[port_num - 1]; | ||
| 1053 | /* Find the right TT. */ | ||
| 1054 | list_for_each_entry(tt_bw, &rh_bw->tts, tt_list) { | ||
| 1055 | if (tt_bw->slot_id != udev->tt->hub->slot_id) | ||
| 1056 | continue; | ||
| 1057 | |||
| 1058 | if (!dev->udev->tt->multi || | ||
| 1059 | (udev->tt->multi && | ||
| 1060 | tt_bw->ttport == dev->udev->ttport)) { | ||
| 1061 | dev->bw_table = &tt_bw->bw_table; | ||
| 1062 | dev->tt_info = tt_bw; | ||
| 1063 | break; | ||
| 1064 | } | ||
| 1065 | } | ||
| 1066 | if (!dev->tt_info) | ||
| 1067 | xhci_warn(xhci, "WARN: Didn't find a matching TT\n"); | ||
| 1068 | } | ||
| 927 | 1069 | ||
| 928 | /* Is this a LS/FS device under an external HS hub? */ | 1070 | /* Is this a LS/FS device under an external HS hub? */ |
| 929 | if (udev->tt && udev->tt->hub->parent) { | 1071 | if (udev->tt && udev->tt->hub->parent) { |
| @@ -1141,8 +1283,8 @@ static u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, · 211 unmodified lines | |||
| 1141 | if (udev->speed == USB_SPEED_SUPER) | 1283 | if (udev->speed == USB_SPEED_SUPER) |
| 1142 | return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); | 1284 | return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); |
| 1143 | 1285 | ||
| 1144 | max_packet = GET_MAX_PACKET(le16_to_cpu(ep->desc.wMaxPacketSize)); | 1286 | max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); |
| 1145 | max_burst = (le16_to_cpu(ep->desc.wMaxPacketSize) & 0x1800) >> 11; | 1287 | max_burst = (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11; |
| 1146 | /* A 0 in max burst means 1 transfer per ESIT */ | 1288 | /* A 0 in max burst means 1 transfer per ESIT */ |
| 1147 | return max_packet * (max_burst + 1); | 1289 | return max_packet * (max_burst + 1); |
| 1148 | } | 1290 | } |
| @@ -1175,10 +1317,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, · 26 unmodified lines | |||
| 1175 | */ | 1317 | */ |
| 1176 | if (usb_endpoint_xfer_isoc(&ep->desc)) | 1318 | if (usb_endpoint_xfer_isoc(&ep->desc)) |
| 1177 | virt_dev->eps[ep_index].new_ring = | 1319 | virt_dev->eps[ep_index].new_ring = |
| 1178 | xhci_ring_alloc(xhci, 8, true, mem_flags); | 1320 | xhci_ring_alloc(xhci, 8, true, true, mem_flags); |
| 1179 | else | 1321 | else |
| 1180 | virt_dev->eps[ep_index].new_ring = | 1322 | virt_dev->eps[ep_index].new_ring = |
| 1181 | xhci_ring_alloc(xhci, 1, true, mem_flags); | 1323 | xhci_ring_alloc(xhci, 1, true, false, mem_flags); |
| 1182 | if (!virt_dev->eps[ep_index].new_ring) { | 1324 | if (!virt_dev->eps[ep_index].new_ring) { |
| 1183 | /* Attempt to use the ring cache */ | 1325 | /* Attempt to use the ring cache */ |
| 1184 | if (virt_dev->num_rings_cached == 0) | 1326 | if (virt_dev->num_rings_cached == 0) |
| @@ -1187,7 +1329,8 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, · 2 unmodified lines | |||
| 1187 | virt_dev->ring_cache[virt_dev->num_rings_cached]; | 1329 | virt_dev->ring_cache[virt_dev->num_rings_cached]; |
| 1188 | virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL; | 1330 | virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL; |
| 1189 | virt_dev->num_rings_cached--; | 1331 | virt_dev->num_rings_cached--; |
| 1190 | xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring); | 1332 | xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring, |
| 1333 | usb_endpoint_xfer_isoc(&ep->desc) ? true : false); | ||
| 1191 | } | 1334 | } |
| 1192 | virt_dev->eps[ep_index].skip = false; | 1335 | virt_dev->eps[ep_index].skip = false; |
| 1193 | ep_ring = virt_dev->eps[ep_index].new_ring; | 1336 | ep_ring = virt_dev->eps[ep_index].new_ring; |
| @@ -1211,7 +1354,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, · 17 unmodified lines | |||
| 1211 | /* Set the max packet size and max burst */ | 1354 | /* Set the max packet size and max burst */ |
| 1212 | switch (udev->speed) { | 1355 | switch (udev->speed) { |
| 1213 | case USB_SPEED_SUPER: | 1356 | case USB_SPEED_SUPER: |
| 1214 | max_packet = le16_to_cpu(ep->desc.wMaxPacketSize); | 1357 | max_packet = usb_endpoint_maxp(&ep->desc); |
| 1215 | ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); | 1358 | ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); |
| 1216 | /* dig out max burst from ep companion desc */ | 1359 | /* dig out max burst from ep companion desc */ |
| 1217 | max_packet = ep->ss_ep_comp.bMaxBurst; | 1360 | max_packet = ep->ss_ep_comp.bMaxBurst; |
| @@ -1223,14 +1366,14 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, · 5 unmodified lines | |||
| 1223 | */ | 1366 | */ |
| 1224 | if (usb_endpoint_xfer_isoc(&ep->desc) || | 1367 | if (usb_endpoint_xfer_isoc(&ep->desc) || |
| 1225 | usb_endpoint_xfer_int(&ep->desc)) { | 1368 | usb_endpoint_xfer_int(&ep->desc)) { |
| 1226 | max_burst = (le16_to_cpu(ep->desc.wMaxPacketSize) | 1369 | max_burst = (usb_endpoint_maxp(&ep->desc) |
| 1227 | & 0x1800) >> 11; | 1370 | & 0x1800) >> 11; |
| 1228 | ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_burst)); | 1371 | ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_burst)); |
| 1229 | } | 1372 | } |
| 1230 | /* Fall through */ | 1373 | /* Fall through */ |
| 1231 | case USB_SPEED_FULL: | 1374 | case USB_SPEED_FULL: |
| 1232 | case USB_SPEED_LOW: | 1375 | case USB_SPEED_LOW: |
| 1233 | max_packet = GET_MAX_PACKET(le16_to_cpu(ep->desc.wMaxPacketSize)); | 1376 | max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); |
| 1234 | ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); | 1377 | ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); |
| 1235 | break; | 1378 | break; |
| 1236 | default: | 1379 | default: |
| @@ -1286,6 +1429,70 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci, · 49 unmodified lines | |||
| 1286 | */ | 1429 | */ |
| 1287 | } | 1430 | } |
| 1288 | 1431 | ||
| 1432 | void xhci_clear_endpoint_bw_info(struct xhci_bw_info *bw_info) | ||
| 1433 | { | ||
| 1434 | bw_info->ep_interval = 0; | ||
| 1435 | bw_info->mult = 0; | ||
| 1436 | bw_info->num_packets = 0; | ||
| 1437 | bw_info->max_packet_size = 0; | ||
| 1438 | bw_info->type = 0; | ||
| 1439 | bw_info->max_esit_payload = 0; | ||
| 1440 | } | ||
| 1441 | |||
| 1442 | void xhci_update_bw_info(struct xhci_hcd *xhci, | ||
| 1443 | struct xhci_container_ctx *in_ctx, | ||
| 1444 | struct xhci_input_control_ctx *ctrl_ctx, | ||
| 1445 | struct xhci_virt_device *virt_dev) | ||
| 1446 | { | ||
| 1447 | struct xhci_bw_info *bw_info; | ||
| 1448 | struct xhci_ep_ctx *ep_ctx; | ||
| 1449 | unsigned int ep_type; | ||
| 1450 | int i; | ||
| 1451 | |||
| 1452 | for (i = 1; i < 31; ++i) { | ||
| 1453 | bw_info = &virt_dev->eps[i].bw_info; | ||
| 1454 | |||
| 1455 | /* We can't tell what endpoint type is being dropped, but | ||
| 1456 | * unconditionally clearing the bandwidth info for non-periodic | ||
| 1457 | * endpoints should be harmless because the info will never be | ||
| 1458 | * set in the first place. | ||
| 1459 | */ | ||
| 1460 | if (!EP_IS_ADDED(ctrl_ctx, i) && EP_IS_DROPPED(ctrl_ctx, i)) { | ||
| 1461 | /* Dropped endpoint */ | ||
| 1462 | xhci_clear_endpoint_bw_info(bw_info); | ||
| 1463 | continue; | ||
| 1464 | } | ||
| 1465 | |||
| 1466 | if (EP_IS_ADDED(ctrl_ctx, i)) { | ||
| 1467 | ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, i); | ||
| 1468 | ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); | ||
| 1469 | |||
| 1470 | /* Ignore non-periodic endpoints */ | ||
| 1471 | if (ep_type != ISOC_OUT_EP && ep_type != INT_OUT_EP && | ||
| 1472 | ep_type != ISOC_IN_EP && | ||
| 1473 | ep_type != INT_IN_EP) | ||
| 1474 | continue; | ||
| 1475 | |||
| 1476 | /* Added or changed endpoint */ | ||
| 1477 | bw_info->ep_interval = CTX_TO_EP_INTERVAL( | ||
| 1478 | le32_to_cpu(ep_ctx->ep_info)); | ||
| 1479 | /* Number of packets and mult are zero-based in the | ||
| 1480 | * input context, but we want one-based for the | ||
| 1481 | * interval table. | ||
| 1482 | */ | ||
| 1483 | bw_info->mult = CTX_TO_EP_MULT( | ||
| 1484 | le32_to_cpu(ep_ctx->ep_info)) + 1; | ||
| 1485 | bw_info->num_packets = CTX_TO_MAX_BURST( | ||
| 1486 | le32_to_cpu(ep_ctx->ep_info2)) + 1; | ||
| 1487 | bw_info->max_packet_size = MAX_PACKET_DECODED( | ||
| 1488 | le32_to_cpu(ep_ctx->ep_info2)); | ||
| 1489 | bw_info->type = ep_type; | ||
| 1490 | bw_info->max_esit_payload = CTX_TO_MAX_ESIT_PAYLOAD( | ||
| 1491 | le32_to_cpu(ep_ctx->tx_info)); | ||
| 1492 | } | ||
| 1493 | } | ||
| 1494 | } | ||
| 1495 | |||
| 1289 | /* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy. | 1496 | /* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy. |
| 1290 | * Useful when you want to change one particular aspect of the endpoint and then | 1497 | * Useful when you want to change one particular aspect of the endpoint and then |
| 1291 | * issue a configure endpoint command. | 1498 | * issue a configure endpoint command. |
| @@ -1344,10 +1551,9 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) · 52 unmodified lines | |||
| 1344 | if (!xhci->scratchpad) | 1551 | if (!xhci->scratchpad) |
| 1345 | goto fail_sp; | 1552 | goto fail_sp; |
| 1346 | 1553 | ||
| 1347 | xhci->scratchpad->sp_array = | 1554 | xhci->scratchpad->sp_array = dma_alloc_coherent(dev, |
| 1348 | pci_alloc_consistent(to_pci_dev(dev), | ||
| 1349 | num_sp * sizeof(u64), | 1555 | num_sp * sizeof(u64), |
| 1350 | &xhci->scratchpad->sp_dma); | 1556 | &xhci->scratchpad->sp_dma, flags); |
| 1351 | if (!xhci->scratchpad->sp_array) | 1557 | if (!xhci->scratchpad->sp_array) |
| 1352 | goto fail_sp2; | 1558 | goto fail_sp2; |
| 1353 | 1559 | ||
| @@ -1364,8 +1570,8 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) · 10 unmodified lines | |||
| 1364 | xhci->dcbaa->dev_context_ptrs[0] = cpu_to_le64(xhci->scratchpad->sp_dma); | 1570 | xhci->dcbaa->dev_context_ptrs[0] = cpu_to_le64(xhci->scratchpad->sp_dma); |
| 1365 | for (i = 0; i < num_sp; i++) { | 1571 | for (i = 0; i < num_sp; i++) { |
| 1366 | dma_addr_t dma; | 1572 | dma_addr_t dma; |
| 1367 | void *buf = pci_alloc_consistent(to_pci_dev(dev), | 1573 | void *buf = dma_alloc_coherent(dev, xhci->page_size, &dma, |
| 1368 | xhci->page_size, &dma); | 1574 | flags); |
| 1369 | if (!buf) | 1575 | if (!buf) |
| 1370 | goto fail_sp5; | 1576 | goto fail_sp5; |
| 1371 | 1577 | ||
| @@ -1378,7 +1584,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) · 6 unmodified lines | |||
| 1378 | 1584 | ||
| 1379 | fail_sp5: | 1585 | fail_sp5: |
| 1380 | for (i = i - 1; i >= 0; i--) { | 1586 | for (i = i - 1; i >= 0; i--) { |
| 1381 | pci_free_consistent(to_pci_dev(dev), xhci->page_size, | 1587 | dma_free_coherent(dev, xhci->page_size, |
| 1382 | xhci->scratchpad->sp_buffers[i], | 1588 | xhci->scratchpad->sp_buffers[i], |
| 1383 | xhci->scratchpad->sp_dma_buffers[i]); | 1589 | xhci->scratchpad->sp_dma_buffers[i]); |
| 1384 | } | 1590 | } |
| @@ -1388,7 +1594,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) · 3 unmodified lines | |||
| 1388 | kfree(xhci->scratchpad->sp_buffers); | 1594 | kfree(xhci->scratchpad->sp_buffers); |
| 1389 | 1595 | ||
| 1390 | fail_sp3: | 1596 | fail_sp3: |
| 1391 | pci_free_consistent(to_pci_dev(dev), num_sp * sizeof(u64), | 1597 | dma_free_coherent(dev, num_sp * sizeof(u64), |
| 1392 | xhci->scratchpad->sp_array, | 1598 | xhci->scratchpad->sp_array, |
| 1393 | xhci->scratchpad->sp_dma); | 1599 | xhci->scratchpad->sp_dma); |
| 1394 | 1600 | ||
| @@ -1412,13 +1618,13 @@ static void scratchpad_free(struct xhci_hcd *xhci) · 17 unmodified lines | |||
| 1412 | num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2); | 1618 | num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2); |
| 1413 | 1619 | ||
| 1414 | for (i = 0; i < num_sp; i++) { | 1620 | for (i = 0; i < num_sp; i++) { |
| 1415 | pci_free_consistent(pdev, xhci->page_size, | 1621 | dma_free_coherent(&pdev->dev, xhci->page_size, |
| 1416 | xhci->scratchpad->sp_buffers[i], | 1622 | xhci->scratchpad->sp_buffers[i], |
| 1417 | xhci->scratchpad->sp_dma_buffers[i]); | 1623 | xhci->scratchpad->sp_dma_buffers[i]); |
| 1418 | } | 1624 | } |
| 1419 | kfree(xhci->scratchpad->sp_dma_buffers); | 1625 | kfree(xhci->scratchpad->sp_dma_buffers); |
| 1420 | kfree(xhci->scratchpad->sp_buffers); | 1626 | kfree(xhci->scratchpad->sp_buffers); |
| 1421 | pci_free_consistent(pdev, num_sp * sizeof(u64), | 1627 | dma_free_coherent(&pdev->dev, num_sp * sizeof(u64), |
| 1422 | xhci->scratchpad->sp_array, | 1628 | xhci->scratchpad->sp_array, |
| 1423 | xhci->scratchpad->sp_dma); | 1629 | xhci->scratchpad->sp_dma); |
| 1424 | kfree(xhci->scratchpad); | 1630 | kfree(xhci->scratchpad); |
| @@ -1463,18 +1669,10 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, · 38 unmodified lines | |||
| 1463 | 1669 | ||
| 1464 | void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv) | 1670 | void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv) |
| 1465 | { | 1671 | { |
| 1466 | int last; | 1672 | if (urb_priv) { |
| 1467 | 1673 | kfree(urb_priv->td[0]); | |
| 1468 | if (!urb_priv) | 1674 | kfree(urb_priv); |
| 1469 | return; | ||
| 1470 | |||
| 1471 | last = urb_priv->length - 1; | ||
| 1472 | if (last >= 0) { | ||
| 1473 | int i; | ||
| 1474 | for (i = 0; i <= last; i++) | ||
| 1475 | kfree(urb_priv->td[i]); | ||
| 1476 | } | 1675 | } |
| 1477 | kfree(urb_priv); | ||
| 1478 | } | 1676 | } |
| 1479 | 1677 | ||
| 1480 | void xhci_free_command(struct xhci_hcd *xhci, | 1678 | void xhci_free_command(struct xhci_hcd *xhci, |
| @@ -1489,6 +1687,8 @@ void xhci_free_command(struct xhci_hcd *xhci, · 8 unmodified lines | |||
| 1489 | void xhci_mem_cleanup(struct xhci_hcd *xhci) | 1687 | void xhci_mem_cleanup(struct xhci_hcd *xhci) |
| 1490 | { | 1688 | { |
| 1491 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); | 1689 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); |
| 1690 | struct dev_info *dev_info, *next; | ||
| 1691 | unsigned long flags; | ||
| 1492 | int size; | 1692 | int size; |
| 1493 | int i; | 1693 | int i; |
| 1494 | 1694 | ||
| @@ -1500,7 +1700,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) · 5 unmodified lines | |||
| 1500 | } | 1700 | } |
| 1501 | size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); | 1701 | size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); |
| 1502 | if (xhci->erst.entries) | 1702 | if (xhci->erst.entries) |
| 1503 | pci_free_consistent(pdev, size, | 1703 | dma_free_coherent(&pdev->dev, size, |
| 1504 | xhci->erst.entries, xhci->erst.erst_dma_addr); | 1704 | xhci->erst.entries, xhci->erst.erst_dma_addr); |
| 1505 | xhci->erst.entries = NULL; | 1705 | xhci->erst.entries = NULL; |
| 1506 | xhci_dbg(xhci, "Freed ERST\n"); | 1706 | xhci_dbg(xhci, "Freed ERST\n"); |
| @@ -1540,17 +1740,25 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) · 33 unmodified lines | |||
| 1540 | 1740 | ||
| 1541 | xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); | 1741 | xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); |
| 1542 | if (xhci->dcbaa) | 1742 | if (xhci->dcbaa) |
| 1543 | pci_free_consistent(pdev, sizeof(*xhci->dcbaa), | 1743 | dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa), |
| 1544 | xhci->dcbaa, xhci->dcbaa->dma); | 1744 | xhci->dcbaa, xhci->dcbaa->dma); |
| 1545 | xhci->dcbaa = NULL; | 1745 | xhci->dcbaa = NULL; |
| 1546 | 1746 | ||
| 1547 | scratchpad_free(xhci); | 1747 | scratchpad_free(xhci); |
| 1548 | 1748 | ||
| 1749 | spin_lock_irqsave(&xhci->lock, flags); | ||
| 1750 | list_for_each_entry_safe(dev_info, next, &xhci->lpm_failed_devs, list) { | ||
| 1751 | list_del(&dev_info->list); | ||
| 1752 | kfree(dev_info); | ||
| 1753 | } | ||
| 1754 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
| 1755 | |||
| 1549 | xhci->num_usb2_ports = 0; | 1756 | xhci->num_usb2_ports = 0; |
| 1550 | xhci->num_usb3_ports = 0; | 1757 | xhci->num_usb3_ports = 0; |
| 1551 | kfree(xhci->usb2_ports); | 1758 | kfree(xhci->usb2_ports); |
| 1552 | kfree(xhci->usb3_ports); | 1759 | kfree(xhci->usb3_ports); |
| 1553 | kfree(xhci->port_array); | 1760 | kfree(xhci->port_array); |
| 1761 | kfree(xhci->rh_bw); | ||
| 1554 | 1762 | ||
| 1555 | xhci->page_size = 0; | 1763 | xhci->page_size = 0; |
| 1556 | xhci->page_shift = 0; | 1764 | xhci->page_shift = 0; |
| @@ -1762,6 +1970,23 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, · 205 unmodified lines | |||
| 1762 | if (port_offset == 0 || (port_offset + port_count - 1) > num_ports) | 1970 | if (port_offset == 0 || (port_offset + port_count - 1) > num_ports) |
| 1763 | /* WTF? "Valid values are ‘1’ to MaxPorts" */ | 1971 | /* WTF? "Valid values are ‘1’ to MaxPorts" */ |
| 1764 | return; | 1972 | return; |
| 1973 | |||
| 1974 | /* Check the host's USB2 LPM capability */ | ||
| 1975 | if ((xhci->hci_version == 0x96) && (major_revision != 0x03) && | ||
| 1976 | (temp & XHCI_L1C)) { | ||
| 1977 | xhci_dbg(xhci, "xHCI 0.96: support USB2 software lpm\n"); | ||
| 1978 | xhci->sw_lpm_support = 1; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | if ((xhci->hci_version >= 0x100) && (major_revision != 0x03)) { | ||
| 1982 | xhci_dbg(xhci, "xHCI 1.0: support USB2 software lpm\n"); | ||
| 1983 | xhci->sw_lpm_support = 1; | ||
| 1984 | if (temp & XHCI_HLC) { | ||
| 1985 | xhci_dbg(xhci, "xHCI 1.0: support USB2 hardware lpm\n"); | ||
| 1986 | xhci->hw_lpm_support = 1; | ||
| 1987 | } | ||
| 1988 | } | ||
| 1989 | |||
| 1765 | port_offset--; | 1990 | port_offset--; |
| 1766 | for (i = port_offset; i < (port_offset + port_count); i++) { | 1991 | for (i = port_offset; i < (port_offset + port_count); i++) { |
| 1767 | /* Duplicate entry. Ignore the port if the revisions differ. */ | 1992 | /* Duplicate entry. Ignore the port if the revisions differ. */ |
| @@ -1806,7 +2031,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) · 38 unmodified lines | |||
| 1806 | __le32 __iomem *addr; | 2031 | __le32 __iomem *addr; |
| 1807 | u32 offset; | 2032 | u32 offset; |
| 1808 | unsigned int num_ports; | 2033 | unsigned int num_ports; |
| 1809 | int i, port_index; | 2034 | int i, j, port_index; |
| 1810 | 2035 | ||
| 1811 | addr = &xhci->cap_regs->hcc_params; | 2036 | addr = &xhci->cap_regs->hcc_params; |
| 1812 | offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr)); | 2037 | offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr)); |
| @@ -1821,6 +2046,18 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) · 8 unmodified lines | |||
| 1821 | if (!xhci->port_array) | 2046 | if (!xhci->port_array) |
| 1822 | return -ENOMEM; | 2047 | return -ENOMEM; |
| 1823 | 2048 | ||
| 2049 | xhci->rh_bw = kzalloc(sizeof(*xhci->rh_bw)*num_ports, flags); | ||
| 2050 | if (!xhci->rh_bw) | ||
| 2051 | return -ENOMEM; | ||
| 2052 | for (i = 0; i < num_ports; i++) { | ||
| 2053 | struct xhci_interval_bw_table *bw_table; | ||
| 2054 | |||
| 2055 | INIT_LIST_HEAD(&xhci->rh_bw[i].tts); | ||
| 2056 | bw_table = &xhci->rh_bw[i].bw_table; | ||
| 2057 | for (j = 0; j < XHCI_MAX_INTERVAL; j++) | ||
| 2058 | INIT_LIST_HEAD(&bw_table->interval_bw[j].endpoints); | ||
| 2059 | } | ||
| 2060 | |||
| 1824 | /* | 2061 | /* |
| 1825 | * For whatever reason, the first capability offset is from the | 2062 | * For whatever reason, the first capability offset is from the |
| 1826 | * capability register base, not from the HCCPARAMS register. | 2063 | * capability register base, not from the HCCPARAMS register. |
| @@ -1959,8 +2196,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) · 132 unmodified lines | |||
| 1959 | * Section 5.4.8 - doorbell array must be | 2196 | * Section 5.4.8 - doorbell array must be |
| 1960 | * "physically contiguous and 64-byte (cache line) aligned". | 2197 | * "physically contiguous and 64-byte (cache line) aligned". |
| 1961 | */ | 2198 | */ |
| 1962 | xhci->dcbaa = pci_alloc_consistent(to_pci_dev(dev), | 2199 | xhci->dcbaa = dma_alloc_coherent(dev, sizeof(*xhci->dcbaa), &dma, |
| 1963 | sizeof(*xhci->dcbaa), &dma); | 2200 | GFP_KERNEL); |
| 1964 | if (!xhci->dcbaa) | 2201 | if (!xhci->dcbaa) |
| 1965 | goto fail; | 2202 | goto fail; |
| 1966 | memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa)); | 2203 | memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa)); |
| @@ -1994,14 +2231,14 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) · 27 unmodified lines | |||
| 1994 | dma_pool_create("xHCI 1KB stream ctx arrays", | 2231 | dma_pool_create("xHCI 1KB stream ctx arrays", |
| 1995 | dev, MEDIUM_STREAM_ARRAY_SIZE, 16, 0); | 2232 | dev, MEDIUM_STREAM_ARRAY_SIZE, 16, 0); |
| 1996 | /* Any stream context array bigger than MEDIUM_STREAM_ARRAY_SIZE | 2233 | /* Any stream context array bigger than MEDIUM_STREAM_ARRAY_SIZE |
| 1997 | * will be allocated with pci_alloc_consistent() | 2234 | * will be allocated with dma_alloc_coherent() |
| 1998 | */ | 2235 | */ |
| 1999 | 2236 | ||
| 2000 | if (!xhci->small_streams_pool || !xhci->medium_streams_pool) | 2237 | if (!xhci->small_streams_pool || !xhci->medium_streams_pool) |
| 2001 | goto fail; | 2238 | goto fail; |
| 2002 | 2239 | ||
| 2003 | /* Set up the command ring to have one segments for now. */ | 2240 | /* Set up the command ring to have one segments for now. */ |
| 2004 | xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, flags); | 2241 | xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, false, flags); |
| 2005 | if (!xhci->cmd_ring) | 2242 | if (!xhci->cmd_ring) |
| 2006 | goto fail; | 2243 | goto fail; |
| 2007 | xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); | 2244 | xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); |
| @@ -2032,14 +2269,16 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) · 24 unmodified lines | |||
| 2032 | * the event ring segment table (ERST). Section 4.9.3. | 2269 | * the event ring segment table (ERST). Section 4.9.3. |
| 2033 | */ | 2270 | */ |
| 2034 | xhci_dbg(xhci, "// Allocating event ring\n"); | 2271 | xhci_dbg(xhci, "// Allocating event ring\n"); |
| 2035 | xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, flags); | 2272 | xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, false, |
| 2273 | flags); | ||
| 2036 | if (!xhci->event_ring) | 2274 | if (!xhci->event_ring) |
| 2037 | goto fail; | 2275 | goto fail; |
| 2038 | if (xhci_check_trb_in_td_math(xhci, flags) < 0) | 2276 | if (xhci_check_trb_in_td_math(xhci, flags) < 0) |
| 2039 | goto fail; | 2277 | goto fail; |
| 2040 | 2278 | ||
| 2041 | xhci->erst.entries = pci_alloc_consistent(to_pci_dev(dev), | 2279 | xhci->erst.entries = dma_alloc_coherent(dev, |
| 2042 | sizeof(struct xhci_erst_entry)*ERST_NUM_SEGS, &dma); | 2280 | sizeof(struct xhci_erst_entry) * ERST_NUM_SEGS, &dma, |
| 2281 | GFP_KERNEL); | ||
| 2043 | if (!xhci->erst.entries) | 2282 | if (!xhci->erst.entries) |
| 2044 | goto fail; | 2283 | goto fail; |
| 2045 | xhci_dbg(xhci, "// Allocated event ring segment table at 0x%llx\n", | 2284 | xhci_dbg(xhci, "// Allocated event ring segment table at 0x%llx\n", |
| @@ -2102,6 +2341,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) · 56 unmodified lines | |||
| 2102 | if (xhci_setup_port_arrays(xhci, flags)) | 2341 | if (xhci_setup_port_arrays(xhci, flags)) |
| 2103 | goto fail; | 2342 | goto fail; |
| 2104 | 2343 | ||
| 2344 | INIT_LIST_HEAD(&xhci->lpm_failed_devs); | ||
| 2345 | |||
| 2105 | return 0; | 2346 | return 0; |
| 2106 | 2347 | ||
| 2107 | fail: | 2348 | fail: |
| @@ -51,61 +51,9 @@ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) · 50 unmodified lines | |||
| 51 | return 0; | 51 | return 0; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | /* called during probe() after chip reset completes */ | 54 | static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) |
| 55 | static int xhci_pci_setup(struct usb_hcd *hcd) | ||
| 56 | { | 55 | { |
| 57 | struct xhci_hcd *xhci; | 56 | struct pci_dev *pdev = to_pci_dev(dev); |
| 58 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
| 59 | int retval; | ||
| 60 | u32 temp; | ||
| 61 | |||
| 62 | hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2; | ||
| 63 | |||
| 64 | if (usb_hcd_is_primary_hcd(hcd)) { | ||
| 65 | xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); | ||
| 66 | if (!xhci) | ||
| 67 | return -ENOMEM; | ||
| 68 | *((struct xhci_hcd **) hcd->hcd_priv) = xhci; | ||
| 69 | xhci->main_hcd = hcd; | ||
| 70 | /* Mark the first roothub as being USB 2.0. | ||
| 71 | * The xHCI driver will register the USB 3.0 roothub. | ||
| 72 | */ | ||
| 73 | hcd->speed = HCD_USB2; | ||
| 74 | hcd->self.root_hub->speed = USB_SPEED_HIGH; | ||
| 75 | /* | ||
| 76 | * USB 2.0 roothub under xHCI has an integrated TT, | ||
| 77 | * (rate matching hub) as opposed to having an OHCI/UHCI | ||
| 78 | * companion controller. | ||
| 79 | */ | ||
| 80 | hcd->has_tt = 1; | ||
| 81 | } else { | ||
| 82 | /* xHCI private pointer was set in xhci_pci_probe for the second | ||
| 83 | * registered roothub. | ||
| 84 | */ | ||
| 85 | xhci = hcd_to_xhci(hcd); | ||
| 86 | temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); | ||
| 87 | if (HCC_64BIT_ADDR(temp)) { | ||
| 88 | xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); | ||
| 89 | dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)); | ||
| 90 | } else { | ||
| 91 | dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32)); | ||
| 92 | } | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | xhci->cap_regs = hcd->regs; | ||
| 97 | xhci->op_regs = hcd->regs + | ||
| 98 | HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase)); | ||
| 99 | xhci->run_regs = hcd->regs + | ||
| 100 | (xhci_readl(xhci, &xhci->cap_regs->run_regs_off) & RTSOFF_MASK); | ||
| 101 | /* Cache read-only capability registers */ | ||
| 102 | xhci->hcs_params1 = xhci_readl(xhci, &xhci->cap_regs->hcs_params1); | ||
| 103 | xhci->hcs_params2 = xhci_readl(xhci, &xhci->cap_regs->hcs_params2); | ||
| 104 | xhci->hcs_params3 = xhci_readl(xhci, &xhci->cap_regs->hcs_params3); | ||
| 105 | xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hc_capbase); | ||
| 106 | xhci->hci_version = HC_VERSION(xhci->hcc_params); | ||
| 107 | xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params); | ||
| 108 | xhci_print_registers(xhci); | ||
| 109 | 57 | ||
| 110 | /* Look for vendor-specific quirks */ | 58 | /* Look for vendor-specific quirks */ |
| 111 | if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && | 59 | if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && |
| @@ -128,6 +76,9 @@ static int xhci_pci_setup(struct usb_hcd *hcd) · 16 unmodified lines | |||
| 128 | if (pdev->vendor == PCI_VENDOR_ID_NEC) | 76 | if (pdev->vendor == PCI_VENDOR_ID_NEC) |
| 129 | xhci->quirks |= XHCI_NEC_HOST; | 77 | xhci->quirks |= XHCI_NEC_HOST; |
| 130 | 78 | ||
| 79 | if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96) | ||
| 80 | xhci->quirks |= XHCI_AMD_0x96_HOST; | ||
| 81 | |||
| 131 | /* AMD PLL quirk */ | 82 | /* AMD PLL quirk */ |
| 132 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) | 83 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) |
| 133 | xhci->quirks |= XHCI_AMD_PLL_FIX; | 84 | xhci->quirks |= XHCI_AMD_PLL_FIX; |
| @@ -136,39 +87,29 @@ static int xhci_pci_setup(struct usb_hcd *hcd) · 2 unmodified lines | |||
| 136 | xhci->quirks |= XHCI_SPURIOUS_SUCCESS; | 87 | xhci->quirks |= XHCI_SPURIOUS_SUCCESS; |
| 137 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; | 88 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; |
| 138 | xhci->limit_active_eps = 64; | 89 | xhci->limit_active_eps = 64; |
| 90 | xhci->quirks |= XHCI_SW_BW_CHECKING; | ||
| 139 | } | 91 | } |
| 140 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 92 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
| 141 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { | 93 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { |
| 142 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 94 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
| 143 | xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); | 95 | xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); |
| 144 | } | 96 | } |
| 97 | } | ||
| 145 | 98 | ||
| 146 | /* Make sure the HC is halted. */ | 99 | /* called during probe() after chip reset completes */ |
| 147 | retval = xhci_halt(xhci); | 100 | static int xhci_pci_setup(struct usb_hcd *hcd) |
| 148 | if (retval) | 101 | { |
| 149 | goto error; | 102 | struct xhci_hcd *xhci; |
| 103 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
| 104 | int retval; | ||
| 150 | 105 | ||
| 151 | xhci_dbg(xhci, "Resetting HCD\n"); | 106 | retval = xhci_gen_setup(hcd, xhci_pci_quirks); |
| 152 | /* Reset the internal HC memory state and registers. */ | ||
| 153 | retval = xhci_reset(xhci); | ||
| 154 | if (retval) | 107 | if (retval) |
| 155 | goto error; | 108 | return retval; |
| 156 | xhci_dbg(xhci, "Reset complete\n"); | ||
| 157 | |||
| 158 | temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); | ||
| 159 | if (HCC_64BIT_ADDR(temp)) { | ||
| 160 | xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); | ||
| 161 | dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)); | ||
| 162 | } else { | ||
| 163 | dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32)); | ||
| 164 | } | ||
| 165 | 109 | ||
| 166 | xhci_dbg(xhci, "Calling HCD init\n"); | 110 | xhci = hcd_to_xhci(hcd); |
| 167 | /* Initialize HCD and host controller data structures. */ | 111 | if (!usb_hcd_is_primary_hcd(hcd)) |
| 168 | retval = xhci_init(hcd); | 112 | return 0; |
| 169 | if (retval) | ||
| 170 | goto error; | ||
| 171 | xhci_dbg(xhci, "Called HCD init\n"); | ||
| 172 | 113 | ||
| 173 | pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn); | 114 | pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn); |
| 174 | xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn); | 115 | xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn); |
| @@ -178,7 +119,6 @@ static int xhci_pci_setup(struct usb_hcd *hcd) · 3 unmodified lines | |||
| 178 | if (!retval) | 119 | if (!retval) |
| 179 | return retval; | 120 | return retval; |
| 180 | 121 | ||
| 181 | error: | ||
| 182 | kfree(xhci); | 122 | kfree(xhci); |
| 183 | return retval; | 123 | return retval; |
| 184 | } | 124 | } |
| @@ -222,7 +162,7 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 37 unmodified lines | |||
| 222 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; | 162 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; |
| 223 | 163 | ||
| 224 | retval = usb_add_hcd(xhci->shared_hcd, dev->irq, | 164 | retval = usb_add_hcd(xhci->shared_hcd, dev->irq, |
| 225 | IRQF_DISABLED | IRQF_SHARED); | 165 | IRQF_SHARED); |
| 226 | if (retval) | 166 | if (retval) |
| 227 | goto put_usb3_hcd; | 167 | goto put_usb3_hcd; |
| 228 | /* Roothub already marked as USB 3.0 speed */ | 168 | /* Roothub already marked as USB 3.0 speed */ |
| @@ -344,6 +284,11 @@ static const struct hc_driver xhci_pci_hc_driver = { · 115 unmodified lines | |||
| 344 | .hub_status_data = xhci_hub_status_data, | 284 | .hub_status_data = xhci_hub_status_data, |
| 345 | .bus_suspend = xhci_bus_suspend, | 285 | .bus_suspend = xhci_bus_suspend, |
| 346 | .bus_resume = xhci_bus_resume, | 286 | .bus_resume = xhci_bus_resume, |
| 287 | /* | ||
| 288 | * call back when device connected and addressed | ||
| 289 | */ | ||
| 290 | .update_device = xhci_update_device, | ||
| 291 | .set_usb2_hw_lpm = xhci_set_usb2_hardware_lpm, | ||
| 347 | }; | 292 | }; |
| 348 | 293 | ||
| 349 | /*-------------------------------------------------------------------------*/ | 294 | /*-------------------------------------------------------------------------*/ |
| @@ -375,12 +320,12 @@ static struct pci_driver xhci_pci_driver = { · 25 unmodified lines | |||
| 375 | #endif | 320 | #endif |
| 376 | }; | 321 | }; |
| 377 | 322 | ||
| 378 | int xhci_register_pci(void) | 323 | int __init xhci_register_pci(void) |
| 379 | { | 324 | { |
| 380 | return pci_register_driver(&xhci_pci_driver); | 325 | return pci_register_driver(&xhci_pci_driver); |
| 381 | } | 326 | } |
| 382 | 327 | ||
| 383 | void xhci_unregister_pci(void) | 328 | void __exit xhci_unregister_pci(void) |
| 384 | { | 329 | { |
| 385 | pci_unregister_driver(&xhci_pci_driver); | 330 | pci_unregister_driver(&xhci_pci_driver); |
| 386 | } | 331 | } |
| @@ -185,7 +185,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer · 184 unmodified lines | |||
| 185 | * prepare_transfer()? | 185 | * prepare_transfer()? |
| 186 | */ | 186 | */ |
| 187 | static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, | 187 | static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, |
| 188 | bool consumer, bool more_trbs_coming) | 188 | bool consumer, bool more_trbs_coming, bool isoc) |
| 189 | { | 189 | { |
| 190 | u32 chain; | 190 | u32 chain; |
| 191 | union xhci_trb *next; | 191 | union xhci_trb *next; |
| @@ -212,11 +212,13 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, · 20 unmodified lines | |||
| 212 | if (!chain && !more_trbs_coming) | 212 | if (!chain && !more_trbs_coming) |
| 213 | break; | 213 | break; |
| 214 | 214 | ||
| 215 | /* If we're not dealing with 0.95 hardware, | 215 | /* If we're not dealing with 0.95 hardware or |
| 216 | * isoc rings on AMD 0.96 host, | ||
| 216 | * carry over the chain bit of the previous TRB | 217 | * carry over the chain bit of the previous TRB |
| 217 | * (which may mean the chain bit is cleared). | 218 | * (which may mean the chain bit is cleared). |
| 218 | */ | 219 | */ |
| 219 | if (!xhci_link_trb_quirk(xhci)) { | 220 | if (!(isoc && (xhci->quirks & XHCI_AMD_0x96_HOST)) |
| 221 | && !xhci_link_trb_quirk(xhci)) { | ||
| 220 | next->link.control &= | 222 | next->link.control &= |
| 221 | cpu_to_le32(~TRB_CHAIN); | 223 | cpu_to_le32(~TRB_CHAIN); |
| 222 | next->link.control |= | 224 | next->link.control |= |
| @@ -1329,10 +1331,8 @@ static void handle_port_status(struct xhci_hcd *xhci, · 1106 unmodified lines | |||
| 1329 | 1331 | ||
| 1330 | if (DEV_SUPERSPEED(temp)) { | 1332 | if (DEV_SUPERSPEED(temp)) { |
| 1331 | xhci_dbg(xhci, "resume SS port %d\n", port_id); | 1333 | xhci_dbg(xhci, "resume SS port %d\n", port_id); |
| 1332 | temp = xhci_port_state_to_neutral(temp); | 1334 | xhci_set_link_state(xhci, port_array, faked_port_index, |
| 1333 | temp &= ~PORT_PLS_MASK; | 1335 | XDEV_U0); |
| 1334 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
| 1335 | xhci_writel(xhci, temp, port_array[faked_port_index]); | ||
| 1336 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | 1336 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, |
| 1337 | faked_port_index); | 1337 | faked_port_index); |
| 1338 | if (!slot_id) { | 1338 | if (!slot_id) { |
| @@ -1342,10 +1342,8 @@ static void handle_port_status(struct xhci_hcd *xhci, · 3 unmodified lines | |||
| 1342 | xhci_ring_device(xhci, slot_id); | 1342 | xhci_ring_device(xhci, slot_id); |
| 1343 | xhci_dbg(xhci, "resume SS port %d finished\n", port_id); | 1343 | xhci_dbg(xhci, "resume SS port %d finished\n", port_id); |
| 1344 | /* Clear PORT_PLC */ | 1344 | /* Clear PORT_PLC */ |
| 1345 | temp = xhci_readl(xhci, port_array[faked_port_index]); | 1345 | xhci_test_and_clear_bit(xhci, port_array, |
| 1346 | temp = xhci_port_state_to_neutral(temp); | 1346 | faked_port_index, PORT_PLC); |
| 1347 | temp |= PORT_PLC; | ||
| 1348 | xhci_writel(xhci, temp, port_array[faked_port_index]); | ||
| 1349 | } else { | 1347 | } else { |
| 1350 | xhci_dbg(xhci, "resume HS port %d\n", port_id); | 1348 | xhci_dbg(xhci, "resume HS port %d\n", port_id); |
| 1351 | bus_state->resume_done[faked_port_index] = jiffies + | 1349 | bus_state->resume_done[faked_port_index] = jiffies + |
| @@ -1356,6 +1354,10 @@ static void handle_port_status(struct xhci_hcd *xhci, · 4 unmodified lines | |||
| 1356 | } | 1354 | } |
| 1357 | } | 1355 | } |
| 1358 | 1356 | ||
| 1357 | if (hcd->speed != HCD_USB3) | ||
| 1358 | xhci_test_and_clear_bit(xhci, port_array, faked_port_index, | ||
| 1359 | PORT_PLC); | ||
| 1360 | |||
| 1359 | cleanup: | 1361 | cleanup: |
| 1360 | /* Update event ring dequeue pointer before dropping the lock */ | 1362 | /* Update event ring dequeue pointer before dropping the lock */ |
| 1361 | inc_deq(xhci, xhci->event_ring, true); | 1363 | inc_deq(xhci, xhci->event_ring, true); |
| @@ -2192,7 +2194,8 @@ cleanup: · 830 unmodified lines | |||
| 2192 | if ((urb->actual_length != urb->transfer_buffer_length && | 2194 | if ((urb->actual_length != urb->transfer_buffer_length && |
| 2193 | (urb->transfer_flags & | 2195 | (urb->transfer_flags & |
218 more lines aren’t shown here.
This diff is large: its 1341 lines aren’t shown here.
This diff is large: its 343 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 304 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 329 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 340 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 279 lines aren’t shown here.
This diff is large: its 1313 lines aren’t shown here.
This diff is large: its 401 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 212 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 293 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.