1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $
4 * $Date: 2008-11-21 05:39:15 $
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/kernel.h>
42 #include <linux/module.h>
43 #include <linux/moduleparam.h>
44 #include <linux/init.h>
45 #include <linux/device.h>
46 #include <linux/errno.h>
47 #include <linux/list.h>
48 #include <linux/interrupt.h>
49 #include <linux/string.h>
50 #include <linux/dma-mapping.h>
51 #include <linux/version.h>
53 #include "dwc_otg_driver.h"
54 #include "dwc_otg_hcd.h"
55 #include "dwc_otg_regs.h"
57 static const char dwc_otg_hcd_name
[] = "dwc_otg";
59 static const struct hc_driver dwc_otg_hc_driver
= {
61 .description
= dwc_otg_hcd_name
,
62 .product_desc
= "DWC OTG Controller",
63 .hcd_priv_size
= sizeof(dwc_otg_hcd_t
),
65 .irq
= dwc_otg_hcd_irq
,
67 .flags
= HCD_MEMORY
| HCD_USB2
,
70 .start
= dwc_otg_hcd_start
,
73 .stop
= dwc_otg_hcd_stop
,
75 .urb_enqueue
= dwc_otg_hcd_urb_enqueue
,
76 .urb_dequeue
= dwc_otg_hcd_urb_dequeue
,
77 .endpoint_disable
= dwc_otg_hcd_endpoint_disable
,
79 .get_frame_number
= dwc_otg_hcd_get_frame_number
,
81 .hub_status_data
= dwc_otg_hcd_hub_status_data
,
82 .hub_control
= dwc_otg_hcd_hub_control
,
88 * Work queue function for starting the HCD when A-Cable is connected.
89 * The dwc_otg_hcd_start() must be called in a process context.
91 static void hcd_start_func(
92 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
95 struct work_struct
*_work
99 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
100 struct usb_hcd
*usb_hcd
= (struct usb_hcd
*)_vp
;
102 struct delayed_work
*dw
= container_of(_work
, struct delayed_work
, work
);
103 struct dwc_otg_hcd
*otg_hcd
= container_of(dw
, struct dwc_otg_hcd
, start_work
);
104 struct usb_hcd
*usb_hcd
= container_of((void *)otg_hcd
, struct usb_hcd
, hcd_priv
);
106 DWC_DEBUGPL(DBG_HCDV
, "%s() %p\n", __func__
, usb_hcd
);
108 dwc_otg_hcd_start(usb_hcd
);
113 * HCD Callback function for starting the HCD when A-Cable is
116 * @param p void pointer to the <code>struct usb_hcd</code>
118 static int32_t dwc_otg_hcd_start_cb(void *p
)
120 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(p
);
121 dwc_otg_core_if_t
*core_if
= dwc_otg_hcd
->core_if
;
124 if (core_if
->op_state
== B_HOST
) {
126 * Reset the port. During a HNP mode switch the reset
127 * needs to occur within 1ms and have a duration of at
130 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
132 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
133 ((struct usb_hcd
*)p
)->self
.is_b_host
= 1;
135 ((struct usb_hcd
*)p
)->self
.is_b_host
= 0;
138 /* Need to start the HCD in a non-interrupt context. */
139 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
140 INIT_WORK(&dwc_otg_hcd
->start_work
, hcd_start_func
, p
);
141 // INIT_DELAYED_WORK(&dwc_otg_hcd->start_work, hcd_start_func, p);
143 // INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
144 INIT_DELAYED_WORK(&dwc_otg_hcd
->start_work
, hcd_start_func
);
146 // schedule_work(&dwc_otg_hcd->start_work);
147 queue_delayed_work(core_if
->wq_otg
, &dwc_otg_hcd
->start_work
, 50 * HZ
/ 1000);
153 * HCD Callback function for stopping the HCD.
155 * @param p void pointer to the <code>struct usb_hcd</code>
157 static int32_t dwc_otg_hcd_stop_cb(void *p
)
159 struct usb_hcd
*usb_hcd
= (struct usb_hcd
*)p
;
160 DWC_DEBUGPL(DBG_HCDV
, "%s(%p)\n", __func__
, p
);
161 dwc_otg_hcd_stop(usb_hcd
);
165 static void del_xfer_timers(dwc_otg_hcd_t
*hcd
)
169 int num_channels
= hcd
->core_if
->core_params
->host_channels
;
170 for (i
= 0; i
< num_channels
; i
++) {
171 del_timer(&hcd
->core_if
->hc_xfer_timer
[i
]);
176 static void del_timers(dwc_otg_hcd_t
*hcd
)
178 del_xfer_timers(hcd
);
179 del_timer(&hcd
->conn_timer
);
183 * Processes all the URBs in a single list of QHs. Completes them with
184 * -ETIMEDOUT and frees the QTD.
186 static void kill_urbs_in_qh_list(dwc_otg_hcd_t
*hcd
, struct list_head
*qh_list
)
188 struct list_head
*qh_item
;
190 struct list_head
*qtd_item
;
193 list_for_each(qh_item
, qh_list
) {
194 qh
= list_entry(qh_item
, dwc_otg_qh_t
, qh_list_entry
);
195 for (qtd_item
= qh
->qtd_list
.next
;
196 qtd_item
!= &qh
->qtd_list
;
197 qtd_item
= qh
->qtd_list
.next
) {
198 qtd
= list_entry(qtd_item
, dwc_otg_qtd_t
, qtd_list_entry
);
199 if (qtd
->urb
!= NULL
) {
200 dwc_otg_hcd_complete_urb(hcd
, qtd
->urb
,
203 dwc_otg_hcd_qtd_remove_and_free(hcd
, qtd
);
209 * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
210 * and periodic schedules. The QTD associated with each URB is removed from
211 * the schedule and freed. This function may be called when a disconnect is
212 * detected or when the HCD is being stopped.
214 static void kill_all_urbs(dwc_otg_hcd_t
*hcd
)
216 kill_urbs_in_qh_list(hcd
, &hcd
->non_periodic_sched_inactive
);
217 kill_urbs_in_qh_list(hcd
, &hcd
->non_periodic_sched_active
);
218 kill_urbs_in_qh_list(hcd
, &hcd
->periodic_sched_inactive
);
219 kill_urbs_in_qh_list(hcd
, &hcd
->periodic_sched_ready
);
220 kill_urbs_in_qh_list(hcd
, &hcd
->periodic_sched_assigned
);
221 kill_urbs_in_qh_list(hcd
, &hcd
->periodic_sched_queued
);
225 * HCD Callback function for disconnect of the HCD.
227 * @param p void pointer to the <code>struct usb_hcd</code>
229 static int32_t dwc_otg_hcd_disconnect_cb(void *p
)
232 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(p
);
234 //DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
237 * Set status flags for the hub driver.
239 dwc_otg_hcd
->flags
.b
.port_connect_status_change
= 1;
240 dwc_otg_hcd
->flags
.b
.port_connect_status
= 0;
243 * Shutdown any transfers in process by clearing the Tx FIFO Empty
244 * interrupt mask and status bits and disabling subsequent host
245 * channel interrupts.
248 intr
.b
.nptxfempty
= 1;
249 intr
.b
.ptxfempty
= 1;
251 dwc_modify_reg32(&dwc_otg_hcd
->core_if
->core_global_regs
->gintmsk
, intr
.d32
, 0);
252 dwc_modify_reg32(&dwc_otg_hcd
->core_if
->core_global_regs
->gintsts
, intr
.d32
, 0);
254 del_timers(dwc_otg_hcd
);
257 * Turn off the vbus power only if the core has transitioned to device
258 * mode. If still in host mode, need to keep power on to detect a
261 if (dwc_otg_is_device_mode(dwc_otg_hcd
->core_if
)) {
262 if (dwc_otg_hcd
->core_if
->op_state
!= A_SUSPEND
) {
263 hprt0_data_t hprt0
= { .d32
=0 };
264 DWC_PRINT("Disconnect: PortPower off\n");
266 dwc_write_reg32(dwc_otg_hcd
->core_if
->host_if
->hprt0
, hprt0
.d32
);
269 dwc_otg_disable_host_interrupts(dwc_otg_hcd
->core_if
);
272 /* Respond with an error status to all URBs in the schedule. */
273 kill_all_urbs(dwc_otg_hcd
);
275 if (dwc_otg_is_host_mode(dwc_otg_hcd
->core_if
)) {
276 /* Clean up any host channels that were in use. */
280 dwc_otg_hc_regs_t
*hc_regs
;
281 hcchar_data_t hcchar
;
283 num_channels
= dwc_otg_hcd
->core_if
->core_params
->host_channels
;
285 if (!dwc_otg_hcd
->core_if
->dma_enable
) {
286 /* Flush out any channel requests in slave mode. */
287 for (i
= 0; i
< num_channels
; i
++) {
288 channel
= dwc_otg_hcd
->hc_ptr_array
[i
];
289 if (list_empty(&channel
->hc_list_entry
)) {
290 hc_regs
= dwc_otg_hcd
->core_if
->host_if
->hc_regs
[i
];
291 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
296 dwc_write_reg32(&hc_regs
->hcchar
, hcchar
.d32
);
302 for (i
= 0; i
< num_channels
; i
++) {
303 channel
= dwc_otg_hcd
->hc_ptr_array
[i
];
304 if (list_empty(&channel
->hc_list_entry
)) {
305 hc_regs
= dwc_otg_hcd
->core_if
->host_if
->hc_regs
[i
];
306 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
308 /* Halt the channel. */
310 dwc_write_reg32(&hc_regs
->hcchar
, hcchar
.d32
);
313 dwc_otg_hc_cleanup(dwc_otg_hcd
->core_if
, channel
);
314 list_add_tail(&channel
->hc_list_entry
,
315 &dwc_otg_hcd
->free_hc_list
);
320 /* A disconnect will end the session so the B-Device is no
321 * longer a B-host. */
322 ((struct usb_hcd
*)p
)->self
.is_b_host
= 0;
327 * Connection timeout function. An OTG host is required to display a
328 * message if the device does not connect within 10 seconds.
330 void dwc_otg_hcd_connect_timeout(unsigned long ptr
)
332 DWC_DEBUGPL(DBG_HCDV
, "%s(%x)\n", __func__
, (int)ptr
);
333 DWC_PRINT("Connect Timeout\n");
334 DWC_ERROR("Device Not Connected/Responding\n");
338 * Start the connection timer. An OTG host is required to display a
339 * message if the device does not connect within 10 seconds. The
340 * timer is deleted if a port connect interrupt occurs before the
343 static void dwc_otg_hcd_start_connect_timer(dwc_otg_hcd_t
*hcd
)
345 init_timer(&hcd
->conn_timer
);
346 hcd
->conn_timer
.function
= dwc_otg_hcd_connect_timeout
;
347 hcd
->conn_timer
.data
= 0;
348 hcd
->conn_timer
.expires
= jiffies
+ (HZ
* 10);
349 add_timer(&hcd
->conn_timer
);
353 * HCD Callback function for disconnect of the HCD.
355 * @param p void pointer to the <code>struct usb_hcd</code>
357 static int32_t dwc_otg_hcd_session_start_cb(void *p
)
359 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(p
);
360 DWC_DEBUGPL(DBG_HCDV
, "%s(%p)\n", __func__
, p
);
361 dwc_otg_hcd_start_connect_timer(dwc_otg_hcd
);
366 * HCD Callback structure for handling mode switching.
368 static dwc_otg_cil_callbacks_t hcd_cil_callbacks
= {
369 .start
= dwc_otg_hcd_start_cb
,
370 .stop
= dwc_otg_hcd_stop_cb
,
371 .disconnect
= dwc_otg_hcd_disconnect_cb
,
372 .session_start
= dwc_otg_hcd_session_start_cb
,
377 * Reset tasklet function
379 static void reset_tasklet_func(unsigned long data
)
381 dwc_otg_hcd_t
*dwc_otg_hcd
= (dwc_otg_hcd_t
*)data
;
382 dwc_otg_core_if_t
*core_if
= dwc_otg_hcd
->core_if
;
385 DWC_DEBUGPL(DBG_HCDV
, "USB RESET tasklet called\n");
387 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
389 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
393 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
394 dwc_otg_hcd
->flags
.b
.port_reset_change
= 1;
397 static struct tasklet_struct reset_tasklet
= {
400 .count
= ATOMIC_INIT(0),
401 .func
= reset_tasklet_func
,
406 * Initializes the HCD. This function allocates memory for and initializes the
407 * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
408 * USB bus with the core and calls the hc_driver->start() function. It returns
409 * a negative error on failure.
411 int dwc_otg_hcd_init(struct device
*dev
)
413 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(dev
);
414 struct usb_hcd
*hcd
= NULL
;
415 dwc_otg_hcd_t
*dwc_otg_hcd
= NULL
;
423 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD INIT\n");
425 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
426 /* 2.6.20+ requires dev.dma_mask to be set prior to calling usb_create_hcd() */
428 /* Set device flags indicating whether the HCD supports DMA. */
429 if (otg_dev
->core_if
->dma_enable
) {
430 DWC_PRINT("Using DMA mode\n");
431 dev
->dma_mask
= (void *)~0;
432 dev
->coherent_dma_mask
= ~0;
434 if (otg_dev
->core_if
->dma_desc_enable
) {
435 DWC_PRINT("Device using Descriptor DMA mode\n");
437 DWC_PRINT("Device using Buffer DMA mode\n");
440 DWC_PRINT("Using Slave mode\n");
441 dev
->dma_mask
= (void *)0;
442 dev
->coherent_dma_mask
= 0;
446 * Allocate memory for the base HCD plus the DWC OTG HCD.
447 * Initialize the base HCD.
449 hcd
= usb_create_hcd(&dwc_otg_hc_driver
, dev
, dev_name(dev
));
455 dev_set_drvdata(dev
, otg_dev
);
456 hcd
->regs
= otg_dev
->base
;
457 hcd
->rsrc_start
= otg_dev
->phys_addr
;
458 hcd
->rsrc_len
= otg_dev
->base_len
;
459 hcd
->self
.otg_port
= 1;
462 /* Initialize the DWC OTG HCD. */
463 dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
464 dwc_otg_hcd
->core_if
= otg_dev
->core_if
;
465 otg_dev
->hcd
= dwc_otg_hcd
;
468 spin_lock_init(&dwc_otg_hcd
->lock
);
470 /* Register the HCD CIL Callbacks */
471 dwc_otg_cil_register_hcd_callbacks(otg_dev
->core_if
,
472 &hcd_cil_callbacks
, hcd
);
474 /* Initialize the non-periodic schedule. */
475 INIT_LIST_HEAD(&dwc_otg_hcd
->non_periodic_sched_inactive
);
476 INIT_LIST_HEAD(&dwc_otg_hcd
->non_periodic_sched_active
);
478 /* Initialize the periodic schedule. */
479 INIT_LIST_HEAD(&dwc_otg_hcd
->periodic_sched_inactive
);
480 INIT_LIST_HEAD(&dwc_otg_hcd
->periodic_sched_ready
);
481 INIT_LIST_HEAD(&dwc_otg_hcd
->periodic_sched_assigned
);
482 INIT_LIST_HEAD(&dwc_otg_hcd
->periodic_sched_queued
);
485 * Create a host channel descriptor for each host channel implemented
486 * in the controller. Initialize the channel descriptor array.
488 INIT_LIST_HEAD(&dwc_otg_hcd
->free_hc_list
);
489 num_channels
= dwc_otg_hcd
->core_if
->core_params
->host_channels
;
490 memset(dwc_otg_hcd
->hc_ptr_array
, 0, sizeof(dwc_otg_hcd
->hc_ptr_array
));
491 for (i
= 0; i
< num_channels
; i
++) {
492 channel
= kmalloc(sizeof(dwc_hc_t
), GFP_KERNEL
);
493 if (channel
== NULL
) {
495 DWC_ERROR("%s: host channel allocation failed\n", __func__
);
498 memset(channel
, 0, sizeof(dwc_hc_t
));
500 dwc_otg_hcd
->hc_ptr_array
[i
] = channel
;
502 init_timer(&dwc_otg_hcd
->core_if
->hc_xfer_timer
[i
]);
504 DWC_DEBUGPL(DBG_HCDV
, "HCD Added channel #%d, hc=%p\n", i
, channel
);
507 /* Initialize the Connection timeout timer. */
508 init_timer(&dwc_otg_hcd
->conn_timer
);
510 /* Initialize reset tasklet. */
511 reset_tasklet
.data
= (unsigned long) dwc_otg_hcd
;
512 dwc_otg_hcd
->reset_tasklet
= &reset_tasklet
;
514 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
515 /* Set device flags indicating whether the HCD supports DMA. */
516 if (otg_dev
->core_if
->dma_enable
) {
517 DWC_PRINT("Using DMA mode\n");
518 dev
->dma_mask
= (void *)~0;
519 dev
->coherent_dma_mask
= ~0;
521 if (otg_dev
->core_if
->dma_desc_enable
){
522 DWC_PRINT("Device using Descriptor DMA mode\n");
524 DWC_PRINT("Device using Buffer DMA mode\n");
527 DWC_PRINT("Using Slave mode\n");
528 dev
->dma_mask
= (void *)0;
529 dev
->dev
.coherent_dma_mask
= 0;
533 * Finish generic HCD initialization and start the HCD. This function
534 * allocates the DMA buffer pool, registers the USB bus, requests the
535 * IRQ line, and calls dwc_otg_hcd_start method.
537 retval
= usb_add_hcd(hcd
, otg_dev
->irq
, IRQF_SHARED
);
543 * Allocate space for storing data on status transactions. Normally no
544 * data is sent, but this space acts as a bit bucket. This must be
545 * done after usb_add_hcd since that function allocates the DMA buffer
548 if (otg_dev
->core_if
->dma_enable
) {
549 dwc_otg_hcd
->status_buf
=
550 dma_alloc_coherent(dev
,
551 DWC_OTG_HCD_STATUS_BUF_SIZE
,
552 &dwc_otg_hcd
->status_buf_dma
,
553 GFP_KERNEL
| GFP_DMA
);
555 dwc_otg_hcd
->status_buf
= kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE
,
558 if (!dwc_otg_hcd
->status_buf
) {
560 DWC_ERROR("%s: status_buf allocation failed\n", __func__
);
564 dwc_otg_hcd
->otg_dev
= otg_dev
;
566 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
567 dev_name(dev
), hcd
->self
.busnum
);
571 /* Error conditions */
575 dwc_otg_hcd_free(hcd
);
578 /* FIXME: 2008/05/03 by Steven
579 * write back to device:
580 * dwc_otg_hcd has already been released by dwc_otg_hcd_free()
582 dev_set_drvdata(dev
, otg_dev
);
590 * Frees memory and resources associated with the HCD and deregisters the bus.
592 void dwc_otg_hcd_remove(struct device
*dev
)
594 dwc_otg_device_t
*otg_dev
= dev_get_drvdata(dev
);
595 dwc_otg_hcd_t
*dwc_otg_hcd
;
598 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD REMOVE\n");
601 DWC_DEBUGPL(DBG_ANY
, "%s: otg_dev NULL!\n", __func__
);
605 dwc_otg_hcd
= otg_dev
->hcd
;
608 DWC_DEBUGPL(DBG_ANY
, "%s: otg_dev->hcd NULL!\n", __func__
);
612 hcd
= dwc_otg_hcd_to_hcd(dwc_otg_hcd
);
615 DWC_DEBUGPL(DBG_ANY
, "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n", __func__
);
619 /* Turn off all interrupts */
620 dwc_write_reg32(&dwc_otg_hcd
->core_if
->core_global_regs
->gintmsk
, 0);
621 dwc_modify_reg32(&dwc_otg_hcd
->core_if
->core_global_regs
->gahbcfg
, 1, 0);
624 dwc_otg_hcd_free(hcd
);
628 /* =========================================================================
629 * Linux HC Driver Functions
630 * ========================================================================= */
633 * Initializes dynamic portions of the DWC_otg HCD state.
635 static void hcd_reinit(dwc_otg_hcd_t
*hcd
)
637 struct list_head
*item
;
644 hcd
->non_periodic_qh_ptr
= &hcd
->non_periodic_sched_active
;
645 hcd
->non_periodic_channels
= 0;
646 hcd
->periodic_channels
= 0;
649 * Put all channels in the free channel list and clean up channel
652 item
= hcd
->free_hc_list
.next
;
653 while (item
!= &hcd
->free_hc_list
) {
655 item
= hcd
->free_hc_list
.next
;
657 num_channels
= hcd
->core_if
->core_params
->host_channels
;
658 for (i
= 0; i
< num_channels
; i
++) {
659 channel
= hcd
->hc_ptr_array
[i
];
660 list_add_tail(&channel
->hc_list_entry
, &hcd
->free_hc_list
);
661 dwc_otg_hc_cleanup(hcd
->core_if
, channel
);
664 /* Initialize the DWC core for host mode operation. */
665 dwc_otg_core_host_init(hcd
->core_if
);
668 /** Initializes the DWC_otg controller and its root hub and prepares it for host
669 * mode operation. Activates the root port. Returns 0 on success and a negative
670 * error code on failure. */
671 int dwc_otg_hcd_start(struct usb_hcd
*hcd
)
673 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
674 dwc_otg_core_if_t
*core_if
= dwc_otg_hcd
->core_if
;
677 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
678 struct usb_device
*udev
;
682 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD START\n");
684 bus
= hcd_to_bus(hcd
);
686 /* Initialize the bus state. If the core is in Device Mode
687 * HALT the USB bus and return. */
688 if (dwc_otg_is_device_mode(core_if
)) {
689 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
690 hcd
->state
= HC_STATE_HALT
;
692 hcd
->state
= HC_STATE_RUNNING
;
696 hcd
->state
= HC_STATE_RUNNING
;
698 /* Initialize and connect root hub if one is not already attached */
700 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD Has Root Hub\n");
701 /* Inform the HUB driver to resume. */
702 usb_hcd_resume_root_hub(hcd
);
705 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD Does Not Have Root Hub\n");
707 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
708 udev
= usb_alloc_dev(NULL
, bus
, 0);
709 udev
->speed
= USB_SPEED_HIGH
;
711 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD Error udev alloc\n");
714 if ((retval
= usb_hcd_register_root_hub(udev
, hcd
)) != 0) {
715 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD Error registering %d\n", retval
);
721 hcd_reinit(dwc_otg_hcd
);
726 static void qh_list_free(dwc_otg_hcd_t
*hcd
, struct list_head
*qh_list
)
728 struct list_head
*item
;
731 if (!qh_list
->next
) {
732 /* The list hasn't been initialized yet. */
736 /* Ensure there are no QTDs or URBs left. */
737 kill_urbs_in_qh_list(hcd
, qh_list
);
739 for (item
= qh_list
->next
; item
!= qh_list
; item
= qh_list
->next
) {
740 qh
= list_entry(item
, dwc_otg_qh_t
, qh_list_entry
);
741 dwc_otg_hcd_qh_remove_and_free(hcd
, qh
);
746 * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
749 void dwc_otg_hcd_stop(struct usb_hcd
*hcd
)
751 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
752 hprt0_data_t hprt0
= { .d32
=0 };
754 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD STOP\n");
756 /* Turn off all host-specific interrupts. */
757 dwc_otg_disable_host_interrupts(dwc_otg_hcd
->core_if
);
760 * The root hub should be disconnected before this function is called.
761 * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
762 * and the QH lists (via ..._hcd_endpoint_disable).
765 /* Turn off the vbus power */
766 DWC_PRINT("PortPower off\n");
768 dwc_write_reg32(dwc_otg_hcd
->core_if
->host_if
->hprt0
, hprt0
.d32
);
771 /** Returns the current frame number. */
772 int dwc_otg_hcd_get_frame_number(struct usb_hcd
*hcd
)
774 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
777 hfnum
.d32
= dwc_read_reg32(&dwc_otg_hcd
->core_if
->
778 host_if
->host_global_regs
->hfnum
);
781 DWC_DEBUGPL(DBG_HCDV
, "DWC OTG HCD GET FRAME NUMBER %d\n", hfnum
.b
.frnum
);
783 return hfnum
.b
.frnum
;
787 * Frees secondary storage associated with the dwc_otg_hcd structure contained
788 * in the struct usb_hcd field.
790 void dwc_otg_hcd_free(struct usb_hcd
*hcd
)
792 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
795 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD FREE\n");
797 del_timers(dwc_otg_hcd
);
799 /* Free memory for QH/QTD lists */
800 qh_list_free(dwc_otg_hcd
, &dwc_otg_hcd
->non_periodic_sched_inactive
);
801 qh_list_free(dwc_otg_hcd
, &dwc_otg_hcd
->non_periodic_sched_active
);
802 qh_list_free(dwc_otg_hcd
, &dwc_otg_hcd
->periodic_sched_inactive
);
803 qh_list_free(dwc_otg_hcd
, &dwc_otg_hcd
->periodic_sched_ready
);
804 qh_list_free(dwc_otg_hcd
, &dwc_otg_hcd
->periodic_sched_assigned
);
805 qh_list_free(dwc_otg_hcd
, &dwc_otg_hcd
->periodic_sched_queued
);
807 /* Free memory for the host channels. */
808 for (i
= 0; i
< MAX_EPS_CHANNELS
; i
++) {
809 dwc_hc_t
*hc
= dwc_otg_hcd
->hc_ptr_array
[i
];
811 DWC_DEBUGPL(DBG_HCDV
, "HCD Free channel #%i, hc=%p\n", i
, hc
);
816 if (dwc_otg_hcd
->core_if
->dma_enable
) {
817 if (dwc_otg_hcd
->status_buf_dma
) {
818 dma_free_coherent(hcd
->self
.controller
,
819 DWC_OTG_HCD_STATUS_BUF_SIZE
,
820 dwc_otg_hcd
->status_buf
,
821 dwc_otg_hcd
->status_buf_dma
);
823 } else if (dwc_otg_hcd
->status_buf
!= NULL
) {
824 kfree(dwc_otg_hcd
->status_buf
);
829 static void dump_urb_info(struct urb
*urb
, char* fn_name
)
831 DWC_PRINT("%s, urb %p\n", fn_name
, urb
);
832 DWC_PRINT(" Device address: %d\n", usb_pipedevice(urb
->pipe
));
833 DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(urb
->pipe
),
834 (usb_pipein(urb
->pipe
) ? "IN" : "OUT"));
835 DWC_PRINT(" Endpoint type: %s\n",
837 switch (usb_pipetype(urb
->pipe
)) {
838 case PIPE_CONTROL
: pipetype
= "CONTROL"; break;
839 case PIPE_BULK
: pipetype
= "BULK"; break;
840 case PIPE_INTERRUPT
: pipetype
= "INTERRUPT"; break;
841 case PIPE_ISOCHRONOUS
: pipetype
= "ISOCHRONOUS"; break;
842 default: pipetype
= "UNKNOWN"; break;
844 DWC_PRINT(" Speed: %s\n",
846 switch (urb
->dev
->speed
) {
847 case USB_SPEED_HIGH
: speed
= "HIGH"; break;
848 case USB_SPEED_FULL
: speed
= "FULL"; break;
849 case USB_SPEED_LOW
: speed
= "LOW"; break;
850 default: speed
= "UNKNOWN"; break;
852 DWC_PRINT(" Max packet size: %d\n",
853 usb_maxpacket(urb
->dev
, urb
->pipe
, usb_pipeout(urb
->pipe
)));
854 DWC_PRINT(" Data buffer length: %d\n", urb
->transfer_buffer_length
);
855 DWC_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
856 urb
->transfer_buffer
, (void *)urb
->transfer_dma
);
857 DWC_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
858 urb
->setup_packet
, (void *)urb
->setup_dma
);
859 DWC_PRINT(" Interval: %d\n", urb
->interval
);
860 if (usb_pipetype(urb
->pipe
) == PIPE_ISOCHRONOUS
) {
862 for (i
= 0; i
< urb
->number_of_packets
; i
++) {
863 DWC_PRINT(" ISO Desc %d:\n", i
);
864 DWC_PRINT(" offset: %d, length %d\n",
865 urb
->iso_frame_desc
[i
].offset
,
866 urb
->iso_frame_desc
[i
].length
);
871 static void dump_channel_info(dwc_otg_hcd_t
*hcd
,
874 if (qh
->channel
!= NULL
) {
875 dwc_hc_t
*hc
= qh
->channel
;
876 struct list_head
*item
;
877 dwc_otg_qh_t
*qh_item
;
878 int num_channels
= hcd
->core_if
->core_params
->host_channels
;
881 dwc_otg_hc_regs_t
*hc_regs
;
882 hcchar_data_t hcchar
;
883 hcsplt_data_t hcsplt
;
884 hctsiz_data_t hctsiz
;
887 hc_regs
= hcd
->core_if
->host_if
->hc_regs
[hc
->hc_num
];
888 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
889 hcsplt
.d32
= dwc_read_reg32(&hc_regs
->hcsplt
);
890 hctsiz
.d32
= dwc_read_reg32(&hc_regs
->hctsiz
);
891 hcdma
= dwc_read_reg32(&hc_regs
->hcdma
);
893 DWC_PRINT(" Assigned to channel %p:\n", hc
);
894 DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar
.d32
, hcsplt
.d32
);
895 DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz
.d32
, hcdma
);
896 DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
897 hc
->dev_addr
, hc
->ep_num
, hc
->ep_is_in
);
898 DWC_PRINT(" ep_type: %d\n", hc
->ep_type
);
899 DWC_PRINT(" max_packet: %d\n", hc
->max_packet
);
900 DWC_PRINT(" data_pid_start: %d\n", hc
->data_pid_start
);
901 DWC_PRINT(" xfer_started: %d\n", hc
->xfer_started
);
902 DWC_PRINT(" halt_status: %d\n", hc
->halt_status
);
903 DWC_PRINT(" xfer_buff: %p\n", hc
->xfer_buff
);
904 DWC_PRINT(" xfer_len: %d\n", hc
->xfer_len
);
905 DWC_PRINT(" qh: %p\n", hc
->qh
);
906 DWC_PRINT(" NP inactive sched:\n");
907 list_for_each(item
, &hcd
->non_periodic_sched_inactive
) {
908 qh_item
= list_entry(item
, dwc_otg_qh_t
, qh_list_entry
);
909 DWC_PRINT(" %p\n", qh_item
);
911 DWC_PRINT(" NP active sched:\n");
912 list_for_each(item
, &hcd
->non_periodic_sched_active
) {
913 qh_item
= list_entry(item
, dwc_otg_qh_t
, qh_list_entry
);
914 DWC_PRINT(" %p\n", qh_item
);
916 DWC_PRINT(" Channels: \n");
917 for (i
= 0; i
< num_channels
; i
++) {
918 dwc_hc_t
*hc
= hcd
->hc_ptr_array
[i
];
919 DWC_PRINT(" %2d: %p\n", i
, hc
);
925 /** Starts processing a USB transfer request specified by a USB Request Block
926 * (URB). mem_flags indicates the type of memory allocation to use while
927 * processing this URB. */
928 int dwc_otg_hcd_urb_enqueue(struct usb_hcd
*hcd
,
930 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
938 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
942 if (CHK_DEBUG_LEVEL(DBG_HCDV
| DBG_HCD_URB
)) {
943 dump_urb_info(urb
, "dwc_otg_hcd_urb_enqueue");
946 if (!dwc_otg_hcd
->flags
.b
.port_connect_status
) {
947 /* No longer connected. */
951 qtd
= dwc_otg_hcd_qtd_create(urb
);
953 DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
957 retval
= dwc_otg_hcd_qtd_add(qtd
, dwc_otg_hcd
);
959 DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
960 "Error status %d\n", retval
);
961 dwc_otg_hcd_qtd_free(qtd
);
967 /** Aborts/cancels a USB transfer request. Always returns 0 to indicate
969 int dwc_otg_hcd_urb_dequeue(struct usb_hcd
*hcd
,
974 dwc_otg_hcd_t
*dwc_otg_hcd
;
975 dwc_otg_qtd_t
*urb_qtd
;
977 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
978 struct usb_host_endpoint
*ep
= dwc_urb_to_endpoint(urb
);
981 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD URB Dequeue\n");
983 dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
985 SPIN_LOCK_IRQSAVE(&dwc_otg_hcd
->lock
, flags
);
987 urb_qtd
= (dwc_otg_qtd_t
*)urb
->hcpriv
;
988 qh
= (dwc_otg_qh_t
*)ep
->hcpriv
;
991 if (CHK_DEBUG_LEVEL(DBG_HCDV
| DBG_HCD_URB
)) {
992 dump_urb_info(urb
, "dwc_otg_hcd_urb_dequeue");
993 if (urb_qtd
== qh
->qtd_in_process
) {
994 dump_channel_info(dwc_otg_hcd
, qh
);
999 if (urb_qtd
== qh
->qtd_in_process
) {
1000 /* The QTD is in process (it has been assigned to a channel). */
1002 if (dwc_otg_hcd
->flags
.b
.port_connect_status
) {
1004 * If still connected (i.e. in host mode), halt the
1005 * channel so it can be used for other transfers. If
1006 * no longer connected, the host registers can't be
1007 * written to halt the channel since the core is in
1010 dwc_otg_hc_halt(dwc_otg_hcd
->core_if
, qh
->channel
,
1011 DWC_OTG_HC_XFER_URB_DEQUEUE
);
1016 * Free the QTD and clean up the associated QH. Leave the QH in the
1017 * schedule if it has any remaining QTDs.
1019 dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd
, urb_qtd
);
1020 if (urb_qtd
== qh
->qtd_in_process
) {
1021 dwc_otg_hcd_qh_deactivate(dwc_otg_hcd
, qh
, 0);
1023 qh
->qtd_in_process
= NULL
;
1024 } else if (list_empty(&qh
->qtd_list
)) {
1025 dwc_otg_hcd_qh_remove(dwc_otg_hcd
, qh
);
1028 SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd
->lock
, flags
);
1032 /* Higher layer software sets URB status. */
1033 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1034 usb_hcd_giveback_urb(hcd
, urb
, status
);
1036 usb_hcd_giveback_urb(hcd
, urb
, NULL
);
1038 if (CHK_DEBUG_LEVEL(DBG_HCDV
| DBG_HCD_URB
)) {
1039 DWC_PRINT("Called usb_hcd_giveback_urb()\n");
1040 DWC_PRINT(" urb->status = %d\n", urb
->status
);
1046 /** Frees resources in the DWC_otg controller related to a given endpoint. Also
1047 * clears state in the HCD related to the endpoint. Any URBs for the endpoint
1048 * must already be dequeued. */
1049 void dwc_otg_hcd_endpoint_disable(struct usb_hcd
*hcd
,
1050 struct usb_host_endpoint
*ep
)
1052 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
1055 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1056 unsigned long flags
;
1060 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
1061 "endpoint=%d\n", ep
->desc
.bEndpointAddress
,
1062 dwc_ep_addr_to_endpoint(ep
->desc
.bEndpointAddress
));
1064 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1066 SPIN_LOCK_IRQSAVE(&dwc_otg_hcd
->lock
, flags
);
1067 qh
= (dwc_otg_qh_t
*)(ep
->hcpriv
);
1071 /** Check that the QTD list is really empty */
1072 if (!list_empty(&qh
->qtd_list
)) {
1073 if (retry
++ < 250) {
1074 SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd
->lock
, flags
);
1075 schedule_timeout_uninterruptible(1);
1079 DWC_WARN("DWC OTG HCD EP DISABLE:"
1080 " QTD List for this endpoint is not empty\n");
1083 dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd
, qh
);
1086 SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd
->lock
, flags
);
1088 #else // LINUX_VERSION_CODE
1090 qh
= (dwc_otg_qh_t
*)(ep
->hcpriv
);
1093 /** Check that the QTD list is really empty */
1094 if (!list_empty(&qh
->qtd_list
)) {
1095 DWC_WARN("DWC OTG HCD EP DISABLE:"
1096 " QTD List for this endpoint is not empty\n");
1099 dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd
, qh
);
1102 #endif // LINUX_VERSION_CODE
1105 /** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
1106 * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
1109 * This function is called by the USB core when an interrupt occurs */
1110 irqreturn_t
dwc_otg_hcd_irq(struct usb_hcd
*hcd
1111 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
1112 , struct pt_regs
*regs
1116 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
1117 return IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd
));
1120 /** Creates Status Change bitmap for the root hub and root port. The bitmap is
1121 * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
1122 * is the status change indicator for the single root port. Returns 1 if either
1123 * change indicator is 1, otherwise returns 0. */
1124 int dwc_otg_hcd_hub_status_data(struct usb_hcd
*hcd
, char *buf
)
1126 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
1129 buf
[0] |= (dwc_otg_hcd
->flags
.b
.port_connect_status_change
||
1130 dwc_otg_hcd
->flags
.b
.port_reset_change
||
1131 dwc_otg_hcd
->flags
.b
.port_enable_change
||
1132 dwc_otg_hcd
->flags
.b
.port_suspend_change
||
1133 dwc_otg_hcd
->flags
.b
.port_over_current_change
) << 1;
1137 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB STATUS DATA:"
1138 " Root port status changed\n");
1139 DWC_DEBUGPL(DBG_HCDV
, " port_connect_status_change: %d\n",
1140 dwc_otg_hcd
->flags
.b
.port_connect_status_change
);
1141 DWC_DEBUGPL(DBG_HCDV
, " port_reset_change: %d\n",
1142 dwc_otg_hcd
->flags
.b
.port_reset_change
);
1143 DWC_DEBUGPL(DBG_HCDV
, " port_enable_change: %d\n",
1144 dwc_otg_hcd
->flags
.b
.port_enable_change
);
1145 DWC_DEBUGPL(DBG_HCDV
, " port_suspend_change: %d\n",
1146 dwc_otg_hcd
->flags
.b
.port_suspend_change
);
1147 DWC_DEBUGPL(DBG_HCDV
, " port_over_current_change: %d\n",
1148 dwc_otg_hcd
->flags
.b
.port_over_current_change
);
1151 return (buf
[0] != 0);
1154 #ifdef DWC_HS_ELECT_TST
1156 * Quick and dirty hack to implement the HS Electrical Test
1157 * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
1159 * This code was copied from our userspace app "hset". It sends a
1160 * Get Device Descriptor control sequence in two parts, first the
1161 * Setup packet by itself, followed some time later by the In and
1162 * Ack packets. Rather than trying to figure out how to add this
1163 * functionality to the normal driver code, we just hijack the
1164 * hardware, using these two function to drive the hardware
1168 dwc_otg_core_global_regs_t
*global_regs
;
1169 dwc_otg_host_global_regs_t
*hc_global_regs
;
1170 dwc_otg_hc_regs_t
*hc_regs
;
1171 uint32_t *data_fifo
;
1173 static void do_setup(void)
1175 gintsts_data_t gintsts
;
1176 hctsiz_data_t hctsiz
;
1177 hcchar_data_t hcchar
;
1182 dwc_write_reg32(&hc_global_regs
->haintmsk
, 0x0001);
1185 dwc_write_reg32(&hc_regs
->hcintmsk
, 0x04a3);
1188 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1189 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1192 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1193 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1196 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1197 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1200 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1201 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1204 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1207 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1210 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1213 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1214 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1217 * Send Setup packet (Get Device Descriptor)
1220 /* Make sure channel is disabled */
1221 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1222 if (hcchar
.b
.chen
) {
1223 //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
1225 // hcchar.b.chen = 1;
1226 dwc_write_reg32(&hc_regs
->hcchar
, hcchar
.d32
);
1231 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1232 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1235 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1236 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1239 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1240 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1243 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1244 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1247 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1250 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1253 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1255 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1256 //if (hcchar.b.chen) {
1257 // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
1263 hctsiz
.b
.xfersize
= 8;
1264 hctsiz
.b
.pktcnt
= 1;
1265 hctsiz
.b
.pid
= DWC_OTG_HC_PID_SETUP
;
1266 dwc_write_reg32(&hc_regs
->hctsiz
, hctsiz
.d32
);
1269 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1270 hcchar
.b
.eptype
= DWC_OTG_EP_TYPE_CONTROL
;
1275 dwc_write_reg32(&hc_regs
->hcchar
, hcchar
.d32
);
1277 /* Fill FIFO with Setup data for Get Device Descriptor */
1278 data_fifo
= (uint32_t *)((char *)global_regs
+ 0x1000);
1279 dwc_write_reg32(data_fifo
++, 0x01000680);
1280 dwc_write_reg32(data_fifo
++, 0x00080000);
1282 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1283 //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
1285 /* Wait for host channel interrupt */
1287 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1288 } while (gintsts
.b
.hcintr
== 0);
1290 //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
1292 /* Disable HCINTs */
1293 dwc_write_reg32(&hc_regs
->hcintmsk
, 0x0000);
1295 /* Disable HAINTs */
1296 dwc_write_reg32(&hc_global_regs
->haintmsk
, 0x0000);
1299 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1300 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1303 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1304 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1307 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1308 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1311 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1314 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1317 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1320 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1321 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1324 static void do_in_ack(void)
1326 gintsts_data_t gintsts
;
1327 hctsiz_data_t hctsiz
;
1328 hcchar_data_t hcchar
;
1331 host_grxsts_data_t grxsts
;
1334 dwc_write_reg32(&hc_global_regs
->haintmsk
, 0x0001);
1337 dwc_write_reg32(&hc_regs
->hcintmsk
, 0x04a3);
1340 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1341 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1344 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1345 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1348 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1349 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1352 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1353 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1356 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1359 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1362 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1365 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1366 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1369 * Receive Control In packet
1372 /* Make sure channel is disabled */
1373 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1374 if (hcchar
.b
.chen
) {
1375 //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
1378 dwc_write_reg32(&hc_regs
->hcchar
, hcchar
.d32
);
1383 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1384 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1387 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1388 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1391 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1392 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1395 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1396 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1399 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1402 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1405 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1407 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1408 //if (hcchar.b.chen) {
1409 // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
1415 hctsiz
.b
.xfersize
= 8;
1416 hctsiz
.b
.pktcnt
= 1;
1417 hctsiz
.b
.pid
= DWC_OTG_HC_PID_DATA1
;
1418 dwc_write_reg32(&hc_regs
->hctsiz
, hctsiz
.d32
);
1421 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1422 hcchar
.b
.eptype
= DWC_OTG_EP_TYPE_CONTROL
;
1427 dwc_write_reg32(&hc_regs
->hcchar
, hcchar
.d32
);
1429 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1430 //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
1432 /* Wait for receive status queue interrupt */
1434 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1435 } while (gintsts
.b
.rxstsqlvl
== 0);
1437 //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
1440 grxsts
.d32
= dwc_read_reg32(&global_regs
->grxstsp
);
1441 //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
1443 /* Clear RXSTSQLVL in GINTSTS */
1445 gintsts
.b
.rxstsqlvl
= 1;
1446 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1448 switch (grxsts
.b
.pktsts
) {
1449 case DWC_GRXSTS_PKTSTS_IN
:
1450 /* Read the data into the host buffer */
1451 if (grxsts
.b
.bcnt
> 0) {
1453 int word_count
= (grxsts
.b
.bcnt
+ 3) / 4;
1455 data_fifo
= (uint32_t *)((char *)global_regs
+ 0x1000);
1457 for (i
= 0; i
< word_count
; i
++) {
1458 (void)dwc_read_reg32(data_fifo
++);
1462 //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt);
1466 //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
1470 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1471 //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
1473 /* Wait for receive status queue interrupt */
1475 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1476 } while (gintsts
.b
.rxstsqlvl
== 0);
1478 //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
1481 grxsts
.d32
= dwc_read_reg32(&global_regs
->grxstsp
);
1482 //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
1484 /* Clear RXSTSQLVL in GINTSTS */
1486 gintsts
.b
.rxstsqlvl
= 1;
1487 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1489 switch (grxsts
.b
.pktsts
) {
1490 case DWC_GRXSTS_PKTSTS_IN_XFER_COMP
:
1494 //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
1498 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1499 //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
1501 /* Wait for host channel interrupt */
1503 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1504 } while (gintsts
.b
.hcintr
== 0);
1506 //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
1509 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1510 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1513 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1514 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1517 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1518 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1521 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1524 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1527 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1530 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1531 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1538 * Send handshake packet
1542 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1543 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1546 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1547 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1550 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1551 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1554 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1557 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1560 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1563 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1564 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1566 /* Make sure channel is disabled */
1567 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1568 if (hcchar
.b
.chen
) {
1569 //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
1572 dwc_write_reg32(&hc_regs
->hcchar
, hcchar
.d32
);
1577 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1578 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1581 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1582 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1585 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1586 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1589 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1590 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1593 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1596 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1599 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1601 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1602 //if (hcchar.b.chen) {
1603 // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
1609 hctsiz
.b
.xfersize
= 0;
1610 hctsiz
.b
.pktcnt
= 1;
1611 hctsiz
.b
.pid
= DWC_OTG_HC_PID_DATA1
;
1612 dwc_write_reg32(&hc_regs
->hctsiz
, hctsiz
.d32
);
1615 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1616 hcchar
.b
.eptype
= DWC_OTG_EP_TYPE_CONTROL
;
1621 dwc_write_reg32(&hc_regs
->hcchar
, hcchar
.d32
);
1623 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1624 //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
1626 /* Wait for host channel interrupt */
1628 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1629 } while (gintsts
.b
.hcintr
== 0);
1631 //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
1633 /* Disable HCINTs */
1634 dwc_write_reg32(&hc_regs
->hcintmsk
, 0x0000);
1636 /* Disable HAINTs */
1637 dwc_write_reg32(&hc_global_regs
->haintmsk
, 0x0000);
1640 haint
.d32
= dwc_read_reg32(&hc_global_regs
->haint
);
1641 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1644 hcint
.d32
= dwc_read_reg32(&hc_regs
->hcint
);
1645 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1648 hcchar
.d32
= dwc_read_reg32(&hc_regs
->hcchar
);
1649 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1652 dwc_write_reg32(&hc_regs
->hcint
, hcint
.d32
);
1655 dwc_write_reg32(&hc_global_regs
->haint
, haint
.d32
);
1658 dwc_write_reg32(&global_regs
->gintsts
, gintsts
.d32
);
1661 gintsts
.d32
= dwc_read_reg32(&global_regs
->gintsts
);
1662 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1664 #endif /* DWC_HS_ELECT_TST */
1666 /** Handles hub class-specific requests. */
1667 int dwc_otg_hcd_hub_control(struct usb_hcd
*hcd
,
1676 dwc_otg_hcd_t
*dwc_otg_hcd
= hcd_to_dwc_otg_hcd(hcd
);
1677 dwc_otg_core_if_t
*core_if
= hcd_to_dwc_otg_hcd(hcd
)->core_if
;
1678 struct usb_hub_descriptor
*desc
;
1679 hprt0_data_t hprt0
= {.d32
= 0};
1681 uint32_t port_status
;
1684 case ClearHubFeature
:
1685 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1686 "ClearHubFeature 0x%x\n", wValue
);
1688 case C_HUB_LOCAL_POWER
:
1689 case C_HUB_OVER_CURRENT
:
1690 /* Nothing required here */
1694 DWC_ERROR("DWC OTG HCD - "
1695 "ClearHubFeature request %xh unknown\n", wValue
);
1698 case ClearPortFeature
:
1699 if (!wIndex
|| wIndex
> 1)
1703 case USB_PORT_FEAT_ENABLE
:
1704 DWC_DEBUGPL(DBG_ANY
, "DWC OTG HCD HUB CONTROL - "
1705 "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
1706 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1708 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1710 case USB_PORT_FEAT_SUSPEND
:
1711 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1712 "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
1713 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1715 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1716 /* Clear Resume bit */
1719 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1721 case USB_PORT_FEAT_POWER
:
1722 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1723 "ClearPortFeature USB_PORT_FEAT_POWER\n");
1724 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1726 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1728 case USB_PORT_FEAT_INDICATOR
:
1729 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1730 "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
1731 /* Port inidicator not supported */
1733 case USB_PORT_FEAT_C_CONNECTION
:
1734 /* Clears drivers internal connect status change
1736 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1737 "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
1738 dwc_otg_hcd
->flags
.b
.port_connect_status_change
= 0;
1740 case USB_PORT_FEAT_C_RESET
:
1741 /* Clears the driver's internal Port Reset Change
1743 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1744 "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
1745 dwc_otg_hcd
->flags
.b
.port_reset_change
= 0;
1747 case USB_PORT_FEAT_C_ENABLE
:
1748 /* Clears the driver's internal Port
1749 * Enable/Disable Change flag */
1750 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1751 "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
1752 dwc_otg_hcd
->flags
.b
.port_enable_change
= 0;
1754 case USB_PORT_FEAT_C_SUSPEND
:
1755 /* Clears the driver's internal Port Suspend
1756 * Change flag, which is set when resume signaling on
1757 * the host port is complete */
1758 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1759 "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
1760 dwc_otg_hcd
->flags
.b
.port_suspend_change
= 0;
1762 case USB_PORT_FEAT_C_OVER_CURRENT
:
1763 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1764 "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
1765 dwc_otg_hcd
->flags
.b
.port_over_current_change
= 0;
1769 DWC_ERROR("DWC OTG HCD - "
1770 "ClearPortFeature request %xh "
1771 "unknown or unsupported\n", wValue
);
1774 case GetHubDescriptor
:
1775 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1776 "GetHubDescriptor\n");
1777 desc
= (struct usb_hub_descriptor
*)buf
;
1778 desc
->bDescLength
= 9;
1779 desc
->bDescriptorType
= 0x29;
1780 desc
->bNbrPorts
= 1;
1781 desc
->wHubCharacteristics
= 0x08;
1782 desc
->bPwrOn2PwrGood
= 1;
1783 desc
->bHubContrCurrent
= 0;
1784 desc
->u
.hs
.DeviceRemovable
[0] = 0;
1785 desc
->u
.hs
.DeviceRemovable
[1] = 0xff;
1788 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1793 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1796 if (!wIndex
|| wIndex
> 1)
1801 if (dwc_otg_hcd
->flags
.b
.port_connect_status_change
)
1802 port_status
|= (1 << USB_PORT_FEAT_C_CONNECTION
);
1804 if (dwc_otg_hcd
->flags
.b
.port_enable_change
)
1805 port_status
|= (1 << USB_PORT_FEAT_C_ENABLE
);
1807 if (dwc_otg_hcd
->flags
.b
.port_suspend_change
)
1808 port_status
|= (1 << USB_PORT_FEAT_C_SUSPEND
);
1810 if (dwc_otg_hcd
->flags
.b
.port_reset_change
)
1811 port_status
|= (1 << USB_PORT_FEAT_C_RESET
);
1813 if (dwc_otg_hcd
->flags
.b
.port_over_current_change
) {
1814 DWC_ERROR("Device Not Supported\n");
1815 port_status
|= (1 << USB_PORT_FEAT_C_OVER_CURRENT
);
1818 if (!dwc_otg_hcd
->flags
.b
.port_connect_status
) {
1820 * The port is disconnected, which means the core is
1821 * either in device mode or it soon will be. Just
1822 * return 0's for the remainder of the port status
1823 * since the port register can't be read if the core
1824 * is in device mode.
1826 *((__le32
*) buf
) = cpu_to_le32(port_status
);
1830 hprt0
.d32
= dwc_read_reg32(core_if
->host_if
->hprt0
);
1831 DWC_DEBUGPL(DBG_HCDV
, " HPRT0: 0x%08x\n", hprt0
.d32
);
1833 if (hprt0
.b
.prtconnsts
)
1834 port_status
|= (1 << USB_PORT_FEAT_CONNECTION
);
1837 port_status
|= (1 << USB_PORT_FEAT_ENABLE
);
1839 if (hprt0
.b
.prtsusp
)
1840 port_status
|= (1 << USB_PORT_FEAT_SUSPEND
);
1842 if (hprt0
.b
.prtovrcurract
)
1843 port_status
|= (1 << USB_PORT_FEAT_OVER_CURRENT
);
1846 port_status
|= (1 << USB_PORT_FEAT_RESET
);
1849 port_status
|= (1 << USB_PORT_FEAT_POWER
);
1851 if (hprt0
.b
.prtspd
== DWC_HPRT0_PRTSPD_HIGH_SPEED
)
1852 port_status
|= USB_PORT_STAT_HIGH_SPEED
;
1853 else if (hprt0
.b
.prtspd
== DWC_HPRT0_PRTSPD_LOW_SPEED
)
1854 port_status
|= USB_PORT_STAT_LOW_SPEED
;
1856 if (hprt0
.b
.prttstctl
)
1857 port_status
|= (1 << USB_PORT_FEAT_TEST
);
1859 /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
1861 *((__le32
*) buf
) = cpu_to_le32(port_status
);
1865 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1867 /* No HUB features supported */
1869 case SetPortFeature
:
1870 if (wValue
!= USB_PORT_FEAT_TEST
&& (!wIndex
|| wIndex
> 1))
1873 if (!dwc_otg_hcd
->flags
.b
.port_connect_status
) {
1875 * The port is disconnected, which means the core is
1876 * either in device mode or it soon will be. Just
1877 * return without doing anything since the port
1878 * register can't be written if the core is in device
1885 case USB_PORT_FEAT_SUSPEND
:
1886 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1887 "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
1888 if (hcd
->self
.otg_port
== wIndex
&&
1889 hcd
->self
.b_hnp_enable
) {
1890 gotgctl_data_t gotgctl
= {.d32
=0};
1891 gotgctl
.b
.hstsethnpen
= 1;
1892 dwc_modify_reg32(&core_if
->core_global_regs
->gotgctl
,
1894 core_if
->op_state
= A_SUSPEND
;
1896 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1897 hprt0
.b
.prtsusp
= 1;
1898 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1899 //DWC_PRINT("SUSPEND: HPRT0=%0x\n", hprt0.d32);
1900 /* Suspend the Phy Clock */
1902 pcgcctl_data_t pcgcctl
= {.d32
=0};
1903 pcgcctl
.b
.stoppclk
= 1;
1904 dwc_write_reg32(core_if
->pcgcctl
, pcgcctl
.d32
);
1907 /* For HNP the bus must be suspended for at least 200ms. */
1908 if (hcd
->self
.b_hnp_enable
) {
1910 //DWC_PRINT("SUSPEND: wait complete! (%d)\n", _hcd->state);
1913 case USB_PORT_FEAT_POWER
:
1914 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1915 "SetPortFeature - USB_PORT_FEAT_POWER\n");
1916 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1918 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1920 case USB_PORT_FEAT_RESET
:
1921 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1922 "SetPortFeature - USB_PORT_FEAT_RESET\n");
1923 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1924 /* When B-Host the Port reset bit is set in
1925 * the Start HCD Callback function, so that
1926 * the reset is started within 1ms of the HNP
1927 * success interrupt. */
1928 if (!hcd
->self
.is_b_host
) {
1930 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1932 /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
1935 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1938 #ifdef DWC_HS_ELECT_TST
1939 case USB_PORT_FEAT_TEST
:
1942 gintmsk_data_t gintmsk
;
1944 t
= (wIndex
>> 8); /* MSB wIndex USB */
1945 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
1946 "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t
);
1947 warn("USB_PORT_FEAT_TEST %d\n", t
);
1949 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1950 hprt0
.b
.prttstctl
= t
;
1951 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1953 /* Setup global vars with reg addresses (quick and
1954 * dirty hack, should be cleaned up)
1956 global_regs
= core_if
->core_global_regs
;
1957 hc_global_regs
= core_if
->host_if
->host_global_regs
;
1958 hc_regs
= (dwc_otg_hc_regs_t
*)((char *)global_regs
+ 0x500);
1959 data_fifo
= (uint32_t *)((char *)global_regs
+ 0x1000);
1961 if (t
== 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
1962 /* Save current interrupt mask */
1963 gintmsk
.d32
= dwc_read_reg32(&global_regs
->gintmsk
);
1965 /* Disable all interrupts while we muck with
1966 * the hardware directly
1968 dwc_write_reg32(&global_regs
->gintmsk
, 0);
1970 /* 15 second delay per the test spec */
1973 /* Drive suspend on the root port */
1974 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1975 hprt0
.b
.prtsusp
= 1;
1977 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1979 /* 15 second delay per the test spec */
1982 /* Drive resume on the root port */
1983 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
1984 hprt0
.b
.prtsusp
= 0;
1986 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1989 /* Clear the resume bit */
1991 dwc_write_reg32(core_if
->host_if
->hprt0
, hprt0
.d32
);
1993 /* Restore interrupts */
1994 dwc_write_reg32(&global_regs
->gintmsk
, gintmsk
.d32
);
1995 } else if (t
== 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
1996 /* Save current interrupt mask */
1997 gintmsk
.d32
= dwc_read_reg32(&global_regs
->gintmsk
);
1999 /* Disable all interrupts while we muck with
2000 * the hardware directly
2002 dwc_write_reg32(&global_regs
->gintmsk
, 0);
2004 /* 15 second delay per the test spec */
2007 /* Send the Setup packet */
2010 /* 15 second delay so nothing else happens for awhile */
2013 /* Restore interrupts */
2014 dwc_write_reg32(&global_regs
->gintmsk
, gintmsk
.d32
);
2015 } else if (t
== 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
2016 /* Save current interrupt mask */
2017 gintmsk
.d32
= dwc_read_reg32(&global_regs
->gintmsk
);
2019 /* Disable all interrupts while we muck with
2020 * the hardware directly
2022 dwc_write_reg32(&global_regs
->gintmsk
, 0);
2024 /* Send the Setup packet */
2027 /* 15 second delay so nothing else happens for awhile */
2030 /* Send the In and Ack packets */
2033 /* 15 second delay so nothing else happens for awhile */
2036 /* Restore interrupts */
2037 dwc_write_reg32(&global_regs
->gintmsk
, gintmsk
.d32
);
2042 #endif /* DWC_HS_ELECT_TST */
2044 case USB_PORT_FEAT_INDICATOR
:
2045 DWC_DEBUGPL(DBG_HCD
, "DWC OTG HCD HUB CONTROL - "
2046 "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
2051 DWC_ERROR("DWC OTG HCD - "
2052 "SetPortFeature request %xh "
2053 "unknown or unsupported\n", wValue
);
2060 DWC_WARN("DWC OTG HCD - "
2061 "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
2062 typeReq
, wIndex
, wValue
);
2070 * Assigns transactions from a QTD to a free host channel and initializes the
2071 * host channel to perform the transactions. The host channel is removed from
2074 * @param hcd The HCD state structure.
2075 * @param qh Transactions from the first QTD for this QH are selected and
2076 * assigned to a free host channel.
2078 static void assign_and_init_hc(dwc_otg_hcd_t
*hcd
, dwc_otg_qh_t
*qh
)
2084 DWC_DEBUGPL(DBG_HCDV
, "%s(%p,%p)\n", __func__
, hcd
, qh
);
2086 hc
= list_entry(hcd
->free_hc_list
.next
, dwc_hc_t
, hc_list_entry
);
2088 /* Remove the host channel from the free list. */
2089 list_del_init(&hc
->hc_list_entry
);
2091 qtd
= list_entry(qh
->qtd_list
.next
, dwc_otg_qtd_t
, qtd_list_entry
);
2094 qh
->qtd_in_process
= qtd
;
2097 * Use usb_pipedevice to determine device address. This address is
2098 * 0 before the SET_ADDRESS command and the correct address afterward.
2100 hc
->dev_addr
= usb_pipedevice(urb
->pipe
);
2101 hc
->ep_num
= usb_pipeendpoint(urb
->pipe
);
2103 if (urb
->dev
->speed
== USB_SPEED_LOW
) {
2104 hc
->speed
= DWC_OTG_EP_SPEED_LOW
;
2105 } else if (urb
->dev
->speed
== USB_SPEED_FULL
) {
2106 hc
->speed
= DWC_OTG_EP_SPEED_FULL
;
2108 hc
->speed
= DWC_OTG_EP_SPEED_HIGH
;
2111 hc
->max_packet
= dwc_max_packet(qh
->maxp
);
2113 hc
->xfer_started
= 0;
2114 hc
->halt_status
= DWC_OTG_HC_XFER_NO_HALT_STATUS
;
2115 hc
->error_state
= (qtd
->error_count
> 0);
2116 hc
->halt_on_queue
= 0;
2117 hc
->halt_pending
= 0;
2121 * The following values may be modified in the transfer type section
2122 * below. The xfer_len value may be reduced when the transfer is
2123 * started to accommodate the max widths of the XferSize and PktCnt
2124 * fields in the HCTSIZn register.
2126 hc
->do_ping
= qh
->ping_state
;
2127 hc
->ep_is_in
= (usb_pipein(urb
->pipe
) != 0);
2128 hc
->data_pid_start
= qh
->data_toggle
;
2129 hc
->multi_count
= 1;
2131 if (hcd
->core_if
->dma_enable
) {
2132 hc
->xfer_buff
= (uint8_t *)urb
->transfer_dma
+ urb
->actual_length
;
2134 hc
->xfer_buff
= (uint8_t *)urb
->transfer_buffer
+ urb
->actual_length
;
2136 hc
->xfer_len
= urb
->transfer_buffer_length
- urb
->actual_length
;
2140 * Set the split attributes
2145 hc
->xact_pos
= qtd
->isoc_split_pos
;
2146 hc
->complete_split
= qtd
->complete_split
;
2147 hc
->hub_addr
= urb
->dev
->tt
->hub
->devnum
;
2148 hc
->port_addr
= urb
->dev
->ttport
;
2151 switch (usb_pipetype(urb
->pipe
)) {
2153 hc
->ep_type
= DWC_OTG_EP_TYPE_CONTROL
;
2154 switch (qtd
->control_phase
) {
2155 case DWC_OTG_CONTROL_SETUP
:
2156 DWC_DEBUGPL(DBG_HCDV
, " Control setup transaction\n");
2159 hc
->data_pid_start
= DWC_OTG_HC_PID_SETUP
;
2160 if (hcd
->core_if
->dma_enable
) {
2161 hc
->xfer_buff
= (uint8_t *)urb
->setup_dma
;
2163 hc
->xfer_buff
= (uint8_t *)urb
->setup_packet
;
2167 case DWC_OTG_CONTROL_DATA
:
2168 DWC_DEBUGPL(DBG_HCDV
, " Control data transaction\n");
2169 hc
->data_pid_start
= qtd
->data_toggle
;
2171 case DWC_OTG_CONTROL_STATUS
:
2173 * Direction is opposite of data direction or IN if no
2176 DWC_DEBUGPL(DBG_HCDV
, " Control status transaction\n");
2177 if (urb
->transfer_buffer_length
== 0) {
2180 hc
->ep_is_in
= (usb_pipein(urb
->pipe
) != USB_DIR_IN
);
2185 hc
->data_pid_start
= DWC_OTG_HC_PID_DATA1
;
2187 if (hcd
->core_if
->dma_enable
) {
2188 hc
->xfer_buff
= (uint8_t *)hcd
->status_buf_dma
;
2190 hc
->xfer_buff
= (uint8_t *)hcd
->status_buf
;
2196 hc
->ep_type
= DWC_OTG_EP_TYPE_BULK
;
2198 case PIPE_INTERRUPT
:
2199 hc
->ep_type
= DWC_OTG_EP_TYPE_INTR
;
2201 case PIPE_ISOCHRONOUS
:
2203 struct usb_iso_packet_descriptor
*frame_desc
;
2204 frame_desc
= &urb
->iso_frame_desc
[qtd
->isoc_frame_index
];
2205 hc
->ep_type
= DWC_OTG_EP_TYPE_ISOC
;
2206 if (hcd
->core_if
->dma_enable
) {
2207 hc
->xfer_buff
= (uint8_t *)urb
->transfer_dma
;
2209 hc
->xfer_buff
= (uint8_t *)urb
->transfer_buffer
;
2211 hc
->xfer_buff
+= frame_desc
->offset
+ qtd
->isoc_split_offset
;
2212 hc
->xfer_len
= frame_desc
->length
- qtd
->isoc_split_offset
;
2214 if (hc
->xact_pos
== DWC_HCSPLIT_XACTPOS_ALL
) {
2215 if (hc
->xfer_len
<= 188) {
2216 hc
->xact_pos
= DWC_HCSPLIT_XACTPOS_ALL
;
2219 hc
->xact_pos
= DWC_HCSPLIT_XACTPOS_BEGIN
;
2226 if (hc
->ep_type
== DWC_OTG_EP_TYPE_INTR
||
2227 hc
->ep_type
== DWC_OTG_EP_TYPE_ISOC
) {
2229 * This value may be modified when the transfer is started to
2230 * reflect the actual transfer length.
2232 hc
->multi_count
= dwc_hb_mult(qh
->maxp
);
2235 dwc_otg_hc_init(hcd
->core_if
, hc
);
2240 * This function selects transactions from the HCD transfer schedule and
2241 * assigns them to available host channels. It is called from HCD interrupt
2242 * handler functions.
2244 * @param hcd The HCD state structure.
2246 * @return The types of new transactions that were assigned to host channels.
2248 dwc_otg_transaction_type_e
dwc_otg_hcd_select_transactions(dwc_otg_hcd_t
*hcd
)
2250 struct list_head
*qh_ptr
;
2253 dwc_otg_transaction_type_e ret_val
= DWC_OTG_TRANSACTION_NONE
;
2256 DWC_DEBUGPL(DBG_HCD
, " Select Transactions\n");
2259 /* Process entries in the periodic ready list. */
2260 qh_ptr
= hcd
->periodic_sched_ready
.next
;
2261 while (qh_ptr
!= &hcd
->periodic_sched_ready
&&
2262 !list_empty(&hcd
->free_hc_list
)) {
2264 qh
= list_entry(qh_ptr
, dwc_otg_qh_t
, qh_list_entry
);
2265 assign_and_init_hc(hcd
, qh
);
2268 * Move the QH from the periodic ready schedule to the
2269 * periodic assigned schedule.
2271 qh_ptr
= qh_ptr
->next
;
2272 list_move(&qh
->qh_list_entry
, &hcd
->periodic_sched_assigned
);
2274 ret_val
= DWC_OTG_TRANSACTION_PERIODIC
;
2278 * Process entries in the inactive portion of the non-periodic
2279 * schedule. Some free host channels may not be used if they are
2280 * reserved for periodic transfers.
2282 qh_ptr
= hcd
->non_periodic_sched_inactive
.next
;
2283 num_channels
= hcd
->core_if
->core_params
->host_channels
;
2284 while (qh_ptr
!= &hcd
->non_periodic_sched_inactive
&&
2285 (hcd
->non_periodic_channels
<
2286 num_channels
- hcd
->periodic_channels
) &&
2287 !list_empty(&hcd
->free_hc_list
)) {
2289 qh
= list_entry(qh_ptr
, dwc_otg_qh_t
, qh_list_entry
);
2290 assign_and_init_hc(hcd
, qh
);
2293 * Move the QH from the non-periodic inactive schedule to the
2294 * non-periodic active schedule.
2296 qh_ptr
= qh_ptr
->next
;
2297 list_move(&qh
->qh_list_entry
, &hcd
->non_periodic_sched_active
);
2299 if (ret_val
== DWC_OTG_TRANSACTION_NONE
) {
2300 ret_val
= DWC_OTG_TRANSACTION_NON_PERIODIC
;
2302 ret_val
= DWC_OTG_TRANSACTION_ALL
;
2305 hcd
->non_periodic_channels
++;
2312 * Attempts to queue a single transaction request for a host channel
2313 * associated with either a periodic or non-periodic transfer. This function
2314 * assumes that there is space available in the appropriate request queue. For
2315 * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
2316 * is available in the appropriate Tx FIFO.
2318 * @param hcd The HCD state structure.
2319 * @param hc Host channel descriptor associated with either a periodic or
2320 * non-periodic transfer.
2321 * @param fifo_dwords_avail Number of DWORDs available in the periodic Tx
2322 * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
2325 * @return 1 if a request is queued and more requests may be needed to
2326 * complete the transfer, 0 if no more requests are required for this
2327 * transfer, -1 if there is insufficient space in the Tx FIFO.
2329 static int queue_transaction(dwc_otg_hcd_t
*hcd
,
2331 uint16_t fifo_dwords_avail
)
2335 if (hcd
->core_if
->dma_enable
) {
2336 if (!hc
->xfer_started
) {
2337 dwc_otg_hc_start_transfer(hcd
->core_if
, hc
);
2338 hc
->qh
->ping_state
= 0;
2341 } else if (hc
->halt_pending
) {
2342 /* Don't queue a request if the channel has been halted. */
2344 } else if (hc
->halt_on_queue
) {
2345 dwc_otg_hc_halt(hcd
->core_if
, hc
, hc
->halt_status
);
2347 } else if (hc
->do_ping
) {
2348 if (!hc
->xfer_started
) {
2349 dwc_otg_hc_start_transfer(hcd
->core_if
, hc
);
2352 } else if (!hc
->ep_is_in
||
2353 hc
->data_pid_start
== DWC_OTG_HC_PID_SETUP
) {
2354 if ((fifo_dwords_avail
* 4) >= hc
->max_packet
) {
2355 if (!hc
->xfer_started
) {
2356 dwc_otg_hc_start_transfer(hcd
->core_if
, hc
);
2359 retval
= dwc_otg_hc_continue_transfer(hcd
->core_if
, hc
);
2365 if (!hc
->xfer_started
) {
2366 dwc_otg_hc_start_transfer(hcd
->core_if
, hc
);
2369 retval
= dwc_otg_hc_continue_transfer(hcd
->core_if
, hc
);
2377 * Processes active non-periodic channels and queues transactions for these
2378 * channels to the DWC_otg controller. After queueing transactions, the NP Tx
2379 * FIFO Empty interrupt is enabled if there are more transactions to queue as
2380 * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
2381 * FIFO Empty interrupt is disabled.
2383 static void process_non_periodic_channels(dwc_otg_hcd_t
*hcd
)
2385 gnptxsts_data_t tx_status
;
2386 struct list_head
*orig_qh_ptr
;
2389 int no_queue_space
= 0;
2390 int no_fifo_space
= 0;
2393 dwc_otg_core_global_regs_t
*global_regs
= hcd
->core_if
->core_global_regs
;
2395 DWC_DEBUGPL(DBG_HCDV
, "Queue non-periodic transactions\n");
2397 tx_status
.d32
= dwc_read_reg32(&global_regs
->gnptxsts
);
2398 DWC_DEBUGPL(DBG_HCDV
, " NP Tx Req Queue Space Avail (before queue): %d\n",
2399 tx_status
.b
.nptxqspcavail
);
2400 DWC_DEBUGPL(DBG_HCDV
, " NP Tx FIFO Space Avail (before queue): %d\n",
2401 tx_status
.b
.nptxfspcavail
);
2404 * Keep track of the starting point. Skip over the start-of-list
2407 if (hcd
->non_periodic_qh_ptr
== &hcd
->non_periodic_sched_active
) {
2408 hcd
->non_periodic_qh_ptr
= hcd
->non_periodic_qh_ptr
->next
;
2410 orig_qh_ptr
= hcd
->non_periodic_qh_ptr
;
2413 * Process once through the active list or until no more space is
2414 * available in the request queue or the Tx FIFO.
2417 tx_status
.d32
= dwc_read_reg32(&global_regs
->gnptxsts
);
2418 if (!hcd
->core_if
->dma_enable
&& tx_status
.b
.nptxqspcavail
== 0) {
2423 qh
= list_entry(hcd
->non_periodic_qh_ptr
, dwc_otg_qh_t
, qh_list_entry
);
2424 status
= queue_transaction(hcd
, qh
->channel
, tx_status
.b
.nptxfspcavail
);
2428 } else if (status
< 0) {
2433 /* Advance to next QH, skipping start-of-list entry. */
2434 hcd
->non_periodic_qh_ptr
= hcd
->non_periodic_qh_ptr
->next
;
2435 if (hcd
->non_periodic_qh_ptr
== &hcd
->non_periodic_sched_active
) {
2436 hcd
->non_periodic_qh_ptr
= hcd
->non_periodic_qh_ptr
->next
;
2439 } while (hcd
->non_periodic_qh_ptr
!= orig_qh_ptr
);
2441 if (!hcd
->core_if
->dma_enable
) {
2442 gintmsk_data_t intr_mask
= {.d32
= 0};
2443 intr_mask
.b
.nptxfempty
= 1;
2446 tx_status
.d32
= dwc_read_reg32(&global_regs
->gnptxsts
);
2447 DWC_DEBUGPL(DBG_HCDV
, " NP Tx Req Queue Space Avail (after queue): %d\n",
2448 tx_status
.b
.nptxqspcavail
);
2449 DWC_DEBUGPL(DBG_HCDV
, " NP Tx FIFO Space Avail (after queue): %d\n",
2450 tx_status
.b
.nptxfspcavail
);
2452 if (more_to_do
|| no_queue_space
|| no_fifo_space
) {
2454 * May need to queue more transactions as the request
2455 * queue or Tx FIFO empties. Enable the non-periodic
2456 * Tx FIFO empty interrupt. (Always use the half-empty
2457 * level to ensure that new requests are loaded as
2458 * soon as possible.)
2460 dwc_modify_reg32(&global_regs
->gintmsk
, 0, intr_mask
.d32
);
2463 * Disable the Tx FIFO empty interrupt since there are
2464 * no more transactions that need to be queued right
2465 * now. This function is called from interrupt
2466 * handlers to queue more transactions as transfer
2469 dwc_modify_reg32(&global_regs
->gintmsk
, intr_mask
.d32
, 0);
2475 * Processes periodic channels for the next frame and queues transactions for
2476 * these channels to the DWC_otg controller. After queueing transactions, the
2477 * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
2478 * to queue as Periodic Tx FIFO or request queue space becomes available.
2479 * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
2481 static void process_periodic_channels(dwc_otg_hcd_t
*hcd
)
2483 hptxsts_data_t tx_status
;
2484 struct list_head
*qh_ptr
;
2487 int no_queue_space
= 0;
2488 int no_fifo_space
= 0;
2490 dwc_otg_host_global_regs_t
*host_regs
;
2491 host_regs
= hcd
->core_if
->host_if
->host_global_regs
;
2493 DWC_DEBUGPL(DBG_HCDV
, "Queue periodic transactions\n");
2495 tx_status
.d32
= dwc_read_reg32(&host_regs
->hptxsts
);
2496 DWC_DEBUGPL(DBG_HCDV
, " P Tx Req Queue Space Avail (before queue): %d\n",
2497 tx_status
.b
.ptxqspcavail
);
2498 DWC_DEBUGPL(DBG_HCDV
, " P Tx FIFO Space Avail (before queue): %d\n",
2499 tx_status
.b
.ptxfspcavail
);
2502 qh_ptr
= hcd
->periodic_sched_assigned
.next
;
2503 while (qh_ptr
!= &hcd
->periodic_sched_assigned
) {
2504 tx_status
.d32
= dwc_read_reg32(&host_regs
->hptxsts
);
2505 if (tx_status
.b
.ptxqspcavail
== 0) {
2510 qh
= list_entry(qh_ptr
, dwc_otg_qh_t
, qh_list_entry
);
2513 * Set a flag if we're queuing high-bandwidth in slave mode.
2514 * The flag prevents any halts to get into the request queue in
2515 * the middle of multiple high-bandwidth packets getting queued.
2517 if (!hcd
->core_if
->dma_enable
&&
2518 qh
->channel
->multi_count
> 1)
2520 hcd
->core_if
->queuing_high_bandwidth
= 1;
2523 status
= queue_transaction(hcd
, qh
->channel
, tx_status
.b
.ptxfspcavail
);
2530 * In Slave mode, stay on the current transfer until there is
2531 * nothing more to do or the high-bandwidth request count is
2532 * reached. In DMA mode, only need to queue one request. The
2533 * controller automatically handles multiple packets for
2534 * high-bandwidth transfers.
2536 if (hcd
->core_if
->dma_enable
|| status
== 0 ||
2537 qh
->channel
->requests
== qh
->channel
->multi_count
) {
2538 qh_ptr
= qh_ptr
->next
;
2540 * Move the QH from the periodic assigned schedule to
2541 * the periodic queued schedule.
2543 list_move(&qh
->qh_list_entry
, &hcd
->periodic_sched_queued
);
2545 /* done queuing high bandwidth */
2546 hcd
->core_if
->queuing_high_bandwidth
= 0;
2550 if (!hcd
->core_if
->dma_enable
) {
2551 dwc_otg_core_global_regs_t
*global_regs
;
2552 gintmsk_data_t intr_mask
= {.d32
= 0};
2554 global_regs
= hcd
->core_if
->core_global_regs
;
2555 intr_mask
.b
.ptxfempty
= 1;
2557 tx_status
.d32
= dwc_read_reg32(&host_regs
->hptxsts
);
2558 DWC_DEBUGPL(DBG_HCDV
, " P Tx Req Queue Space Avail (after queue): %d\n",
2559 tx_status
.b
.ptxqspcavail
);
2560 DWC_DEBUGPL(DBG_HCDV
, " P Tx FIFO Space Avail (after queue): %d\n",
2561 tx_status
.b
.ptxfspcavail
);
2563 if (!list_empty(&hcd
->periodic_sched_assigned
) ||
2564 no_queue_space
|| no_fifo_space
) {
2566 * May need to queue more transactions as the request
2567 * queue or Tx FIFO empties. Enable the periodic Tx
2568 * FIFO empty interrupt. (Always use the half-empty
2569 * level to ensure that new requests are loaded as
2570 * soon as possible.)
2572 dwc_modify_reg32(&global_regs
->gintmsk
, 0, intr_mask
.d32
);
2575 * Disable the Tx FIFO empty interrupt since there are
2576 * no more transactions that need to be queued right
2577 * now. This function is called from interrupt
2578 * handlers to queue more transactions as transfer
2581 dwc_modify_reg32(&global_regs
->gintmsk
, intr_mask
.d32
, 0);
2587 * This function processes the currently active host channels and queues
2588 * transactions for these channels to the DWC_otg controller. It is called
2589 * from HCD interrupt handler functions.
2591 * @param hcd The HCD state structure.
2592 * @param tr_type The type(s) of transactions to queue (non-periodic,
2593 * periodic, or both).
2595 void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t
*hcd
,
2596 dwc_otg_transaction_type_e tr_type
)
2599 DWC_DEBUGPL(DBG_HCD
, "Queue Transactions\n");
2601 /* Process host channels associated with periodic transfers. */
2602 if ((tr_type
== DWC_OTG_TRANSACTION_PERIODIC
||
2603 tr_type
== DWC_OTG_TRANSACTION_ALL
) &&
2604 !list_empty(&hcd
->periodic_sched_assigned
)) {
2606 process_periodic_channels(hcd
);
2609 /* Process host channels associated with non-periodic transfers. */
2610 if (tr_type
== DWC_OTG_TRANSACTION_NON_PERIODIC
||
2611 tr_type
== DWC_OTG_TRANSACTION_ALL
) {
2612 if (!list_empty(&hcd
->non_periodic_sched_active
)) {
2613 process_non_periodic_channels(hcd
);
2616 * Ensure NP Tx FIFO empty interrupt is disabled when
2617 * there are no non-periodic transfers to process.
2619 gintmsk_data_t gintmsk
= {.d32
= 0};
2620 gintmsk
.b
.nptxfempty
= 1;
2621 dwc_modify_reg32(&hcd
->core_if
->core_global_regs
->gintmsk
,
2628 * Sets the final status of an URB and returns it to the device driver. Any
2629 * required cleanup of the URB is performed.
2631 void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t
*hcd
, struct urb
*urb
, int status
)
2634 if (CHK_DEBUG_LEVEL(DBG_HCDV
| DBG_HCD_URB
)) {
2635 DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
2636 __func__
, urb
, usb_pipedevice(urb
->pipe
),
2637 usb_pipeendpoint(urb
->pipe
),
2638 usb_pipein(urb
->pipe
) ? "IN" : "OUT", status
);
2639 if (usb_pipetype(urb
->pipe
) == PIPE_ISOCHRONOUS
) {
2641 for (i
= 0; i
< urb
->number_of_packets
; i
++) {
2642 DWC_PRINT(" ISO Desc %d status: %d\n",
2643 i
, urb
->iso_frame_desc
[i
].status
);
2649 urb
->status
= status
;
2651 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2652 usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd
), urb
, status
);
2654 usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd
), urb
, NULL
);
2659 * Returns the Queue Head for an URB.
2661 dwc_otg_qh_t
*dwc_urb_to_qh(struct urb
*urb
)
2663 struct usb_host_endpoint
*ep
= dwc_urb_to_endpoint(urb
);
2664 return (dwc_otg_qh_t
*)ep
->hcpriv
;
2668 void dwc_print_setup_data(uint8_t *setup
)
2671 if (CHK_DEBUG_LEVEL(DBG_HCD
)){
2672 DWC_PRINT("Setup Data = MSB ");
2673 for (i
= 7; i
>= 0; i
--) DWC_PRINT("%02x ", setup
[i
]);
2675 DWC_PRINT(" bmRequestType Tranfer = %s\n", (setup
[0] & 0x80) ? "Device-to-Host" : "Host-to-Device");
2676 DWC_PRINT(" bmRequestType Type = ");
2677 switch ((setup
[0] & 0x60) >> 5) {
2678 case 0: DWC_PRINT("Standard\n"); break;
2679 case 1: DWC_PRINT("Class\n"); break;
2680 case 2: DWC_PRINT("Vendor\n"); break;
2681 case 3: DWC_PRINT("Reserved\n"); break;
2683 DWC_PRINT(" bmRequestType Recipient = ");
2684 switch (setup
[0] & 0x1f) {
2685 case 0: DWC_PRINT("Device\n"); break;
2686 case 1: DWC_PRINT("Interface\n"); break;
2687 case 2: DWC_PRINT("Endpoint\n"); break;
2688 case 3: DWC_PRINT("Other\n"); break;
2689 default: DWC_PRINT("Reserved\n"); break;
2691 DWC_PRINT(" bRequest = 0x%0x\n", setup
[1]);
2692 DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *)&setup
[2]));
2693 DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *)&setup
[4]));
2694 DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *)&setup
[6]));
2699 void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t
*hcd
) {
2700 #if defined(DEBUG) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2701 DWC_PRINT("Frame remaining at SOF:\n");
2702 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2703 hcd
->frrem_samples
, hcd
->frrem_accum
,
2704 (hcd
->frrem_samples
> 0) ?
2705 hcd
->frrem_accum
/hcd
->frrem_samples
: 0);
2708 DWC_PRINT("Frame remaining at start_transfer (uframe 7):\n");
2709 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2710 hcd
->core_if
->hfnum_7_samples
, hcd
->core_if
->hfnum_7_frrem_accum
,
2711 (hcd
->core_if
->hfnum_7_samples
> 0) ?
2712 hcd
->core_if
->hfnum_7_frrem_accum
/hcd
->core_if
->hfnum_7_samples
: 0);
2713 DWC_PRINT("Frame remaining at start_transfer (uframe 0):\n");
2714 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2715 hcd
->core_if
->hfnum_0_samples
, hcd
->core_if
->hfnum_0_frrem_accum
,
2716 (hcd
->core_if
->hfnum_0_samples
> 0) ?
2717 hcd
->core_if
->hfnum_0_frrem_accum
/hcd
->core_if
->hfnum_0_samples
: 0);
2718 DWC_PRINT("Frame remaining at start_transfer (uframe 1-6):\n");
2719 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2720 hcd
->core_if
->hfnum_other_samples
, hcd
->core_if
->hfnum_other_frrem_accum
,
2721 (hcd
->core_if
->hfnum_other_samples
> 0) ?
2722 hcd
->core_if
->hfnum_other_frrem_accum
/hcd
->core_if
->hfnum_other_samples
: 0);
2725 DWC_PRINT("Frame remaining at sample point A (uframe 7):\n");
2726 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2727 hcd
->hfnum_7_samples_a
, hcd
->hfnum_7_frrem_accum_a
,
2728 (hcd
->hfnum_7_samples_a
> 0) ?
2729 hcd
->hfnum_7_frrem_accum_a
/hcd
->hfnum_7_samples_a
: 0);
2730 DWC_PRINT("Frame remaining at sample point A (uframe 0):\n");
2731 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2732 hcd
->hfnum_0_samples_a
, hcd
->hfnum_0_frrem_accum_a
,
2733 (hcd
->hfnum_0_samples_a
> 0) ?
2734 hcd
->hfnum_0_frrem_accum_a
/hcd
->hfnum_0_samples_a
: 0);
2735 DWC_PRINT("Frame remaining at sample point A (uframe 1-6):\n");
2736 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2737 hcd
->hfnum_other_samples_a
, hcd
->hfnum_other_frrem_accum_a
,
2738 (hcd
->hfnum_other_samples_a
> 0) ?
2739 hcd
->hfnum_other_frrem_accum_a
/hcd
->hfnum_other_samples_a
: 0);
2742 DWC_PRINT("Frame remaining at sample point B (uframe 7):\n");
2743 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2744 hcd
->hfnum_7_samples_b
, hcd
->hfnum_7_frrem_accum_b
,
2745 (hcd
->hfnum_7_samples_b
> 0) ?
2746 hcd
->hfnum_7_frrem_accum_b
/hcd
->hfnum_7_samples_b
: 0);
2747 DWC_PRINT("Frame remaining at sample point B (uframe 0):\n");
2748 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2749 hcd
->hfnum_0_samples_b
, hcd
->hfnum_0_frrem_accum_b
,
2750 (hcd
->hfnum_0_samples_b
> 0) ?
2751 hcd
->hfnum_0_frrem_accum_b
/hcd
->hfnum_0_samples_b
: 0);
2752 DWC_PRINT("Frame remaining at sample point B (uframe 1-6):\n");
2753 DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2754 hcd
->hfnum_other_samples_b
, hcd
->hfnum_other_frrem_accum_b
,
2755 (hcd
->hfnum_other_samples_b
> 0) ?
2756 hcd
->hfnum_other_frrem_accum_b
/hcd
->hfnum_other_samples_b
: 0);
2760 void dwc_otg_hcd_dump_state(dwc_otg_hcd_t
*hcd
)
2765 gnptxsts_data_t np_tx_status
;
2766 hptxsts_data_t p_tx_status
;
2768 num_channels
= hcd
->core_if
->core_params
->host_channels
;
2770 DWC_PRINT("************************************************************\n");
2771 DWC_PRINT("HCD State:\n");
2772 DWC_PRINT(" Num channels: %d\n", num_channels
);
2773 for (i
= 0; i
< num_channels
; i
++) {
2774 dwc_hc_t
*hc
= hcd
->hc_ptr_array
[i
];
2775 DWC_PRINT(" Channel %d:\n", i
);
2776 DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
2777 hc
->dev_addr
, hc
->ep_num
, hc
->ep_is_in
);
2778 DWC_PRINT(" speed: %d\n", hc
->speed
);
2779 DWC_PRINT(" ep_type: %d\n", hc
->ep_type
);
2780 DWC_PRINT(" max_packet: %d\n", hc
->max_packet
);
2781 DWC_PRINT(" data_pid_start: %d\n", hc
->data_pid_start
);
2782 DWC_PRINT(" multi_count: %d\n", hc
->multi_count
);
2783 DWC_PRINT(" xfer_started: %d\n", hc
->xfer_started
);
2784 DWC_PRINT(" xfer_buff: %p\n", hc
->xfer_buff
);
2785 DWC_PRINT(" xfer_len: %d\n", hc
->xfer_len
);
2786 DWC_PRINT(" xfer_count: %d\n", hc
->xfer_count
);
2787 DWC_PRINT(" halt_on_queue: %d\n", hc
->halt_on_queue
);
2788 DWC_PRINT(" halt_pending: %d\n", hc
->halt_pending
);
2789 DWC_PRINT(" halt_status: %d\n", hc
->halt_status
);
2790 DWC_PRINT(" do_split: %d\n", hc
->do_split
);
2791 DWC_PRINT(" complete_split: %d\n", hc
->complete_split
);
2792 DWC_PRINT(" hub_addr: %d\n", hc
->hub_addr
);
2793 DWC_PRINT(" port_addr: %d\n", hc
->port_addr
);
2794 DWC_PRINT(" xact_pos: %d\n", hc
->xact_pos
);
2795 DWC_PRINT(" requests: %d\n", hc
->requests
);
2796 DWC_PRINT(" qh: %p\n", hc
->qh
);
2797 if (hc
->xfer_started
) {
2799 hcchar_data_t hcchar
;
2800 hctsiz_data_t hctsiz
;
2802 hcintmsk_data_t hcintmsk
;
2803 hfnum
.d32
= dwc_read_reg32(&hcd
->core_if
->host_if
->host_global_regs
->hfnum
);
2804 hcchar
.d32
= dwc_read_reg32(&hcd
->core_if
->host_if
->hc_regs
[i
]->hcchar
);
2805 hctsiz
.d32
= dwc_read_reg32(&hcd
->core_if
->host_if
->hc_regs
[i
]->hctsiz
);
2806 hcint
.d32
= dwc_read_reg32(&hcd
->core_if
->host_if
->hc_regs
[i
]->hcint
);
2807 hcintmsk
.d32
= dwc_read_reg32(&hcd
->core_if
->host_if
->hc_regs
[i
]->hcintmsk
);
2808 DWC_PRINT(" hfnum: 0x%08x\n", hfnum
.d32
);
2809 DWC_PRINT(" hcchar: 0x%08x\n", hcchar
.d32
);
2810 DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz
.d32
);
2811 DWC_PRINT(" hcint: 0x%08x\n", hcint
.d32
);
2812 DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk
.d32
);
2814 if (hc
->xfer_started
&& hc
->qh
&& hc
->qh
->qtd_in_process
) {
2817 qtd
= hc
->qh
->qtd_in_process
;
2819 DWC_PRINT(" URB Info:\n");
2820 DWC_PRINT(" qtd: %p, urb: %p\n", qtd
, urb
);
2822 DWC_PRINT(" Dev: %d, EP: %d %s\n",
2823 usb_pipedevice(urb
->pipe
), usb_pipeendpoint(urb
->pipe
),
2824 usb_pipein(urb
->pipe
) ? "IN" : "OUT");
2825 DWC_PRINT(" Max packet size: %d\n",
2826 usb_maxpacket(urb
->dev
, urb
->pipe
, usb_pipeout(urb
->pipe
)));
2827 DWC_PRINT(" transfer_buffer: %p\n", urb
->transfer_buffer
);
2828 DWC_PRINT(" transfer_dma: %p\n", (void *)urb
->transfer_dma
);
2829 DWC_PRINT(" transfer_buffer_length: %d\n", urb
->transfer_buffer_length
);
2830 DWC_PRINT(" actual_length: %d\n", urb
->actual_length
);
2834 DWC_PRINT(" non_periodic_channels: %d\n", hcd
->non_periodic_channels
);
2835 DWC_PRINT(" periodic_channels: %d\n", hcd
->periodic_channels
);
2836 DWC_PRINT(" periodic_usecs: %d\n", hcd
->periodic_usecs
);
2837 np_tx_status
.d32
= dwc_read_reg32(&hcd
->core_if
->core_global_regs
->gnptxsts
);
2838 DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n", np_tx_status
.b
.nptxqspcavail
);
2839 DWC_PRINT(" NP Tx FIFO Space Avail: %d\n", np_tx_status
.b
.nptxfspcavail
);
2840 p_tx_status
.d32
= dwc_read_reg32(&hcd
->core_if
->host_if
->host_global_regs
->hptxsts
);
2841 DWC_PRINT(" P Tx Req Queue Space Avail: %d\n", p_tx_status
.b
.ptxqspcavail
);
2842 DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status
.b
.ptxfspcavail
);
2843 dwc_otg_hcd_dump_frrem(hcd
);
2844 dwc_otg_dump_global_registers(hcd
->core_if
);
2845 dwc_otg_dump_host_registers(hcd
->core_if
);
2846 DWC_PRINT("************************************************************\n");
2850 #endif /* DWC_DEVICE_ONLY */