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

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

Archive Download this file



interactive