Root/target/linux/cns3xxx/files/drivers/usb/dwc/otg_hcd.c

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

Archive Download this file



interactive