1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd.c $
7 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9 * otherwise expressly agreed to in writing between Synopsys and you.
11 * The Software IS NOT an item of Licensed Software or Licensed Product under
12 * any End User Software License Agreement or Agreement for Licensed Product
13 * with Synopsys or any supplement thereto. You are permitted to use and
14 * redistribute this Software in source and binary forms, with or without
15 * modification, provided that redistributions of source code must retain this
16 * notice. You may not view, use, disclose, copy or distribute this file or
17 * any information contained herein except pursuant to this license grant from
18 * Synopsys. If you do not agree with this notice, including the disclaimer
19 * below, then you are not authorized to use the Software.
21 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 * ========================================================================== */
33 #ifndef DWC_DEVICE_ONLY
38 * This file contains the implementation of the HCD. In Linux, the HCD
39 * implements the hc_driver API.
41 #include <linux/clk.h>
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/irq.h>
53 #include <linux/platform_device.h>
55 #include "dwc_otg_driver.h"
56 #include "dwc_otg_hcd.h"
57 #include "dwc_otg_regs.h"
59 static int dwc_otg_hcd_suspend(struct usb_hcd *hcd)
61 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd);
62 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
64 pcgcctl_data_t pcgcctl;
66 if(core_if->op_state == B_PERIPHERAL)
68 DWC_PRINT("%s, usb device mode\n", __func__);
71 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
72 DWC_PRINT("%s suspend, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
73 if(hprt0.b.prtconnsts) // usb device connected
81 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
84 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
90 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
93 pcgcctl.d32 = dwc_read_reg32(core_if->pcgcctl);
94 pcgcctl.b.pwrclmp = 1;//power clamp
95 dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
97 //pcgcctl.b.rstpdwnmodule = 1;//reset PDM
98 pcgcctl.b.stoppclk = 1;//stop phy clk
99 dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
101 else //no device connect
103 if (core_if->hcd_cb && core_if->hcd_cb->suspend) {
104 core_if->hcd_cb->suspend( core_if->hcd_cb->p, 0);
108 clk_disable(core_if->otg_dev->phyclk);
109 clk_disable(core_if->otg_dev->ahbclk);
114 static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
116 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd);
117 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
119 pcgcctl_data_t pcgcctl;
120 gintmsk_data_t gintmsk;
122 if(core_if->op_state == B_PERIPHERAL)
124 DWC_PRINT("%s, usb device mode\n", __func__);
127 clk_enable(core_if->otg_dev->phyclk);
128 clk_enable(core_if->otg_dev->ahbclk);
132 pcgcctl.d32 = dwc_read_reg32(core_if->pcgcctl);;
133 pcgcctl.b.stoppclk = 0;//stop phy clk
134 dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
136 pcgcctl.b.pwrclmp = 0;//power clamp
137 dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
140 gintmsk.d32 = dwc_read_reg32(&core_if->core_global_regs->gintmsk);
141 gintmsk.b.portintr = 0;
142 dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
144 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
145 DWC_PRINT("%s resume, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
146 if(hprt0.b.prtconnsts)
148 //hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
149 //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
153 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
155 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
156 //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
161 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
165 hprt0.b.prtconndet = 1;
166 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
168 //hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
169 //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
175 if (core_if->hcd_cb && core_if->hcd_cb->suspend) {
176 core_if->hcd_cb->suspend( core_if->hcd_cb->p, 1);
179 gintmsk.b.portintr = 1;
180 dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
185 static const char dwc_otg_hcd_name [] = "dwc_otg_hcd";
187 static const struct hc_driver dwc_otg_hc_driver = {
189 .description = dwc_otg_hcd_name,
190 .product_desc = "DWC OTG Controller",
191 .hcd_priv_size = sizeof(dwc_otg_hcd_t),
193 .irq = dwc_otg_hcd_irq,
195 .flags = HCD_MEMORY | HCD_USB2,
198 .start = dwc_otg_hcd_start,
203 * core/hcd.c call hcd->driver->bus_suspend
204 * otherwise system can not be suspended
207 .bus_suspend = dwc_otg_hcd_suspend,
208 .bus_resume = dwc_otg_hcd_resume,
210 .stop = dwc_otg_hcd_stop,
212 .urb_enqueue = dwc_otg_hcd_urb_enqueue,
213 .urb_dequeue = dwc_otg_hcd_urb_dequeue,
214 .endpoint_disable = dwc_otg_hcd_endpoint_disable,
216 .get_frame_number = dwc_otg_hcd_get_frame_number,
218 .hub_status_data = dwc_otg_hcd_hub_status_data,
219 .hub_control = dwc_otg_hcd_hub_control,
224 #ifdef CONFIG_USB11_HOST
225 static const struct hc_driver host11_hc_driver = {
227 .description = "host11_hcd",
228 .product_desc = "DWC OTG Controller",
229 .hcd_priv_size = sizeof(dwc_otg_hcd_t),
231 .irq = dwc_otg_hcd_irq,
233 .flags = HCD_MEMORY | HCD_USB2,
236 .start = dwc_otg_hcd_start,
241 * core/hcd.c call hcd->driver->bus_suspend
242 * otherwise system can not be suspended
245 .bus_suspend = dwc_otg_hcd_suspend,
246 .bus_resume = dwc_otg_hcd_resume,
248 .stop = dwc_otg_hcd_stop,
250 .urb_enqueue = dwc_otg_hcd_urb_enqueue,
251 .urb_dequeue = dwc_otg_hcd_urb_dequeue,
252 .endpoint_disable = dwc_otg_hcd_endpoint_disable,
254 .get_frame_number = dwc_otg_hcd_get_frame_number,
256 .hub_status_data = dwc_otg_hcd_hub_status_data,
257 .hub_control = dwc_otg_hcd_hub_control,
262 #ifdef CONFIG_USB20_HOST
263 static const struct hc_driver host20_hc_driver = {
265 .description = "host20_hcd",
266 .product_desc = "DWC OTG Controller",
267 .hcd_priv_size = sizeof(dwc_otg_hcd_t),
269 .irq = dwc_otg_hcd_irq,
271 .flags = HCD_MEMORY | HCD_USB2,
274 .start = dwc_otg_hcd_start,
279 * core/hcd.c call hcd->driver->bus_suspend
280 * otherwise system can not be suspended
283 .bus_suspend = dwc_otg_hcd_suspend,
284 .bus_resume = dwc_otg_hcd_resume,
286 .stop = dwc_otg_hcd_stop,
288 .urb_enqueue = dwc_otg_hcd_urb_enqueue,
289 .urb_dequeue = dwc_otg_hcd_urb_dequeue,
290 .endpoint_disable = dwc_otg_hcd_endpoint_disable,
292 .get_frame_number = dwc_otg_hcd_get_frame_number,
294 .hub_status_data = dwc_otg_hcd_hub_status_data,
295 .hub_control = dwc_otg_hcd_hub_control,
302 * Work queue function for starting the HCD when A-Cable is connected.
303 * The dwc_otg_hcd_start() must be called in a process context.
305 static void hcd_start_func(struct work_struct *work)
307 dwc_otg_hcd_t *dwc_otg_hcd = container_of(work, dwc_otg_hcd_t, start_work);
308 struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
310 DWC_DEBUGPL(DBG_HCDV, "%s() %p %p\n", __func__, dwc_otg_hcd, hcd);
312 dwc_otg_hcd_start(hcd);
317 * HCD Callback function for starting the HCD when A-Cable is
320 * @param _p void pointer to the <code>struct usb_hcd</code>
322 static int32_t dwc_otg_hcd_start_cb(void *_p)
324 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p);
325 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
328 if (core_if->op_state == B_HOST) {
330 * Reset the port. During a HNP mode switch the reset
331 * needs to occur within 1ms and have a duration of at
334 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
336 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
337 ((struct usb_hcd *)_p)->self.is_b_host = 1;
339 ((struct usb_hcd *)_p)->self.is_b_host = 0;
342 /* Need to start the HCD in a non-interrupt context. */
343 // INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func, _p);
344 INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
345 schedule_work(&dwc_otg_hcd->start_work);
352 * HCD Callback function for stopping the HCD.
354 * @param _p void pointer to the <code>struct usb_hcd</code>
356 static int32_t dwc_otg_hcd_stop_cb( void *_p )
358 struct usb_hcd *usb_hcd = (struct usb_hcd *)_p;
359 DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
360 dwc_otg_hcd_stop( usb_hcd );
364 static void del_xfer_timers(dwc_otg_hcd_t *_hcd)
368 int num_channels = _hcd->core_if->core_params->host_channels;
369 for (i = 0; i < num_channels; i++) {
370 del_timer(&_hcd->core_if->hc_xfer_timer[i]);
375 static void del_timers(dwc_otg_hcd_t *_hcd)
377 del_xfer_timers(_hcd);
378 del_timer(&_hcd->conn_timer);
382 * Processes all the URBs in a single list of QHs. Completes them with
383 * -ETIMEDOUT and frees the QTD.
385 static void kill_urbs_in_qh_list(dwc_otg_hcd_t *_hcd, struct list_head *_qh_list)
387 struct list_head *qh_item;
389 struct list_head *qtd_item;
392 struct usb_host_endpoint *ep;
394 list_for_each(qh_item, _qh_list) {
395 qh = list_entry(qh_item, dwc_otg_qh_t, qh_list_entry);
396 for (qtd_item = qh->qtd_list.next;
397 qtd_item != &qh->qtd_list;
398 qtd_item = qh->qtd_list.next) {
399 qtd = list_entry(qtd_item, dwc_otg_qtd_t, qtd_list_entry);
400 if (qtd->urb != NULL) {
404 // urb will be re entry to ep->urb_list if use ETIMEOUT
405 dwc_otg_hcd_complete_urb(_hcd, qtd->urb,
406 -ETIMEDOUT);//ESHUTDOWN
408 //if(!list_empty(&ep->urb_list))
409 DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
410 __func__, urb, usb_pipedevice(urb->pipe),
411 usb_pipeendpoint(urb->pipe),
412 usb_pipein(urb->pipe) ? "IN" : "OUT", urb->unlinked);
415 urb->unlinked = -ESHUTDOWN;
418 dwc_otg_hcd_qtd_remove_and_free(qtd);
424 * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
425 * and periodic schedules. The QTD associated with each URB is removed from
426 * the schedule and freed. This function may be called when a disconnect is
427 * detected or when the HCD is being stopped.
429 static void kill_all_urbs(dwc_otg_hcd_t *_hcd)
431 kill_urbs_in_qh_list(_hcd, &_hcd->non_periodic_sched_inactive);
432 kill_urbs_in_qh_list(_hcd, &_hcd->non_periodic_sched_active);
433 kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_inactive);
434 kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_ready);
435 kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_assigned);
436 kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_queued);
440 * HCD Callback function for disconnect of the HCD.
442 * @param _p void pointer to the <code>struct usb_hcd</code>
444 static int32_t dwc_otg_hcd_disconnect_cb( void *_p )
447 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p);
449 //DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
452 * Set status flags for the hub driver.
454 dwc_otg_hcd->flags.b.port_connect_status_change = 1;
455 dwc_otg_hcd->flags.b.port_connect_status = 0;
458 * Shutdown any transfers in process by clearing the Tx FIFO Empty
459 * interrupt mask and status bits and disabling subsequent host
460 * channel interrupts.
463 intr.b.nptxfempty = 1;
464 intr.b.ptxfempty = 1;
466 dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintmsk, intr.d32, 0);
467 dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintsts, intr.d32, 0);
469 del_timers(dwc_otg_hcd);
472 * Turn off the vbus power only if the core has transitioned to device
473 * mode. If still in host mode, need to keep power on to detect a
476 if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
477 if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
478 hprt0_data_t hprt0 = { .d32=0 };
479 DWC_PRINT("Disconnect: PortPower off\n");
481 dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
484 dwc_otg_disable_host_interrupts( dwc_otg_hcd->core_if );
487 /* Respond with an error status to all URBs in the schedule. */
488 kill_all_urbs(dwc_otg_hcd);
490 if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
491 /* Clean up any host channels that were in use. */
495 dwc_otg_hc_regs_t *hc_regs;
496 hcchar_data_t hcchar;
498 num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
500 if (!dwc_otg_hcd->core_if->dma_enable) {
501 /* Flush out any channel requests in slave mode. */
502 for (i = 0; i < num_channels; i++) {
503 channel = dwc_otg_hcd->hc_ptr_array[i];
504 if (list_empty(&channel->hc_list_entry)) {
505 hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
506 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
511 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
517 for (i = 0; i < num_channels; i++) {
518 channel = dwc_otg_hcd->hc_ptr_array[i];
519 if (list_empty(&channel->hc_list_entry)) {
520 hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
521 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
523 /* Halt the channel. */
525 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
528 dwc_otg_hc_cleanup(dwc_otg_hcd->core_if, channel);
529 list_add_tail(&channel->hc_list_entry,
530 &dwc_otg_hcd->free_hc_list);
535 /* A disconnect will end the session so the B-Device is no
536 * longer a B-host. */
537 ((struct usb_hcd *)_p)->self.is_b_host = 0;
542 * Connection timeout function. An OTG host is required to display a
543 * message if the device does not connect within 10 seconds.
545 void dwc_otg_hcd_connect_timeout( unsigned long _ptr )
547 DWC_DEBUGPL(DBG_HCDV, "%s(%x)\n", __func__, (int)_ptr);
548 DWC_PRINT( "Connect Timeout\n");
549 DWC_ERROR( "Device Not Connected/Responding\n" );
553 * Start the connection timer. An OTG host is required to display a
554 * message if the device does not connect within 10 seconds. The
555 * timer is deleted if a port connect interrupt occurs before the
558 static void dwc_otg_hcd_start_connect_timer( dwc_otg_hcd_t *_hcd)
560 init_timer( &_hcd->conn_timer );
561 _hcd->conn_timer.function = dwc_otg_hcd_connect_timeout;
562 _hcd->conn_timer.data = (unsigned long)0;
563 _hcd->conn_timer.expires = jiffies + (HZ*10);
564 add_timer( &_hcd->conn_timer );
568 * HCD Callback function for disconnect of the HCD.
570 * @param _p void pointer to the <code>struct usb_hcd</code>
572 static int32_t dwc_otg_hcd_session_start_cb( void *_p )
574 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p);
575 DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
576 dwc_otg_hcd_start_connect_timer( dwc_otg_hcd );
581 * suspend: 0 usb phy enable
584 static int32_t dwc_otg_phy_suspend_cb( void *_p, int suspend)
586 unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
589 *otg_phy_con1 |= (0x01<<2);
590 *otg_phy_con1 |= (0x01<<3); // exit suspend.
591 *otg_phy_con1 &= ~(0x01<<2);
593 DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
597 *otg_phy_con1 |= (0x01<<2);
598 *otg_phy_con1 &= ~(0x01<<3); // enter suspend.
599 DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
606 * HCD Callback structure for handling mode switching.
608 static dwc_otg_cil_callbacks_t hcd_cil_callbacks = {
609 .start = dwc_otg_hcd_start_cb,
610 .stop = dwc_otg_hcd_stop_cb,
611 .disconnect = dwc_otg_hcd_disconnect_cb,
612 .session_start = dwc_otg_hcd_session_start_cb,
613 .suspend = dwc_otg_phy_suspend_cb,
618 * Reset tasklet function
620 static void reset_tasklet_func (unsigned long data)
622 dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t*)data;
623 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
626 DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
628 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
630 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
634 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
635 dwc_otg_hcd->flags.b.port_reset_change = 1;
640 static struct tasklet_struct reset_tasklet = {
643 .count = ATOMIC_INIT(0),
644 .func = reset_tasklet_func,
649 * Initializes the HCD. This function allocates memory for and initializes the
650 * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
651 * USB bus with the core and calls the hc_driver->start() function. It returns
652 * a negative error on failure.
654 extern uint32_t g_dbg_lvl;
655 int __devinit dwc_otg_hcd_init(struct device *dev)
657 struct usb_hcd *hcd = NULL;
658 dwc_otg_hcd_t *dwc_otg_hcd = NULL;
659 dwc_otg_device_t *otg_dev = dev->platform_data;
666 #if 1 //kaiker .these code must execute before usb_create_hcd
667 /* Set device flags indicating whether the HCD supports DMA. */
668 static u64 usb_dmamask = 0xffffffffUL;
669 if (otg_dev->core_if->dma_enable) {
670 dev->dma_mask = &usb_dmamask;
671 dev->coherent_dma_mask = ~0;
673 dev->dma_mask = (void *)0;
674 dev->coherent_dma_mask = 0;
677 DWC_PRINT("dwc_otg_hcd_init everest\n");
681 * Allocate memory for the base HCD plus the DWC OTG HCD.
682 * Initialize the base HCD.
684 hcd = usb_create_hcd(&dwc_otg_hc_driver, dev, dev_name(dev));
689 hcd->regs = otg_dev->base;
690 hcd->self.otg_port = 1;
692 /* Initialize the DWC OTG HCD. */
693 dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
695 spin_lock_init(&dwc_otg_hcd->global_lock);
697 dwc_otg_hcd->core_if = otg_dev->core_if;
698 otg_dev->hcd = dwc_otg_hcd;
700 #ifdef CONFIG_USB20_OTG_EN
701 dwc_otg_hcd->host_enabled = 1;
703 dwc_otg_hcd->host_enabled = 0;
706 /* Register the HCD CIL Callbacks */
707 dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
708 &hcd_cil_callbacks, hcd);
710 /* Initialize the non-periodic schedule. */
711 INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive);
712 INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active);
714 /* Initialize the periodic schedule. */
715 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive);
716 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready);
717 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned);
718 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued);
721 * Create a host channel descriptor for each host channel implemented
722 * in the controller. Initialize the channel descriptor array.
724 INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list);
725 num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
726 for (i = 0; i < num_channels; i++) {
727 channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL);
728 if (channel == NULL) {
730 DWC_ERROR("%s: host channel allocation failed\n", __func__);
733 memset(channel, 0, sizeof(dwc_hc_t));
735 dwc_otg_hcd->hc_ptr_array[i] = channel;
737 init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
740 DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel);
743 /* Initialize the Connection timeout timer. */
744 init_timer( &dwc_otg_hcd->conn_timer );
746 /* Initialize reset tasklet. */
747 reset_tasklet.data = (unsigned long) dwc_otg_hcd;
748 dwc_otg_hcd->reset_tasklet = &reset_tasklet;
750 * Finish generic HCD initialization and start the HCD. This function
751 * allocates the DMA buffer pool, registers the USB bus, requests the
752 * IRQ line, and calls dwc_otg_hcd_start method.
754 retval = usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0),
757 DWC_ERROR("usb_add_hcd fail,everest\n");
761 * Allocate space for storing data on status transactions. Normally no
762 * data is sent, but this space acts as a bit bucket. This must be
763 * done after usb_add_hcd since that function allocates the DMA buffer
766 if (otg_dev->core_if->dma_enable) {
767 dwc_otg_hcd->status_buf =
768 dma_alloc_coherent(dev,
769 DWC_OTG_HCD_STATUS_BUF_SIZE,
770 &dwc_otg_hcd->status_buf_dma,
771 GFP_KERNEL | GFP_DMA);
773 dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
776 if (dwc_otg_hcd->status_buf == NULL) {
778 DWC_ERROR("%s: status_buf allocation failed\n", __func__);
782 DWC_PRINT("%s end,everest\n",__func__);
783 // DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
784 // dev->bus_id, hcd->self.busnum);
788 /* Error conditions */
792 dwc_otg_hcd_free(hcd);
796 DWC_PRINT("dwc_otg_hcd_init error,everest\n");
800 #ifdef CONFIG_USB11_HOST
802 * suspend: 0 usb phy enable
805 static int32_t host11_phy_suspend_cb( void *_p, int suspend)
807 unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
810 *otg_phy_con1 &= ~(0x01<<28);
811 DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
815 *otg_phy_con1 |= (0x01<<28);
816 DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
821 static dwc_otg_cil_callbacks_t host11_cil_callbacks = {
822 .start = dwc_otg_hcd_start_cb,
823 .stop = dwc_otg_hcd_stop_cb,
824 .disconnect = dwc_otg_hcd_disconnect_cb,
825 .session_start = dwc_otg_hcd_session_start_cb,
826 .suspend = host11_phy_suspend_cb,
830 static struct tasklet_struct host11_reset_tasklet = {
833 .count = ATOMIC_INIT(0),
834 .func = reset_tasklet_func,
838 int __devinit host11_hcd_init(struct device *dev)
840 struct usb_hcd *hcd = NULL;
841 dwc_otg_hcd_t *dwc_otg_hcd = NULL;
842 dwc_otg_device_t *otg_dev = dev->platform_data;
849 #if 1 //kaiker .these code must execute before usb_create_hcd
850 /* Set device flags indicating whether the HCD supports DMA. */
851 static u64 usb_dmamask = 0xffffffffUL;
852 if (otg_dev->core_if->dma_enable) {
853 // DWC_PRINT("Using DMA mode\n");
854 dev->dma_mask = &usb_dmamask;
855 dev->coherent_dma_mask = ~0;
857 // DWC_PRINT("Using Slave mode\n");
858 dev->dma_mask = (void *)0;
859 dev->coherent_dma_mask = 0;
862 DWC_PRINT("%s everest\n",__func__);
865 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
868 * Allocate memory for the base HCD plus the DWC OTG HCD.
869 * Initialize the base HCD.
871 hcd = usb_create_hcd(&host11_hc_driver, dev, dev_name(dev));
876 hcd->regs = otg_dev->base;
877 hcd->self.otg_port = 1;
879 /* Initialize the DWC OTG HCD. */
880 dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
881 dwc_otg_hcd->core_if = otg_dev->core_if;
882 otg_dev->hcd = dwc_otg_hcd;
884 #ifdef CONFIG_USB11_HOST_EN
885 dwc_otg_hcd->host_enabled = 1;
887 dwc_otg_hcd->host_enabled = 0;
890 spin_lock_init(&dwc_otg_hcd->global_lock);
893 /* Register the HCD CIL Callbacks */
894 dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
895 &host11_cil_callbacks, hcd);
897 /* Initialize the non-periodic schedule. */
898 INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive);
899 INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active);
901 /* Initialize the periodic schedule. */
902 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive);
903 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready);
904 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned);
905 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued);
908 * Create a host channel descriptor for each host channel implemented
909 * in the controller. Initialize the channel descriptor array.
911 INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list);
912 num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
913 for (i = 0; i < num_channels; i++) {
914 channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL);
915 if (channel == NULL) {
917 DWC_ERROR("%s: host channel allocation failed\n", __func__);
920 memset(channel, 0, sizeof(dwc_hc_t));
922 dwc_otg_hcd->hc_ptr_array[i] = channel;
924 init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
927 DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel);
930 /* Initialize the Connection timeout timer. */
931 init_timer( &dwc_otg_hcd->conn_timer );
933 /* Initialize reset tasklet. */
934 host11_reset_tasklet.data = (unsigned long) dwc_otg_hcd;
935 dwc_otg_hcd->reset_tasklet = &host11_reset_tasklet;
937 * Finish generic HCD initialization and start the HCD. This function
938 * allocates the DMA buffer pool, registers the USB bus, requests the
939 * IRQ line, and calls dwc_otg_hcd_start method.
941 retval = usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0),
944 DWC_ERROR("usb_add_hcd fail,everest\n");
948 * Allocate space for storing data on status transactions. Normally no
949 * data is sent, but this space acts as a bit bucket. This must be
950 * done after usb_add_hcd since that function allocates the DMA buffer
953 if (otg_dev->core_if->dma_enable) {
954 dwc_otg_hcd->status_buf =
955 dma_alloc_coherent(dev,
956 DWC_OTG_HCD_STATUS_BUF_SIZE,
957 &dwc_otg_hcd->status_buf_dma,
958 GFP_KERNEL | GFP_DMA);
960 dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
963 if (dwc_otg_hcd->status_buf == NULL) {
965 DWC_ERROR("%s: status_buf allocation failed\n", __func__);
969 DWC_PRINT("%s end,everest\n",__func__);
970 // DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
971 // dev->bus_id, hcd->self.busnum);
975 /* Error conditions */
979 dwc_otg_hcd_free(hcd);
983 DWC_PRINT("dwc_otg_hcd_init error,everest\n");
987 #ifdef CONFIG_USB20_HOST
990 * suspend: 0 usb phy enable
993 static int32_t host20_phy_suspend_cb( void *_p, int suspend)
995 unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
998 regval = *otg_phy_con1;
1001 regval |= (0x01<<14); // exit suspend.
1002 regval &= ~(0x01<<13);
1004 DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
1008 regval &= ~(0x01<<14); // exit suspend.
1009 regval |= (0x01<<13); // software control
1010 DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
1012 *otg_phy_con1 = regval;
1017 static dwc_otg_cil_callbacks_t host20_cil_callbacks = {
1018 .start = dwc_otg_hcd_start_cb,
1019 .stop = dwc_otg_hcd_stop_cb,
1020 .disconnect = dwc_otg_hcd_disconnect_cb,
1021 .session_start = dwc_otg_hcd_session_start_cb,
1022 .suspend = host20_phy_suspend_cb,
1026 static struct tasklet_struct host20_reset_tasklet = {
1029 .count = ATOMIC_INIT(0),
1030 .func = reset_tasklet_func,
1034 int __devinit host20_hcd_init(struct device *dev)
1036 struct usb_hcd *hcd = NULL;
1037 dwc_otg_hcd_t *dwc_otg_hcd = NULL;
1038 dwc_otg_device_t *otg_dev = dev->platform_data;
1045 #if 1 //kaiker .these code must execute before usb_create_hcd
1046 /* Set device flags indicating whether the HCD supports DMA. */
1047 static u64 usb_dmamask = 0xffffffffUL;
1048 if (otg_dev->core_if->dma_enable) {
1049 // DWC_PRINT("Using DMA mode\n");
1050 dev->dma_mask = &usb_dmamask;
1051 dev->coherent_dma_mask = ~0;
1053 // DWC_PRINT("Using Slave mode\n");
1054 dev->dma_mask = (void *)0;
1055 dev->coherent_dma_mask = 0;
1058 DWC_PRINT("%s everest\n",__func__);
1059 // g_dbg_lvl = 0xff;
1061 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
1064 * Allocate memory for the base HCD plus the DWC OTG HCD.
1065 * Initialize the base HCD.
1067 hcd = usb_create_hcd(&host20_hc_driver, dev, dev_name(dev));
1072 hcd->regs = otg_dev->base;
1073 hcd->self.otg_port = 1;
1075 /* Initialize the DWC OTG HCD. */
1076 dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1077 dwc_otg_hcd->core_if = otg_dev->core_if;
1078 otg_dev->hcd = dwc_otg_hcd;
1080 #ifdef CONFIG_USB20_HOST_EN
1081 dwc_otg_hcd->host_enabled = 1;
1083 dwc_otg_hcd->host_enabled = 0;
1086 spin_lock_init(&dwc_otg_hcd->global_lock);
1089 /* Register the HCD CIL Callbacks */
1090 dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
1091 &host20_cil_callbacks, hcd);
1093 /* Initialize the non-periodic schedule. */
1094 INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive);
1095 INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active);
1097 /* Initialize the periodic schedule. */
1098 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive);
1099 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready);
1100 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned);
1101 INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued);
1104 * Create a host channel descriptor for each host channel implemented
1105 * in the controller. Initialize the channel descriptor array.
1107 INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list);
1108 num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
1109 for (i = 0; i < num_channels; i++) {
1110 channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL);
1111 if (channel == NULL) {
1113 DWC_ERROR("%s: host channel allocation failed\n", __func__);
1116 memset(channel, 0, sizeof(dwc_hc_t));
1117 channel->hc_num = i;
1118 dwc_otg_hcd->hc_ptr_array[i] = channel;
1120 init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
1123 DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel);
1126 /* Initialize the Connection timeout timer. */
1127 init_timer( &dwc_otg_hcd->conn_timer );
1129 /* Initialize reset tasklet. */
1130 host20_reset_tasklet.data = (unsigned long) dwc_otg_hcd;
1131 dwc_otg_hcd->reset_tasklet = &host20_reset_tasklet;
1133 * Finish generic HCD initialization and start the HCD. This function
1134 * allocates the DMA buffer pool, registers the USB bus, requests the
1135 * IRQ line, and calls dwc_otg_hcd_start method.
1137 retval = usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0),
1140 DWC_ERROR("usb_add_hcd fail,everest\n");
1144 * Allocate space for storing data on status transactions. Normally no
1145 * data is sent, but this space acts as a bit bucket. This must be
1146 * done after usb_add_hcd since that function allocates the DMA buffer
1149 if (otg_dev->core_if->dma_enable) {
1150 dwc_otg_hcd->status_buf =
1151 dma_alloc_coherent(dev,
1152 DWC_OTG_HCD_STATUS_BUF_SIZE,
1153 &dwc_otg_hcd->status_buf_dma,
1154 GFP_KERNEL | GFP_DMA);
1156 dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
1159 if (dwc_otg_hcd->status_buf == NULL) {
1161 DWC_ERROR("%s: status_buf allocation failed\n", __func__);
1165 DWC_PRINT("%s end,everest\n",__func__);
1169 /* Error conditions */
1171 usb_remove_hcd(hcd);
1173 dwc_otg_hcd_free(hcd);
1177 DWC_PRINT("dwc_otg_hcd_init error,everest\n");
1184 * Frees memory and resources associated with the HCD and deregisters the bus.
1186 void dwc_otg_hcd_remove(struct device *dev)
1188 dwc_otg_device_t *otg_dev = dev->platform_data;
1189 dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
1190 struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
1192 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
1194 /* Turn off all interrupts */
1195 dwc_write_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0);
1196 dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gahbcfg, 1, 0);
1198 usb_remove_hcd(hcd);
1199 dwc_otg_hcd_free(hcd);
1206 /* =========================================================================
1207 * Linux HC Driver Functions
1208 * ========================================================================= */
1211 * Initializes dynamic portions of the DWC_otg HCD state.
1213 static void hcd_reinit(dwc_otg_hcd_t *_hcd)
1215 struct list_head *item;
1219 DWC_DEBUGPL(DBG_HCD, "%s: Enter\n", __func__);
1221 _hcd->flags.d32 = 0;
1223 _hcd->non_periodic_qh_ptr = &_hcd->non_periodic_sched_active;
1224 _hcd->non_periodic_channels = 0;
1225 _hcd->periodic_channels = 0;
1228 * Put all channels in the free channel list and clean up channel
1231 item = _hcd->free_hc_list.next;
1232 while (item != &_hcd->free_hc_list) {
1234 item = _hcd->free_hc_list.next;
1236 num_channels = _hcd->core_if->core_params->host_channels;
1237 for (i = 0; i < num_channels; i++) {
1238 channel = _hcd->hc_ptr_array[i];
1239 list_add_tail(&channel->hc_list_entry, &_hcd->free_hc_list);
1240 dwc_otg_hc_cleanup(_hcd->core_if, channel);
1243 /* Initialize the DWC core for host mode operation. */
1244 dwc_otg_core_host_init(_hcd->core_if);
1247 /** Initializes the DWC_otg controller and its root hub and prepares it for host
1248 * mode operation. Activates the root port. Returns 0 on success and a negative
1249 * error code on failure. */
1250 int dwc_otg_hcd_start(struct usb_hcd *_hcd)
1252 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
1253 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
1254 unsigned long flags;
1256 struct usb_bus *bus;
1258 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
1259 spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
1261 DWC_PRINT("dwc_otg_hcd_start! everest\n");
1262 bus = hcd_to_bus(_hcd);
1263 _hcd->state = HC_STATE_RUNNING;
1265 /* Initialize and connect root hub if one is not already attached */
1266 if (bus->root_hub) {
1267 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
1268 /* Inform the HUB driver to resume. */
1269 usb_hcd_resume_root_hub(_hcd);
1275 struct usb_device *udev;6
1276 udev = usb_alloc_dev(NULL, bus, 0);
1277 udev->speed = USB_SPEED_HIGH;
1279 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n");
1284 if ((retval = usb_hcd_register_root_hub(udev, _hcd)) != 0) {
1285 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error registering %d\n", retval);
1290 /* Initialize the bus state. If the core is in Device Mode
1291 * HALT the USB bus and return. */
1292 if (!dwc_otg_hcd->host_enabled || dwc_otg_is_device_mode (core_if)) {
1293 DWC_PRINT("dwc_otg_hcd_start controller in device mode,everest\n");
1294 //_hcd->state = HC_STATE_HALT;
1297 hcd_reinit(dwc_otg_hcd);
1299 spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
1304 static void qh_list_free(dwc_otg_hcd_t *_hcd, struct list_head *_qh_list)
1306 struct list_head *item;
1309 if (_qh_list->next == NULL) {
1310 /* The list hasn't been initialized yet. */
1314 /* Ensure there are no QTDs or URBs left. */
1315 kill_urbs_in_qh_list(_hcd, _qh_list);
1317 for (item = _qh_list->next; item != _qh_list; item = _qh_list->next) {
1318 qh = list_entry(item, dwc_otg_qh_t, qh_list_entry);
1319 dwc_otg_hcd_qh_remove_and_free(_hcd, qh);
1324 * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
1327 void dwc_otg_hcd_stop(struct usb_hcd *_hcd)
1329 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
1330 hprt0_data_t hprt0 = { .d32=0 };
1332 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
1334 /* Turn off all host-specific interrupts. */
1335 dwc_otg_disable_host_interrupts( dwc_otg_hcd->core_if );
1338 * The root hub should be disconnected before this function is called.
1339 * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
1340 * and the QH lists (via ..._hcd_endpoint_disable).
1343 /* Turn off the vbus power */
1344 DWC_PRINT("PortPower off\n");
1346 dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
1352 /** Returns the current frame number. */
1353 int dwc_otg_hcd_get_frame_number(struct usb_hcd *_hcd)
1355 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
1358 hfnum.d32 = dwc_read_reg32(&dwc_otg_hcd->core_if->
1359 host_if->host_global_regs->hfnum);
1362 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n", hfnum.b.frnum);
1364 return hfnum.b.frnum;
1368 * Frees secondary storage associated with the dwc_otg_hcd structure contained
1369 * in the struct usb_hcd field.
1371 void dwc_otg_hcd_free(struct usb_hcd *_hcd)
1373 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
1376 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
1378 del_timers(dwc_otg_hcd);
1380 /* Free memory for QH/QTD lists */
1381 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
1382 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
1383 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
1384 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
1385 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
1386 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
1388 /* Free memory for the host channels. */
1389 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
1390 dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i];
1392 DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n", i, hc);
1397 if (dwc_otg_hcd->core_if->dma_enable) {
1398 if (dwc_otg_hcd->status_buf_dma) {
1399 dma_free_coherent(_hcd->self.controller,
1400 DWC_OTG_HCD_STATUS_BUF_SIZE,
1401 dwc_otg_hcd->status_buf,
1402 dwc_otg_hcd->status_buf_dma);
1404 } else if (dwc_otg_hcd->status_buf != NULL) {
1405 kfree(dwc_otg_hcd->status_buf);
1413 static void dump_urb_info(struct urb *_urb, char* _fn_name)
1415 DWC_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe));
1416 DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(_urb->pipe),
1417 (usb_pipein(_urb->pipe) ? "IN" : "OUT"));
1418 DWC_PRINT(" Endpoint type: %s\n",
1420 switch (usb_pipetype(_urb->pipe)) {
1421 case PIPE_CONTROL: pipetype = "CONTROL"; break;
1422 case PIPE_BULK: pipetype = "BULK"; break;
1423 case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
1424 case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
1425 default: pipetype = "UNKNOWN"; break;
1427 DWC_PRINT(" Speed: %s\n",
1429 switch (_urb->dev->speed) {
1430 case USB_SPEED_HIGH: speed = "HIGH"; break;
1431 case USB_SPEED_FULL: speed = "FULL"; break;
1432 case USB_SPEED_LOW: speed = "LOW"; break;
1433 default: speed = "UNKNOWN"; break;
1435 DWC_PRINT(" Max packet size: %d\n",
1436 usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe)));
1437 DWC_PRINT(" Data buffer length: %d\n", _urb->transfer_buffer_length);
1438 DWC_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
1439 _urb->transfer_buffer, (void *)_urb->transfer_dma);
1440 DWC_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
1441 _urb->setup_packet, (void *)_urb->setup_dma);
1442 DWC_PRINT(" Interval: %d\n", _urb->interval);
1443 if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) {
1445 for (i = 0; i < _urb->number_of_packets; i++) {
1446 DWC_PRINT(" ISO Desc %d:\n", i);
1447 DWC_PRINT(" offset: %d, length %d\n",
1448 _urb->iso_frame_desc[i].offset,
1449 _urb->iso_frame_desc[i].length);
1454 static void dump_channel_info(dwc_otg_hcd_t *_hcd,
1457 if (qh->channel != NULL) {
1458 dwc_hc_t *hc = qh->channel;
1459 struct list_head *item;
1460 dwc_otg_qh_t *qh_item;
1461 int num_channels = _hcd->core_if->core_params->host_channels;
1464 dwc_otg_hc_regs_t *hc_regs;
1465 hcchar_data_t hcchar;
1466 hcsplt_data_t hcsplt;
1467 hctsiz_data_t hctsiz;
1470 hc_regs = _hcd->core_if->host_if->hc_regs[hc->hc_num];
1471 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1472 hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
1473 hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
1474 hcdma = dwc_read_reg32(&hc_regs->hcdma);
1476 DWC_PRINT(" Assigned to channel %p:\n", hc);
1477 DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
1478 DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
1479 DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
1480 hc->dev_addr, hc->ep_num, hc->ep_is_in);
1481 DWC_PRINT(" ep_type: %d\n", hc->ep_type);
1482 DWC_PRINT(" max_packet: %d\n", hc->max_packet);
1483 DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
1484 DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
1485 DWC_PRINT(" halt_status: %d\n", hc->halt_status);
1486 DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
1487 DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
1488 DWC_PRINT(" qh: %p\n", hc->qh);
1489 DWC_PRINT(" NP inactive sched:\n");
1490 list_for_each(item, &_hcd->non_periodic_sched_inactive) {
1491 qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
1492 DWC_PRINT(" %p\n", qh_item);
1494 DWC_PRINT(" NP active sched:\n");
1495 list_for_each(item, &_hcd->non_periodic_sched_active) {
1496 qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
1497 DWC_PRINT(" %p\n", qh_item);
1499 DWC_PRINT(" Channels: \n");
1500 for (i = 0; i < num_channels; i++) {
1501 dwc_hc_t *hc = _hcd->hc_ptr_array[i];
1502 DWC_PRINT(" %2d: %p\n", i, hc);
1508 /** Starts processing a USB transfer request specified by a USB Request Block
1509 * (URB). mem_flags indicates the type of memory allocation to use while
1510 * processing this URB. */
1511 int dwc_otg_hcd_urb_enqueue(struct usb_hcd *_hcd,
1516 dwc_otg_hcd_t * dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
1517 dwc_otg_qtd_t * qtd;
1518 unsigned long flags;
1520 retval = usb_hcd_link_urb_to_ep(_hcd, _urb);
1523 DWC_PRINT("%s, usb_hcd_link_urb_to_ep error\n", __func__);
1527 spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
1530 * Make sure the start of frame interrupt is enabled now that
1531 * we know we should have queued data. The SOF interrupt
1532 * handler automatically disables itself when idle to reduce
1533 * the number of interrupts. See dwc_otg_hcd_handle_sof_intr()
1536 dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0,
1540 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
1541 dump_urb_info(_urb, "dwc_otg_hcd_urb_enqueue");
1544 if (!dwc_otg_hcd->flags.b.port_connect_status) {
1545 /* No longer connected. */
1549 qtd = dwc_otg_hcd_qtd_create(_urb);
1551 DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
1555 retval = dwc_otg_hcd_qtd_add(qtd, dwc_otg_hcd);
1557 DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
1558 "Error status %d\n", retval);
1559 dwc_otg_hcd_qtd_free(qtd);
1562 spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
1567 /** Aborts/cancels a USB transfer request. Always returns 0 to indicate
1569 int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status)
1571 unsigned long flags;
1572 dwc_otg_hcd_t * dwc_otg_hcd;
1573 dwc_otg_qtd_t * urb_qtd;
1575 struct usb_host_endpoint *_ep = _urb->ep;//dwc_urb_to_endpoint(_urb);
1578 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
1579 urb_qtd = (dwc_otg_qtd_t *) _urb->hcpriv;
1582 DWC_PRINT("%s=====================================================\n",__func__);
1583 DWC_PRINT("urb->ep is null\n");
1586 qh = (dwc_otg_qh_t *) _ep->hcpriv;
1587 spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
1589 retval = usb_hcd_check_unlink_urb(_hcd, _urb, _status);
1591 spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
1597 DWC_PRINT("%s,urb_qtd is null\n",__func__);
1601 dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
1604 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
1605 dump_urb_info(_urb, "dwc_otg_hcd_urb_dequeue");
1606 if (urb_qtd == qh->qtd_in_process) {
1607 dump_channel_info(dwc_otg_hcd, qh);
1613 if (urb_qtd == qh->qtd_in_process) {
1614 /* The QTD is in process (it has been assigned to a channel). */
1615 if (dwc_otg_hcd->flags.b.port_connect_status) {
1618 * If still connected (i.e. in host mode), halt the
1619 * channel so it can be used for other transfers. If
1620 * no longer connected, the host registers can't be
1621 * written to halt the channel since the core is in
1624 dwc_otg_hc_halt(dwc_otg_hcd->core_if, qh->channel,
1625 DWC_OTG_HC_XFER_URB_DEQUEUE);
1630 * Free the QTD and clean up the associated QH. Leave the QH in the
1631 * schedule if it has any remaining QTDs.
1633 dwc_otg_hcd_qtd_remove_and_free(urb_qtd);
1634 if (urb_qtd == qh->qtd_in_process) {
1635 dwc_otg_hcd_qh_deactivate(dwc_otg_hcd, qh, 0);
1637 qh->qtd_in_process = NULL;
1638 } else if (list_empty(&qh->qtd_list)) {
1639 dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh);
1644 spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
1645 _urb->hcpriv = NULL;
1646 //usb_hcd_unlink_urb_from_ep(_hcd, _urb);
1647 /* Higher layer software sets URB status. */
1648 usb_hcd_giveback_urb(_hcd, _urb, _status);
1649 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
1650 DWC_PRINT("Called usb_hcd_giveback_urb()\n");
1651 DWC_PRINT(" urb->status = %d\n", _status);
1657 /** Frees resources in the DWC_otg controller related to a given endpoint. Also
1658 * clears state in the HCD related to the endpoint. Any URBs for the endpoint
1659 * must already be dequeued. */
1660 void dwc_otg_hcd_endpoint_disable(struct usb_hcd *_hcd,
1661 struct usb_host_endpoint *_ep)
1664 unsigned long flags;
1666 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
1668 spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
1670 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
1671 "endpoint=%d\n", _ep->desc.bEndpointAddress,
1672 dwc_ep_addr_to_endpoint(_ep->desc.bEndpointAddress));
1674 qh = (dwc_otg_qh_t *)(_ep->hcpriv);
1677 /** Check that the QTD list is really empty */
1678 if (!list_empty(&qh->qtd_list)) {
1679 DWC_WARN("DWC OTG HCD EP DISABLE:"
1680 " QTD List for this endpoint is not empty\n");
1684 dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
1688 spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
1693 /** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
1694 * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
1697 * This function is called by the USB core when an interrupt occurs */
1698 irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *_hcd)
1701 unsigned long flags;
1702 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
1704 spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
1706 result = IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd));
1708 spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
1713 /** Creates Status Change bitmap for the root hub and root port. The bitmap is
1714 * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
1715 * is the status change indicator for the single root port. Returns 1 if either
1716 * change indicator is 1, otherwise returns 0. */
1717 int dwc_otg_hcd_hub_status_data(struct usb_hcd *_hcd,
1720 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
1723 _buf[0] |= (dwc_otg_hcd->flags.b.port_connect_status_change ||
1724 dwc_otg_hcd->flags.b.port_reset_change ||
1725 dwc_otg_hcd->flags.b.port_enable_change ||
1726 dwc_otg_hcd->flags.b.port_suspend_change ||
1727 dwc_otg_hcd->flags.b.port_over_current_change) << 1;
1731 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
1732 " Root port status changed\n");
1733 DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
1734 dwc_otg_hcd->flags.b.port_connect_status_change);
1735 DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
1736 dwc_otg_hcd->flags.b.port_reset_change);
1737 DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
1738 dwc_otg_hcd->flags.b.port_enable_change);
1739 DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
1740 dwc_otg_hcd->flags.b.port_suspend_change);
1741 DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
1742 dwc_otg_hcd->flags.b.port_over_current_change);
1745 return (_buf[0] != 0);
1748 #ifdef DWC_HS_ELECT_TST
1750 * Quick and dirty hack to implement the HS Electrical Test
1751 * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
1753 * This code was copied from our userspace app "hset". It sends a
1754 * Get Device Descriptor control sequence in two parts, first the
1755 * Setup packet by itself, followed some time later by the In and
1756 * Ack packets. Rather than trying to figure out how to add this
1757 * functionality to the normal driver code, we just hijack the
1758 * hardware, using these two function to drive the hardware
1762 dwc_otg_core_global_regs_t *global_regs;
1763 dwc_otg_host_global_regs_t *hc_global_regs;
1764 dwc_otg_hc_regs_t *hc_regs;
1765 uint32_t *data_fifo;
1767 static void do_setup(void)
1769 gintsts_data_t gintsts;
1770 hctsiz_data_t hctsiz;
1771 hcchar_data_t hcchar;
1776 dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
1779 dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
1782 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1783 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1786 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1787 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1790 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1791 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1794 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1795 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1798 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1801 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1804 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1807 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1808 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1811 * Send Setup packet (Get Device Descriptor)
1814 /* Make sure channel is disabled */
1815 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1816 if (hcchar.b.chen) {
1817 //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
1819 // hcchar.b.chen = 1;
1820 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1825 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1826 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1829 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1830 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1833 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1834 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1837 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1838 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1841 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1844 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1847 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1849 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1850 //if (hcchar.b.chen) {
1851 // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
1857 hctsiz.b.xfersize = 8;
1858 hctsiz.b.pktcnt = 1;
1859 hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
1860 dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
1863 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1864 hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
1869 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1871 /* Fill FIFO with Setup data for Get Device Descriptor */
1872 data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
1873 dwc_write_reg32(data_fifo++, 0x01000680);
1874 dwc_write_reg32(data_fifo++, 0x00080000);
1876 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1877 //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
1879 /* Wait for host channel interrupt */
1881 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1882 } while (gintsts.b.hcintr == 0);
1884 //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
1886 /* Disable HCINTs */
1887 dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
1889 /* Disable HAINTs */
1890 dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
1893 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1894 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1897 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1898 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1901 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1902 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1905 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1908 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1911 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1914 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1915 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1918 static void do_in_ack(void)
1920 gintsts_data_t gintsts;
1921 hctsiz_data_t hctsiz;
1922 hcchar_data_t hcchar;
1925 host_grxsts_data_t grxsts;
1928 dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
1931 dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
1934 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1935 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1938 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1939 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1942 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1943 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1946 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1947 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1950 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1953 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1956 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1959 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1960 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1963 * Receive Control In packet
1966 /* Make sure channel is disabled */
1967 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1968 if (hcchar.b.chen) {
1969 //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
1972 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1977 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1978 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1981 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1982 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1985 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1986 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1989 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1990 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1993 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1996 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1999 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
2001 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2002 //if (hcchar.b.chen) {
2003 // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
2009 hctsiz.b.xfersize = 8;
2010 hctsiz.b.pktcnt = 1;
2011 hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
2012 dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
2015 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2016 hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
2021 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2023 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2024 //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
2026 /* Wait for receive status queue interrupt */
2028 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2029 } while (gintsts.b.rxstsqlvl == 0);
2031 //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
2034 grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
2035 //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
2037 /* Clear RXSTSQLVL in GINTSTS */
2039 gintsts.b.rxstsqlvl = 1;
2040 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
2042 switch (grxsts.b.pktsts) {
2043 case DWC_GRXSTS_PKTSTS_IN:
2044 /* Read the data into the host buffer */
2045 if (grxsts.b.bcnt > 0) {
2047 int word_count = (grxsts.b.bcnt + 3) / 4;
2049 data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
2051 for (i = 0; i < word_count; i++) {
2052 (void)dwc_read_reg32(data_fifo++);
2056 //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt);
2060 //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
2064 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2065 //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
2067 /* Wait for receive status queue interrupt */
2069 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2070 } while (gintsts.b.rxstsqlvl == 0);
2072 //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
2075 grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
2076 //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
2078 /* Clear RXSTSQLVL in GINTSTS */
2080 gintsts.b.rxstsqlvl = 1;
2081 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
2083 switch (grxsts.b.pktsts) {
2084 case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
2088 //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
2092 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2093 //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
2095 /* Wait for host channel interrupt */
2097 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2098 } while (gintsts.b.hcintr == 0);
2100 //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
2103 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
2104 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
2107 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
2108 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
2111 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2112 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
2115 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
2118 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
2121 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
2124 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2125 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
2132 * Send handshake packet
2136 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
2137 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
2140 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
2141 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
2144 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2145 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
2148 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
2151 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
2154 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
2157 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2158 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
2160 /* Make sure channel is disabled */
2161 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2162 if (hcchar.b.chen) {
2163 //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
2166 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2171 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2172 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
2175 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
2176 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
2179 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
2180 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
2183 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2184 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
2187 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
2190 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
2193 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
2195 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2196 //if (hcchar.b.chen) {
2197 // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
2203 hctsiz.b.xfersize = 0;
2204 hctsiz.b.pktcnt = 1;
2205 hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
2206 dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
2209 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2210 hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
2215 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2217 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2218 //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
2220 /* Wait for host channel interrupt */
2222 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2223 } while (gintsts.b.hcintr == 0);
2225 //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
2227 /* Disable HCINTs */
2228 dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
2230 /* Disable HAINTs */
2231 dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
2234 haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
2235 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
2238 hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
2239 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
2242 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2243 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
2246 dwc_write_reg32(&hc_regs->hcint, hcint.d32);
2249 dwc_write_reg32(&hc_global_regs->haint, haint.d32);
2252 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
2255 gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
2256 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
2258 #endif /* DWC_HS_ELECT_TST */
2260 /** Handles hub class-specific requests.*/
2261 int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd,
2269 unsigned long flags;
2271 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
2272 dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd (_hcd)->core_if;
2273 struct usb_hub_descriptor *desc;
2274 hprt0_data_t hprt0 = {.d32 = 0};
2276 uint32_t port_status;
2277 spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
2280 case ClearHubFeature:
2281 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2282 "ClearHubFeature 0x%x\n", _wValue);
2284 case C_HUB_LOCAL_POWER:
2285 case C_HUB_OVER_CURRENT:
2286 /* Nothing required here */
2290 DWC_ERROR ("DWC OTG HCD - "
2291 "ClearHubFeature request %xh unknown\n", _wValue);
2294 case ClearPortFeature:
2295 if (!_wIndex || _wIndex > 1)
2299 case USB_PORT_FEAT_ENABLE:
2300 DWC_DEBUGPL (DBG_ANY, "DWC OTG HCD HUB CONTROL - "
2301 "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
2302 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2304 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2306 case USB_PORT_FEAT_SUSPEND:
2307 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2308 "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
2309 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2311 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2312 /* Clear Resume bit */
2315 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2317 case USB_PORT_FEAT_POWER:
2318 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2319 "ClearPortFeature USB_PORT_FEAT_POWER\n");
2320 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2322 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2324 case USB_PORT_FEAT_INDICATOR:
2325 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2326 "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
2327 /* Port inidicator not supported */
2329 case USB_PORT_FEAT_C_CONNECTION:
2330 /* Clears drivers internal connect status change
2332 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2333 "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
2334 dwc_otg_hcd->flags.b.port_connect_status_change = 0;
2336 case USB_PORT_FEAT_C_RESET:
2337 /* Clears the driver's internal Port Reset Change
2339 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2340 "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
2341 dwc_otg_hcd->flags.b.port_reset_change = 0;
2343 case USB_PORT_FEAT_C_ENABLE:
2344 /* Clears the driver's internal Port
2345 * Enable/Disable Change flag */
2346 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2347 "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
2348 dwc_otg_hcd->flags.b.port_enable_change = 0;
2350 case USB_PORT_FEAT_C_SUSPEND:
2351 /* Clears the driver's internal Port Suspend
2352 * Change flag, which is set when resume signaling on
2353 * the host port is complete */
2354 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2355 "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
2356 dwc_otg_hcd->flags.b.port_suspend_change = 0;
2358 case USB_PORT_FEAT_C_OVER_CURRENT:
2359 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2360 "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
2361 dwc_otg_hcd->flags.b.port_over_current_change = 0;
2365 DWC_ERROR ("DWC OTG HCD - "
2366 "ClearPortFeature request %xh "
2367 "unknown or unsupported\n", _wValue);
2370 case GetHubDescriptor:
2371 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2372 "GetHubDescriptor\n");
2373 desc = (struct usb_hub_descriptor *)_buf;
2374 desc->bDescLength = 9;
2375 desc->bDescriptorType = 0x29;
2376 desc->bNbrPorts = 1;
2377 desc->wHubCharacteristics = 0x08;
2378 desc->bPwrOn2PwrGood = 1;
2379 desc->bHubContrCurrent = 0;
2380 desc->bitmap[0] = 0;
2381 desc->bitmap[1] = 0xff;
2384 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2386 memset (_buf, 0, 4);
2389 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2392 if (!_wIndex || _wIndex > 1)
2397 if (dwc_otg_hcd->flags.b.port_connect_status_change)
2398 port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
2400 if (dwc_otg_hcd->flags.b.port_enable_change)
2401 port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
2403 if (dwc_otg_hcd->flags.b.port_suspend_change)
2404 port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
2406 if (dwc_otg_hcd->flags.b.port_reset_change)
2407 port_status |= (1 << USB_PORT_FEAT_C_RESET);
2409 if (dwc_otg_hcd->flags.b.port_over_current_change) {
2410 DWC_ERROR("Device Not Supported\n");
2411 port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
2414 if (!dwc_otg_hcd->flags.b.port_connect_status) {
2416 * The port is disconnected, which means the core is
2417 * either in device mode or it soon will be. Just
2418 * return 0's for the remainder of the port status
2419 * since the port register can't be read if the core
2420 * is in device mode.
2422 *((__le32 *) _buf) = cpu_to_le32(port_status);
2426 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
2427 DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
2429 if (hprt0.b.prtconnsts)
2430 port_status |= (1 << USB_PORT_FEAT_CONNECTION);
2433 port_status |= (1 << USB_PORT_FEAT_ENABLE);
2435 if (hprt0.b.prtsusp)
2436 port_status |= (1 << USB_PORT_FEAT_SUSPEND);
2438 if (hprt0.b.prtovrcurract)
2439 port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
2442 port_status |= (1 << USB_PORT_FEAT_RESET);
2445 port_status |= (1 << USB_PORT_FEAT_POWER);
2447 if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
2448 port_status |= (1 << USB_PORT_FEAT_HIGHSPEED);
2450 else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
2451 port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
2453 if (hprt0.b.prttstctl)
2454 port_status |= (1 << USB_PORT_FEAT_TEST);
2456 /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
2458 *((__le32 *) _buf) = cpu_to_le32(port_status);
2462 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2464 /* No HUB features supported */
2466 case SetPortFeature:
2467 if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
2470 if (!dwc_otg_hcd->flags.b.port_connect_status) {
2472 * The port is disconnected, which means the core is
2473 * either in device mode or it soon will be. Just
2474 * return without doing anything since the port
2475 * register can't be written if the core is in device
2482 case USB_PORT_FEAT_SUSPEND:
2483 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2484 "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
2485 if (_hcd->self.otg_port == _wIndex &&
2486 _hcd->self.b_hnp_enable) {
2487 gotgctl_data_t gotgctl = {.d32=0};
2488 gotgctl.b.hstsethnpen = 1;
2489 dwc_modify_reg32( &core_if->core_global_regs->gotgctl,
2491 core_if->op_state = A_SUSPEND;
2493 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2494 hprt0.b.prtsusp = 1;
2495 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2496 //DWC_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32);
2497 /* Suspend the Phy Clock */
2499 pcgcctl_data_t pcgcctl = {.d32=0};
2500 pcgcctl.b.stoppclk = 1;
2501 dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
2504 /* For HNP the bus must be suspended for at least 200ms.*/
2505 if (_hcd->self.b_hnp_enable) {
2507 //DWC_PRINT( "SUSPEND: wait complete! (%d)\n", _hcd->state);
2510 case USB_PORT_FEAT_POWER:
2511 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2512 "SetPortFeature - USB_PORT_FEAT_POWER\n");
2513 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2515 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2517 case USB_PORT_FEAT_RESET:
2518 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2519 "SetPortFeature - USB_PORT_FEAT_RESET\n");
2520 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2521 /* When B-Host the Port reset bit is set in
2522 * the Start HCD Callback function, so that
2523 * the reset is started within 1ms of the HNP
2524 * success interrupt. */
2525 if (!_hcd->self.is_b_host) {
2527 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2529 /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
2532 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2535 #ifdef DWC_HS_ELECT_TST
2536 case USB_PORT_FEAT_TEST:
2539 gintmsk_data_t gintmsk;
2541 t = (_wIndex >> 8); /* MSB wIndex USB */
2542 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2543 "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
2544 warn("USB_PORT_FEAT_TEST %d\n", t);
2546 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2547 hprt0.b.prttstctl = t;
2548 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2550 /* Setup global vars with reg addresses (quick and
2551 * dirty hack, should be cleaned up)
2553 global_regs = core_if->core_global_regs;
2554 hc_global_regs = core_if->host_if->host_global_regs;
2555 hc_regs = (dwc_otg_hc_regs_t *)((char *)global_regs + 0x500);
2556 data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
2558 if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
2559 /* Save current interrupt mask */
2560 gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
2562 /* Disable all interrupts while we muck with
2563 * the hardware directly
2565 dwc_write_reg32(&global_regs->gintmsk, 0);
2567 /* 15 second delay per the test spec */
2570 /* Drive suspend on the root port */
2571 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2572 hprt0.b.prtsusp = 1;
2574 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2576 /* 15 second delay per the test spec */
2579 /* Drive resume on the root port */
2580 hprt0.d32 = dwc_otg_read_hprt0 (core_if);
2581 hprt0.b.prtsusp = 0;
2583 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2586 /* Clear the resume bit */
2588 dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
2590 /* Restore interrupts */
2591 dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
2592 } else if (t == 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
2593 /* Save current interrupt mask */
2594 gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
2596 /* Disable all interrupts while we muck with
2597 * the hardware directly
2599 dwc_write_reg32(&global_regs->gintmsk, 0);
2601 /* 15 second delay per the test spec */
2604 /* Send the Setup packet */
2607 /* 15 second delay so nothing else happens for awhile */
2610 /* Restore interrupts */
2611 dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
2612 } else if (t == 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
2613 /* Save current interrupt mask */
2614 gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
2616 /* Disable all interrupts while we muck with
2617 * the hardware directly
2619 dwc_write_reg32(&global_regs->gintmsk, 0);
2621 /* Send the Setup packet */
2624 /* 15 second delay so nothing else happens for awhile */
2627 /* Send the In and Ack packets */
2630 /* 15 second delay so nothing else happens for awhile */
2633 /* Restore interrupts */
2634 dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
2639 #endif /* DWC_HS_ELECT_TST */
2641 case USB_PORT_FEAT_INDICATOR:
2642 DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2643 "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
2648 DWC_ERROR ("DWC OTG HCD - "
2649 "SetPortFeature request %xh "
2650 "unknown or unsupported\n", _wValue);
2657 DWC_WARN ("DWC OTG HCD - "
2658 "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
2659 _typeReq, _wIndex, _wValue);
2663 spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
2669 * Assigns transactions from a QTD to a free host channel and initializes the
2670 * host channel to perform the transactions. The host channel is removed from
2673 * @param _hcd The HCD state structure.
2674 * @param _qh Transactions from the first QTD for this QH are selected and
2675 * assigned to a free host channel.
2677 static void assign_and_init_hc(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
2683 DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _hcd, _qh);
2684 hc = list_entry(_hcd->free_hc_list.next, dwc_hc_t, hc_list_entry);
2686 /* Remove the host channel from the free list. */
2687 list_del_init(&hc->hc_list_entry);
2689 qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
2692 _qh->qtd_in_process = qtd;
2695 * Use usb_pipedevice to determine device address. This address is
2696 * 0 before the SET_ADDRESS command and the correct address afterward.
2698 hc->dev_addr = usb_pipedevice(urb->pipe);
2699 hc->ep_num = usb_pipeendpoint(urb->pipe);
2701 if (urb->dev->speed == USB_SPEED_LOW) {
2702 hc->speed = DWC_OTG_EP_SPEED_LOW;
2704 * yk@rk 20101216 fix bandwidth check error when full/low speed
2707 _hcd->core_if->core_params->speed = DWC_SPEED_PARAM_FULL;
2708 } else if (urb->dev->speed == USB_SPEED_FULL) {
2709 hc->speed = DWC_OTG_EP_SPEED_FULL;
2711 * yk@rk 20101216 fix bandwidth check error when full/low speed
2712 * device connected. warning: only support 1 device at root hub.
2714 _hcd->core_if->core_params->speed = DWC_SPEED_PARAM_FULL;
2716 hc->speed = DWC_OTG_EP_SPEED_HIGH;
2719 hc->max_packet = dwc_max_packet(_qh->maxp);
2721 hc->xfer_started = 0;
2722 hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
2723 hc->error_state = (qtd->error_count > 0);
2724 hc->halt_on_queue = 0;
2725 hc->halt_pending = 0;
2729 * The following values may be modified in the transfer type section
2730 * below. The xfer_len value may be reduced when the transfer is
2731 * started to accommodate the max widths of the XferSize and PktCnt
2732 * fields in the HCTSIZn register.
2734 hc->do_ping = _qh->ping_state;
2735 hc->ep_is_in = (usb_pipein(urb->pipe) != 0);
2736 hc->data_pid_start = _qh->data_toggle;
2737 hc->multi_count = 1;
2739 if (_hcd->core_if->dma_enable) {
2740 hc->xfer_buff = (uint8_t *)urb->transfer_dma + urb->actual_length;
2742 hc->xfer_buff = (uint8_t *)urb->transfer_buffer + urb->actual_length;
2744 hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
2748 * Set the split attributes
2751 if (_qh->do_split) {
2753 hc->xact_pos = qtd->isoc_split_pos;
2754 hc->complete_split = qtd->complete_split;
2755 hc->hub_addr = urb->dev->tt->hub->devnum;
2756 hc->port_addr = urb->dev->ttport;
2759 switch (usb_pipetype(urb->pipe)) {
2761 hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
2762 switch (qtd->control_phase) {
2763 case DWC_OTG_CONTROL_SETUP:
2764 DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
2767 hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
2768 if (_hcd->core_if->dma_enable) {
2769 hc->xfer_buff = (uint8_t *)urb->setup_dma;
2771 hc->xfer_buff = (uint8_t *)urb->setup_packet;
2775 case DWC_OTG_CONTROL_DATA:
2776 DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
2777 hc->data_pid_start = qtd->data_toggle;
2779 case DWC_OTG_CONTROL_STATUS:
2781 * Direction is opposite of data direction or IN if no
2784 DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
2785 if (urb->transfer_buffer_length == 0) {
2788 hc->ep_is_in = (usb_pipein(urb->pipe) != USB_DIR_IN);
2793 hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
2795 if (_hcd->core_if->dma_enable) {
2796 hc->xfer_buff = (uint8_t *)_hcd->status_buf_dma;
2798 hc->xfer_buff = (uint8_t *)_hcd->status_buf;
2804 hc->ep_type = DWC_OTG_EP_TYPE_BULK;
2806 case PIPE_INTERRUPT:
2807 hc->ep_type = DWC_OTG_EP_TYPE_INTR;
2809 case PIPE_ISOCHRONOUS:
2811 struct usb_iso_packet_descriptor *frame_desc;
2812 frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
2813 hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
2814 if (_hcd->core_if->dma_enable) {
2815 hc->xfer_buff = (uint8_t *)urb->transfer_dma;
2817 hc->xfer_buff = (uint8_t *)urb->transfer_buffer;
2819 hc->xfer_buff += frame_desc->offset + qtd->isoc_split_offset;
2820 hc->xfer_len = frame_desc->length - qtd->isoc_split_offset;
2822 if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
2823 if (hc->xfer_len <= 188) {
2824 hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
2827 hc->xact_pos = DWC_HCSPLIT_XACTPOS_BEGIN;
2834 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2835 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2837 * This value may be modified when the transfer is started to
2838 * reflect the actual transfer length.
2840 hc->multi_count = dwc_hb_mult(_qh->maxp);
2843 dwc_otg_hc_init(_hcd->core_if, hc);
2848 * This function selects transactions from the HCD transfer schedule and
2849 * assigns them to available host channels. It is called from HCD interrupt
2850 * handler functions.
2852 * @param _hcd The HCD state structure.
2854 * @return The types of new transactions that were assigned to host channels.
2856 dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *_hcd)
2858 struct list_head *qh_ptr;
2861 dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
2864 DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
2867 /* Process entries in the periodic ready list. */
2868 qh_ptr = _hcd->periodic_sched_ready.next;
2869 while (qh_ptr != &_hcd->periodic_sched_ready &&
2870 !list_empty(&_hcd->free_hc_list)) {
2872 qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
2873 assign_and_init_hc(_hcd, qh);
2876 * Move the QH from the periodic ready schedule to the
2877 * periodic assigned schedule.
2879 qh_ptr = qh_ptr->next;
2880 list_move(&qh->qh_list_entry, &_hcd->periodic_sched_assigned);
2882 ret_val = DWC_OTG_TRANSACTION_PERIODIC;
2886 * Process entries in the inactive portion of the non-periodic
2887 * schedule. Some free host channels may not be used if they are
2888 * reserved for periodic transfers.
2890 qh_ptr = _hcd->non_periodic_sched_inactive.next;
2891 num_channels = _hcd->core_if->core_params->host_channels;
2892 while (qh_ptr != &_hcd->non_periodic_sched_inactive &&
2894 (_hcd->non_periodic_channels <
2895 num_channels - _hcd->periodic_channels) &&
2897 !list_empty(&_hcd->free_hc_list)) {
2899 qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
2900 assign_and_init_hc(_hcd, qh);
2903 * Move the QH from the non-periodic inactive schedule to the
2904 * non-periodic active schedule.
2906 qh_ptr = qh_ptr->next;
2907 list_move(&qh->qh_list_entry, &_hcd->non_periodic_sched_active);
2909 if (ret_val == DWC_OTG_TRANSACTION_NONE) {
2910 ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
2912 ret_val = DWC_OTG_TRANSACTION_ALL;
2915 _hcd->non_periodic_channels++;
2922 * Attempts to queue a single transaction request for a host channel
2923 * associated with either a periodic or non-periodic transfer. This function
2924 * assumes that there is space available in the appropriate request queue. For
2925 * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
2926 * is available in the appropriate Tx FIFO.
2928 * @param _hcd The HCD state structure.
2929 * @param _hc Host channel descriptor associated with either a periodic or
2930 * non-periodic transfer.
2931 * @param _fifo_dwords_avail Number of DWORDs available in the periodic Tx
2932 * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
2935 * @return 1 if a request is queued and more requests may be needed to
2936 * complete the transfer, 0 if no more requests are required for this
2937 * transfer, -1 if there is insufficient space in the Tx FIFO.
2939 static int queue_transaction(dwc_otg_hcd_t *_hcd,
2941 uint16_t _fifo_dwords_avail)
2945 if (_hcd->core_if->dma_enable) {
2946 if (!_hc->xfer_started) {
2947 dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
2948 _hc->qh->ping_state = 0;
2951 } else if (_hc->halt_pending) {
2952 /* Don't queue a request if the channel has been halted. */
2954 } else if (_hc->halt_on_queue) {
2955 dwc_otg_hc_halt(_hcd->core_if, _hc, _hc->halt_status);
2957 } else if (_hc->do_ping) {
2958 if (!_hc->xfer_started) {
2959 dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
2962 } else if (!_hc->ep_is_in ||
2963 _hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
2964 if ((_fifo_dwords_avail * 4) >= _hc->max_packet) {
2965 if (!_hc->xfer_started) {
2966 dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
2969 retval = dwc_otg_hc_continue_transfer(_hcd->core_if, _hc);
2975 if (!_hc->xfer_started) {
2976 dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
2979 retval = dwc_otg_hc_continue_transfer(_hcd->core_if, _hc);
2987 * Processes active non-periodic channels and queues transactions for these
2988 * channels to the DWC_otg controller. After queueing transactions, the NP Tx
2989 * FIFO Empty interrupt is enabled if there are more transactions to queue as
2990 * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
2991 * FIFO Empty interrupt is disabled.
2993 static void process_non_periodic_channels(dwc_otg_hcd_t *_hcd)
2995 gnptxsts_data_t tx_status;
2996 struct list_head *orig_qh_ptr;
2999 int no_queue_space = 0;
3000 int no_fifo_space = 0;
3003 dwc_otg_core_global_regs_t *global_regs = _hcd->core_if->core_global_regs;
3005 DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
3007 tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
3008 DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (before queue): %d\n",
3009 tx_status.b.nptxqspcavail);
3010 DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
3011 tx_status.b.nptxfspcavail);
3014 * Keep track of the starting point. Skip over the start-of-list
3017 if (_hcd->non_periodic_qh_ptr == &_hcd->non_periodic_sched_active) {
3018 _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
3020 orig_qh_ptr = _hcd->non_periodic_qh_ptr;
3023 * Process once through the active list or until no more space is
3024 * available in the request queue or the Tx FIFO.
3027 tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
3028 if (!_hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
3033 qh = list_entry(_hcd->non_periodic_qh_ptr, dwc_otg_qh_t, qh_list_entry);
3034 status = queue_transaction(_hcd, qh->channel, tx_status.b.nptxfspcavail);
3038 } else if (status < 0) {
3043 /* Advance to next QH, skipping start-of-list entry. */
3044 _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
3045 if (_hcd->non_periodic_qh_ptr == &_hcd->non_periodic_sched_active) {
3046 _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
3049 } while (_hcd->non_periodic_qh_ptr != orig_qh_ptr);
3051 if (!_hcd->core_if->dma_enable) {
3052 gintmsk_data_t intr_mask = {.d32 = 0};
3053 intr_mask.b.nptxfempty = 1;
3056 tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
3057 DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (after queue): %d\n",
3058 tx_status.b.nptxqspcavail);
3059 DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (after queue): %d\n",
3060 tx_status.b.nptxfspcavail);
3062 if (more_to_do || no_queue_space || no_fifo_space) {
3064 * May need to queue more transactions as the request
3065 * queue or Tx FIFO empties. Enable the non-periodic
3066 * Tx FIFO empty interrupt. (Always use the half-empty
3067 * level to ensure that new requests are loaded as
3068 * soon as possible.)
3070 dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
3073 * Disable the Tx FIFO empty interrupt since there are
3074 * no more transactions that need to be queued right
3075 * now. This function is called from interrupt
3076 * handlers to queue more transactions as transfer
3079 dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
3085 * Processes periodic channels for the next frame and queues transactions for
3086 * these channels to the DWC_otg controller. After queueing transactions, the
3087 * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
3088 * to queue as Periodic Tx FIFO or request queue space becomes available.
3089 * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
3091 static void process_periodic_channels(dwc_otg_hcd_t *_hcd)
3093 hptxsts_data_t tx_status;
3094 struct list_head *qh_ptr;
3097 int no_queue_space = 0;
3098 int no_fifo_space = 0;
3100 dwc_otg_host_global_regs_t *host_regs;
3101 host_regs = _hcd->core_if->host_if->host_global_regs;
3103 DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
3105 tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
3106 DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (before queue): %d\n",
3107 tx_status.b.ptxqspcavail);
3108 DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
3109 tx_status.b.ptxfspcavail);
3112 qh_ptr = _hcd->periodic_sched_assigned.next;
3113 while (qh_ptr != &_hcd->periodic_sched_assigned) {
3114 tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
3115 if (tx_status.b.ptxqspcavail == 0) {
3120 qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
3123 * Set a flag if we're queuing high-bandwidth in slave mode.
3124 * The flag prevents any halts to get into the request queue in
3125 * the middle of multiple high-bandwidth packets getting queued.
3127 if ((!_hcd->core_if->dma_enable) &&
3128 (qh->channel->multi_count > 1))
3130 _hcd->core_if->queuing_high_bandwidth = 1;
3133 status = queue_transaction(_hcd, qh->channel, tx_status.b.ptxfspcavail);
3140 * In Slave mode, stay on the current transfer until there is
3141 * nothing more to do or the high-bandwidth request count is
3142 * reached. In DMA mode, only need to queue one request. The
3143 * controller automatically handles multiple packets for
3144 * high-bandwidth transfers.
3146 if (_hcd->core_if->dma_enable ||
3148 qh->channel->requests == qh->channel->multi_count)) {
3149 qh_ptr = qh_ptr->next;
3151 * Move the QH from the periodic assigned schedule to
3152 * the periodic queued schedule.
3154 list_move(&qh->qh_list_entry, &_hcd->periodic_sched_queued);
3156 /* done queuing high bandwidth */
3157 _hcd->core_if->queuing_high_bandwidth = 0;
3161 if (!_hcd->core_if->dma_enable) {
3162 dwc_otg_core_global_regs_t *global_regs;
3163 gintmsk_data_t intr_mask = {.d32 = 0};
3165 global_regs = _hcd->core_if->core_global_regs;
3166 intr_mask.b.ptxfempty = 1;
3168 tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
3169 DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (after queue): %d\n",
3170 tx_status.b.ptxqspcavail);
3171 DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (after queue): %d\n",
3172 tx_status.b.ptxfspcavail);
3174 if (!(list_empty(&_hcd->periodic_sched_assigned)) ||
3175 no_queue_space || no_fifo_space) {
3177 * May need to queue more transactions as the request
3178 * queue or Tx FIFO empties. Enable the periodic Tx
3179 * FIFO empty interrupt. (Always use the half-empty
3180 * level to ensure that new requests are loaded as
3181 * soon as possible.)
3183 dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
3186 * Disable the Tx FIFO empty interrupt since there are
3187 * no more transactions that need to be queued right
3188 * now. This function is called from interrupt
3189 * handlers to queue more transactions as transfer
3192 dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
3198 * This function processes the currently active host channels and queues
3199 * transactions for these channels to the DWC_otg controller. It is called
3200 * from HCD interrupt handler functions.
3202 * @param _hcd The HCD state structure.
3203 * @param _tr_type The type(s) of transactions to queue (non-periodic,
3204 * periodic, or both).
3206 void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *_hcd,
3207 dwc_otg_transaction_type_e _tr_type)
3210 DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
3212 /* Process host channels associated with periodic transfers. */
3213 if ((_tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
3214 _tr_type == DWC_OTG_TRANSACTION_ALL) &&
3215 !list_empty(&_hcd->periodic_sched_assigned)) {
3217 process_periodic_channels(_hcd);
3220 /* Process host channels associated with non-periodic transfers. */
3221 if ((_tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
3222 _tr_type == DWC_OTG_TRANSACTION_ALL)) {
3223 if (!list_empty(&_hcd->non_periodic_sched_active)) {
3224 process_non_periodic_channels(_hcd);
3227 * Ensure NP Tx FIFO empty interrupt is disabled when
3228 * there are no non-periodic transfers to process.
3230 gintmsk_data_t gintmsk = {.d32 = 0};
3231 gintmsk.b.nptxfempty = 1;
3232 dwc_modify_reg32(&_hcd->core_if->core_global_regs->gintmsk,
3239 * Sets the final status of an URB and returns it to the device driver. Any
3240 * required cleanup of the URB is performed.
3242 void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t * _hcd, struct urb *_urb,
3244 __releases(_hcd->lock)
3245 __acquires(_hcd->lock)
3249 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
3250 DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
3251 __func__, _urb, usb_pipedevice(_urb->pipe),
3252 usb_pipeendpoint(_urb->pipe),
3253 usb_pipein(_urb->pipe) ? "IN" : "OUT", _status);
3254 if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) {
3256 for (i = 0; i < _urb->number_of_packets; i++) {
3257 DWC_PRINT(" ISO Desc %d status: %d\n",
3258 i, _urb->iso_frame_desc[i].status);
3265 _urb->hcpriv = NULL;
3266 //usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(_hcd), _urb);
3267 spin_unlock(&_hcd->lock);
3268 usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(_hcd), _urb, _status);
3269 spin_lock(&_hcd->lock);
3272 void dwc_otg_clear_halt(struct urb *_urb)
3274 struct dwc_otg_qh *_qh;
3275 struct usb_host_endpoint *ep = dwc_urb_to_endpoint(_urb);
3276 if((ep)&&(ep->hcpriv))
3278 _qh = (dwc_otg_qh_t *) ep->hcpriv;
3279 _qh->data_toggle = 0;
3283 * Returns the Queue Head for an URB.
3285 dwc_otg_qh_t * dwc_urb_to_qh(struct urb *_urb)
3287 struct usb_host_endpoint *ep = dwc_urb_to_endpoint(_urb);
3288 return (dwc_otg_qh_t *) ep->hcpriv;
3292 void dwc_print_setup_data (uint8_t *setup)
3295 if (CHK_DEBUG_LEVEL(DBG_HCD)){
3296 DWC_PRINT("Setup Data = MSB ");
3297 for (i=7; i>=0; i--) DWC_PRINT ("%02x ", setup[i]);
3299 DWC_PRINT(" bmRequestType Tranfer = %s\n", (setup[0]&0x80) ? "Device-to-Host" : "Host-to-Device");
3300 DWC_PRINT(" bmRequestType Type = ");
3301 switch ((setup[0]&0x60) >> 5) {
3302 case 0: DWC_PRINT("Standard\n"); break;
3303 case 1: DWC_PRINT("Class\n"); break;
3304 case 2: DWC_PRINT("Vendor\n"); break;
3305 case 3: DWC_PRINT("Reserved\n"); break;
3307 DWC_PRINT(" bmRequestType Recipient = ");
3308 switch (setup[0]&0x1f) {
3309 case 0: DWC_PRINT("Device\n"); break;
3310 case 1: DWC_PRINT("Interface\n"); break;
3311 case 2: DWC_PRINT("Endpoint\n"); break;
3312 case 3: DWC_PRINT("Other\n"); break;
3313 default: DWC_PRINT("Reserved\n"); break;
3315 DWC_PRINT(" bRequest = 0x%0x\n", setup[1]);
3316 DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *)&setup[2]));
3317 DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *)&setup[4]));
3318 DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *)&setup[6]));
3323 void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *_hcd) {
3325 DWC_PRINT("Frame remaining at SOF:\n");
3326 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3327 _hcd->frrem_samples, _hcd->frrem_accum,
3328 (_hcd->frrem_samples > 0) ?
3329 _hcd->frrem_accum/_hcd->frrem_samples : 0);
3332 DWC_PRINT("Frame remaining at start_transfer (uframe 7):\n");
3333 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3334 _hcd->core_if->hfnum_7_samples, _hcd->core_if->hfnum_7_frrem_accum,
3335 (_hcd->core_if->hfnum_7_samples > 0) ?
3336 _hcd->core_if->hfnum_7_frrem_accum/_hcd->core_if->hfnum_7_samples : 0);
3337 DWC_PRINT("Frame remaining at start_transfer (uframe 0):\n");
3338 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3339 _hcd->core_if->hfnum_0_samples, _hcd->core_if->hfnum_0_frrem_accum,
3340 (_hcd->core_if->hfnum_0_samples > 0) ?
3341 _hcd->core_if->hfnum_0_frrem_accum/_hcd->core_if->hfnum_0_samples : 0);
3342 DWC_PRINT("Frame remaining at start_transfer (uframe 1-6):\n");
3343 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3344 _hcd->core_if->hfnum_other_samples, _hcd->core_if->hfnum_other_frrem_accum,
3345 (_hcd->core_if->hfnum_other_samples > 0) ?
3346 _hcd->core_if->hfnum_other_frrem_accum/_hcd->core_if->hfnum_other_samples : 0);
3349 DWC_PRINT("Frame remaining at sample point A (uframe 7):\n");
3350 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3351 _hcd->hfnum_7_samples_a, _hcd->hfnum_7_frrem_accum_a,
3352 (_hcd->hfnum_7_samples_a > 0) ?
3353 _hcd->hfnum_7_frrem_accum_a/_hcd->hfnum_7_samples_a : 0);
3354 DWC_PRINT("Frame remaining at sample point A (uframe 0):\n");
3355 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3356 _hcd->hfnum_0_samples_a, _hcd->hfnum_0_frrem_accum_a,
3357 (_hcd->hfnum_0_samples_a > 0) ?
3358 _hcd->hfnum_0_frrem_accum_a/_hcd->hfnum_0_samples_a : 0);
3359 DWC_PRINT("Frame remaining at sample point A (uframe 1-6):\n");
3360 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3361 _hcd->hfnum_other_samples_a, _hcd->hfnum_other_frrem_accum_a,
3362 (_hcd->hfnum_other_samples_a > 0) ?
3363 _hcd->hfnum_other_frrem_accum_a/_hcd->hfnum_other_samples_a : 0);
3366 DWC_PRINT("Frame remaining at sample point B (uframe 7):\n");
3367 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3368 _hcd->hfnum_7_samples_b, _hcd->hfnum_7_frrem_accum_b,
3369 (_hcd->hfnum_7_samples_b > 0) ?
3370 _hcd->hfnum_7_frrem_accum_b/_hcd->hfnum_7_samples_b : 0);
3371 DWC_PRINT("Frame remaining at sample point B (uframe 0):\n");
3372 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3373 _hcd->hfnum_0_samples_b, _hcd->hfnum_0_frrem_accum_b,
3374 (_hcd->hfnum_0_samples_b > 0) ?
3375 _hcd->hfnum_0_frrem_accum_b/_hcd->hfnum_0_samples_b : 0);
3376 DWC_PRINT("Frame remaining at sample point B (uframe 1-6):\n");
3377 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
3378 _hcd->hfnum_other_samples_b, _hcd->hfnum_other_frrem_accum_b,
3379 (_hcd->hfnum_other_samples_b > 0) ?
3380 _hcd->hfnum_other_frrem_accum_b/_hcd->hfnum_other_samples_b : 0);
3384 void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *_hcd)
3389 gnptxsts_data_t np_tx_status;
3390 hptxsts_data_t p_tx_status;
3392 num_channels = _hcd->core_if->core_params->host_channels;
3394 DWC_PRINT("************************************************************\n");
3395 DWC_PRINT("HCD State:\n");
3396 DWC_PRINT(" Num channels: %d\n", num_channels);
3397 for (i = 0; i < num_channels; i++) {
3398 dwc_hc_t *hc = _hcd->hc_ptr_array[i];
3399 DWC_PRINT(" Channel %d:\n", i);
3400 DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
3401 hc->dev_addr, hc->ep_num, hc->ep_is_in);
3402 DWC_PRINT(" speed: %d\n", hc->speed);
3403 DWC_PRINT(" ep_type: %d\n", hc->ep_type);
3404 DWC_PRINT(" max_packet: %d\n", hc->max_packet);
3405 DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
3406 DWC_PRINT(" multi_count: %d\n", hc->multi_count);
3407 DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
3408 DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
3409 DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
3410 DWC_PRINT(" xfer_count: %d\n", hc->xfer_count);
3411 DWC_PRINT(" halt_on_queue: %d\n", hc->halt_on_queue);
3412 DWC_PRINT(" halt_pending: %d\n", hc->halt_pending);
3413 DWC_PRINT(" halt_status: %d\n", hc->halt_status);
3414 DWC_PRINT(" do_split: %d\n", hc->do_split);
3415 DWC_PRINT(" complete_split: %d\n", hc->complete_split);
3416 DWC_PRINT(" hub_addr: %d\n", hc->hub_addr);
3417 DWC_PRINT(" port_addr: %d\n", hc->port_addr);
3418 DWC_PRINT(" xact_pos: %d\n", hc->xact_pos);
3419 DWC_PRINT(" requests: %d\n", hc->requests);
3420 DWC_PRINT(" qh: %p\n", hc->qh);
3421 if (hc->xfer_started) {
3423 hcchar_data_t hcchar;
3424 hctsiz_data_t hctsiz;
3426 hcintmsk_data_t hcintmsk;
3427 hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum);
3428 hcchar.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcchar);
3429 hctsiz.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hctsiz);
3430 hcint.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcint);
3431 hcintmsk.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcintmsk);
3432 DWC_PRINT(" hfnum: 0x%08x\n", hfnum.d32);
3433 DWC_PRINT(" hcchar: 0x%08x\n", hcchar.d32);
3434 DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz.d32);
3435 DWC_PRINT(" hcint: 0x%08x\n", hcint.d32);
3436 DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk.d32);
3438 if (hc->xfer_started && (hc->qh != NULL) && (hc->qh->qtd_in_process != NULL)) {
3441 qtd = hc->qh->qtd_in_process;
3443 DWC_PRINT(" URB Info:\n");
3444 DWC_PRINT(" qtd: %p, urb: %p\n", qtd, urb);
3446 DWC_PRINT(" Dev: %d, EP: %d %s\n",
3447 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe),
3448 usb_pipein(urb->pipe) ? "IN" : "OUT");
3449 DWC_PRINT(" Max packet size: %d\n",
3450 usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
3451 DWC_PRINT(" transfer_buffer: %p\n", urb->transfer_buffer);
3452 DWC_PRINT(" transfer_dma: %p\n", (void *)urb->transfer_dma);
3453 DWC_PRINT(" transfer_buffer_length: %d\n", urb->transfer_buffer_length);
3454 DWC_PRINT(" actual_length: %d\n", urb->actual_length);
3458 DWC_PRINT(" non_periodic_channels: %d\n", _hcd->non_periodic_channels);
3459 DWC_PRINT(" periodic_channels: %d\n", _hcd->periodic_channels);
3460 DWC_PRINT(" periodic_usecs: %d\n", _hcd->periodic_usecs);
3461 np_tx_status.d32 = dwc_read_reg32(&_hcd->core_if->core_global_regs->gnptxsts);
3462 DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n", np_tx_status.b.nptxqspcavail);
3463 DWC_PRINT(" NP Tx FIFO Space Avail: %d\n", np_tx_status.b.nptxfspcavail);
3464 p_tx_status.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hptxsts);
3465 DWC_PRINT(" P Tx Req Queue Space Avail: %d\n", p_tx_status.b.ptxqspcavail);
3466 DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
3467 dwc_otg_hcd_dump_frrem(_hcd);
3468 dwc_otg_dump_global_registers(_hcd->core_if);
3469 dwc_otg_dump_host_registers(_hcd->core_if);
3470 DWC_PRINT("************************************************************\n");
3474 #endif /* DWC_DEVICE_ONLY */