Root/target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_hcd.c

1/* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $
3 * $Revision: 1.4 $
4 * $Date: 2008-11-21 05:39:15 $
5 * $Change: 1064940 $
6 *
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.
10 *
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.
20 *
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
31 * DAMAGE.
32 * ========================================================================== */
33#ifndef DWC_DEVICE_ONLY
34
35/**
36 * @file
37 *
38 * This file contains the implementation of the HCD. In Linux, the HCD
39 * implements the hc_driver API.
40 */
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>
52
53#include "dwc_otg_driver.h"
54#include "dwc_otg_hcd.h"
55#include "dwc_otg_regs.h"
56
57static const char dwc_otg_hcd_name[] = "dwc_otg";
58
59static const struct hc_driver dwc_otg_hc_driver = {
60
61    .description = dwc_otg_hcd_name,
62    .product_desc = "DWC OTG Controller",
63    .hcd_priv_size = sizeof(dwc_otg_hcd_t),
64
65    .irq = dwc_otg_hcd_irq,
66
67    .flags = HCD_MEMORY | HCD_USB2,
68
69    //.reset =
70    .start = dwc_otg_hcd_start,
71    //.suspend =
72    //.resume =
73    .stop = dwc_otg_hcd_stop,
74
75    .urb_enqueue = dwc_otg_hcd_urb_enqueue,
76    .urb_dequeue = dwc_otg_hcd_urb_dequeue,
77    .endpoint_disable = dwc_otg_hcd_endpoint_disable,
78
79    .get_frame_number = dwc_otg_hcd_get_frame_number,
80
81    .hub_status_data = dwc_otg_hcd_hub_status_data,
82    .hub_control = dwc_otg_hcd_hub_control,
83    //.hub_suspend =
84    //.hub_resume =
85};
86
87/**
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.
90 */
91static void hcd_start_func(
92#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
93               void *_vp
94#else
95               struct work_struct *_work
96#endif
97              )
98{
99#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
100    struct usb_hcd *usb_hcd = (struct usb_hcd *)_vp;
101#else
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);
105#endif
106    DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, usb_hcd);
107    if (usb_hcd) {
108        dwc_otg_hcd_start(usb_hcd);
109    }
110}
111
112/**
113 * HCD Callback function for starting the HCD when A-Cable is
114 * connected.
115 *
116 * @param p void pointer to the <code>struct usb_hcd</code>
117 */
118static int32_t dwc_otg_hcd_start_cb(void *p)
119{
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;
122    hprt0_data_t hprt0;
123
124    if (core_if->op_state == B_HOST) {
125        /*
126         * Reset the port. During a HNP mode switch the reset
127         * needs to occur within 1ms and have a duration of at
128         * least 50ms.
129         */
130        hprt0.d32 = dwc_otg_read_hprt0(core_if);
131        hprt0.b.prtrst = 1;
132        dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
133        ((struct usb_hcd *)p)->self.is_b_host = 1;
134    } else {
135        ((struct usb_hcd *)p)->self.is_b_host = 0;
136    }
137
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);
142#else
143// INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
144    INIT_DELAYED_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
145#endif
146// schedule_work(&dwc_otg_hcd->start_work);
147    queue_delayed_work(core_if->wq_otg, &dwc_otg_hcd->start_work, 50 * HZ / 1000);
148
149    return 1;
150}
151
152/**
153 * HCD Callback function for stopping the HCD.
154 *
155 * @param p void pointer to the <code>struct usb_hcd</code>
156 */
157static int32_t dwc_otg_hcd_stop_cb(void *p)
158{
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);
162    return 1;
163}
164
165static void del_xfer_timers(dwc_otg_hcd_t *hcd)
166{
167#ifdef DEBUG
168    int i;
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]);
172    }
173#endif
174}
175
176static void del_timers(dwc_otg_hcd_t *hcd)
177{
178    del_xfer_timers(hcd);
179    del_timer(&hcd->conn_timer);
180}
181
182/**
183 * Processes all the URBs in a single list of QHs. Completes them with
184 * -ETIMEDOUT and frees the QTD.
185 */
186static void kill_urbs_in_qh_list(dwc_otg_hcd_t *hcd, struct list_head *qh_list)
187{
188    struct list_head *qh_item;
189    dwc_otg_qh_t *qh;
190    struct list_head *qtd_item;
191    dwc_otg_qtd_t *qtd;
192
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,
201                             -ETIMEDOUT);
202            }
203            dwc_otg_hcd_qtd_remove_and_free(hcd, qtd);
204        }
205    }
206}
207
208/**
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.
213 */
214static void kill_all_urbs(dwc_otg_hcd_t *hcd)
215{
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);
222}
223
224/**
225 * HCD Callback function for disconnect of the HCD.
226 *
227 * @param p void pointer to the <code>struct usb_hcd</code>
228 */
229static int32_t dwc_otg_hcd_disconnect_cb(void *p)
230{
231    gintsts_data_t intr;
232    dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(p);
233
234    //DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
235
236    /*
237     * Set status flags for the hub driver.
238     */
239    dwc_otg_hcd->flags.b.port_connect_status_change = 1;
240    dwc_otg_hcd->flags.b.port_connect_status = 0;
241
242    /*
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.
246     */
247    intr.d32 = 0;
248    intr.b.nptxfempty = 1;
249    intr.b.ptxfempty = 1;
250    intr.b.hcintr = 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);
253
254    del_timers(dwc_otg_hcd);
255
256    /*
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
259     * reconnection.
260     */
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");
265            hprt0.b.prtpwr = 0;
266            dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
267        }
268
269        dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
270    }
271
272    /* Respond with an error status to all URBs in the schedule. */
273    kill_all_urbs(dwc_otg_hcd);
274
275    if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
276        /* Clean up any host channels that were in use. */
277        int num_channels;
278        int i;
279        dwc_hc_t *channel;
280        dwc_otg_hc_regs_t *hc_regs;
281        hcchar_data_t hcchar;
282
283        num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
284
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);
292                    if (hcchar.b.chen) {
293                        hcchar.b.chen = 0;
294                        hcchar.b.chdis = 1;
295                        hcchar.b.epdir = 0;
296                        dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
297                    }
298                }
299            }
300        }
301
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);
307                if (hcchar.b.chen) {
308                    /* Halt the channel. */
309                    hcchar.b.chdis = 1;
310                    dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
311                }
312
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);
316            }
317        }
318    }
319
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;
323    return 1;
324}
325
326/**
327 * Connection timeout function. An OTG host is required to display a
328 * message if the device does not connect within 10 seconds.
329 */
330void dwc_otg_hcd_connect_timeout(unsigned long ptr)
331{
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");
335}
336
337/**
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
341 * timer expires.
342 */
343static void dwc_otg_hcd_start_connect_timer(dwc_otg_hcd_t *hcd)
344{
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);
350}
351
352/**
353 * HCD Callback function for disconnect of the HCD.
354 *
355 * @param p void pointer to the <code>struct usb_hcd</code>
356 */
357static int32_t dwc_otg_hcd_session_start_cb(void *p)
358{
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);
362    return 1;
363}
364
365/**
366 * HCD Callback structure for handling mode switching.
367 */
368static 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,
373    .p = 0,
374};
375
376/**
377 * Reset tasklet function
378 */
379static void reset_tasklet_func(unsigned long data)
380{
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;
383    hprt0_data_t hprt0;
384
385    DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
386
387    hprt0.d32 = dwc_otg_read_hprt0(core_if);
388    hprt0.b.prtrst = 1;
389    dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
390    mdelay(60);
391
392    hprt0.b.prtrst = 0;
393    dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
394    dwc_otg_hcd->flags.b.port_reset_change = 1;
395}
396
397static struct tasklet_struct reset_tasklet = {
398    .next = NULL,
399    .state = 0,
400    .count = ATOMIC_INIT(0),
401    .func = reset_tasklet_func,
402    .data = 0,
403};
404
405/**
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.
410 */
411int dwc_otg_hcd_init(struct device *dev)
412{
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;
416
417    int num_channels;
418    int i;
419    dwc_hc_t *channel;
420
421    int retval = 0;
422
423    DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
424
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() */
427
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;
433
434        if (otg_dev->core_if->dma_desc_enable) {
435            DWC_PRINT("Device using Descriptor DMA mode\n");
436        } else {
437            DWC_PRINT("Device using Buffer DMA mode\n");
438        }
439    } else {
440        DWC_PRINT("Using Slave mode\n");
441        dev->dma_mask = (void *)0;
442        dev->coherent_dma_mask = 0;
443    }
444#endif
445    /*
446     * Allocate memory for the base HCD plus the DWC OTG HCD.
447     * Initialize the base HCD.
448     */
449    hcd = usb_create_hcd(&dwc_otg_hc_driver, dev, dev_name(dev));
450    if (!hcd) {
451        retval = -ENOMEM;
452        goto error1;
453    }
454
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;
460    hcd->has_tt = 1;
461
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;
466
467    /* */
468    spin_lock_init(&dwc_otg_hcd->lock);
469
470    /* Register the HCD CIL Callbacks */
471    dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
472                       &hcd_cil_callbacks, hcd);
473
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);
477
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);
483
484    /*
485     * Create a host channel descriptor for each host channel implemented
486     * in the controller. Initialize the channel descriptor array.
487     */
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) {
494            retval = -ENOMEM;
495            DWC_ERROR("%s: host channel allocation failed\n", __func__);
496            goto error2;
497        }
498        memset(channel, 0, sizeof(dwc_hc_t));
499        channel->hc_num = i;
500        dwc_otg_hcd->hc_ptr_array[i] = channel;
501#ifdef DEBUG
502        init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
503#endif
504        DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel);
505    }
506
507    /* Initialize the Connection timeout timer. */
508    init_timer(&dwc_otg_hcd->conn_timer);
509
510    /* Initialize reset tasklet. */
511    reset_tasklet.data = (unsigned long) dwc_otg_hcd;
512    dwc_otg_hcd->reset_tasklet = &reset_tasklet;
513
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;
520
521        if (otg_dev->core_if->dma_desc_enable){
522            DWC_PRINT("Device using Descriptor DMA mode\n");
523        } else {
524            DWC_PRINT("Device using Buffer DMA mode\n");
525        }
526    } else {
527        DWC_PRINT("Using Slave mode\n");
528        dev->dma_mask = (void *)0;
529        dev->dev.coherent_dma_mask = 0;
530    }
531#endif
532    /*
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.
536     */
537    retval = usb_add_hcd(hcd, otg_dev->irq, IRQF_SHARED);
538    if (retval < 0) {
539        goto error2;
540    }
541
542    /*
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
546     * pool.
547     */
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);
554    } else {
555        dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
556                          GFP_KERNEL);
557    }
558    if (!dwc_otg_hcd->status_buf) {
559        retval = -ENOMEM;
560        DWC_ERROR("%s: status_buf allocation failed\n", __func__);
561        goto error3;
562    }
563
564    dwc_otg_hcd->otg_dev = otg_dev;
565
566    DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
567            dev_name(dev), hcd->self.busnum);
568
569    return 0;
570
571    /* Error conditions */
572 error3:
573    usb_remove_hcd(hcd);
574 error2:
575    dwc_otg_hcd_free(hcd);
576    usb_put_hcd(hcd);
577
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()
581     */
582    dev_set_drvdata(dev, otg_dev);
583
584 error1:
585    return retval;
586}
587
588/**
589 * Removes the HCD.
590 * Frees memory and resources associated with the HCD and deregisters the bus.
591 */
592void dwc_otg_hcd_remove(struct device *dev)
593{
594    dwc_otg_device_t *otg_dev = dev_get_drvdata(dev);
595    dwc_otg_hcd_t *dwc_otg_hcd;
596    struct usb_hcd *hcd;
597
598    DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
599
600    if (!otg_dev) {
601        DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
602        return;
603    }
604
605    dwc_otg_hcd = otg_dev->hcd;
606
607    if (!dwc_otg_hcd) {
608        DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
609        return;
610    }
611
612    hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
613
614    if (!hcd) {
615        DWC_DEBUGPL(DBG_ANY, "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n", __func__);
616        return;
617    }
618
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);
622
623    usb_remove_hcd(hcd);
624    dwc_otg_hcd_free(hcd);
625    usb_put_hcd(hcd);
626}
627
628/* =========================================================================
629 * Linux HC Driver Functions
630 * ========================================================================= */
631
632/**
633 * Initializes dynamic portions of the DWC_otg HCD state.
634 */
635static void hcd_reinit(dwc_otg_hcd_t *hcd)
636{
637    struct list_head *item;
638    int num_channels;
639    int i;
640    dwc_hc_t *channel;
641
642    hcd->flags.d32 = 0;
643
644    hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
645    hcd->non_periodic_channels = 0;
646    hcd->periodic_channels = 0;
647
648    /*
649     * Put all channels in the free channel list and clean up channel
650     * states.
651     */
652    item = hcd->free_hc_list.next;
653    while (item != &hcd->free_hc_list) {
654        list_del(item);
655        item = hcd->free_hc_list.next;
656    }
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);
662    }
663
664    /* Initialize the DWC core for host mode operation. */
665    dwc_otg_core_host_init(hcd->core_if);
666}
667
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. */
671int dwc_otg_hcd_start(struct usb_hcd *hcd)
672{
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;
675      struct usb_bus *bus;
676
677#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
678      struct usb_device *udev;
679    int retval;
680#endif
681
682    DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
683
684    bus = hcd_to_bus(hcd);
685
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;
691#else
692        hcd->state = HC_STATE_RUNNING;
693#endif
694        return 0;
695    }
696    hcd->state = HC_STATE_RUNNING;
697
698    /* Initialize and connect root hub if one is not already attached */
699    if (bus->root_hub) {
700        DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
701        /* Inform the HUB driver to resume. */
702        usb_hcd_resume_root_hub(hcd);
703    }
704    else {
705        DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Does Not Have Root Hub\n");
706
707#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
708        udev = usb_alloc_dev(NULL, bus, 0);
709        udev->speed = USB_SPEED_HIGH;
710        if (!udev) {
711            DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n");
712            return -ENODEV;
713        }
714        if ((retval = usb_hcd_register_root_hub(udev, hcd)) != 0) {
715            DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error registering %d\n", retval);
716            return -ENODEV;
717        }
718#endif
719    }
720
721    hcd_reinit(dwc_otg_hcd);
722
723    return 0;
724}
725
726static void qh_list_free(dwc_otg_hcd_t *hcd, struct list_head *qh_list)
727{
728    struct list_head *item;
729    dwc_otg_qh_t *qh;
730
731    if (!qh_list->next) {
732        /* The list hasn't been initialized yet. */
733        return;
734    }
735
736    /* Ensure there are no QTDs or URBs left. */
737    kill_urbs_in_qh_list(hcd, qh_list);
738
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);
742    }
743}
744
745/**
746 * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
747 * stopped.
748 */
749void dwc_otg_hcd_stop(struct usb_hcd *hcd)
750{
751    dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
752    hprt0_data_t hprt0 = { .d32=0 };
753
754    DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
755
756    /* Turn off all host-specific interrupts. */
757    dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
758
759    /*
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).
763     */
764
765    /* Turn off the vbus power */
766    DWC_PRINT("PortPower off\n");
767    hprt0.b.prtpwr = 0;
768    dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
769}
770
771/** Returns the current frame number. */
772int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd)
773{
774    dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
775    hfnum_data_t hfnum;
776
777    hfnum.d32 = dwc_read_reg32(&dwc_otg_hcd->core_if->
778                   host_if->host_global_regs->hfnum);
779
780#ifdef DEBUG_SOF
781    DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n", hfnum.b.frnum);
782#endif
783    return hfnum.b.frnum;
784}
785
786/**
787 * Frees secondary storage associated with the dwc_otg_hcd structure contained
788 * in the struct usb_hcd field.
789 */
790void dwc_otg_hcd_free(struct usb_hcd *hcd)
791{
792    dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
793    int i;
794
795    DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
796
797    del_timers(dwc_otg_hcd);
798
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);
806
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];
810        if (hc != NULL) {
811            DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n", i, hc);
812            kfree(hc);
813        }
814    }
815
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);
822        }
823    } else if (dwc_otg_hcd->status_buf != NULL) {
824        kfree(dwc_otg_hcd->status_buf);
825    }
826}
827
828#ifdef DEBUG
829static void dump_urb_info(struct urb *urb, char* fn_name)
830{
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",
836          ({char *pipetype;
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;
843           }; pipetype;}));
844    DWC_PRINT(" Speed: %s\n",
845          ({char *speed;
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;
851           }; speed;}));
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) {
861        int i;
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);
867        }
868    }
869}
870
871static void dump_channel_info(dwc_otg_hcd_t *hcd,
872                  dwc_otg_qh_t *qh)
873{
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;
879        int i;
880
881        dwc_otg_hc_regs_t *hc_regs;
882        hcchar_data_t hcchar;
883        hcsplt_data_t hcsplt;
884        hctsiz_data_t hctsiz;
885        uint32_t hcdma;
886
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);
892
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);
910        }
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);
915        }
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);
920        }
921    }
922}
923#endif
924
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. */
928int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
929                struct urb *urb,
930#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
931                int mem_flags
932#else
933                gfp_t mem_flags
934#endif
935              )
936{
937    int retval = 0;
938    dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
939    dwc_otg_qtd_t *qtd;
940
941#ifdef DEBUG
942    if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
943        dump_urb_info(urb, "dwc_otg_hcd_urb_enqueue");
944    }
945#endif
946    if (!dwc_otg_hcd->flags.b.port_connect_status) {
947        /* No longer connected. */
948        return -ENODEV;
949    }
950
951    qtd = dwc_otg_hcd_qtd_create(urb);
952    if (qtd == NULL) {
953        DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
954        return -ENOMEM;
955    }
956
957    retval = dwc_otg_hcd_qtd_add(qtd, dwc_otg_hcd);
958    if (retval < 0) {
959        DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
960              "Error status %d\n", retval);
961        dwc_otg_hcd_qtd_free(qtd);
962    }
963
964    return retval;
965}
966
967/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
968 * success. */
969int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd,
970                struct urb *urb,
971                int status)
972{
973    unsigned long flags;
974    dwc_otg_hcd_t *dwc_otg_hcd;
975    dwc_otg_qtd_t *urb_qtd;
976    dwc_otg_qh_t *qh;
977#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
978    struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
979#endif
980
981    DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
982
983    dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
984
985    SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags);
986
987    urb_qtd = (dwc_otg_qtd_t *)urb->hcpriv;
988    qh = (dwc_otg_qh_t *)ep->hcpriv;
989
990#ifdef DEBUG
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);
995        }
996    }
997#endif
998
999    if (urb_qtd == qh->qtd_in_process) {
1000        /* The QTD is in process (it has been assigned to a channel). */
1001
1002        if (dwc_otg_hcd->flags.b.port_connect_status) {
1003            /*
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
1008             * device mode.
1009             */
1010            dwc_otg_hc_halt(dwc_otg_hcd->core_if, qh->channel,
1011                    DWC_OTG_HC_XFER_URB_DEQUEUE);
1012        }
1013    }
1014
1015    /*
1016     * Free the QTD and clean up the associated QH. Leave the QH in the
1017     * schedule if it has any remaining QTDs.
1018     */
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);
1022        qh->channel = NULL;
1023        qh->qtd_in_process = NULL;
1024    } else if (list_empty(&qh->qtd_list)) {
1025        dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh);
1026    }
1027
1028    SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
1029
1030    urb->hcpriv = NULL;
1031
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);
1035#else
1036    usb_hcd_giveback_urb(hcd, urb, NULL);
1037#endif
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);
1041    }
1042
1043    return 0;
1044}
1045
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. */
1049void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
1050                  struct usb_host_endpoint *ep)
1051{
1052    dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1053    dwc_otg_qh_t *qh;
1054
1055#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1056    unsigned long flags;
1057    int retry = 0;
1058#endif
1059
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));
1063
1064#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1065rescan:
1066    SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags);
1067    qh = (dwc_otg_qh_t *)(ep->hcpriv);
1068    if (!qh)
1069        goto done;
1070
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);
1076            goto rescan;
1077        }
1078
1079        DWC_WARN("DWC OTG HCD EP DISABLE:"
1080             " QTD List for this endpoint is not empty\n");
1081    }
1082
1083    dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
1084    ep->hcpriv = NULL;
1085done:
1086    SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
1087
1088#else // LINUX_VERSION_CODE
1089
1090    qh = (dwc_otg_qh_t *)(ep->hcpriv);
1091    if (qh != NULL) {
1092#ifdef DEBUG
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");
1097        }
1098#endif
1099        dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
1100        ep->hcpriv = NULL;
1101    }
1102#endif // LINUX_VERSION_CODE
1103}
1104
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
1107 * interrupt.
1108 *
1109 * This function is called by the USB core when an interrupt occurs */
1110irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd
1111#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
1112                , struct pt_regs *regs
1113#endif
1114              )
1115{
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));
1118}
1119
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. */
1124int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, char *buf)
1125{
1126    dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1127
1128    buf[0] = 0;
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;
1134
1135#ifdef DEBUG
1136    if (buf[0]) {
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);
1149    }
1150#endif
1151    return (buf[0] != 0);
1152}
1153
1154#ifdef DWC_HS_ELECT_TST
1155/*
1156 * Quick and dirty hack to implement the HS Electrical Test
1157 * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
1158 *
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
1165 * directly.
1166 */
1167
1168dwc_otg_core_global_regs_t *global_regs;
1169dwc_otg_host_global_regs_t *hc_global_regs;
1170dwc_otg_hc_regs_t *hc_regs;
1171uint32_t *data_fifo;
1172
1173static void do_setup(void)
1174{
1175    gintsts_data_t gintsts;
1176    hctsiz_data_t hctsiz;
1177    hcchar_data_t hcchar;
1178    haint_data_t haint;
1179    hcint_data_t hcint;
1180
1181    /* Enable HAINTs */
1182    dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
1183
1184    /* Enable HCINTs */
1185    dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
1186
1187    /* Read GINTSTS */
1188    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1189    //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1190
1191    /* Read HAINT */
1192    haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1193    //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1194
1195    /* Read HCINT */
1196    hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1197    //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1198
1199    /* Read HCCHAR */
1200    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1201    //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1202
1203    /* Clear HCINT */
1204    dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1205
1206    /* Clear HAINT */
1207    dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1208
1209    /* Clear GINTSTS */
1210    dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1211
1212    /* Read GINTSTS */
1213    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1214    //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1215
1216    /*
1217     * Send Setup packet (Get Device Descriptor)
1218     */
1219
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);
1224        hcchar.b.chdis = 1;
1225// hcchar.b.chen = 1;
1226        dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1227        //sleep(1);
1228        mdelay(1000);
1229
1230        /* Read GINTSTS */
1231        gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1232        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1233
1234        /* Read HAINT */
1235        haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1236        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1237
1238        /* Read HCINT */
1239        hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1240        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1241
1242        /* Read HCCHAR */
1243        hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1244        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1245
1246        /* Clear HCINT */
1247        dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1248
1249        /* Clear HAINT */
1250        dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1251
1252        /* Clear GINTSTS */
1253        dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1254
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);
1258        //}
1259    }
1260
1261    /* Set HCTSIZ */
1262    hctsiz.d32 = 0;
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);
1267
1268    /* Set HCCHAR */
1269    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1270    hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
1271    hcchar.b.epdir = 0;
1272    hcchar.b.epnum = 0;
1273    hcchar.b.mps = 8;
1274    hcchar.b.chen = 1;
1275    dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1276
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);
1281
1282    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1283    //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
1284
1285    /* Wait for host channel interrupt */
1286    do {
1287        gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1288    } while (gintsts.b.hcintr == 0);
1289
1290    //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
1291
1292    /* Disable HCINTs */
1293    dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
1294
1295    /* Disable HAINTs */
1296    dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
1297
1298    /* Read HAINT */
1299    haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1300    //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1301
1302    /* Read HCINT */
1303    hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1304    //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1305
1306    /* Read HCCHAR */
1307    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1308    //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1309
1310    /* Clear HCINT */
1311    dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1312
1313    /* Clear HAINT */
1314    dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1315
1316    /* Clear GINTSTS */
1317    dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1318
1319    /* Read GINTSTS */
1320    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1321    //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1322}
1323
1324static void do_in_ack(void)
1325{
1326    gintsts_data_t gintsts;
1327    hctsiz_data_t hctsiz;
1328    hcchar_data_t hcchar;
1329    haint_data_t haint;
1330    hcint_data_t hcint;
1331    host_grxsts_data_t grxsts;
1332
1333    /* Enable HAINTs */
1334    dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
1335
1336    /* Enable HCINTs */
1337    dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
1338
1339    /* Read GINTSTS */
1340    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1341    //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1342
1343    /* Read HAINT */
1344    haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1345    //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1346
1347    /* Read HCINT */
1348    hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1349    //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1350
1351    /* Read HCCHAR */
1352    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1353    //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1354
1355    /* Clear HCINT */
1356    dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1357
1358    /* Clear HAINT */
1359    dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1360
1361    /* Clear GINTSTS */
1362    dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1363
1364    /* Read GINTSTS */
1365    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1366    //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1367
1368    /*
1369     * Receive Control In packet
1370     */
1371
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);
1376        hcchar.b.chdis = 1;
1377        hcchar.b.chen = 1;
1378        dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1379        //sleep(1);
1380        mdelay(1000);
1381
1382        /* Read GINTSTS */
1383        gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1384        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1385
1386        /* Read HAINT */
1387        haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1388        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1389
1390        /* Read HCINT */
1391        hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1392        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1393
1394        /* Read HCCHAR */
1395        hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1396        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1397
1398        /* Clear HCINT */
1399        dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1400
1401        /* Clear HAINT */
1402        dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1403
1404        /* Clear GINTSTS */
1405        dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1406
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);
1410        //}
1411    }
1412
1413    /* Set HCTSIZ */
1414    hctsiz.d32 = 0;
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);
1419
1420    /* Set HCCHAR */
1421    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1422    hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
1423    hcchar.b.epdir = 1;
1424    hcchar.b.epnum = 0;
1425    hcchar.b.mps = 8;
1426    hcchar.b.chen = 1;
1427    dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1428
1429    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1430    //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
1431
1432    /* Wait for receive status queue interrupt */
1433    do {
1434        gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1435    } while (gintsts.b.rxstsqlvl == 0);
1436
1437    //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
1438
1439    /* Read RXSTS */
1440    grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
1441    //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
1442
1443    /* Clear RXSTSQLVL in GINTSTS */
1444    gintsts.d32 = 0;
1445    gintsts.b.rxstsqlvl = 1;
1446    dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1447
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) {
1452            int i;
1453            int word_count = (grxsts.b.bcnt + 3) / 4;
1454
1455            data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
1456
1457            for (i = 0; i < word_count; i++) {
1458                (void)dwc_read_reg32(data_fifo++);
1459            }
1460        }
1461
1462        //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt);
1463    break;
1464
1465    default:
1466        //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
1467    break;
1468    }
1469
1470    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1471    //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
1472
1473    /* Wait for receive status queue interrupt */
1474    do {
1475        gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1476    } while (gintsts.b.rxstsqlvl == 0);
1477
1478    //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
1479
1480    /* Read RXSTS */
1481    grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
1482    //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
1483
1484    /* Clear RXSTSQLVL in GINTSTS */
1485    gintsts.d32 = 0;
1486    gintsts.b.rxstsqlvl = 1;
1487    dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1488
1489    switch (grxsts.b.pktsts) {
1490    case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
1491    break;
1492
1493    default:
1494        //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
1495    break;
1496    }
1497
1498    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1499    //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
1500
1501    /* Wait for host channel interrupt */
1502    do {
1503        gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1504    } while (gintsts.b.hcintr == 0);
1505
1506    //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
1507
1508    /* Read HAINT */
1509    haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1510    //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1511
1512    /* Read HCINT */
1513    hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1514    //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1515
1516    /* Read HCCHAR */
1517    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1518    //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1519
1520    /* Clear HCINT */
1521    dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1522
1523    /* Clear HAINT */
1524    dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1525
1526    /* Clear GINTSTS */
1527    dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1528
1529    /* Read GINTSTS */
1530    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1531    //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1532
1533// usleep(100000);
1534// mdelay(100);
1535    mdelay(1);
1536
1537    /*
1538     * Send handshake packet
1539     */
1540
1541    /* Read HAINT */
1542    haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1543    //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1544
1545    /* Read HCINT */
1546    hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1547    //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1548
1549    /* Read HCCHAR */
1550    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1551    //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1552
1553    /* Clear HCINT */
1554    dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1555
1556    /* Clear HAINT */
1557    dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1558
1559    /* Clear GINTSTS */
1560    dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1561
1562    /* Read GINTSTS */
1563    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1564    //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1565
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);
1570        hcchar.b.chdis = 1;
1571        hcchar.b.chen = 1;
1572        dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1573        //sleep(1);
1574        mdelay(1000);
1575
1576        /* Read GINTSTS */
1577        gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1578        //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1579
1580        /* Read HAINT */
1581        haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1582        //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1583
1584        /* Read HCINT */
1585        hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1586        //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1587
1588        /* Read HCCHAR */
1589        hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1590        //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1591
1592        /* Clear HCINT */
1593        dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1594
1595        /* Clear HAINT */
1596        dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1597
1598        /* Clear GINTSTS */
1599        dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1600
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);
1604        //}
1605    }
1606
1607    /* Set HCTSIZ */
1608    hctsiz.d32 = 0;
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);
1613
1614    /* Set HCCHAR */
1615    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1616    hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
1617    hcchar.b.epdir = 0;
1618    hcchar.b.epnum = 0;
1619    hcchar.b.mps = 8;
1620    hcchar.b.chen = 1;
1621    dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1622
1623    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1624    //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
1625
1626    /* Wait for host channel interrupt */
1627    do {
1628        gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1629    } while (gintsts.b.hcintr == 0);
1630
1631    //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
1632
1633    /* Disable HCINTs */
1634    dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
1635
1636    /* Disable HAINTs */
1637    dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
1638
1639    /* Read HAINT */
1640    haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
1641    //fprintf(stderr, "HAINT: %08x\n", haint.d32);
1642
1643    /* Read HCINT */
1644    hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
1645    //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
1646
1647    /* Read HCCHAR */
1648    hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1649    //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
1650
1651    /* Clear HCINT */
1652    dwc_write_reg32(&hc_regs->hcint, hcint.d32);
1653
1654    /* Clear HAINT */
1655    dwc_write_reg32(&hc_global_regs->haint, haint.d32);
1656
1657    /* Clear GINTSTS */
1658    dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
1659
1660    /* Read GINTSTS */
1661    gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
1662    //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
1663}
1664#endif /* DWC_HS_ELECT_TST */
1665
1666/** Handles hub class-specific requests. */
1667int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
1668                u16 typeReq,
1669                u16 wValue,
1670                u16 wIndex,
1671                char *buf,
1672                u16 wLength)
1673{
1674    int retval = 0;
1675
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};
1680
1681    uint32_t port_status;
1682
1683    switch (typeReq) {
1684    case ClearHubFeature:
1685        DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
1686                "ClearHubFeature 0x%x\n", wValue);
1687        switch (wValue) {
1688        case C_HUB_LOCAL_POWER:
1689        case C_HUB_OVER_CURRENT:
1690            /* Nothing required here */
1691            break;
1692        default:
1693            retval = -EINVAL;
1694            DWC_ERROR("DWC OTG HCD - "
1695                  "ClearHubFeature request %xh unknown\n", wValue);
1696        }
1697        break;
1698    case ClearPortFeature:
1699        if (!wIndex || wIndex > 1)
1700            goto error;
1701
1702        switch (wValue) {
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);
1707            hprt0.b.prtena = 1;
1708            dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1709            break;
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);
1714            hprt0.b.prtres = 1;
1715            dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1716            /* Clear Resume bit */
1717            mdelay(100);
1718            hprt0.b.prtres = 0;
1719            dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1720            break;
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);
1725            hprt0.b.prtpwr = 0;
1726            dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1727            break;
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 */
1732            break;
1733        case USB_PORT_FEAT_C_CONNECTION:
1734            /* Clears drivers internal connect status change
1735             * flag */
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;
1739            break;
1740        case USB_PORT_FEAT_C_RESET:
1741            /* Clears the driver's internal Port Reset Change
1742             * flag */
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;
1746            break;
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;
1753            break;
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;
1761            break;
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;
1766            break;
1767        default:
1768            retval = -EINVAL;
1769            DWC_ERROR("DWC OTG HCD - "
1770                  "ClearPortFeature request %xh "
1771                  "unknown or unsupported\n", wValue);
1772        }
1773        break;
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#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
1785        desc->u.hs.DeviceRemovable[0] = 0;
1786        desc->u.hs.DeviceRemovable[1] = 0xff;
1787#endif
1788        break;
1789    case GetHubStatus:
1790        DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
1791                "GetHubStatus\n");
1792        memset(buf, 0, 4);
1793        break;
1794    case GetPortStatus:
1795        DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
1796                "GetPortStatus\n");
1797
1798        if (!wIndex || wIndex > 1)
1799            goto error;
1800
1801        port_status = 0;
1802
1803        if (dwc_otg_hcd->flags.b.port_connect_status_change)
1804            port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
1805
1806        if (dwc_otg_hcd->flags.b.port_enable_change)
1807            port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
1808
1809        if (dwc_otg_hcd->flags.b.port_suspend_change)
1810            port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
1811
1812        if (dwc_otg_hcd->flags.b.port_reset_change)
1813            port_status |= (1 << USB_PORT_FEAT_C_RESET);
1814
1815        if (dwc_otg_hcd->flags.b.port_over_current_change) {
1816            DWC_ERROR("Device Not Supported\n");
1817            port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
1818        }
1819
1820        if (!dwc_otg_hcd->flags.b.port_connect_status) {
1821            /*
1822             * The port is disconnected, which means the core is
1823             * either in device mode or it soon will be. Just
1824             * return 0's for the remainder of the port status
1825             * since the port register can't be read if the core
1826             * is in device mode.
1827             */
1828            *((__le32 *) buf) = cpu_to_le32(port_status);
1829            break;
1830        }
1831
1832        hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
1833        DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
1834
1835        if (hprt0.b.prtconnsts)
1836            port_status |= (1 << USB_PORT_FEAT_CONNECTION);
1837
1838        if (hprt0.b.prtena)
1839            port_status |= (1 << USB_PORT_FEAT_ENABLE);
1840
1841        if (hprt0.b.prtsusp)
1842            port_status |= (1 << USB_PORT_FEAT_SUSPEND);
1843
1844        if (hprt0.b.prtovrcurract)
1845            port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
1846
1847        if (hprt0.b.prtrst)
1848            port_status |= (1 << USB_PORT_FEAT_RESET);
1849
1850        if (hprt0.b.prtpwr)
1851            port_status |= (1 << USB_PORT_FEAT_POWER);
1852
1853        if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
1854            port_status |= USB_PORT_STAT_HIGH_SPEED;
1855        else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
1856            port_status |= USB_PORT_STAT_LOW_SPEED;
1857
1858        if (hprt0.b.prttstctl)
1859            port_status |= (1 << USB_PORT_FEAT_TEST);
1860
1861        /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
1862
1863        *((__le32 *) buf) = cpu_to_le32(port_status);
1864
1865        break;
1866    case SetHubFeature:
1867        DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
1868                "SetHubFeature\n");
1869        /* No HUB features supported */
1870        break;
1871    case SetPortFeature:
1872        if (wValue != USB_PORT_FEAT_TEST && (!wIndex || wIndex > 1))
1873            goto error;
1874
1875        if (!dwc_otg_hcd->flags.b.port_connect_status) {
1876            /*
1877             * The port is disconnected, which means the core is
1878             * either in device mode or it soon will be. Just
1879             * return without doing anything since the port
1880             * register can't be written if the core is in device
1881             * mode.
1882             */
1883            break;
1884        }
1885
1886        switch (wValue) {
1887        case USB_PORT_FEAT_SUSPEND:
1888            DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
1889                    "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
1890            if (hcd->self.otg_port == wIndex &&
1891                hcd->self.b_hnp_enable) {
1892                gotgctl_data_t gotgctl = {.d32=0};
1893                gotgctl.b.hstsethnpen = 1;
1894                dwc_modify_reg32(&core_if->core_global_regs->gotgctl,
1895                          0, gotgctl.d32);
1896                core_if->op_state = A_SUSPEND;
1897            }
1898            hprt0.d32 = dwc_otg_read_hprt0(core_if);
1899            hprt0.b.prtsusp = 1;
1900            dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1901            //DWC_PRINT("SUSPEND: HPRT0=%0x\n", hprt0.d32);
1902            /* Suspend the Phy Clock */
1903            {
1904                pcgcctl_data_t pcgcctl = {.d32=0};
1905                pcgcctl.b.stoppclk = 1;
1906                dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
1907            }
1908
1909            /* For HNP the bus must be suspended for at least 200ms. */
1910            if (hcd->self.b_hnp_enable) {
1911                mdelay(200);
1912                //DWC_PRINT("SUSPEND: wait complete! (%d)\n", _hcd->state);
1913            }
1914            break;
1915        case USB_PORT_FEAT_POWER:
1916            DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
1917                    "SetPortFeature - USB_PORT_FEAT_POWER\n");
1918            hprt0.d32 = dwc_otg_read_hprt0(core_if);
1919            hprt0.b.prtpwr = 1;
1920            dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1921            break;
1922        case USB_PORT_FEAT_RESET:
1923            DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
1924                    "SetPortFeature - USB_PORT_FEAT_RESET\n");
1925            hprt0.d32 = dwc_otg_read_hprt0(core_if);
1926            /* When B-Host the Port reset bit is set in
1927             * the Start HCD Callback function, so that
1928             * the reset is started within 1ms of the HNP
1929             * success interrupt. */
1930            if (!hcd->self.is_b_host) {
1931                hprt0.b.prtrst = 1;
1932                dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1933            }
1934            /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
1935            MDELAY(60);
1936            hprt0.b.prtrst = 0;
1937            dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1938            break;
1939
1940#ifdef DWC_HS_ELECT_TST
1941        case USB_PORT_FEAT_TEST:
1942        {
1943            uint32_t t;
1944            gintmsk_data_t gintmsk;
1945
1946            t = (wIndex >> 8); /* MSB wIndex USB */
1947            DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
1948                    "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
1949            warn("USB_PORT_FEAT_TEST %d\n", t);
1950            if (t < 6) {
1951                hprt0.d32 = dwc_otg_read_hprt0(core_if);
1952                hprt0.b.prttstctl = t;
1953                dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1954            } else {
1955                /* Setup global vars with reg addresses (quick and
1956                 * dirty hack, should be cleaned up)
1957                 */
1958                global_regs = core_if->core_global_regs;
1959                hc_global_regs = core_if->host_if->host_global_regs;
1960                hc_regs = (dwc_otg_hc_regs_t *)((char *)global_regs + 0x500);
1961                data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
1962
1963                if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
1964                    /* Save current interrupt mask */
1965                    gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
1966
1967                    /* Disable all interrupts while we muck with
1968                     * the hardware directly
1969                     */
1970                    dwc_write_reg32(&global_regs->gintmsk, 0);
1971
1972                    /* 15 second delay per the test spec */
1973                    mdelay(15000);
1974
1975                    /* Drive suspend on the root port */
1976                    hprt0.d32 = dwc_otg_read_hprt0(core_if);
1977                    hprt0.b.prtsusp = 1;
1978                    hprt0.b.prtres = 0;
1979                    dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1980
1981                    /* 15 second delay per the test spec */
1982                    mdelay(15000);
1983
1984                    /* Drive resume on the root port */
1985                    hprt0.d32 = dwc_otg_read_hprt0(core_if);
1986                    hprt0.b.prtsusp = 0;
1987                    hprt0.b.prtres = 1;
1988                    dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1989                    mdelay(100);
1990
1991                    /* Clear the resume bit */
1992                    hprt0.b.prtres = 0;
1993                    dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
1994
1995                    /* Restore interrupts */
1996                    dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
1997                } else if (t == 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
1998                    /* Save current interrupt mask */
1999                    gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
2000
2001                    /* Disable all interrupts while we muck with
2002                     * the hardware directly
2003                     */
2004                    dwc_write_reg32(&global_regs->gintmsk, 0);
2005
2006                    /* 15 second delay per the test spec */
2007                    mdelay(15000);
2008
2009                    /* Send the Setup packet */
2010                    do_setup();
2011
2012                    /* 15 second delay so nothing else happens for awhile */
2013                    mdelay(15000);
2014
2015                    /* Restore interrupts */
2016                    dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
2017                } else if (t == 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
2018                    /* Save current interrupt mask */
2019                    gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
2020
2021                    /* Disable all interrupts while we muck with
2022                     * the hardware directly
2023                     */
2024                    dwc_write_reg32(&global_regs->gintmsk, 0);
2025
2026                    /* Send the Setup packet */
2027                    do_setup();
2028
2029                    /* 15 second delay so nothing else happens for awhile */
2030                    mdelay(15000);
2031
2032                    /* Send the In and Ack packets */
2033                    do_in_ack();
2034
2035                    /* 15 second delay so nothing else happens for awhile */
2036                    mdelay(15000);
2037
2038                    /* Restore interrupts */
2039                    dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
2040                }
2041            }
2042            break;
2043        }
2044#endif /* DWC_HS_ELECT_TST */
2045
2046        case USB_PORT_FEAT_INDICATOR:
2047            DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2048                    "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
2049            /* Not supported */
2050            break;
2051        default:
2052            retval = -EINVAL;
2053            DWC_ERROR("DWC OTG HCD - "
2054                  "SetPortFeature request %xh "
2055                  "unknown or unsupported\n", wValue);
2056            break;
2057        }
2058        break;
2059    default:
2060    error:
2061        retval = -EINVAL;
2062        DWC_WARN("DWC OTG HCD - "
2063             "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
2064             typeReq, wIndex, wValue);
2065        break;
2066    }
2067
2068    return retval;
2069}
2070
2071/**
2072 * Assigns transactions from a QTD to a free host channel and initializes the
2073 * host channel to perform the transactions. The host channel is removed from
2074 * the free list.
2075 *
2076 * @param hcd The HCD state structure.
2077 * @param qh Transactions from the first QTD for this QH are selected and
2078 * assigned to a free host channel.
2079 */
2080static void assign_and_init_hc(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
2081{
2082    dwc_hc_t *hc;
2083    dwc_otg_qtd_t *qtd;
2084    struct urb *urb;
2085
2086    DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, qh);
2087
2088    hc = list_entry(hcd->free_hc_list.next, dwc_hc_t, hc_list_entry);
2089
2090    /* Remove the host channel from the free list. */
2091    list_del_init(&hc->hc_list_entry);
2092
2093    qtd = list_entry(qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
2094    urb = qtd->urb;
2095    qh->channel = hc;
2096    qh->qtd_in_process = qtd;
2097
2098    /*
2099     * Use usb_pipedevice to determine device address. This address is
2100     * 0 before the SET_ADDRESS command and the correct address afterward.
2101     */
2102    hc->dev_addr = usb_pipedevice(urb->pipe);
2103    hc->ep_num = usb_pipeendpoint(urb->pipe);
2104
2105    if (urb->dev->speed == USB_SPEED_LOW) {
2106        hc->speed = DWC_OTG_EP_SPEED_LOW;
2107    } else if (urb->dev->speed == USB_SPEED_FULL) {
2108        hc->speed = DWC_OTG_EP_SPEED_FULL;
2109    } else {
2110        hc->speed = DWC_OTG_EP_SPEED_HIGH;
2111    }
2112
2113    hc->max_packet = dwc_max_packet(qh->maxp);
2114
2115    hc->xfer_started = 0;
2116    hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
2117    hc->error_state = (qtd->error_count > 0);
2118    hc->halt_on_queue = 0;
2119    hc->halt_pending = 0;
2120    hc->requests = 0;
2121
2122    /*
2123     * The following values may be modified in the transfer type section
2124     * below. The xfer_len value may be reduced when the transfer is
2125     * started to accommodate the max widths of the XferSize and PktCnt
2126     * fields in the HCTSIZn register.
2127     */
2128    hc->do_ping = qh->ping_state;
2129    hc->ep_is_in = (usb_pipein(urb->pipe) != 0);
2130    hc->data_pid_start = qh->data_toggle;
2131    hc->multi_count = 1;
2132
2133    if (hcd->core_if->dma_enable) {
2134        hc->xfer_buff = (uint8_t *)urb->transfer_dma + urb->actual_length;
2135    } else {
2136        hc->xfer_buff = (uint8_t *)urb->transfer_buffer + urb->actual_length;
2137    }
2138    hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
2139    hc->xfer_count = 0;
2140
2141    /*
2142     * Set the split attributes
2143     */
2144    hc->do_split = 0;
2145    if (qh->do_split) {
2146        hc->do_split = 1;
2147        hc->xact_pos = qtd->isoc_split_pos;
2148        hc->complete_split = qtd->complete_split;
2149        hc->hub_addr = urb->dev->tt->hub->devnum;
2150        hc->port_addr = urb->dev->ttport;
2151    }
2152
2153    switch (usb_pipetype(urb->pipe)) {
2154    case PIPE_CONTROL:
2155        hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
2156        switch (qtd->control_phase) {
2157        case DWC_OTG_CONTROL_SETUP:
2158            DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
2159            hc->do_ping = 0;
2160            hc->ep_is_in = 0;
2161            hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
2162            if (hcd->core_if->dma_enable) {
2163                hc->xfer_buff = (uint8_t *)urb->setup_dma;
2164            } else {
2165                hc->xfer_buff = (uint8_t *)urb->setup_packet;
2166            }
2167            hc->xfer_len = 8;
2168            break;
2169        case DWC_OTG_CONTROL_DATA:
2170            DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
2171            hc->data_pid_start = qtd->data_toggle;
2172            break;
2173        case DWC_OTG_CONTROL_STATUS:
2174            /*
2175             * Direction is opposite of data direction or IN if no
2176             * data.
2177             */
2178            DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
2179            if (urb->transfer_buffer_length == 0) {
2180                hc->ep_is_in = 1;
2181            } else {
2182                hc->ep_is_in = (usb_pipein(urb->pipe) != USB_DIR_IN);
2183            }
2184            if (hc->ep_is_in) {
2185                hc->do_ping = 0;
2186            }
2187            hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
2188            hc->xfer_len = 0;
2189            if (hcd->core_if->dma_enable) {
2190                hc->xfer_buff = (uint8_t *)hcd->status_buf_dma;
2191            } else {
2192                hc->xfer_buff = (uint8_t *)hcd->status_buf;
2193            }
2194            break;
2195        }
2196        break;
2197    case PIPE_BULK:
2198        hc->ep_type = DWC_OTG_EP_TYPE_BULK;
2199        break;
2200    case PIPE_INTERRUPT:
2201        hc->ep_type = DWC_OTG_EP_TYPE_INTR;
2202        break;
2203    case PIPE_ISOCHRONOUS:
2204        {
2205            struct usb_iso_packet_descriptor *frame_desc;
2206            frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
2207            hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
2208            if (hcd->core_if->dma_enable) {
2209                hc->xfer_buff = (uint8_t *)urb->transfer_dma;
2210            } else {
2211                hc->xfer_buff = (uint8_t *)urb->transfer_buffer;
2212            }
2213            hc->xfer_buff += frame_desc->offset + qtd->isoc_split_offset;
2214            hc->xfer_len = frame_desc->length - qtd->isoc_split_offset;
2215
2216            if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
2217                if (hc->xfer_len <= 188) {
2218                    hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
2219                }
2220                else {
2221                    hc->xact_pos = DWC_HCSPLIT_XACTPOS_BEGIN;
2222                }
2223            }
2224        }
2225        break;
2226    }
2227
2228    if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2229        hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2230        /*
2231         * This value may be modified when the transfer is started to
2232         * reflect the actual transfer length.
2233         */
2234        hc->multi_count = dwc_hb_mult(qh->maxp);
2235    }
2236
2237    dwc_otg_hc_init(hcd->core_if, hc);
2238    hc->qh = qh;
2239}
2240
2241/**
2242 * This function selects transactions from the HCD transfer schedule and
2243 * assigns them to available host channels. It is called from HCD interrupt
2244 * handler functions.
2245 *
2246 * @param hcd The HCD state structure.
2247 *
2248 * @return The types of new transactions that were assigned to host channels.
2249 */
2250dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *hcd)
2251{
2252    struct list_head *qh_ptr;
2253    dwc_otg_qh_t *qh;
2254    int num_channels;
2255    dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
2256
2257#ifdef DEBUG_SOF
2258    DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
2259#endif
2260
2261    /* Process entries in the periodic ready list. */
2262    qh_ptr = hcd->periodic_sched_ready.next;
2263    while (qh_ptr != &hcd->periodic_sched_ready &&
2264           !list_empty(&hcd->free_hc_list)) {
2265
2266        qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
2267        assign_and_init_hc(hcd, qh);
2268
2269        /*
2270         * Move the QH from the periodic ready schedule to the
2271         * periodic assigned schedule.
2272         */
2273        qh_ptr = qh_ptr->next;
2274        list_move(&qh->qh_list_entry, &hcd->periodic_sched_assigned);
2275
2276        ret_val = DWC_OTG_TRANSACTION_PERIODIC;
2277    }
2278
2279    /*
2280     * Process entries in the inactive portion of the non-periodic
2281     * schedule. Some free host channels may not be used if they are
2282     * reserved for periodic transfers.
2283     */
2284    qh_ptr = hcd->non_periodic_sched_inactive.next;
2285    num_channels = hcd->core_if->core_params->host_channels;
2286    while (qh_ptr != &hcd->non_periodic_sched_inactive &&
2287           (hcd->non_periodic_channels <
2288        num_channels - hcd->periodic_channels) &&
2289           !list_empty(&hcd->free_hc_list)) {
2290
2291        qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
2292        assign_and_init_hc(hcd, qh);
2293
2294        /*
2295         * Move the QH from the non-periodic inactive schedule to the
2296         * non-periodic active schedule.
2297         */
2298        qh_ptr = qh_ptr->next;
2299        list_move(&qh->qh_list_entry, &hcd->non_periodic_sched_active);
2300
2301        if (ret_val == DWC_OTG_TRANSACTION_NONE) {
2302            ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
2303        } else {
2304            ret_val = DWC_OTG_TRANSACTION_ALL;
2305        }
2306
2307        hcd->non_periodic_channels++;
2308    }
2309
2310    return ret_val;
2311}
2312
2313/**
2314 * Attempts to queue a single transaction request for a host channel
2315 * associated with either a periodic or non-periodic transfer. This function
2316 * assumes that there is space available in the appropriate request queue. For
2317 * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
2318 * is available in the appropriate Tx FIFO.
2319 *
2320 * @param hcd The HCD state structure.
2321 * @param hc Host channel descriptor associated with either a periodic or
2322 * non-periodic transfer.
2323 * @param fifo_dwords_avail Number of DWORDs available in the periodic Tx
2324 * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
2325 * transfers.
2326 *
2327 * @return 1 if a request is queued and more requests may be needed to
2328 * complete the transfer, 0 if no more requests are required for this
2329 * transfer, -1 if there is insufficient space in the Tx FIFO.
2330 */
2331static int queue_transaction(dwc_otg_hcd_t *hcd,
2332                 dwc_hc_t *hc,
2333                 uint16_t fifo_dwords_avail)
2334{
2335    int retval;
2336
2337    if (hcd->core_if->dma_enable) {
2338        if (!hc->xfer_started) {
2339            dwc_otg_hc_start_transfer(hcd->core_if, hc);
2340            hc->qh->ping_state = 0;
2341        }
2342        retval = 0;
2343    } else if (hc->halt_pending) {
2344        /* Don't queue a request if the channel has been halted. */
2345        retval = 0;
2346    } else if (hc->halt_on_queue) {
2347        dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status);
2348        retval = 0;
2349    } else if (hc->do_ping) {
2350        if (!hc->xfer_started) {
2351            dwc_otg_hc_start_transfer(hcd->core_if, hc);
2352        }
2353        retval = 0;
2354    } else if (!hc->ep_is_in ||
2355           hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
2356        if ((fifo_dwords_avail * 4) >= hc->max_packet) {
2357            if (!hc->xfer_started) {
2358                dwc_otg_hc_start_transfer(hcd->core_if, hc);
2359                retval = 1;
2360            } else {
2361                retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
2362            }
2363        } else {
2364            retval = -1;
2365        }
2366    } else {
2367        if (!hc->xfer_started) {
2368            dwc_otg_hc_start_transfer(hcd->core_if, hc);
2369            retval = 1;
2370        } else {
2371            retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
2372        }
2373    }
2374
2375    return retval;
2376}
2377
2378/**
2379 * Processes active non-periodic channels and queues transactions for these
2380 * channels to the DWC_otg controller. After queueing transactions, the NP Tx
2381 * FIFO Empty interrupt is enabled if there are more transactions to queue as
2382 * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
2383 * FIFO Empty interrupt is disabled.
2384 */
2385static void process_non_periodic_channels(dwc_otg_hcd_t *hcd)
2386{
2387    gnptxsts_data_t tx_status;
2388    struct list_head *orig_qh_ptr;
2389    dwc_otg_qh_t *qh;
2390    int status;
2391    int no_queue_space = 0;
2392    int no_fifo_space = 0;
2393    int more_to_do = 0;
2394
2395    dwc_otg_core_global_regs_t *global_regs = hcd->core_if->core_global_regs;
2396
2397    DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
2398#ifdef DEBUG
2399    tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
2400    DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (before queue): %d\n",
2401            tx_status.b.nptxqspcavail);
2402    DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
2403            tx_status.b.nptxfspcavail);
2404#endif
2405    /*
2406     * Keep track of the starting point. Skip over the start-of-list
2407     * entry.
2408     */
2409    if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
2410        hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
2411    }
2412    orig_qh_ptr = hcd->non_periodic_qh_ptr;
2413
2414    /*
2415     * Process once through the active list or until no more space is
2416     * available in the request queue or the Tx FIFO.
2417     */
2418    do {
2419        tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
2420        if (!hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
2421            no_queue_space = 1;
2422            break;
2423        }
2424
2425        qh = list_entry(hcd->non_periodic_qh_ptr, dwc_otg_qh_t, qh_list_entry);
2426        status = queue_transaction(hcd, qh->channel, tx_status.b.nptxfspcavail);
2427
2428        if (status > 0) {
2429            more_to_do = 1;
2430        } else if (status < 0) {
2431            no_fifo_space = 1;
2432            break;
2433        }
2434
2435        /* Advance to next QH, skipping start-of-list entry. */
2436        hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
2437        if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
2438            hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
2439        }
2440
2441    } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
2442
2443    if (!hcd->core_if->dma_enable) {
2444        gintmsk_data_t intr_mask = {.d32 = 0};
2445        intr_mask.b.nptxfempty = 1;
2446
2447#ifdef DEBUG
2448        tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
2449        DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (after queue): %d\n",
2450                tx_status.b.nptxqspcavail);
2451        DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (after queue): %d\n",
2452                tx_status.b.nptxfspcavail);
2453#endif
2454        if (more_to_do || no_queue_space || no_fifo_space) {
2455            /*
2456             * May need to queue more transactions as the request
2457             * queue or Tx FIFO empties. Enable the non-periodic
2458             * Tx FIFO empty interrupt. (Always use the half-empty
2459             * level to ensure that new requests are loaded as
2460             * soon as possible.)
2461             */
2462            dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
2463        } else {
2464            /*
2465             * Disable the Tx FIFO empty interrupt since there are
2466             * no more transactions that need to be queued right
2467             * now. This function is called from interrupt
2468             * handlers to queue more transactions as transfer
2469             * states change.
2470             */
2471            dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
2472        }
2473    }
2474}
2475
2476/**
2477 * Processes periodic channels for the next frame and queues transactions for
2478 * these channels to the DWC_otg controller. After queueing transactions, the
2479 * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
2480 * to queue as Periodic Tx FIFO or request queue space becomes available.
2481 * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
2482 */
2483static void process_periodic_channels(dwc_otg_hcd_t *hcd)
2484{
2485    hptxsts_data_t tx_status;
2486    struct list_head *qh_ptr;
2487    dwc_otg_qh_t *qh;
2488    int status;
2489    int no_queue_space = 0;
2490    int no_fifo_space = 0;
2491
2492    dwc_otg_host_global_regs_t *host_regs;
2493    host_regs = hcd->core_if->host_if->host_global_regs;
2494
2495    DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
2496#ifdef DEBUG
2497    tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
2498    DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (before queue): %d\n",
2499            tx_status.b.ptxqspcavail);
2500    DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
2501            tx_status.b.ptxfspcavail);
2502#endif
2503
2504    qh_ptr = hcd->periodic_sched_assigned.next;
2505    while (qh_ptr != &hcd->periodic_sched_assigned) {
2506        tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
2507        if (tx_status.b.ptxqspcavail == 0) {
2508            no_queue_space = 1;
2509            break;
2510        }
2511
2512        qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
2513
2514        /*
2515         * Set a flag if we're queuing high-bandwidth in slave mode.
2516         * The flag prevents any halts to get into the request queue in
2517         * the middle of multiple high-bandwidth packets getting queued.
2518         */
2519        if (!hcd->core_if->dma_enable &&
2520            qh->channel->multi_count > 1)
2521        {
2522            hcd->core_if->queuing_high_bandwidth = 1;
2523        }
2524
2525        status = queue_transaction(hcd, qh->channel, tx_status.b.ptxfspcavail);
2526        if (status < 0) {
2527            no_fifo_space = 1;
2528            break;
2529        }
2530
2531        /*
2532         * In Slave mode, stay on the current transfer until there is
2533         * nothing more to do or the high-bandwidth request count is
2534         * reached. In DMA mode, only need to queue one request. The
2535         * controller automatically handles multiple packets for
2536         * high-bandwidth transfers.
2537         */
2538        if (hcd->core_if->dma_enable || status == 0 ||
2539            qh->channel->requests == qh->channel->multi_count) {
2540            qh_ptr = qh_ptr->next;
2541            /*
2542             * Move the QH from the periodic assigned schedule to
2543             * the periodic queued schedule.
2544             */
2545            list_move(&qh->qh_list_entry, &hcd->periodic_sched_queued);
2546
2547            /* done queuing high bandwidth */
2548            hcd->core_if->queuing_high_bandwidth = 0;
2549        }
2550    }
2551
2552    if (!hcd->core_if->dma_enable) {
2553        dwc_otg_core_global_regs_t *global_regs;
2554        gintmsk_data_t intr_mask = {.d32 = 0};
2555
2556        global_regs = hcd->core_if->core_global_regs;
2557        intr_mask.b.ptxfempty = 1;
2558#ifdef DEBUG
2559        tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
2560        DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (after queue): %d\n",
2561                tx_status.b.ptxqspcavail);
2562        DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (after queue): %d\n",
2563                tx_status.b.ptxfspcavail);
2564#endif
2565        if (!list_empty(&hcd->periodic_sched_assigned) ||
2566            no_queue_space || no_fifo_space) {
2567            /*
2568             * May need to queue more transactions as the request
2569             * queue or Tx FIFO empties. Enable the periodic Tx
2570             * FIFO empty interrupt. (Always use the half-empty
2571             * level to ensure that new requests are loaded as
2572             * soon as possible.)
2573             */
2574            dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
2575        } else {
2576            /*
2577             * Disable the Tx FIFO empty interrupt since there are
2578             * no more transactions that need to be queued right
2579             * now. This function is called from interrupt
2580             * handlers to queue more transactions as transfer
2581             * states change.
2582             */
2583            dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
2584        }
2585    }
2586}
2587
2588/**
2589 * This function processes the currently active host channels and queues
2590 * transactions for these channels to the DWC_otg controller. It is called
2591 * from HCD interrupt handler functions.
2592 *
2593 * @param hcd The HCD state structure.
2594 * @param tr_type The type(s) of transactions to queue (non-periodic,
2595 * periodic, or both).
2596 */
2597void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *hcd,
2598                    dwc_otg_transaction_type_e tr_type)
2599{
2600#ifdef DEBUG_SOF
2601    DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
2602#endif
2603    /* Process host channels associated with periodic transfers. */
2604    if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
2605         tr_type == DWC_OTG_TRANSACTION_ALL) &&
2606        !list_empty(&hcd->periodic_sched_assigned)) {
2607
2608        process_periodic_channels(hcd);
2609    }
2610
2611    /* Process host channels associated with non-periodic transfers. */
2612    if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
2613        tr_type == DWC_OTG_TRANSACTION_ALL) {
2614        if (!list_empty(&hcd->non_periodic_sched_active)) {
2615            process_non_periodic_channels(hcd);
2616        } else {
2617            /*
2618             * Ensure NP Tx FIFO empty interrupt is disabled when
2619             * there are no non-periodic transfers to process.
2620             */
2621            gintmsk_data_t gintmsk = {.d32 = 0};
2622            gintmsk.b.nptxfempty = 1;
2623            dwc_modify_reg32(&hcd->core_if->core_global_regs->gintmsk,
2624                     gintmsk.d32, 0);
2625        }
2626    }
2627}
2628
2629/**
2630 * Sets the final status of an URB and returns it to the device driver. Any
2631 * required cleanup of the URB is performed.
2632 */
2633void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *hcd, struct urb *urb, int status)
2634{
2635#ifdef DEBUG
2636    if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
2637        DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
2638              __func__, urb, usb_pipedevice(urb->pipe),
2639              usb_pipeendpoint(urb->pipe),
2640              usb_pipein(urb->pipe) ? "IN" : "OUT", status);
2641        if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
2642            int i;
2643            for (i = 0; i < urb->number_of_packets; i++) {
2644                DWC_PRINT(" ISO Desc %d status: %d\n",
2645                      i, urb->iso_frame_desc[i].status);
2646            }
2647        }
2648    }
2649#endif
2650
2651    urb->status = status;
2652    urb->hcpriv = NULL;
2653#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2654    usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
2655#else
2656    usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, NULL);
2657#endif
2658}
2659
2660/*
2661 * Returns the Queue Head for an URB.
2662 */
2663dwc_otg_qh_t *dwc_urb_to_qh(struct urb *urb)
2664{
2665    struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
2666    return (dwc_otg_qh_t *)ep->hcpriv;
2667}
2668
2669#ifdef DEBUG
2670void dwc_print_setup_data(uint8_t *setup)
2671{
2672    int i;
2673    if (CHK_DEBUG_LEVEL(DBG_HCD)){
2674        DWC_PRINT("Setup Data = MSB ");
2675        for (i = 7; i >= 0; i--) DWC_PRINT("%02x ", setup[i]);
2676        DWC_PRINT("\n");
2677        DWC_PRINT(" bmRequestType Tranfer = %s\n", (setup[0] & 0x80) ? "Device-to-Host" : "Host-to-Device");
2678        DWC_PRINT(" bmRequestType Type = ");
2679        switch ((setup[0] & 0x60) >> 5) {
2680        case 0: DWC_PRINT("Standard\n"); break;
2681        case 1: DWC_PRINT("Class\n"); break;
2682        case 2: DWC_PRINT("Vendor\n"); break;
2683        case 3: DWC_PRINT("Reserved\n"); break;
2684        }
2685        DWC_PRINT(" bmRequestType Recipient = ");
2686        switch (setup[0] & 0x1f) {
2687        case 0: DWC_PRINT("Device\n"); break;
2688        case 1: DWC_PRINT("Interface\n"); break;
2689        case 2: DWC_PRINT("Endpoint\n"); break;
2690        case 3: DWC_PRINT("Other\n"); break;
2691        default: DWC_PRINT("Reserved\n"); break;
2692        }
2693        DWC_PRINT(" bRequest = 0x%0x\n", setup[1]);
2694        DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *)&setup[2]));
2695        DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *)&setup[4]));
2696        DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *)&setup[6]));
2697    }
2698}
2699#endif
2700
2701void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *hcd) {
2702#if defined(DEBUG) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2703    DWC_PRINT("Frame remaining at SOF:\n");
2704    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2705          hcd->frrem_samples, hcd->frrem_accum,
2706          (hcd->frrem_samples > 0) ?
2707          hcd->frrem_accum/hcd->frrem_samples : 0);
2708
2709    DWC_PRINT("\n");
2710    DWC_PRINT("Frame remaining at start_transfer (uframe 7):\n");
2711    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2712          hcd->core_if->hfnum_7_samples, hcd->core_if->hfnum_7_frrem_accum,
2713          (hcd->core_if->hfnum_7_samples > 0) ?
2714          hcd->core_if->hfnum_7_frrem_accum/hcd->core_if->hfnum_7_samples : 0);
2715    DWC_PRINT("Frame remaining at start_transfer (uframe 0):\n");
2716    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2717          hcd->core_if->hfnum_0_samples, hcd->core_if->hfnum_0_frrem_accum,
2718          (hcd->core_if->hfnum_0_samples > 0) ?
2719          hcd->core_if->hfnum_0_frrem_accum/hcd->core_if->hfnum_0_samples : 0);
2720    DWC_PRINT("Frame remaining at start_transfer (uframe 1-6):\n");
2721    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2722          hcd->core_if->hfnum_other_samples, hcd->core_if->hfnum_other_frrem_accum,
2723          (hcd->core_if->hfnum_other_samples > 0) ?
2724          hcd->core_if->hfnum_other_frrem_accum/hcd->core_if->hfnum_other_samples : 0);
2725
2726    DWC_PRINT("\n");
2727    DWC_PRINT("Frame remaining at sample point A (uframe 7):\n");
2728    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2729          hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a,
2730          (hcd->hfnum_7_samples_a > 0) ?
2731          hcd->hfnum_7_frrem_accum_a/hcd->hfnum_7_samples_a : 0);
2732    DWC_PRINT("Frame remaining at sample point A (uframe 0):\n");
2733    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2734          hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a,
2735          (hcd->hfnum_0_samples_a > 0) ?
2736          hcd->hfnum_0_frrem_accum_a/hcd->hfnum_0_samples_a : 0);
2737    DWC_PRINT("Frame remaining at sample point A (uframe 1-6):\n");
2738    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2739          hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a,
2740          (hcd->hfnum_other_samples_a > 0) ?
2741          hcd->hfnum_other_frrem_accum_a/hcd->hfnum_other_samples_a : 0);
2742
2743    DWC_PRINT("\n");
2744    DWC_PRINT("Frame remaining at sample point B (uframe 7):\n");
2745    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2746          hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b,
2747          (hcd->hfnum_7_samples_b > 0) ?
2748          hcd->hfnum_7_frrem_accum_b/hcd->hfnum_7_samples_b : 0);
2749    DWC_PRINT("Frame remaining at sample point B (uframe 0):\n");
2750    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2751          hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b,
2752          (hcd->hfnum_0_samples_b > 0) ?
2753          hcd->hfnum_0_frrem_accum_b/hcd->hfnum_0_samples_b : 0);
2754    DWC_PRINT("Frame remaining at sample point B (uframe 1-6):\n");
2755    DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
2756          hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b,
2757          (hcd->hfnum_other_samples_b > 0) ?
2758          hcd->hfnum_other_frrem_accum_b/hcd->hfnum_other_samples_b : 0);
2759#endif
2760}
2761
2762void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *hcd)
2763{
2764#ifdef DEBUG
2765    int num_channels;
2766    int i;
2767    gnptxsts_data_t np_tx_status;
2768    hptxsts_data_t p_tx_status;
2769
2770    num_channels = hcd->core_if->core_params->host_channels;
2771    DWC_PRINT("\n");
2772    DWC_PRINT("************************************************************\n");
2773    DWC_PRINT("HCD State:\n");
2774    DWC_PRINT(" Num channels: %d\n", num_channels);
2775    for (i = 0; i < num_channels; i++) {
2776        dwc_hc_t *hc = hcd->hc_ptr_array[i];
2777        DWC_PRINT(" Channel %d:\n", i);
2778        DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
2779              hc->dev_addr, hc->ep_num, hc->ep_is_in);
2780        DWC_PRINT(" speed: %d\n", hc->speed);
2781        DWC_PRINT(" ep_type: %d\n", hc->ep_type);
2782        DWC_PRINT(" max_packet: %d\n", hc->max_packet);
2783        DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
2784        DWC_PRINT(" multi_count: %d\n", hc->multi_count);
2785        DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
2786        DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
2787        DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
2788        DWC_PRINT(" xfer_count: %d\n", hc->xfer_count);
2789        DWC_PRINT(" halt_on_queue: %d\n", hc->halt_on_queue);
2790        DWC_PRINT(" halt_pending: %d\n", hc->halt_pending);
2791        DWC_PRINT(" halt_status: %d\n", hc->halt_status);
2792        DWC_PRINT(" do_split: %d\n", hc->do_split);
2793        DWC_PRINT(" complete_split: %d\n", hc->complete_split);
2794        DWC_PRINT(" hub_addr: %d\n", hc->hub_addr);
2795        DWC_PRINT(" port_addr: %d\n", hc->port_addr);
2796        DWC_PRINT(" xact_pos: %d\n", hc->xact_pos);
2797        DWC_PRINT(" requests: %d\n", hc->requests);
2798        DWC_PRINT(" qh: %p\n", hc->qh);
2799        if (hc->xfer_started) {
2800            hfnum_data_t hfnum;
2801            hcchar_data_t hcchar;
2802            hctsiz_data_t hctsiz;
2803            hcint_data_t hcint;
2804            hcintmsk_data_t hcintmsk;
2805            hfnum.d32 = dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hfnum);
2806            hcchar.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcchar);
2807            hctsiz.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hctsiz);
2808            hcint.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcint);
2809            hcintmsk.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcintmsk);
2810            DWC_PRINT(" hfnum: 0x%08x\n", hfnum.d32);
2811            DWC_PRINT(" hcchar: 0x%08x\n", hcchar.d32);
2812            DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz.d32);
2813            DWC_PRINT(" hcint: 0x%08x\n", hcint.d32);
2814            DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk.d32);
2815        }
2816        if (hc->xfer_started && hc->qh && hc->qh->qtd_in_process) {
2817            dwc_otg_qtd_t *qtd;
2818            struct urb *urb;
2819            qtd = hc->qh->qtd_in_process;
2820            urb = qtd->urb;
2821            DWC_PRINT(" URB Info:\n");
2822            DWC_PRINT(" qtd: %p, urb: %p\n", qtd, urb);
2823            if (urb) {
2824                DWC_PRINT(" Dev: %d, EP: %d %s\n",
2825                      usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe),
2826                      usb_pipein(urb->pipe) ? "IN" : "OUT");
2827                DWC_PRINT(" Max packet size: %d\n",
2828                      usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
2829                DWC_PRINT(" transfer_buffer: %p\n", urb->transfer_buffer);
2830                DWC_PRINT(" transfer_dma: %p\n", (void *)urb->transfer_dma);
2831                DWC_PRINT(" transfer_buffer_length: %d\n", urb->transfer_buffer_length);
2832                DWC_PRINT(" actual_length: %d\n", urb->actual_length);
2833            }
2834        }
2835    }
2836    DWC_PRINT(" non_periodic_channels: %d\n", hcd->non_periodic_channels);
2837    DWC_PRINT(" periodic_channels: %d\n", hcd->periodic_channels);
2838    DWC_PRINT(" periodic_usecs: %d\n", hcd->periodic_usecs);
2839    np_tx_status.d32 = dwc_read_reg32(&hcd->core_if->core_global_regs->gnptxsts);
2840    DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n", np_tx_status.b.nptxqspcavail);
2841    DWC_PRINT(" NP Tx FIFO Space Avail: %d\n", np_tx_status.b.nptxfspcavail);
2842    p_tx_status.d32 = dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hptxsts);
2843    DWC_PRINT(" P Tx Req Queue Space Avail: %d\n", p_tx_status.b.ptxqspcavail);
2844    DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
2845    dwc_otg_hcd_dump_frrem(hcd);
2846    dwc_otg_dump_global_registers(hcd->core_if);
2847    dwc_otg_dump_host_registers(hcd->core_if);
2848    DWC_PRINT("************************************************************\n");
2849    DWC_PRINT("\n");
2850#endif
2851}
2852#endif /* DWC_DEVICE_ONLY */
2853

Archive Download this file



interactive