]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
dwc_otg: fix summarize urb->actual_length for isochronous transfers
[mirror_ubuntu-artful-kernel.git] / drivers / usb / host / dwc_otg / dwc_otg_hcd_linux.c
CommitLineData
ccd93fb3 1
2/* ==========================================================================
3 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $
4 * $Revision: #20 $
5 * $Date: 2011/10/26 $
6 * $Change: 1872981 $
7 *
8 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
9 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
10 * otherwise expressly agreed to in writing between Synopsys and you.
11 *
12 * The Software IS NOT an item of Licensed Software or Licensed Product under
13 * any End User Software License Agreement or Agreement for Licensed Product
14 * with Synopsys or any supplement thereto. You are permitted to use and
15 * redistribute this Software in source and binary forms, with or without
16 * modification, provided that redistributions of source code must retain this
17 * notice. You may not view, use, disclose, copy or distribute this file or
18 * any information contained herein except pursuant to this license grant from
19 * Synopsys. If you do not agree with this notice, including the disclaimer
20 * below, then you are not authorized to use the Software.
21 *
22 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 * DAMAGE.
33 * ========================================================================== */
34#ifndef DWC_DEVICE_ONLY
35
36/**
37 * @file
38 *
39 * This file contains the implementation of the HCD. In Linux, the HCD
40 * implements the hc_driver API.
41 */
42#include <linux/kernel.h>
43#include <linux/module.h>
44#include <linux/moduleparam.h>
45#include <linux/init.h>
46#include <linux/device.h>
47#include <linux/errno.h>
48#include <linux/list.h>
49#include <linux/interrupt.h>
50#include <linux/string.h>
51#include <linux/dma-mapping.h>
52#include <linux/version.h>
53#include <asm/io.h>
a1465ff0 54#ifdef CONFIG_ARM
ccd93fb3 55#include <asm/fiq.h>
a1465ff0 56#endif
ccd93fb3 57#include <linux/usb.h>
58#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
59#include <../drivers/usb/core/hcd.h>
60#else
61#include <linux/usb/hcd.h>
62#endif
63#include <asm/bug.h>
64
65#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
66#define USB_URB_EP_LINKING 1
67#else
68#define USB_URB_EP_LINKING 0
69#endif
70
71#include "dwc_otg_hcd_if.h"
72#include "dwc_otg_dbg.h"
73#include "dwc_otg_driver.h"
74#include "dwc_otg_hcd.h"
75
a1465ff0
MZ
76#ifndef __virt_to_bus
77#define __virt_to_bus __virt_to_phys
78#define __bus_to_virt __phys_to_virt
79#define __pfn_to_bus(x) __pfn_to_phys(x)
80#define __bus_to_pfn(x) __phys_to_pfn(x)
81#endif
82
ccd93fb3 83extern unsigned char _dwc_otg_fiq_stub, _dwc_otg_fiq_stub_end;
84
85/**
86 * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
87 * qualified with its direction (possible 32 endpoints per device).
88 */
89#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
90 ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
91
92static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
93
94extern bool fiq_enable;
95
96/** @name Linux HC Driver API Functions */
97/** @{ */
98/* manage i/o requests, device state */
99static int dwc_otg_urb_enqueue(struct usb_hcd *hcd,
100#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
101 struct usb_host_endpoint *ep,
102#endif
103 struct urb *urb, gfp_t mem_flags);
104
105#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
106#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
107static int dwc_otg_urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
108#endif
109#else /* kernels at or post 2.6.30 */
110static int dwc_otg_urb_dequeue(struct usb_hcd *hcd,
111 struct urb *urb, int status);
112#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) */
113
114static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
115#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
116static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
117#endif
118static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
119extern int hcd_start(struct usb_hcd *hcd);
120extern void hcd_stop(struct usb_hcd *hcd);
121static int get_frame_number(struct usb_hcd *hcd);
122extern int hub_status_data(struct usb_hcd *hcd, char *buf);
123extern int hub_control(struct usb_hcd *hcd,
124 u16 typeReq,
125 u16 wValue, u16 wIndex, char *buf, u16 wLength);
126
127struct wrapper_priv_data {
128 dwc_otg_hcd_t *dwc_otg_hcd;
129};
130
131/** @} */
132
133static struct hc_driver dwc_otg_hc_driver = {
134
135 .description = dwc_otg_hcd_name,
136 .product_desc = "DWC OTG Controller",
137 .hcd_priv_size = sizeof(struct wrapper_priv_data),
138
139 .irq = dwc_otg_hcd_irq,
140
141 .flags = HCD_MEMORY | HCD_USB2,
142
143 //.reset =
144 .start = hcd_start,
145 //.suspend =
146 //.resume =
147 .stop = hcd_stop,
148
149 .urb_enqueue = dwc_otg_urb_enqueue,
150 .urb_dequeue = dwc_otg_urb_dequeue,
151 .endpoint_disable = endpoint_disable,
152#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
153 .endpoint_reset = endpoint_reset,
154#endif
155 .get_frame_number = get_frame_number,
156
157 .hub_status_data = hub_status_data,
158 .hub_control = hub_control,
159 //.bus_suspend =
160 //.bus_resume =
161};
162
163/** Gets the dwc_otg_hcd from a struct usb_hcd */
164static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
165{
166 struct wrapper_priv_data *p;
167 p = (struct wrapper_priv_data *)(hcd->hcd_priv);
168 return p->dwc_otg_hcd;
169}
170
171/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
172static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t * dwc_otg_hcd)
173{
174 return dwc_otg_hcd_get_priv_data(dwc_otg_hcd);
175}
176
177/** Gets the usb_host_endpoint associated with an URB. */
178inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
179{
180 struct usb_device *dev = urb->dev;
181 int ep_num = usb_pipeendpoint(urb->pipe);
182
183 if (usb_pipein(urb->pipe))
184 return dev->ep_in[ep_num];
185 else
186 return dev->ep_out[ep_num];
187}
188
189static int _disconnect(dwc_otg_hcd_t * hcd)
190{
191 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
192
193 usb_hcd->self.is_b_host = 0;
194 return 0;
195}
196
197static int _start(dwc_otg_hcd_t * hcd)
198{
199 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
200
201 usb_hcd->self.is_b_host = dwc_otg_hcd_is_b_host(hcd);
202 hcd_start(usb_hcd);
203
204 return 0;
205}
206
207static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr,
208 uint32_t * port_addr)
209{
210 struct urb *urb = (struct urb *)urb_handle;
211 struct usb_bus *bus;
212#if 1 //GRAYG - temporary
213 if (NULL == urb_handle)
214 DWC_ERROR("**** %s - NULL URB handle\n", __func__);//GRAYG
215 if (NULL == urb->dev)
216 DWC_ERROR("**** %s - URB has no device\n", __func__);//GRAYG
217 if (NULL == port_addr)
218 DWC_ERROR("**** %s - NULL port_address\n", __func__);//GRAYG
219#endif
220 if (urb->dev->tt) {
221 if (NULL == urb->dev->tt->hub) {
222 DWC_ERROR("**** %s - (URB's transactor has no TT - giving no hub)\n",
223 __func__); //GRAYG
224 //*hub_addr = (u8)usb_pipedevice(urb->pipe); //GRAYG
225 *hub_addr = 0; //GRAYG
226 // we probably shouldn't have a transaction translator if
227 // there's no associated hub?
228 } else {
229 bus = hcd_to_bus(dwc_otg_hcd_to_hcd(hcd));
230 if (urb->dev->tt->hub == bus->root_hub)
231 *hub_addr = 0;
232 else
233 *hub_addr = urb->dev->tt->hub->devnum;
234 }
235 *port_addr = urb->dev->tt->multi ? urb->dev->ttport : 1;
236 } else {
237 *hub_addr = 0;
238 *port_addr = urb->dev->ttport;
239 }
240 return 0;
241}
242
243static int _speed(dwc_otg_hcd_t * hcd, void *urb_handle)
244{
245 struct urb *urb = (struct urb *)urb_handle;
246 return urb->dev->speed;
247}
248
249static int _get_b_hnp_enable(dwc_otg_hcd_t * hcd)
250{
251 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
252 return usb_hcd->self.b_hnp_enable;
253}
254
255static void allocate_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
256 struct urb *urb)
257{
258 hcd_to_bus(hcd)->bandwidth_allocated += bw / urb->interval;
259 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
260 hcd_to_bus(hcd)->bandwidth_isoc_reqs++;
261 } else {
262 hcd_to_bus(hcd)->bandwidth_int_reqs++;
263 }
264}
265
266static void free_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
267 struct urb *urb)
268{
269 hcd_to_bus(hcd)->bandwidth_allocated -= bw / urb->interval;
270 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
271 hcd_to_bus(hcd)->bandwidth_isoc_reqs--;
272 } else {
273 hcd_to_bus(hcd)->bandwidth_int_reqs--;
274 }
275}
276
277/**
278 * Sets the final status of an URB and returns it to the device driver. Any
279 * required cleanup of the URB is performed. The HCD lock should be held on
280 * entry.
281 */
282static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
283 dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
284{
285 struct urb *urb = (struct urb *)urb_handle;
286 urb_tq_entry_t *new_entry;
287 int rc = 0;
288 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
289 DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n",
290 __func__, urb, usb_pipedevice(urb->pipe),
291 usb_pipeendpoint(urb->pipe),
292 usb_pipein(urb->pipe) ? "IN" : "OUT", status);
293 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
294 int i;
295 for (i = 0; i < urb->number_of_packets; i++) {
296 DWC_PRINTF(" ISO Desc %d status: %d\n",
297 i, urb->iso_frame_desc[i].status);
298 }
299 }
300 }
301 new_entry = DWC_ALLOC_ATOMIC(sizeof(urb_tq_entry_t));
302 urb->actual_length = dwc_otg_hcd_urb_get_actual_length(dwc_otg_urb);
303 /* Convert status value. */
304 switch (status) {
305 case -DWC_E_PROTOCOL:
306 status = -EPROTO;
307 break;
308 case -DWC_E_IN_PROGRESS:
309 status = -EINPROGRESS;
310 break;
311 case -DWC_E_PIPE:
312 status = -EPIPE;
313 break;
314 case -DWC_E_IO:
315 status = -EIO;
316 break;
317 case -DWC_E_TIMEOUT:
318 status = -ETIMEDOUT;
319 break;
320 case -DWC_E_OVERFLOW:
321 status = -EOVERFLOW;
322 break;
323 case -DWC_E_SHUTDOWN:
324 status = -ESHUTDOWN;
325 break;
326 default:
327 if (status) {
328 DWC_PRINTF("Uknown urb status %d\n", status);
329
330 }
331 }
332
333 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
334 int i;
335
336 urb->error_count = dwc_otg_hcd_urb_get_error_count(dwc_otg_urb);
a44eea26 337 urb->actual_length = 0;
ccd93fb3 338 for (i = 0; i < urb->number_of_packets; ++i) {
339 urb->iso_frame_desc[i].actual_length =
340 dwc_otg_hcd_urb_get_iso_desc_actual_length
341 (dwc_otg_urb, i);
a44eea26 342 urb->actual_length += urb->iso_frame_desc[i].actual_length;
ccd93fb3 343 urb->iso_frame_desc[i].status =
344 dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_urb, i);
345 }
346 }
347
348 urb->status = status;
349 urb->hcpriv = NULL;
350 if (!status) {
351 if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
352 (urb->actual_length < urb->transfer_buffer_length)) {
353 urb->status = -EREMOTEIO;
354 }
355 }
356
357 if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ||
358 (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
359 struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
360 if (ep) {
361 free_bus_bandwidth(dwc_otg_hcd_to_hcd(hcd),
362 dwc_otg_hcd_get_ep_bandwidth(hcd,
363 ep->hcpriv),
364 urb);
365 }
366 }
367 DWC_FREE(dwc_otg_urb);
368 if (!new_entry) {
369 DWC_ERROR("dwc_otg_hcd: complete: cannot allocate URB TQ entry\n");
370 urb->status = -EPROTO;
371 /* don't schedule the tasklet -
372 * directly return the packet here with error. */
373#if USB_URB_EP_LINKING
374 usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
375#endif
376#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
377 usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
378#else
379 usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, urb->status);
380#endif
381 } else {
382 new_entry->urb = urb;
383#if USB_URB_EP_LINKING
384 rc = usb_hcd_check_unlink_urb(dwc_otg_hcd_to_hcd(hcd), urb, urb->status);
385 if(0 == rc) {
386 usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
387 }
388#endif
389 if(0 == rc) {
390 DWC_TAILQ_INSERT_TAIL(&hcd->completed_urb_list, new_entry,
391 urb_tq_entries);
392 DWC_TASK_HI_SCHEDULE(hcd->completion_tasklet);
393 }
394 }
395 return 0;
396}
397
398static struct dwc_otg_hcd_function_ops hcd_fops = {
399 .start = _start,
400 .disconnect = _disconnect,
401 .hub_info = _hub_info,
402 .speed = _speed,
403 .complete = _complete,
404 .get_b_hnp_enable = _get_b_hnp_enable,
405};
406
a1465ff0
MZ
407#ifdef CONFIG_ARM64
408
409static int simfiq_irq = -1;
410
411void local_fiq_enable(void)
412{
413 if (simfiq_irq >= 0)
414 enable_irq(simfiq_irq);
415}
416
417void local_fiq_disable(void)
418{
419 if (simfiq_irq >= 0)
420 disable_irq(simfiq_irq);
421}
422
423irqreturn_t fiq_irq_handler(int irq, void *dev_id)
424{
425 dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *)dev_id;
426
427 if (fiq_fsm_enable)
428 dwc_otg_fiq_fsm(dwc_otg_hcd->fiq_state, dwc_otg_hcd->core_if->core_params->host_channels);
429 else
430 dwc_otg_fiq_nop(dwc_otg_hcd->fiq_state);
431
432 return IRQ_HANDLED;
433}
434
435#else
ccd93fb3 436static struct fiq_handler fh = {
437 .name = "usb_fiq",
438};
439
a1465ff0
MZ
440#endif
441
ccd93fb3 442static void hcd_init_fiq(void *cookie)
443{
444 dwc_otg_device_t *otg_dev = cookie;
445 dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
a1465ff0
MZ
446#ifdef CONFIG_ARM64
447 int retval = 0;
448 int irq;
449#else
ccd93fb3 450 struct pt_regs regs;
451 int irq;
452
453 if (claim_fiq(&fh)) {
454 DWC_ERROR("Can't claim FIQ");
455 BUG();
456 }
457 DWC_WARN("FIQ on core %d at 0x%08x",
458 smp_processor_id(),
459 (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
460 DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
461 set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
462 memset(&regs,0,sizeof(regs));
463
464 regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
465 if (fiq_fsm_enable) {
466 regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
467 //regs.ARM_r10 = dwc_otg_hcd->dma;
468 regs.ARM_fp = (long) dwc_otg_fiq_fsm;
469 } else {
470 regs.ARM_fp = (long) dwc_otg_fiq_nop;
471 }
472
473 regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
474
475// __show_regs(&regs);
476 set_fiq_regs(&regs);
a1465ff0 477#endif
ccd93fb3 478
479 //Set the mphi periph to the required registers
480 dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base;
481 dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c;
482 dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28;
483 dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c;
484 dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
485 dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
486 DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
487 //Enable mphi peripheral
488 writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
489#ifdef DEBUG
490 if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
491 DWC_WARN("MPHI periph has been enabled");
492 else
493 DWC_WARN("MPHI periph has NOT been enabled");
494#endif
495 // Enable FIQ interrupt from USB peripheral
a1465ff0
MZ
496#ifdef CONFIG_ARM64
497 irq = platform_get_irq(otg_dev->os_dep.platformdev, 1);
498
499 if (irq < 0) {
500 DWC_ERROR("Can't get SIM-FIQ irq");
501 return;
502 }
503
504 retval = request_irq(irq, fiq_irq_handler, 0, "dwc_otg_sim-fiq", dwc_otg_hcd);
505
506 if (retval < 0) {
507 DWC_ERROR("Unable to request SIM-FIQ irq\n");
508 return;
509 }
510
511 simfiq_irq = irq;
512#else
ccd93fb3 513#ifdef CONFIG_MULTI_IRQ_HANDLER
514 irq = platform_get_irq(otg_dev->os_dep.platformdev, 1);
515#else
516 irq = INTERRUPT_VC_USB;
517#endif
518 if (irq < 0) {
519 DWC_ERROR("Can't get FIQ irq");
520 return;
521 }
522 enable_fiq(irq);
523 local_fiq_enable();
a1465ff0
MZ
524#endif
525
ccd93fb3 526}
527
528/**
529 * Initializes the HCD. This function allocates memory for and initializes the
530 * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
531 * USB bus with the core and calls the hc_driver->start() function. It returns
532 * a negative error on failure.
533 */
534int hcd_init(dwc_bus_dev_t *_dev)
535{
536 struct usb_hcd *hcd = NULL;
537 dwc_otg_hcd_t *dwc_otg_hcd = NULL;
538 dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
539 int retval = 0;
540 u64 dmamask;
541
542 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev);
543
544 /* Set device flags indicating whether the HCD supports DMA. */
545 if (dwc_otg_is_dma_enable(otg_dev->core_if))
546 dmamask = DMA_BIT_MASK(32);
547 else
548 dmamask = 0;
549
550#if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE)
551 dma_set_mask(&_dev->dev, dmamask);
552 dma_set_coherent_mask(&_dev->dev, dmamask);
553#elif defined(PCI_INTERFACE)
554 pci_set_dma_mask(_dev, dmamask);
555 pci_set_consistent_dma_mask(_dev, dmamask);
556#endif
557
558 /*
559 * Allocate memory for the base HCD plus the DWC OTG HCD.
560 * Initialize the base HCD.
561 */
562#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
563 hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, _dev->dev.bus_id);
564#else
565 hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, dev_name(&_dev->dev));
566 hcd->has_tt = 1;
567// hcd->uses_new_polling = 1;
568// hcd->poll_rh = 0;
569#endif
570 if (!hcd) {
571 retval = -ENOMEM;
572 goto error1;
573 }
574
575 hcd->regs = otg_dev->os_dep.base;
576
577
578 /* Initialize the DWC OTG HCD. */
579 dwc_otg_hcd = dwc_otg_hcd_alloc_hcd();
580 if (!dwc_otg_hcd) {
581 goto error2;
582 }
583 ((struct wrapper_priv_data *)(hcd->hcd_priv))->dwc_otg_hcd =
584 dwc_otg_hcd;
585 otg_dev->hcd = dwc_otg_hcd;
586 otg_dev->hcd->otg_dev = otg_dev;
587
a1465ff0
MZ
588#ifdef CONFIG_ARM64
589 if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if))
590 goto error2;
591
592 if (fiq_enable)
593 hcd_init_fiq(otg_dev);
594#else
ccd93fb3 595 if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if)) {
596 goto error2;
597 }
598
599 if (fiq_enable) {
600 if (num_online_cpus() > 1) {
601 /* bcm2709: can run the FIQ on a separate core to IRQs */
602 smp_call_function_single(1, hcd_init_fiq, otg_dev, 1);
603 } else {
604 smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
605 }
606 }
a1465ff0 607#endif
ccd93fb3 608
609 hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
610#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) //don't support for LM(with 2.6.20.1 kernel)
611#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) //version field absent later
612 hcd->self.otg_version = dwc_otg_get_otg_version(otg_dev->core_if);
613#endif
614 /* Don't support SG list at this point */
615 hcd->self.sg_tablesize = 0;
616#endif
617 /*
618 * Finish generic HCD initialization and start the HCD. This function
619 * allocates the DMA buffer pool, registers the USB bus, requests the
620 * IRQ line, and calls hcd_start method.
621 */
622#ifdef PLATFORM_INTERFACE
623 retval = usb_add_hcd(hcd, platform_get_irq(_dev, fiq_enable ? 0 : 1), IRQF_SHARED);
624#else
625 retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED);
626#endif
627 if (retval < 0) {
628 goto error2;
629 }
630
631 dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
632 return 0;
633
634error2:
635 usb_put_hcd(hcd);
636error1:
637 return retval;
638}
639
640/**
641 * Removes the HCD.
642 * Frees memory and resources associated with the HCD and deregisters the bus.
643 */
644void hcd_remove(dwc_bus_dev_t *_dev)
645{
646 dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
647 dwc_otg_hcd_t *dwc_otg_hcd;
648 struct usb_hcd *hcd;
649
650 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE otg_dev=%p\n", otg_dev);
651
652 if (!otg_dev) {
653 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
654 return;
655 }
656
657 dwc_otg_hcd = otg_dev->hcd;
658
659 if (!dwc_otg_hcd) {
660 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
661 return;
662 }
663
664 hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
665
666 if (!hcd) {
667 DWC_DEBUGPL(DBG_ANY,
668 "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n",
669 __func__);
670 return;
671 }
672 usb_remove_hcd(hcd);
673 dwc_otg_hcd_set_priv_data(dwc_otg_hcd, NULL);
674 dwc_otg_hcd_remove(dwc_otg_hcd);
675 usb_put_hcd(hcd);
676}
677
678/* =========================================================================
679 * Linux HC Driver Functions
680 * ========================================================================= */
681
682/** Initializes the DWC_otg controller and its root hub and prepares it for host
683 * mode operation. Activates the root port. Returns 0 on success and a negative
684 * error code on failure. */
685int hcd_start(struct usb_hcd *hcd)
686{
687 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
688 struct usb_bus *bus;
689
690 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
691 bus = hcd_to_bus(hcd);
692
693 hcd->state = HC_STATE_RUNNING;
694 if (dwc_otg_hcd_start(dwc_otg_hcd, &hcd_fops)) {
695 return 0;
696 }
697
698 /* Initialize and connect root hub if one is not already attached */
699 if (bus->root_hub) {
700 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
701 /* Inform the HUB driver to resume. */
702 usb_hcd_resume_root_hub(hcd);
703 }
704
705 return 0;
706}
707
708/**
709 * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
710 * stopped.
711 */
712void hcd_stop(struct usb_hcd *hcd)
713{
714 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
715
716 dwc_otg_hcd_stop(dwc_otg_hcd);
717}
718
719/** Returns the current frame number. */
720static int get_frame_number(struct usb_hcd *hcd)
721{
722 hprt0_data_t hprt0;
723 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
724 hprt0.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0);
725 if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
726 return dwc_otg_hcd_get_frame_number(dwc_otg_hcd) >> 3;
727 else
728 return dwc_otg_hcd_get_frame_number(dwc_otg_hcd);
729}
730
731#ifdef DEBUG
732static void dump_urb_info(struct urb *urb, char *fn_name)
733{
734 DWC_PRINTF("%s, urb %p\n", fn_name, urb);
735 DWC_PRINTF(" Device address: %d\n", usb_pipedevice(urb->pipe));
736 DWC_PRINTF(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
737 (usb_pipein(urb->pipe) ? "IN" : "OUT"));
738 DWC_PRINTF(" Endpoint type: %s\n", ( {
739 char *pipetype;
740 switch (usb_pipetype(urb->pipe)) {
741case PIPE_CONTROL:
742pipetype = "CONTROL"; break; case PIPE_BULK:
743pipetype = "BULK"; break; case PIPE_INTERRUPT:
744pipetype = "INTERRUPT"; break; case PIPE_ISOCHRONOUS:
745pipetype = "ISOCHRONOUS"; break; default:
746 pipetype = "UNKNOWN"; break;};
747 pipetype;}
748 )) ;
749 DWC_PRINTF(" Speed: %s\n", ( {
750 char *speed; switch (urb->dev->speed) {
751case USB_SPEED_HIGH:
752speed = "HIGH"; break; case USB_SPEED_FULL:
753speed = "FULL"; break; case USB_SPEED_LOW:
754speed = "LOW"; break; default:
755 speed = "UNKNOWN"; break;};
756 speed;}
757 )) ;
758 DWC_PRINTF(" Max packet size: %d\n",
759 usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
760 DWC_PRINTF(" Data buffer length: %d\n", urb->transfer_buffer_length);
761 DWC_PRINTF(" Transfer buffer: %p, Transfer DMA: %p\n",
762 urb->transfer_buffer, (void *)urb->transfer_dma);
763 DWC_PRINTF(" Setup buffer: %p, Setup DMA: %p\n",
764 urb->setup_packet, (void *)urb->setup_dma);
765 DWC_PRINTF(" Interval: %d\n", urb->interval);
766 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
767 int i;
768 for (i = 0; i < urb->number_of_packets; i++) {
769 DWC_PRINTF(" ISO Desc %d:\n", i);
770 DWC_PRINTF(" offset: %d, length %d\n",
771 urb->iso_frame_desc[i].offset,
772 urb->iso_frame_desc[i].length);
773 }
774 }
775}
776#endif
777
778/** Starts processing a USB transfer request specified by a USB Request Block
779 * (URB). mem_flags indicates the type of memory allocation to use while
780 * processing this URB. */
781static int dwc_otg_urb_enqueue(struct usb_hcd *hcd,
782#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
783 struct usb_host_endpoint *ep,
784#endif
785 struct urb *urb, gfp_t mem_flags)
786{
787 int retval = 0;
788#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
789 struct usb_host_endpoint *ep = urb->ep;
790#endif
791 dwc_irqflags_t irqflags;
792 void **ref_ep_hcpriv = &ep->hcpriv;
793 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
794 dwc_otg_hcd_urb_t *dwc_otg_urb;
795 int i;
796 int alloc_bandwidth = 0;
797 uint8_t ep_type = 0;
798 uint32_t flags = 0;
799 void *buf;
800
801#ifdef DEBUG
802 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
803 dump_urb_info(urb, "dwc_otg_urb_enqueue");
804 }
805#endif
806
807 if (!urb->transfer_buffer && urb->transfer_buffer_length)
808 return -EINVAL;
809
810 if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
811 || (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
812 if (!dwc_otg_hcd_is_bandwidth_allocated
813 (dwc_otg_hcd, ref_ep_hcpriv)) {
814 alloc_bandwidth = 1;
815 }
816 }
817
818 switch (usb_pipetype(urb->pipe)) {
819 case PIPE_CONTROL:
820 ep_type = USB_ENDPOINT_XFER_CONTROL;
821 break;
822 case PIPE_ISOCHRONOUS:
823 ep_type = USB_ENDPOINT_XFER_ISOC;
824 break;
825 case PIPE_BULK:
826 ep_type = USB_ENDPOINT_XFER_BULK;
827 break;
828 case PIPE_INTERRUPT:
829 ep_type = USB_ENDPOINT_XFER_INT;
830 break;
831 default:
832 DWC_WARN("Wrong EP type - %d\n", usb_pipetype(urb->pipe));
833 }
834
835 /* # of packets is often 0 - do we really need to call this then? */
836 dwc_otg_urb = dwc_otg_hcd_urb_alloc(dwc_otg_hcd,
837 urb->number_of_packets,
838 mem_flags == GFP_ATOMIC ? 1 : 0);
839
840 if(dwc_otg_urb == NULL)
841 return -ENOMEM;
842
843 if (!dwc_otg_urb && urb->number_of_packets)
844 return -ENOMEM;
845
846 dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_urb, usb_pipedevice(urb->pipe),
847 usb_pipeendpoint(urb->pipe), ep_type,
848 usb_pipein(urb->pipe),
849 usb_maxpacket(urb->dev, urb->pipe,
850 !(usb_pipein(urb->pipe))));
851
852 buf = urb->transfer_buffer;
853 if (hcd->self.uses_dma && !buf && urb->transfer_buffer_length) {
854 /*
855 * Calculate virtual address from physical address,
856 * because some class driver may not fill transfer_buffer.
857 * In Buffer DMA mode virual address is used,
858 * when handling non DWORD aligned buffers.
859 */
860 buf = (void *)__bus_to_virt((unsigned long)urb->transfer_dma);
861 dev_warn_once(&urb->dev->dev,
862 "USB transfer_buffer was NULL, will use __bus_to_virt(%pad)=%p\n",
863 &urb->transfer_dma, buf);
864 }
865
866 if (!(urb->transfer_flags & URB_NO_INTERRUPT))
867 flags |= URB_GIVEBACK_ASAP;
868 if (urb->transfer_flags & URB_ZERO_PACKET)
869 flags |= URB_SEND_ZERO_PACKET;
870
871 dwc_otg_hcd_urb_set_params(dwc_otg_urb, urb, buf,
872 urb->transfer_dma,
873 urb->transfer_buffer_length,
874 urb->setup_packet,
875 urb->setup_dma, flags, urb->interval);
876
877 for (i = 0; i < urb->number_of_packets; ++i) {
878 dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_urb, i,
879 urb->
880 iso_frame_desc[i].offset,
881 urb->
882 iso_frame_desc[i].length);
883 }
884
885 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags);
886 urb->hcpriv = dwc_otg_urb;
887#if USB_URB_EP_LINKING
888 retval = usb_hcd_link_urb_to_ep(hcd, urb);
889 if (0 == retval)
890#endif
891 {
892 retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb,
893 /*(dwc_otg_qh_t **)*/
894 ref_ep_hcpriv, 1);
895 if (0 == retval) {
896 if (alloc_bandwidth) {
897 allocate_bus_bandwidth(hcd,
898 dwc_otg_hcd_get_ep_bandwidth(
899 dwc_otg_hcd, *ref_ep_hcpriv),
900 urb);
901 }
902 } else {
903 DWC_DEBUGPL(DBG_HCD, "DWC OTG dwc_otg_hcd_urb_enqueue failed rc %d\n", retval);
904#if USB_URB_EP_LINKING
905 usb_hcd_unlink_urb_from_ep(hcd, urb);
906#endif
907 DWC_FREE(dwc_otg_urb);
908 urb->hcpriv = NULL;
909 if (retval == -DWC_E_NO_DEVICE)
910 retval = -ENODEV;
911 }
912 }
913#if USB_URB_EP_LINKING
914 else
915 {
916 DWC_FREE(dwc_otg_urb);
917 urb->hcpriv = NULL;
918 }
919#endif
920 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
921 return retval;
922}
923
924/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
925 * success. */
926#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
927static int dwc_otg_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
928#else
929static int dwc_otg_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
930#endif
931{
932 dwc_irqflags_t flags;
933 dwc_otg_hcd_t *dwc_otg_hcd;
934 int rc;
935
936 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
937
938 dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
939
940#ifdef DEBUG
941 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
942 dump_urb_info(urb, "dwc_otg_urb_dequeue");
943 }
944#endif
945
946 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
947 rc = usb_hcd_check_unlink_urb(hcd, urb, status);
948 if (0 == rc) {
949 if(urb->hcpriv != NULL) {
950 dwc_otg_hcd_urb_dequeue(dwc_otg_hcd,
951 (dwc_otg_hcd_urb_t *)urb->hcpriv);
952
953 DWC_FREE(urb->hcpriv);
954 urb->hcpriv = NULL;
955 }
956 }
957
958 if (0 == rc) {
959 /* Higher layer software sets URB status. */
960#if USB_URB_EP_LINKING
961 usb_hcd_unlink_urb_from_ep(hcd, urb);
962#endif
963 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
964
965
966#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
967 usb_hcd_giveback_urb(hcd, urb);
968#else
969 usb_hcd_giveback_urb(hcd, urb, status);
970#endif
971 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
972 DWC_PRINTF("Called usb_hcd_giveback_urb() \n");
973 DWC_PRINTF(" 1urb->status = %d\n", urb->status);
974 }
975 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue OK\n");
976 } else {
977 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
978 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue failed - rc %d\n",
979 rc);
980 }
981
982 return rc;
983}
984
985/* Frees resources in the DWC_otg controller related to a given endpoint. Also
986 * clears state in the HCD related to the endpoint. Any URBs for the endpoint
987 * must already be dequeued. */
988static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
989{
990 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
991
992 DWC_DEBUGPL(DBG_HCD,
993 "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
994 "endpoint=%d\n", ep->desc.bEndpointAddress,
995 dwc_ep_addr_to_endpoint(ep->desc.bEndpointAddress));
996 dwc_otg_hcd_endpoint_disable(dwc_otg_hcd, ep->hcpriv, 250);
997 ep->hcpriv = NULL;
998}
999
1000#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
1001/* Resets endpoint specific parameter values, in current version used to reset
1002 * the data toggle(as a WA). This function can be called from usb_clear_halt routine */
1003static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
1004{
1005 dwc_irqflags_t flags;
1006 struct usb_device *udev = NULL;
1007 int epnum = usb_endpoint_num(&ep->desc);
1008 int is_out = usb_endpoint_dir_out(&ep->desc);
1009 int is_control = usb_endpoint_xfer_control(&ep->desc);
1010 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1011 struct device *dev = DWC_OTG_OS_GETDEV(dwc_otg_hcd->otg_dev->os_dep);
1012
1013 if (dev)
1014 udev = to_usb_device(dev);
1015 else
1016 return;
1017
1018 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n", epnum);
1019
1020 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
1021 usb_settoggle(udev, epnum, is_out, 0);
1022 if (is_control)
1023 usb_settoggle(udev, epnum, !is_out, 0);
1024
1025 if (ep->hcpriv) {
1026 dwc_otg_hcd_endpoint_reset(dwc_otg_hcd, ep->hcpriv);
1027 }
1028 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
1029}
1030#endif
1031
1032/** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
1033 * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
1034 * interrupt.
1035 *
1036 * This function is called by the USB core when an interrupt occurs */
1037static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd)
1038{
1039 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1040 int32_t retval = dwc_otg_hcd_handle_intr(dwc_otg_hcd);
1041 if (retval != 0) {
1042 S3C2410X_CLEAR_EINTPEND();
1043 }
1044 return IRQ_RETVAL(retval);
1045}
1046
1047/** Creates Status Change bitmap for the root hub and root port. The bitmap is
1048 * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
1049 * is the status change indicator for the single root port. Returns 1 if either
1050 * change indicator is 1, otherwise returns 0. */
1051int hub_status_data(struct usb_hcd *hcd, char *buf)
1052{
1053 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1054
1055 buf[0] = 0;
1056 buf[0] |= (dwc_otg_hcd_is_status_changed(dwc_otg_hcd, 1)) << 1;
1057
1058 return (buf[0] != 0);
1059}
1060
1061/** Handles hub class-specific requests. */
1062int hub_control(struct usb_hcd *hcd,
1063 u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
1064{
1065 int retval;
1066
1067 retval = dwc_otg_hcd_hub_control(hcd_to_dwc_otg_hcd(hcd),
1068 typeReq, wValue, wIndex, buf, wLength);
1069
1070 switch (retval) {
1071 case -DWC_E_INVALID:
1072 retval = -EINVAL;
1073 break;
1074 }
1075
1076 return retval;
1077}
1078
1079#endif /* DWC_DEVICE_ONLY */