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

1/* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.c $
3 * $Revision: 1.5 $
4 * $Date: 2008-11-27 09:21:25 $
5 * $Change: 1115682 $
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_HOST_ONLY
34
35/** @file
36 * This file implements the Peripheral Controller Driver.
37 *
38 * The Peripheral Controller Driver (PCD) is responsible for
39 * translating requests from the Function Driver into the appropriate
40 * actions on the DWC_otg controller. It isolates the Function Driver
41 * from the specifics of the controller by providing an API to the
42 * Function Driver.
43 *
44 * The Peripheral Controller Driver for Linux will implement the
45 * Gadget API, so that the existing Gadget drivers can be used.
46 * (Gadget Driver is the Linux terminology for a Function Driver.)
47 *
48 * The Linux Gadget API is defined in the header file
49 * <code><linux/usb_gadget.h></code>. The USB EP operations API is
50 * defined in the structure <code>usb_ep_ops</code> and the USB
51 * Controller API is defined in the structure
52 * <code>usb_gadget_ops</code>.
53 *
54 * An important function of the PCD is managing interrupts generated
55 * by the DWC_otg controller. The implementation of the DWC_otg device
56 * mode interrupt service routines is in dwc_otg_pcd_intr.c.
57 *
58 * @todo Add Device Mode test modes (Test J mode, Test K mode, etc).
59 * @todo Does it work when the request size is greater than DEPTSIZ
60 * transfer size
61 *
62 */
63
64
65#include <linux/kernel.h>
66#include <linux/module.h>
67#include <linux/moduleparam.h>
68#include <linux/init.h>
69#include <linux/device.h>
70#include <linux/errno.h>
71#include <linux/list.h>
72#include <linux/interrupt.h>
73#include <linux/string.h>
74#include <linux/dma-mapping.h>
75#include <linux/version.h>
76
77#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
78# include <linux/usb/ch9.h>
79#else
80# include <linux/usb_ch9.h>
81#endif
82
83#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
84#include <linux/usb/gadget.h>
85#else
86#include <linux/usb_gadget.h>
87#endif
88
89#include "dwc_otg_driver.h"
90#include "dwc_otg_pcd.h"
91
92
93/**
94 * Static PCD pointer for use in usb_gadget_register_driver and
95 * usb_gadget_unregister_driver. Initialized in dwc_otg_pcd_init.
96 */
97static dwc_otg_pcd_t *s_pcd = 0;
98
99
100/* Display the contents of the buffer */
101extern void dump_msg(const u8 *buf, unsigned int length);
102
103
104/**
105 * This function completes a request. It call's the request call back.
106 */
107void dwc_otg_request_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_request_t *req,
108                  int status)
109{
110    unsigned stopped = ep->stopped;
111
112    DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, ep);
113    list_del_init(&req->queue);
114
115    if (req->req.status == -EINPROGRESS) {
116        req->req.status = status;
117    } else {
118        status = req->req.status;
119    }
120
121    /* don't modify queue heads during completion callback */
122    ep->stopped = 1;
123    SPIN_UNLOCK(&ep->pcd->lock);
124    req->req.complete(&ep->ep, &req->req);
125    SPIN_LOCK(&ep->pcd->lock);
126
127    if (ep->pcd->request_pending > 0) {
128        --ep->pcd->request_pending;
129    }
130
131    ep->stopped = stopped;
132}
133
134/**
135 * This function terminates all the requsts in the EP request queue.
136 */
137void dwc_otg_request_nuke(dwc_otg_pcd_ep_t *ep)
138{
139    dwc_otg_pcd_request_t *req;
140
141    ep->stopped = 1;
142
143    /* called with irqs blocked?? */
144    while (!list_empty(&ep->queue)) {
145        req = list_entry(ep->queue.next, dwc_otg_pcd_request_t,
146                 queue);
147        dwc_otg_request_done(ep, req, -ESHUTDOWN);
148    }
149}
150
151/* USB Endpoint Operations */
152/*
153 * The following sections briefly describe the behavior of the Gadget
154 * API endpoint operations implemented in the DWC_otg driver
155 * software. Detailed descriptions of the generic behavior of each of
156 * these functions can be found in the Linux header file
157 * include/linux/usb_gadget.h.
158 *
159 * The Gadget API provides wrapper functions for each of the function
160 * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
161 * function, which then calls the underlying PCD function. The
162 * following sections are named according to the wrapper
163 * functions. Within each section, the corresponding DWC_otg PCD
164 * function name is specified.
165 *
166 */
167
168/**
169 * This function assigns periodic Tx FIFO to an periodic EP
170 * in shared Tx FIFO mode
171 */
172static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t *core_if)
173{
174    uint32_t PerTxMsk = 1;
175    int i;
176    for(i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; ++i)
177    {
178        if((PerTxMsk & core_if->p_tx_msk) == 0) {
179            core_if->p_tx_msk |= PerTxMsk;
180            return i + 1;
181        }
182        PerTxMsk <<= 1;
183    }
184    return 0;
185}
186/**
187 * This function releases periodic Tx FIFO
188 * in shared Tx FIFO mode
189 */
190static void release_perio_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
191{
192    core_if->p_tx_msk = (core_if->p_tx_msk & (1 << (fifo_num - 1))) ^ core_if->p_tx_msk;
193}
194/**
195 * This function assigns periodic Tx FIFO to an periodic EP
196 * in shared Tx FIFO mode
197 */
198static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if)
199{
200    uint32_t TxMsk = 1;
201    int i;
202
203    for(i = 0; i < core_if->hwcfg4.b.num_in_eps; ++i)
204    {
205        if((TxMsk & core_if->tx_msk) == 0) {
206            core_if->tx_msk |= TxMsk;
207            return i + 1;
208        }
209        TxMsk <<= 1;
210    }
211    return 0;
212}
213/**
214 * This function releases periodic Tx FIFO
215 * in shared Tx FIFO mode
216 */
217static void release_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
218{
219    core_if->tx_msk = (core_if->tx_msk & (1 << (fifo_num - 1))) ^ core_if->tx_msk;
220}
221
222/**
223 * This function is called by the Gadget Driver for each EP to be
224 * configured for the current configuration (SET_CONFIGURATION).
225 *
226 * This function initializes the dwc_otg_ep_t data structure, and then
227 * calls dwc_otg_ep_activate.
228 */
229static int dwc_otg_pcd_ep_enable(struct usb_ep *usb_ep,
230                 const struct usb_endpoint_descriptor *ep_desc)
231{
232    dwc_otg_pcd_ep_t *ep = 0;
233    dwc_otg_pcd_t *pcd = 0;
234    unsigned long flags;
235
236    DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, usb_ep, ep_desc);
237
238    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
239    if (!usb_ep || !ep_desc || ep->desc ||
240            ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
241        DWC_WARN("%s, bad ep or descriptor\n", __func__);
242        return -EINVAL;
243    }
244    if (ep == &ep->pcd->ep0) {
245        DWC_WARN("%s, bad ep(0)\n", __func__);
246        return -EINVAL;
247    }
248
249    /* Check FIFO size? */
250    if (!ep_desc->wMaxPacketSize) {
251        DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
252        return -ERANGE;
253    }
254
255    pcd = ep->pcd;
256    if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
257        DWC_WARN("%s, bogus device state\n", __func__);
258        return -ESHUTDOWN;
259    }
260
261    SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
262
263    ep->desc = ep_desc;
264    ep->ep.maxpacket = le16_to_cpu (ep_desc->wMaxPacketSize);
265
266    /*
267     * Activate the EP
268     */
269    ep->stopped = 0;
270
271    ep->dwc_ep.is_in = (USB_DIR_IN & ep_desc->bEndpointAddress) != 0;
272    ep->dwc_ep.maxpacket = ep->ep.maxpacket;
273
274    ep->dwc_ep.type = ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
275
276    if(ep->dwc_ep.is_in) {
277        if(!pcd->otg_dev->core_if->en_multiple_tx_fifo) {
278            ep->dwc_ep.tx_fifo_num = 0;
279
280            if (ep->dwc_ep.type == USB_ENDPOINT_XFER_ISOC) {
281                /*
282                 * if ISOC EP then assign a Periodic Tx FIFO.
283                 */
284                ep->dwc_ep.tx_fifo_num = assign_perio_tx_fifo(pcd->otg_dev->core_if);
285             }
286        } else {
287            /*
288             * if Dedicated FIFOs mode is on then assign a Tx FIFO.
289             */
290            ep->dwc_ep.tx_fifo_num = assign_tx_fifo(pcd->otg_dev->core_if);
291
292        }
293    }
294    /* Set initial data PID. */
295    if (ep->dwc_ep.type == USB_ENDPOINT_XFER_BULK) {
296        ep->dwc_ep.data_pid_start = 0;
297    }
298
299    DWC_DEBUGPL(DBG_PCD, "Activate %s-%s: type=%d, mps=%d desc=%p\n",
300                    ep->ep.name, (ep->dwc_ep.is_in ?"IN":"OUT"),
301                    ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc);
302
303    if(ep->dwc_ep.type != USB_ENDPOINT_XFER_ISOC) {
304        ep->dwc_ep.desc_addr = dwc_otg_ep_alloc_desc_chain(&ep->dwc_ep.dma_desc_addr, MAX_DMA_DESC_CNT);
305    }
306
307    dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
308    SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
309
310    return 0;
311}
312
313/**
314 * This function is called when an EP is disabled due to disconnect or
315 * change in configuration. Any pending requests will terminate with a
316 * status of -ESHUTDOWN.
317 *
318 * This function modifies the dwc_otg_ep_t data structure for this EP,
319 * and then calls dwc_otg_ep_deactivate.
320 */
321static int dwc_otg_pcd_ep_disable(struct usb_ep *usb_ep)
322{
323    dwc_otg_pcd_ep_t *ep;
324    dwc_otg_pcd_t *pcd = 0;
325    unsigned long flags;
326
327    DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, usb_ep);
328    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
329    if (!usb_ep || !ep->desc) {
330        DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
331            usb_ep ? ep->ep.name : NULL);
332        return -EINVAL;
333    }
334
335    SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
336
337    dwc_otg_request_nuke(ep);
338
339    dwc_otg_ep_deactivate(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
340    ep->desc = 0;
341    ep->stopped = 1;
342
343    if(ep->dwc_ep.is_in) {
344        dwc_otg_flush_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
345        release_perio_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
346        release_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
347    }
348
349    /* Free DMA Descriptors */
350    pcd = ep->pcd;
351
352    SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
353
354    if(ep->dwc_ep.type != USB_ENDPOINT_XFER_ISOC && ep->dwc_ep.desc_addr) {
355        dwc_otg_ep_free_desc_chain(ep->dwc_ep.desc_addr, ep->dwc_ep.dma_desc_addr, MAX_DMA_DESC_CNT);
356    }
357
358    DWC_DEBUGPL(DBG_PCD, "%s disabled\n", usb_ep->name);
359    return 0;
360}
361
362
363/**
364 * This function allocates a request object to use with the specified
365 * endpoint.
366 *
367 * @param ep The endpoint to be used with with the request
368 * @param gfp_flags the GFP_* flags to use.
369 */
370static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
371#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
372                             int gfp_flags
373#else
374                             gfp_t gfp_flags
375#endif
376                           )
377{
378    dwc_otg_pcd_request_t *req;
379
380    DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d)\n", __func__, ep, gfp_flags);
381    if (0 == ep) {
382        DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
383        return 0;
384    }
385    req = kmalloc(sizeof(dwc_otg_pcd_request_t), gfp_flags);
386    if (0 == req) {
387        DWC_WARN("%s() %s\n", __func__,
388                 "request allocation failed!\n");
389        return 0;
390    }
391    memset(req, 0, sizeof(dwc_otg_pcd_request_t));
392    req->req.dma = DMA_ADDR_INVALID;
393    INIT_LIST_HEAD(&req->queue);
394    return &req->req;
395}
396
397/**
398 * This function frees a request object.
399 *
400 * @param ep The endpoint associated with the request
401 * @param req The request being freed
402 */
403static void dwc_otg_pcd_free_request(struct usb_ep *ep,
404                     struct usb_request *req)
405{
406    dwc_otg_pcd_request_t *request;
407    DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, ep, req);
408
409    if (0 == ep || 0 == req) {
410        DWC_WARN("%s() %s\n", __func__,
411                 "Invalid ep or req argument!\n");
412        return;
413    }
414
415    request = container_of(req, dwc_otg_pcd_request_t, req);
416    kfree(request);
417}
418
419#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
420/**
421 * This function allocates an I/O buffer to be used for a transfer
422 * to/from the specified endpoint.
423 *
424 * @param usb_ep The endpoint to be used with with the request
425 * @param bytes The desired number of bytes for the buffer
426 * @param dma Pointer to the buffer's DMA address; must be valid
427 * @param gfp_flags the GFP_* flags to use.
428 * @return address of a new buffer or null is buffer could not be allocated.
429 */
430static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes,
431                      dma_addr_t *dma,
432#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
433                      int gfp_flags
434#else
435                      gfp_t gfp_flags
436#endif
437                    )
438{
439    void *buf;
440    dwc_otg_pcd_ep_t *ep;
441    dwc_otg_pcd_t *pcd = 0;
442
443    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
444    pcd = ep->pcd;
445
446    DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes,
447                dma, gfp_flags);
448
449    /* Check dword alignment */
450    if ((bytes & 0x3UL) != 0) {
451        DWC_WARN("%s() Buffer size is not a multiple of"
452                 "DWORD size (%d)",__func__, bytes);
453    }
454
455    if (GET_CORE_IF(pcd)->dma_enable) {
456        buf = dma_alloc_coherent (NULL, bytes, dma, gfp_flags);
457    }
458    else {
459        buf = kmalloc(bytes, gfp_flags);
460    }
461
462    /* Check dword alignment */
463    if (((int)buf & 0x3UL) != 0) {
464        DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
465                    __func__, buf);
466    }
467
468    return buf;
469}
470
471/**
472 * This function frees an I/O buffer that was allocated by alloc_buffer.
473 *
474 * @param usb_ep the endpoint associated with the buffer
475 * @param buf address of the buffer
476 * @param dma The buffer's DMA address
477 * @param bytes The number of bytes of the buffer
478 */
479static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf,
480                    dma_addr_t dma, unsigned bytes)
481{
482    dwc_otg_pcd_ep_t *ep;
483    dwc_otg_pcd_t *pcd = 0;
484
485    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
486    pcd = ep->pcd;
487
488    DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%0x,%d)\n", __func__, ep, buf, dma, bytes);
489
490    if (GET_CORE_IF(pcd)->dma_enable) {
491        dma_free_coherent (NULL, bytes, buf, dma);
492    }
493    else {
494        kfree(buf);
495    }
496}
497#endif
498
499
500/**
501 * This function is used to submit an I/O Request to an EP.
502 *
503 * - When the request completes the request's completion callback
504 * is called to return the request to the driver.
505 * - An EP, except control EPs, may have multiple requests
506 * pending.
507 * - Once submitted the request cannot be examined or modified.
508 * - Each request is turned into one or more packets.
509 * - A BULK EP can queue any amount of data; the transfer is
510 * packetized.
511 * - Zero length Packets are specified with the request 'zero'
512 * flag.
513 */
514static int dwc_otg_pcd_ep_queue(struct usb_ep *usb_ep,
515                struct usb_request *usb_req,
516#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
517                int gfp_flags
518#else
519                gfp_t gfp_flags
520#endif
521                  )
522{
523    int prevented = 0;
524    dwc_otg_pcd_request_t *req;
525    dwc_otg_pcd_ep_t *ep;
526    dwc_otg_pcd_t *pcd;
527    unsigned long flags = 0;
528    dwc_otg_core_if_t *_core_if;
529
530    DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%d)\n",
531            __func__, usb_ep, usb_req, gfp_flags);
532
533    req = container_of(usb_req, dwc_otg_pcd_request_t, req);
534    if (!usb_req || !usb_req->complete || !usb_req->buf ||
535            !list_empty(&req->queue)) {
536        DWC_WARN("%s, bad params\n", __func__);
537        return -EINVAL;
538    }
539
540    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
541    if (!usb_ep || (!ep->desc && ep->dwc_ep.num != 0)/* || ep->stopped != 0*/) {
542        DWC_WARN("%s, bad ep\n", __func__);
543        return -EINVAL;
544    }
545
546    pcd = ep->pcd;
547    if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
548        DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
549        DWC_WARN("%s, bogus device state\n", __func__);
550        return -ESHUTDOWN;
551    }
552
553
554    DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
555               usb_ep->name, usb_req, usb_req->length, usb_req->buf);
556
557    if (!GET_CORE_IF(pcd)->core_params->opt) {
558        if (ep->dwc_ep.num != 0) {
559            DWC_ERROR("%s queue req %p, len %d buf %p\n",
560                      usb_ep->name, usb_req, usb_req->length, usb_req->buf);
561        }
562    }
563
564    SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
565
566
567    /**************************************************
568         New add by kaiker ,for DMA mode bug
569    ************************************************/
570    //by kaiker ,for RT3052 USB OTG device mode
571
572    _core_if = GET_CORE_IF(pcd);
573
574    if (_core_if->dma_enable)
575    {
576         usb_req->dma = virt_to_phys((void *)usb_req->buf);
577
578        if(ep->dwc_ep.is_in)
579        {
580#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) || defined(CONFIG_MIPS)
581            if(usb_req->length)
582                dma_cache_wback_inv((unsigned long)usb_req->buf, usb_req->length + 2);
583#endif
584        }
585    }
586
587
588
589#if defined(DEBUG) & defined(VERBOSE)
590    dump_msg(usb_req->buf, usb_req->length);
591#endif
592
593    usb_req->status = -EINPROGRESS;
594    usb_req->actual = 0;
595
596    /*
597     * For EP0 IN without premature status, zlp is required?
598     */
599    if (ep->dwc_ep.num == 0 && ep->dwc_ep.is_in) {
600        DWC_DEBUGPL(DBG_PCDV, "%s-OUT ZLP\n", usb_ep->name);
601        //_req->zero = 1;
602    }
603
604    /* Start the transfer */
605    if (list_empty(&ep->queue) && !ep->stopped) {
606        /* EP0 Transfer? */
607        if (ep->dwc_ep.num == 0) {
608            switch (pcd->ep0state) {
609            case EP0_IN_DATA_PHASE:
610                DWC_DEBUGPL(DBG_PCD,
611                        "%s ep0: EP0_IN_DATA_PHASE\n",
612                        __func__);
613                break;
614
615            case EP0_OUT_DATA_PHASE:
616                DWC_DEBUGPL(DBG_PCD,
617                        "%s ep0: EP0_OUT_DATA_PHASE\n",
618                        __func__);
619                if (pcd->request_config) {
620                    /* Complete STATUS PHASE */
621                    ep->dwc_ep.is_in = 1;
622                    pcd->ep0state = EP0_IN_STATUS_PHASE;
623                }
624                break;
625
626            case EP0_IN_STATUS_PHASE:
627                DWC_DEBUGPL(DBG_PCD,
628                        "%s ep0: EP0_IN_STATUS_PHASE\n",
629                        __func__);
630                break;
631
632            default:
633                DWC_DEBUGPL(DBG_ANY, "ep0: odd state %d\n",
634                        pcd->ep0state);
635                SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
636                return -EL2HLT;
637            }
638            ep->dwc_ep.dma_addr = usb_req->dma;
639            ep->dwc_ep.start_xfer_buff = usb_req->buf;
640            ep->dwc_ep.xfer_buff = usb_req->buf;
641            ep->dwc_ep.xfer_len = usb_req->length;
642            ep->dwc_ep.xfer_count = 0;
643            ep->dwc_ep.sent_zlp = 0;
644            ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
645
646            if(usb_req->zero) {
647                if((ep->dwc_ep.xfer_len % ep->dwc_ep.maxpacket == 0)
648                        && (ep->dwc_ep.xfer_len != 0)) {
649                    ep->dwc_ep.sent_zlp = 1;
650                }
651
652            }
653
654            dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep->dwc_ep);
655        }
656        else {
657
658            uint32_t max_transfer = GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
659
660            /* Setup and start the Transfer */
661            ep->dwc_ep.dma_addr = usb_req->dma;
662            ep->dwc_ep.start_xfer_buff = usb_req->buf;
663            ep->dwc_ep.xfer_buff = usb_req->buf;
664            ep->dwc_ep.sent_zlp = 0;
665            ep->dwc_ep.total_len = usb_req->length;
666            ep->dwc_ep.xfer_len = 0;
667            ep->dwc_ep.xfer_count = 0;
668
669            if(max_transfer > MAX_TRANSFER_SIZE) {
670                ep->dwc_ep.maxxfer = max_transfer - (max_transfer % ep->dwc_ep.maxpacket);
671            } else {
672                ep->dwc_ep.maxxfer = max_transfer;
673            }
674
675            if(usb_req->zero) {
676                if((ep->dwc_ep.total_len % ep->dwc_ep.maxpacket == 0)
677                        && (ep->dwc_ep.total_len != 0)) {
678                    ep->dwc_ep.sent_zlp = 1;
679                }
680
681            }
682            dwc_otg_ep_start_transfer(GET_CORE_IF(pcd), &ep->dwc_ep);
683        }
684    }
685
686    if ((req != 0) || prevented) {
687        ++pcd->request_pending;
688        list_add_tail(&req->queue, &ep->queue);
689        if (ep->dwc_ep.is_in && ep->stopped && !(GET_CORE_IF(pcd)->dma_enable)) {
690            /** @todo NGS Create a function for this. */
691            diepmsk_data_t diepmsk = { .d32 = 0};
692            diepmsk.b.intktxfemp = 1;
693            if(&GET_CORE_IF(pcd)->multiproc_int_enable) {
694                dwc_modify_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepeachintmsk[ep->dwc_ep.num],
695                            0, diepmsk.d32);
696            } else {
697                dwc_modify_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
698            }
699        }
700    }
701
702    SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
703    return 0;
704}
705
706/**
707 * This function cancels an I/O request from an EP.
708 */
709static int dwc_otg_pcd_ep_dequeue(struct usb_ep *usb_ep,
710                  struct usb_request *usb_req)
711{
712    dwc_otg_pcd_request_t *req;
713    dwc_otg_pcd_ep_t *ep;
714    dwc_otg_pcd_t *pcd;
715    unsigned long flags;
716
717    DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, usb_ep, usb_req);
718
719    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
720    if (!usb_ep || !usb_req || (!ep->desc && ep->dwc_ep.num != 0)) {
721        DWC_WARN("%s, bad argument\n", __func__);
722        return -EINVAL;
723    }
724    pcd = ep->pcd;
725    if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
726        DWC_WARN("%s, bogus device state\n", __func__);
727        return -ESHUTDOWN;
728    }
729
730    SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
731    DWC_DEBUGPL(DBG_PCDV, "%s %s %s %p\n", __func__, usb_ep->name,
732                    ep->dwc_ep.is_in ? "IN" : "OUT",
733                    usb_req);
734
735    /* make sure it's actually queued on this endpoint */
736    list_for_each_entry(req, &ep->queue, queue)
737    {
738        if (&req->req == usb_req) {
739            break;
740        }
741    }
742
743    if (&req->req != usb_req) {
744        SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
745        return -EINVAL;
746    }
747
748    if (!list_empty(&req->queue)) {
749        dwc_otg_request_done(ep, req, -ECONNRESET);
750    }
751    else {
752        req = 0;
753    }
754
755    SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
756
757    return req ? 0 : -EOPNOTSUPP;
758}
759
760/**
761 * usb_ep_set_halt stalls an endpoint.
762 *
763 * usb_ep_clear_halt clears an endpoint halt and resets its data
764 * toggle.
765 *
766 * Both of these functions are implemented with the same underlying
767 * function. The behavior depends on the value argument.
768 *
769 * @param[in] usb_ep the Endpoint to halt or clear halt.
770 * @param[in] value
771 * - 0 means clear_halt.
772 * - 1 means set_halt,
773 * - 2 means clear stall lock flag.
774 * - 3 means set stall lock flag.
775 */
776static int dwc_otg_pcd_ep_set_halt(struct usb_ep *usb_ep, int value)
777{
778    int retval = 0;
779    unsigned long flags;
780    dwc_otg_pcd_ep_t *ep = 0;
781
782
783    DWC_DEBUGPL(DBG_PCD,"HALT %s %d\n", usb_ep->name, value);
784
785    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
786
787    if (!usb_ep || (!ep->desc && ep != &ep->pcd->ep0) ||
788            ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
789        DWC_WARN("%s, bad ep\n", __func__);
790        return -EINVAL;
791    }
792
793    SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
794    if (!list_empty(&ep->queue)) {
795        DWC_WARN("%s() %s XFer In process\n", __func__, usb_ep->name);
796        retval = -EAGAIN;
797    }
798    else if (value == 0) {
799        dwc_otg_ep_clear_stall(ep->pcd->otg_dev->core_if,
800                    &ep->dwc_ep);
801    }
802    else if(value == 1) {
803        if (ep->dwc_ep.is_in == 1 && ep->pcd->otg_dev->core_if->dma_desc_enable) {
804            dtxfsts_data_t txstatus;
805            fifosize_data_t txfifosize;
806
807            txfifosize.d32 = dwc_read_reg32(&ep->pcd->otg_dev->core_if->core_global_regs->dptxfsiz_dieptxf[ep->dwc_ep.tx_fifo_num]);
808            txstatus.d32 = dwc_read_reg32(&ep->pcd->otg_dev->core_if->dev_if->in_ep_regs[ep->dwc_ep.num]->dtxfsts);
809
810            if(txstatus.b.txfspcavail < txfifosize.b.depth) {
811                DWC_WARN("%s() %s Data In Tx Fifo\n", __func__, usb_ep->name);
812                retval = -EAGAIN;
813            }
814            else {
815                if (ep->dwc_ep.num == 0) {
816                    ep->pcd->ep0state = EP0_STALL;
817                }
818
819                ep->stopped = 1;
820                dwc_otg_ep_set_stall(ep->pcd->otg_dev->core_if,
821                            &ep->dwc_ep);
822            }
823        }
824        else {
825            if (ep->dwc_ep.num == 0) {
826                ep->pcd->ep0state = EP0_STALL;
827            }
828
829            ep->stopped = 1;
830            dwc_otg_ep_set_stall(ep->pcd->otg_dev->core_if,
831                        &ep->dwc_ep);
832        }
833    }
834    else if (value == 2) {
835        ep->dwc_ep.stall_clear_flag = 0;
836    }
837    else if (value == 3) {
838        ep->dwc_ep.stall_clear_flag = 1;
839    }
840
841    SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
842    return retval;
843}
844
845/**
846 * This function allocates a DMA Descriptor chain for the Endpoint
847 * buffer to be used for a transfer to/from the specified endpoint.
848 */
849dwc_otg_dma_desc_t* dwc_otg_ep_alloc_desc_chain(uint32_t * dma_desc_addr, uint32_t count)
850{
851
852    return dma_alloc_coherent(NULL, count * sizeof(dwc_otg_dma_desc_t), dma_desc_addr, GFP_KERNEL);
853}
854
855/**
856 * This function frees a DMA Descriptor chain that was allocated by ep_alloc_desc.
857 */
858void dwc_otg_ep_free_desc_chain(dwc_otg_dma_desc_t* desc_addr, uint32_t dma_desc_addr, uint32_t count)
859{
860    dma_free_coherent(NULL, count * sizeof(dwc_otg_dma_desc_t), desc_addr, dma_desc_addr);
861}
862
863#ifdef DWC_EN_ISOC
864
865/**
866 * This function initializes a descriptor chain for Isochronous transfer
867 *
868 * @param core_if Programming view of DWC_otg controller.
869 * @param dwc_ep The EP to start the transfer on.
870 *
871 */
872void dwc_otg_iso_ep_start_ddma_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
873{
874
875     dsts_data_t dsts = { .d32 = 0};
876    depctl_data_t depctl = { .d32 = 0 };
877    volatile uint32_t *addr;
878     int i, j;
879
880    if(dwc_ep->is_in)
881        dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl / dwc_ep->bInterval;
882    else
883        dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
884
885
886    /** Allocate descriptors for double buffering */
887    dwc_ep->iso_desc_addr = dwc_otg_ep_alloc_desc_chain(&dwc_ep->iso_dma_desc_addr,dwc_ep->desc_cnt*2);
888    if(dwc_ep->desc_addr) {
889        DWC_WARN("%s, can't allocate DMA descriptor chain\n", __func__);
890        return;
891    }
892
893    dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
894
895    /** ISO OUT EP */
896    if(dwc_ep->is_in == 0) {
897        desc_sts_data_t sts = { .d32 =0 };
898        dwc_otg_dma_desc_t* dma_desc = dwc_ep->iso_desc_addr;
899        dma_addr_t dma_ad;
900        uint32_t data_per_desc;
901        dwc_otg_dev_out_ep_regs_t *out_regs =
902            core_if->dev_if->out_ep_regs[dwc_ep->num];
903        int offset;
904
905        addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
906        dma_ad = (dma_addr_t)dwc_read_reg32(&(out_regs->doepdma));
907
908        /** Buffer 0 descriptors setup */
909        dma_ad = dwc_ep->dma_addr0;
910
911        sts.b_iso_out.bs = BS_HOST_READY;
912        sts.b_iso_out.rxsts = 0;
913        sts.b_iso_out.l = 0;
914        sts.b_iso_out.sp = 0;
915        sts.b_iso_out.ioc = 0;
916        sts.b_iso_out.pid = 0;
917        sts.b_iso_out.framenum = 0;
918
919        offset = 0;
920        for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
921        {
922
923            for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
924            {
925                data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
926                    dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
927
928                data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
929                sts.b_iso_out.rxbytes = data_per_desc;
930                writel((uint32_t)dma_ad, &dma_desc->buf);
931                writel(sts.d32, &dma_desc->status);
932
933                offset += data_per_desc;
934                dma_desc ++;
935                (uint32_t)dma_ad += data_per_desc;
936            }
937        }
938
939        for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
940        {
941            data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
942                dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
943            data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
944            sts.b_iso_out.rxbytes = data_per_desc;
945            writel((uint32_t)dma_ad, &dma_desc->buf);
946            writel(sts.d32, &dma_desc->status);
947
948            offset += data_per_desc;
949            dma_desc ++;
950            (uint32_t)dma_ad += data_per_desc;
951        }
952
953        sts.b_iso_out.ioc = 1;
954        data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
955            dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
956        data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
957        sts.b_iso_out.rxbytes = data_per_desc;
958
959        writel((uint32_t)dma_ad, &dma_desc->buf);
960        writel(sts.d32, &dma_desc->status);
961        dma_desc ++;
962
963        /** Buffer 1 descriptors setup */
964        sts.b_iso_out.ioc = 0;
965        dma_ad = dwc_ep->dma_addr1;
966
967        offset = 0;
968        for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
969        {
970            for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
971            {
972                data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
973                    dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
974                data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
975                sts.b_iso_out.rxbytes = data_per_desc;
976                writel((uint32_t)dma_ad, &dma_desc->buf);
977                writel(sts.d32, &dma_desc->status);
978
979                offset += data_per_desc;
980                dma_desc ++;
981                (uint32_t)dma_ad += data_per_desc;
982            }
983        }
984        for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
985        {
986            data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
987                dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
988            data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
989            sts.b_iso_out.rxbytes = data_per_desc;
990            writel((uint32_t)dma_ad, &dma_desc->buf);
991            writel(sts.d32, &dma_desc->status);
992
993            offset += data_per_desc;
994            dma_desc ++;
995            (uint32_t)dma_ad += data_per_desc;
996        }
997
998        sts.b_iso_out.ioc = 1;
999        sts.b_iso_out.l = 1;
1000        data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
1001            dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
1002        data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
1003        sts.b_iso_out.rxbytes = data_per_desc;
1004
1005        writel((uint32_t)dma_ad, &dma_desc->buf);
1006        writel(sts.d32, &dma_desc->status);
1007
1008        dwc_ep->next_frame = 0;
1009
1010        /** Write dma_ad into DOEPDMA register */
1011        dwc_write_reg32(&(out_regs->doepdma),(uint32_t)dwc_ep->iso_dma_desc_addr);
1012
1013    }
1014    /** ISO IN EP */
1015    else {
1016        desc_sts_data_t sts = { .d32 =0 };
1017        dwc_otg_dma_desc_t* dma_desc = dwc_ep->iso_desc_addr;
1018        dma_addr_t dma_ad;
1019        dwc_otg_dev_in_ep_regs_t *in_regs =
1020            core_if->dev_if->in_ep_regs[dwc_ep->num];
1021        unsigned int frmnumber;
1022        fifosize_data_t txfifosize,rxfifosize;
1023
1024        txfifosize.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[dwc_ep->num]->dtxfsts);
1025        rxfifosize.d32 = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
1026
1027
1028        addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
1029
1030        dma_ad = dwc_ep->dma_addr0;
1031
1032        dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
1033
1034        sts.b_iso_in.bs = BS_HOST_READY;
1035        sts.b_iso_in.txsts = 0;
1036        sts.b_iso_in.sp = (dwc_ep->data_per_frame % dwc_ep->maxpacket)? 1 : 0;
1037        sts.b_iso_in.ioc = 0;
1038        sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
1039
1040
1041        frmnumber = dwc_ep->next_frame;
1042
1043        sts.b_iso_in.framenum = frmnumber;
1044        sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
1045        sts.b_iso_in.l = 0;
1046
1047        /** Buffer 0 descriptors setup */
1048        for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
1049        {
1050            writel((uint32_t)dma_ad, &dma_desc->buf);
1051            writel(sts.d32, &dma_desc->status);
1052            dma_desc ++;
1053
1054            (uint32_t)dma_ad += dwc_ep->data_per_frame;
1055            sts.b_iso_in.framenum += dwc_ep->bInterval;
1056        }
1057
1058        sts.b_iso_in.ioc = 1;
1059        writel((uint32_t)dma_ad, &dma_desc->buf);
1060        writel(sts.d32, &dma_desc->status);
1061        ++dma_desc;
1062
1063        /** Buffer 1 descriptors setup */
1064        sts.b_iso_in.ioc = 0;
1065        dma_ad = dwc_ep->dma_addr1;
1066
1067        for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
1068        {
1069            writel((uint32_t)dma_ad, &dma_desc->buf);
1070            writel(sts.d32, &dma_desc->status);
1071            dma_desc ++;
1072
1073            (uint32_t)dma_ad += dwc_ep->data_per_frame;
1074            sts.b_iso_in.framenum += dwc_ep->bInterval;
1075
1076            sts.b_iso_in.ioc = 0;
1077        }
1078        sts.b_iso_in.ioc = 1;
1079        sts.b_iso_in.l = 1;
1080
1081        writel((uint32_t)dma_ad, &dma_desc->buf);
1082        writel(sts.d32, &dma_desc->status);
1083
1084        dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval;
1085
1086        /** Write dma_ad into diepdma register */
1087        dwc_write_reg32(&(in_regs->diepdma),(uint32_t)dwc_ep->iso_dma_desc_addr);
1088    }
1089    /** Enable endpoint, clear nak */
1090    depctl.d32 = 0;
1091    depctl.b.epena = 1;
1092    depctl.b.usbactep = 1;
1093    depctl.b.cnak = 1;
1094
1095    dwc_modify_reg32(addr, depctl.d32,depctl.d32);
1096    depctl.d32 = dwc_read_reg32(addr);
1097}
1098
1099/**
1100 * This function initializes a descriptor chain for Isochronous transfer
1101 *
1102 * @param core_if Programming view of DWC_otg controller.
1103 * @param ep The EP to start the transfer on.
1104 *
1105 */
1106
1107void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
1108{
1109    depctl_data_t depctl = { .d32 = 0 };
1110    volatile uint32_t *addr;
1111
1112
1113    if(ep->is_in) {
1114        addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
1115    } else {
1116        addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
1117    }
1118
1119
1120    if(core_if->dma_enable == 0 || core_if->dma_desc_enable!= 0) {
1121        return;
1122    } else {
1123        deptsiz_data_t deptsiz = { .d32 = 0 };
1124
1125        ep->xfer_len = ep->data_per_frame * ep->buf_proc_intrvl / ep->bInterval;
1126        ep->pkt_cnt = (ep->xfer_len - 1 + ep->maxpacket) /
1127                ep->maxpacket;
1128        ep->xfer_count = 0;
1129        ep->xfer_buff = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
1130        ep->dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
1131
1132        if(ep->is_in) {
1133            /* Program the transfer size and packet count
1134             * as follows: xfersize = N * maxpacket +
1135             * short_packet pktcnt = N + (short_packet
1136             * exist ? 1 : 0)
1137             */
1138            deptsiz.b.mc = ep->pkt_per_frm;
1139            deptsiz.b.xfersize = ep->xfer_len;
1140            deptsiz.b.pktcnt =
1141                (ep->xfer_len - 1 + ep->maxpacket) /
1142                ep->maxpacket;
1143            dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz, deptsiz.d32);
1144
1145            /* Write the DMA register */
1146            dwc_write_reg32 (&(core_if->dev_if->in_ep_regs[ep->num]->diepdma), (uint32_t)ep->dma_addr);
1147
1148        } else {
1149            deptsiz.b.pktcnt =
1150                    (ep->xfer_len + (ep->maxpacket - 1)) /
1151                    ep->maxpacket;
1152            deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
1153
1154            dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
1155
1156            /* Write the DMA register */
1157            dwc_write_reg32 (&(core_if->dev_if->out_ep_regs[ep->num]->doepdma), (uint32_t)ep->dma_addr);
1158
1159        }
1160        /** Enable endpoint, clear nak */
1161        depctl.d32 = 0;
1162        dwc_modify_reg32(addr, depctl.d32,depctl.d32);
1163
1164        depctl.b.epena = 1;
1165        depctl.b.cnak = 1;
1166
1167        dwc_modify_reg32(addr, depctl.d32,depctl.d32);
1168    }
1169}
1170
1171
1172/**
1173 * This function does the setup for a data transfer for an EP and
1174 * starts the transfer. For an IN transfer, the packets will be
1175 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
1176 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
1177 *
1178 * @param core_if Programming view of DWC_otg controller.
1179 * @param ep The EP to start the transfer on.
1180 */
1181
1182void dwc_otg_iso_ep_start_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
1183{
1184     if(core_if->dma_enable) {
1185        if(core_if->dma_desc_enable) {
1186            if(ep->is_in) {
1187                ep->desc_cnt = ep->pkt_cnt / ep->pkt_per_frm;
1188            } else {
1189                ep->desc_cnt = ep->pkt_cnt;
1190            }
1191            dwc_otg_iso_ep_start_ddma_transfer(core_if, ep);
1192        } else {
1193            if(core_if->pti_enh_enable) {
1194                dwc_otg_iso_ep_start_buf_transfer(core_if, ep);
1195            } else {
1196                ep->cur_pkt_addr = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
1197                ep->cur_pkt_dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
1198                dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
1199            }
1200        }
1201    } else {
1202        ep->cur_pkt_addr = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
1203        ep->cur_pkt_dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
1204        dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
1205    }
1206}
1207
1208/**
1209 * This function does the setup for a data transfer for an EP and
1210 * starts the transfer. For an IN transfer, the packets will be
1211 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
1212 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
1213 *
1214 * @param core_if Programming view of DWC_otg controller.
1215 * @param ep The EP to start the transfer on.
1216 */
1217
1218void dwc_otg_iso_ep_stop_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
1219{
1220    depctl_data_t depctl = { .d32 = 0 };
1221    volatile uint32_t *addr;
1222
1223    if(ep->is_in == 1) {
1224        addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
1225    }
1226    else {
1227        addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
1228    }
1229
1230    /* disable the ep */
1231    depctl.d32 = dwc_read_reg32(addr);
1232
1233    depctl.b.epdis = 1;
1234    depctl.b.snak = 1;
1235
1236    dwc_write_reg32(addr, depctl.d32);
1237
1238    if(core_if->dma_desc_enable &&
1239        ep->iso_desc_addr && ep->iso_dma_desc_addr) {
1240        dwc_otg_ep_free_desc_chain(ep->iso_desc_addr,ep->iso_dma_desc_addr,ep->desc_cnt * 2);
1241    }
1242
1243    /* reset varibales */
1244    ep->dma_addr0 = 0;
1245    ep->dma_addr1 = 0;
1246    ep->xfer_buff0 = 0;
1247    ep->xfer_buff1 = 0;
1248    ep->data_per_frame = 0;
1249    ep->data_pattern_frame = 0;
1250    ep->sync_frame = 0;
1251    ep->buf_proc_intrvl = 0;
1252    ep->bInterval = 0;
1253    ep->proc_buf_num = 0;
1254    ep->pkt_per_frm = 0;
1255    ep->pkt_per_frm = 0;
1256    ep->desc_cnt = 0;
1257    ep->iso_desc_addr = 0;
1258    ep->iso_dma_desc_addr = 0;
1259}
1260
1261
1262/**
1263 * This function is used to submit an ISOC Transfer Request to an EP.
1264 *
1265 * - Every time a sync period completes the request's completion callback
1266 * is called to provide data to the gadget driver.
1267 * - Once submitted the request cannot be modified.
1268 * - Each request is turned into periodic data packets untill ISO
1269 * Transfer is stopped..
1270 */
1271static int dwc_otg_pcd_iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
1272#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1273                int gfp_flags
1274#else
1275                gfp_t gfp_flags
1276#endif
1277)
1278{
1279    dwc_otg_pcd_ep_t *ep;
1280    dwc_otg_pcd_t *pcd;
1281    dwc_ep_t *dwc_ep;
1282    unsigned long flags = 0;
1283    int32_t frm_data;
1284    dwc_otg_core_if_t *core_if;
1285    dcfg_data_t dcfg;
1286    dsts_data_t dsts;
1287
1288
1289    if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
1290        DWC_WARN("%s, bad params\n", __func__);
1291        return -EINVAL;
1292    }
1293
1294    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
1295
1296    if (!usb_ep || !ep->desc || ep->dwc_ep.num == 0) {
1297        DWC_WARN("%s, bad ep\n", __func__);
1298        return -EINVAL;
1299    }
1300
1301    pcd = ep->pcd;
1302    core_if = GET_CORE_IF(pcd);
1303
1304    dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
1305
1306    if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
1307        DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
1308        DWC_WARN("%s, bogus device state\n", __func__);
1309        return -ESHUTDOWN;
1310    }
1311
1312    SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
1313
1314    dwc_ep = &ep->dwc_ep;
1315
1316    if(ep->iso_req) {
1317        DWC_WARN("%s, iso request in progress\n", __func__);
1318    }
1319    req->status = -EINPROGRESS;
1320
1321    dwc_ep->dma_addr0 = req->dma0;
1322    dwc_ep->dma_addr1 = req->dma1;
1323
1324    dwc_ep->xfer_buff0 = req->buf0;
1325    dwc_ep->xfer_buff1 = req->buf1;
1326
1327    ep->iso_req = req;
1328
1329    dwc_ep->data_per_frame = req->data_per_frame;
1330
1331    /** @todo - pattern data support is to be implemented in the future */
1332    dwc_ep->data_pattern_frame = req->data_pattern_frame;
1333    dwc_ep->sync_frame = req->sync_frame;
1334
1335    dwc_ep->buf_proc_intrvl = req->buf_proc_intrvl;
1336
1337    dwc_ep->bInterval = 1 << (ep->desc->bInterval - 1);
1338
1339    dwc_ep->proc_buf_num = 0;
1340
1341    dwc_ep->pkt_per_frm = 0;
1342    frm_data = ep->dwc_ep.data_per_frame;
1343    while(frm_data > 0) {
1344        dwc_ep->pkt_per_frm++;
1345        frm_data -= ep->dwc_ep.maxpacket;
1346    }
1347
1348    dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
1349
1350    if(req->flags & USB_REQ_ISO_ASAP) {
1351        dwc_ep->next_frame = dsts.b.soffn + 1;
1352        if(dwc_ep->bInterval != 1){
1353            dwc_ep->next_frame = dwc_ep->next_frame + (dwc_ep->bInterval - 1 - dwc_ep->next_frame % dwc_ep->bInterval);
1354        }
1355    } else {
1356        dwc_ep->next_frame = req->start_frame;
1357    }
1358
1359
1360    if(!core_if->pti_enh_enable) {
1361        dwc_ep->pkt_cnt = dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
1362    } else {
1363        dwc_ep->pkt_cnt =
1364            (dwc_ep->data_per_frame * (dwc_ep->buf_proc_intrvl / dwc_ep->bInterval)
1365            - 1 + dwc_ep->maxpacket) / dwc_ep->maxpacket;
1366    }
1367
1368    if(core_if->dma_desc_enable) {
1369        dwc_ep->desc_cnt =
1370            dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
1371    }
1372
1373    dwc_ep->pkt_info = kmalloc(sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt, GFP_KERNEL);
1374    if(!dwc_ep->pkt_info) {
1375        return -ENOMEM;
1376    }
1377    if(core_if->pti_enh_enable) {
1378        memset(dwc_ep->pkt_info, 0, sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt);
1379    }
1380
1381    dwc_ep->cur_pkt = 0;
1382
1383    SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
1384
1385    dwc_otg_iso_ep_start_transfer(core_if, dwc_ep);
1386
1387    return 0;
1388}
1389
1390/**
1391 * This function stops ISO EP Periodic Data Transfer.
1392 */
1393static int dwc_otg_pcd_iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
1394{
1395    dwc_otg_pcd_ep_t *ep;
1396    dwc_otg_pcd_t *pcd;
1397    dwc_ep_t *dwc_ep;
1398    unsigned long flags;
1399
1400    ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
1401
1402    if (!usb_ep || !ep->desc || ep->dwc_ep.num == 0) {
1403        DWC_WARN("%s, bad ep\n", __func__);
1404        return -EINVAL;
1405    }
1406
1407    pcd = ep->pcd;
1408
1409    if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
1410        DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
1411        DWC_WARN("%s, bogus device state\n", __func__);
1412        return -ESHUTDOWN;
1413    }
1414
1415    dwc_ep = &ep->dwc_ep;
1416
1417    dwc_otg_iso_ep_stop_transfer(GET_CORE_IF(pcd), dwc_ep);
1418
1419    kfree(dwc_ep->pkt_info);
1420
1421    SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
1422
1423    if(ep->iso_req != req) {
1424        return -EINVAL;
1425    }
1426
1427    req->status = -ECONNRESET;
1428
1429    SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
1430
1431
1432    ep->iso_req = 0;
1433
1434    return 0;
1435}
1436
1437/**
1438 * This function is used for perodical data exchnage between PCD and gadget drivers.
1439 * for Isochronous EPs
1440 *
1441 * - Every time a sync period completes this function is called to
1442 * perform data exchange between PCD and gadget
1443 */
1444void dwc_otg_iso_buffer_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_iso_request_t *req)
1445{
1446     int i;
1447    struct usb_gadget_iso_packet_descriptor *iso_packet;
1448    dwc_ep_t *dwc_ep;
1449
1450    dwc_ep = &ep->dwc_ep;
1451
1452    if(ep->iso_req->status == -ECONNRESET) {
1453        DWC_PRINT("Device has already disconnected\n");
1454        /*Device has been disconnected*/
1455        return;
1456    }
1457
1458    if(dwc_ep->proc_buf_num != 0) {
1459        iso_packet = ep->iso_req->iso_packet_desc0;
1460    }
1461
1462    else {
1463        iso_packet = ep->iso_req->iso_packet_desc1;
1464    }
1465
1466    /* Fill in ISOC packets descriptors & pass to gadget driver*/
1467
1468    for(i = 0; i < dwc_ep->pkt_cnt; ++i) {
1469        iso_packet[i].status = dwc_ep->pkt_info[i].status;
1470        iso_packet[i].offset = dwc_ep->pkt_info[i].offset;
1471        iso_packet[i].actual_length = dwc_ep->pkt_info[i].length;
1472        dwc_ep->pkt_info[i].status = 0;
1473        dwc_ep->pkt_info[i].offset = 0;
1474        dwc_ep->pkt_info[i].length = 0;
1475    }
1476
1477    /* Call callback function to process data buffer */
1478    ep->iso_req->status = 0;/* success */
1479
1480    SPIN_UNLOCK(&ep->pcd->lock);
1481    ep->iso_req->process_buffer(&ep->ep, ep->iso_req);
1482    SPIN_LOCK(&ep->pcd->lock);
1483}
1484
1485
1486static struct usb_iso_request *dwc_otg_pcd_alloc_iso_request(struct usb_ep *ep,int packets,
1487#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1488                int gfp_flags
1489#else
1490                gfp_t gfp_flags
1491#endif
1492)
1493{
1494    struct usb_iso_request *pReq = NULL;
1495    uint32_t req_size;
1496
1497
1498    req_size = sizeof(struct usb_iso_request);
1499    req_size += (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
1500
1501
1502    pReq = kmalloc(req_size, gfp_flags);
1503    if (!pReq) {
1504        DWC_WARN("%s, can't allocate Iso Request\n", __func__);
1505        return 0;
1506    }
1507    pReq->iso_packet_desc0 = (void*) (pReq + 1);
1508
1509    pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
1510
1511    return pReq;
1512}
1513
1514static void dwc_otg_pcd_free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
1515{
1516    kfree(req);
1517}
1518
1519static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops =
1520{
1521    .ep_ops =
1522    {
1523        .enable = dwc_otg_pcd_ep_enable,
1524        .disable = dwc_otg_pcd_ep_disable,
1525
1526        .alloc_request = dwc_otg_pcd_alloc_request,
1527        .free_request = dwc_otg_pcd_free_request,
1528
1529#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
1530        .alloc_buffer = dwc_otg_pcd_alloc_buffer,
1531        .free_buffer = dwc_otg_pcd_free_buffer,
1532#endif
1533
1534        .queue = dwc_otg_pcd_ep_queue,
1535        .dequeue = dwc_otg_pcd_ep_dequeue,
1536
1537        .set_halt = dwc_otg_pcd_ep_set_halt,
1538        .fifo_status = 0,
1539        .fifo_flush = 0,
1540    },
1541    .iso_ep_start = dwc_otg_pcd_iso_ep_start,
1542    .iso_ep_stop = dwc_otg_pcd_iso_ep_stop,
1543    .alloc_iso_request = dwc_otg_pcd_alloc_iso_request,
1544    .free_iso_request = dwc_otg_pcd_free_iso_request,
1545};
1546
1547#else
1548
1549
1550static struct usb_ep_ops dwc_otg_pcd_ep_ops =
1551{
1552    .enable = dwc_otg_pcd_ep_enable,
1553    .disable = dwc_otg_pcd_ep_disable,
1554
1555    .alloc_request = dwc_otg_pcd_alloc_request,
1556    .free_request = dwc_otg_pcd_free_request,
1557
1558#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
1559    .alloc_buffer = dwc_otg_pcd_alloc_buffer,
1560    .free_buffer = dwc_otg_pcd_free_buffer,
1561#endif
1562
1563    .queue = dwc_otg_pcd_ep_queue,
1564    .dequeue = dwc_otg_pcd_ep_dequeue,
1565
1566    .set_halt = dwc_otg_pcd_ep_set_halt,
1567    .fifo_status = 0,
1568    .fifo_flush = 0,
1569
1570
1571};
1572
1573#endif /* DWC_EN_ISOC */
1574/* Gadget Operations */
1575/**
1576 * The following gadget operations will be implemented in the DWC_otg
1577 * PCD. Functions in the API that are not described below are not
1578 * implemented.
1579 *
1580 * The Gadget API provides wrapper functions for each of the function
1581 * pointers defined in usb_gadget_ops. The Gadget Driver calls the
1582 * wrapper function, which then calls the underlying PCD function. The
1583 * following sections are named according to the wrapper functions
1584 * (except for ioctl, which doesn't have a wrapper function). Within
1585 * each section, the corresponding DWC_otg PCD function name is
1586 * specified.
1587 *
1588 */
1589
1590/**
1591 *Gets the USB Frame number of the last SOF.
1592 */
1593static int dwc_otg_pcd_get_frame(struct usb_gadget *gadget)
1594{
1595    dwc_otg_pcd_t *pcd;
1596
1597    DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, gadget);
1598
1599    if (gadget == 0) {
1600        return -ENODEV;
1601    }
1602    else {
1603        pcd = container_of(gadget, dwc_otg_pcd_t, gadget);
1604        dwc_otg_get_frame_number(GET_CORE_IF(pcd));
1605    }
1606
1607    return 0;
1608}
1609
1610void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t *pcd)
1611{
1612    uint32_t *addr = (uint32_t *)&(GET_CORE_IF(pcd)->core_global_regs->gotgctl);
1613    gotgctl_data_t mem;
1614    gotgctl_data_t val;
1615
1616    val.d32 = dwc_read_reg32(addr);
1617    if (val.b.sesreq) {
1618        DWC_ERROR("Session Request Already active!\n");
1619            return;
1620    }
1621
1622    DWC_NOTICE("Session Request Initated\n");
1623    mem.d32 = dwc_read_reg32(addr);
1624    mem.b.sesreq = 1;
1625    dwc_write_reg32(addr, mem.d32);
1626
1627    /* Start the SRP timer */
1628    dwc_otg_pcd_start_srp_timer(pcd);
1629    return;
1630}
1631
1632void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t *pcd, int set)
1633{
1634    dctl_data_t dctl = {.d32=0};
1635    volatile uint32_t *addr = &(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dctl);
1636
1637    if (dwc_otg_is_device_mode(GET_CORE_IF(pcd))) {
1638        if (pcd->remote_wakeup_enable) {
1639            if (set) {
1640                dctl.b.rmtwkupsig = 1;
1641                dwc_modify_reg32(addr, 0, dctl.d32);
1642                DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n");
1643                mdelay(1);
1644                dwc_modify_reg32(addr, dctl.d32, 0);
1645                DWC_DEBUGPL(DBG_PCD, "Clear Remote Wakeup\n");
1646            }
1647            else {
1648            }
1649        }
1650        else {
1651            DWC_DEBUGPL(DBG_PCD, "Remote Wakeup is disabled\n");
1652        }
1653    }
1654    return;
1655}
1656
1657/**
1658 * Initiates Session Request Protocol (SRP) to wakeup the host if no
1659 * session is in progress. If a session is already in progress, but
1660 * the device is suspended, remote wakeup signaling is started.
1661 *
1662 */
1663static int dwc_otg_pcd_wakeup(struct usb_gadget *gadget)
1664{
1665    unsigned long flags;
1666    dwc_otg_pcd_t *pcd;
1667    dsts_data_t dsts;
1668    gotgctl_data_t gotgctl;
1669
1670    DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, gadget);
1671
1672    if (gadget == 0) {
1673        return -ENODEV;
1674    }
1675    else {
1676        pcd = container_of(gadget, dwc_otg_pcd_t, gadget);
1677    }
1678    SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
1679
1680    /*
1681     * This function starts the Protocol if no session is in progress. If
1682     * a session is already in progress, but the device is suspended,
1683     * remote wakeup signaling is started.
1684     */
1685
1686    /* Check if valid session */
1687    gotgctl.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->core_global_regs->gotgctl));
1688    if (gotgctl.b.bsesvld) {
1689        /* Check if suspend state */
1690        dsts.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts));
1691        if (dsts.b.suspsts) {
1692            dwc_otg_pcd_remote_wakeup(pcd, 1);
1693        }
1694    }
1695    else {
1696        dwc_otg_pcd_initiate_srp(pcd);
1697    }
1698
1699    SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
1700    return 0;
1701}
1702
1703static const struct usb_gadget_ops dwc_otg_pcd_ops =
1704{
1705    .get_frame = dwc_otg_pcd_get_frame,
1706    .wakeup = dwc_otg_pcd_wakeup,
1707    // current versions must always be self-powered
1708};
1709
1710/**
1711 * This function updates the otg values in the gadget structure.
1712 */
1713void dwc_otg_pcd_update_otg(dwc_otg_pcd_t *pcd, const unsigned reset)
1714{
1715
1716    if (!pcd->gadget.is_otg)
1717        return;
1718
1719    if (reset) {
1720        pcd->b_hnp_enable = 0;
1721        pcd->a_hnp_support = 0;
1722        pcd->a_alt_hnp_support = 0;
1723    }
1724
1725    pcd->gadget.b_hnp_enable = pcd->b_hnp_enable;
1726    pcd->gadget.a_hnp_support = pcd->a_hnp_support;
1727    pcd->gadget.a_alt_hnp_support = pcd->a_alt_hnp_support;
1728}
1729
1730/**
1731 * This function is the top level PCD interrupt handler.
1732 */
1733static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev
1734#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
1735                   , struct pt_regs *r
1736#endif
1737                 )
1738{
1739    dwc_otg_pcd_t *pcd = dev;
1740    int32_t retval = IRQ_NONE;
1741
1742    retval = dwc_otg_pcd_handle_intr(pcd);
1743    return IRQ_RETVAL(retval);
1744}
1745
1746/**
1747 * PCD Callback function for initializing the PCD when switching to
1748 * device mode.
1749 *
1750 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
1751 */
1752static int32_t dwc_otg_pcd_start_cb(void *p)
1753{
1754    dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
1755
1756    /*
1757     * Initialized the Core for Device mode.
1758     */
1759    if (dwc_otg_is_device_mode(GET_CORE_IF(pcd))) {
1760        dwc_otg_core_dev_init(GET_CORE_IF(pcd));
1761    }
1762    return 1;
1763}
1764
1765/**
1766 * PCD Callback function for stopping the PCD when switching to Host
1767 * mode.
1768 *
1769 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
1770 */
1771static int32_t dwc_otg_pcd_stop_cb(void *p)
1772{
1773    dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
1774    extern void dwc_otg_pcd_stop(dwc_otg_pcd_t *_pcd);
1775
1776    dwc_otg_pcd_stop(pcd);
1777    return 1;
1778}
1779
1780
1781/**
1782 * PCD Callback function for notifying the PCD when resuming from
1783 * suspend.
1784 *
1785 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
1786 */
1787static int32_t dwc_otg_pcd_suspend_cb(void *p)
1788{
1789    dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
1790
1791    if (pcd->driver && pcd->driver->resume) {
1792        SPIN_UNLOCK(&pcd->lock);
1793        pcd->driver->suspend(&pcd->gadget);
1794        SPIN_LOCK(&pcd->lock);
1795    }
1796
1797    return 1;
1798}
1799
1800
1801/**
1802 * PCD Callback function for notifying the PCD when resuming from
1803 * suspend.
1804 *
1805 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
1806 */
1807static int32_t dwc_otg_pcd_resume_cb(void *p)
1808{
1809    dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
1810
1811    if (pcd->driver && pcd->driver->resume) {
1812            SPIN_UNLOCK(&pcd->lock);
1813            pcd->driver->resume(&pcd->gadget);
1814            SPIN_LOCK(&pcd->lock);
1815    }
1816
1817    /* Stop the SRP timeout timer. */
1818    if ((GET_CORE_IF(pcd)->core_params->phy_type != DWC_PHY_TYPE_PARAM_FS) ||
1819        (!GET_CORE_IF(pcd)->core_params->i2c_enable)) {
1820        if (GET_CORE_IF(pcd)->srp_timer_started) {
1821            GET_CORE_IF(pcd)->srp_timer_started = 0;
1822            del_timer(&pcd->srp_timer);
1823        }
1824    }
1825    return 1;
1826}
1827
1828
1829/**
1830 * PCD Callback structure for handling mode switching.
1831 */
1832static dwc_otg_cil_callbacks_t pcd_callbacks =
1833{
1834    .start = dwc_otg_pcd_start_cb,
1835    .stop = dwc_otg_pcd_stop_cb,
1836    .suspend = dwc_otg_pcd_suspend_cb,
1837    .resume_wakeup = dwc_otg_pcd_resume_cb,
1838    .p = 0, /* Set at registration */
1839};
1840
1841/**
1842 * This function is called when the SRP timer expires. The SRP should
1843 * complete within 6 seconds.
1844 */
1845static void srp_timeout(unsigned long ptr)
1846{
1847    gotgctl_data_t gotgctl;
1848    dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *)ptr;
1849    volatile uint32_t *addr = &core_if->core_global_regs->gotgctl;
1850
1851    gotgctl.d32 = dwc_read_reg32(addr);
1852
1853    core_if->srp_timer_started = 0;
1854
1855    if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
1856        (core_if->core_params->i2c_enable)) {
1857        DWC_PRINT("SRP Timeout\n");
1858
1859        if ((core_if->srp_success) &&
1860            (gotgctl.b.bsesvld)) {
1861            if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
1862                core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
1863            }
1864
1865            /* Clear Session Request */
1866            gotgctl.d32 = 0;
1867            gotgctl.b.sesreq = 1;
1868            dwc_modify_reg32(&core_if->core_global_regs->gotgctl,
1869                      gotgctl.d32, 0);
1870
1871            core_if->srp_success = 0;
1872        }
1873        else {
1874            DWC_ERROR("Device not connected/responding\n");
1875            gotgctl.b.sesreq = 0;
1876            dwc_write_reg32(addr, gotgctl.d32);
1877        }
1878    }
1879    else if (gotgctl.b.sesreq) {
1880        DWC_PRINT("SRP Timeout\n");
1881
1882        DWC_ERROR("Device not connected/responding\n");
1883        gotgctl.b.sesreq = 0;
1884        dwc_write_reg32(addr, gotgctl.d32);
1885    }
1886    else {
1887        DWC_PRINT(" SRP GOTGCTL=%0x\n", gotgctl.d32);
1888    }
1889}
1890
1891/**
1892 * Start the SRP timer to detect when the SRP does not complete within
1893 * 6 seconds.
1894 *
1895 * @param pcd the pcd structure.
1896 */
1897void dwc_otg_pcd_start_srp_timer(dwc_otg_pcd_t *pcd)
1898{
1899    struct timer_list *srp_timer = &pcd->srp_timer;
1900    GET_CORE_IF(pcd)->srp_timer_started = 1;
1901    init_timer(srp_timer);
1902    srp_timer->function = srp_timeout;
1903    srp_timer->data = (unsigned long)GET_CORE_IF(pcd);
1904    srp_timer->expires = jiffies + (HZ*6);
1905    add_timer(srp_timer);
1906}
1907
1908/**
1909 * Tasklet
1910 *
1911 */
1912extern void start_next_request(dwc_otg_pcd_ep_t *ep);
1913
1914static void start_xfer_tasklet_func (unsigned long data)
1915{
1916    dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t*)data;
1917    dwc_otg_core_if_t *core_if = pcd->otg_dev->core_if;
1918
1919    int i;
1920    depctl_data_t diepctl;
1921
1922    DWC_DEBUGPL(DBG_PCDV, "Start xfer tasklet\n");
1923
1924    diepctl.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
1925
1926    if (pcd->ep0.queue_sof) {
1927        pcd->ep0.queue_sof = 0;
1928        start_next_request (&pcd->ep0);
1929        // break;
1930    }
1931
1932    for (i=0; i<core_if->dev_if->num_in_eps; i++)
1933    {
1934        depctl_data_t diepctl;
1935        diepctl.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[i]->diepctl);
1936
1937        if (pcd->in_ep[i].queue_sof) {
1938            pcd->in_ep[i].queue_sof = 0;
1939            start_next_request (&pcd->in_ep[i]);
1940            // break;
1941        }
1942    }
1943
1944    return;
1945}
1946
1947
1948
1949
1950
1951
1952
1953static struct tasklet_struct start_xfer_tasklet = {
1954    .next = NULL,
1955    .state = 0,
1956    .count = ATOMIC_INIT(0),
1957    .func = start_xfer_tasklet_func,
1958    .data = 0,
1959};
1960/**
1961 * This function initialized the pcd Dp structures to there default
1962 * state.
1963 *
1964 * @param pcd the pcd structure.
1965 */
1966void dwc_otg_pcd_reinit(dwc_otg_pcd_t *pcd)
1967{
1968    static const char * names[] =
1969        {
1970
1971            "ep0",
1972            "ep1in",
1973            "ep2in",
1974            "ep3in",
1975            "ep4in",
1976            "ep5in",
1977            "ep6in",
1978            "ep7in",
1979            "ep8in",
1980            "ep9in",
1981            "ep10in",
1982            "ep11in",
1983            "ep12in",
1984            "ep13in",
1985            "ep14in",
1986            "ep15in",
1987            "ep1out",
1988            "ep2out",
1989            "ep3out",
1990            "ep4out",
1991            "ep5out",
1992            "ep6out",
1993            "ep7out",
1994            "ep8out",
1995            "ep9out",
1996            "ep10out",
1997            "ep11out",
1998            "ep12out",
1999            "ep13out",
2000            "ep14out",
2001            "ep15out"
2002
2003    };
2004
2005    int i;
2006    int in_ep_cntr, out_ep_cntr;
2007    uint32_t hwcfg1;
2008    uint32_t num_in_eps = (GET_CORE_IF(pcd))->dev_if->num_in_eps;
2009    uint32_t num_out_eps = (GET_CORE_IF(pcd))->dev_if->num_out_eps;
2010    dwc_otg_pcd_ep_t *ep;
2011
2012    DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
2013
2014    INIT_LIST_HEAD (&pcd->gadget.ep_list);
2015    pcd->gadget.ep0 = &pcd->ep0.ep;
2016    pcd->gadget.speed = USB_SPEED_UNKNOWN;
2017
2018    INIT_LIST_HEAD (&pcd->gadget.ep0->ep_list);
2019
2020    /**
2021     * Initialize the EP0 structure.
2022     */
2023    ep = &pcd->ep0;
2024
2025    /* Init EP structure */
2026    ep->desc = 0;
2027    ep->pcd = pcd;
2028    ep->stopped = 1;
2029
2030    /* Init DWC ep structure */
2031    ep->dwc_ep.num = 0;
2032    ep->dwc_ep.active = 0;
2033    ep->dwc_ep.tx_fifo_num = 0;
2034    /* Control until ep is actvated */
2035    ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
2036    ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
2037    ep->dwc_ep.dma_addr = 0;
2038    ep->dwc_ep.start_xfer_buff = 0;
2039    ep->dwc_ep.xfer_buff = 0;
2040    ep->dwc_ep.xfer_len = 0;
2041    ep->dwc_ep.xfer_count = 0;
2042    ep->dwc_ep.sent_zlp = 0;
2043    ep->dwc_ep.total_len = 0;
2044    ep->queue_sof = 0;
2045    ep->dwc_ep.desc_addr = 0;
2046    ep->dwc_ep.dma_desc_addr = 0;
2047
2048
2049    /* Init the usb_ep structure. */
2050    ep->ep.name = names[0];
2051    ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
2052
2053    /**
2054     * @todo NGS: What should the max packet size be set to
2055     * here? Before EP type is set?
2056     */
2057    ep->ep.maxpacket = MAX_PACKET_SIZE;
2058
2059    list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
2060
2061    INIT_LIST_HEAD (&ep->queue);
2062    /**
2063     * Initialize the EP structures.
2064     */
2065    in_ep_cntr = 0;
2066    hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 3;
2067
2068    for (i = 1; in_ep_cntr < num_in_eps; i++)
2069    {
2070        if((hwcfg1 & 0x1) == 0) {
2071            dwc_otg_pcd_ep_t *ep = &pcd->in_ep[in_ep_cntr];
2072            in_ep_cntr ++;
2073
2074            /* Init EP structure */
2075            ep->desc = 0;
2076            ep->pcd = pcd;
2077            ep->stopped = 1;
2078
2079            /* Init DWC ep structure */
2080            ep->dwc_ep.is_in = 1;
2081            ep->dwc_ep.num = i;
2082            ep->dwc_ep.active = 0;
2083            ep->dwc_ep.tx_fifo_num = 0;
2084
2085            /* Control until ep is actvated */
2086            ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
2087            ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
2088            ep->dwc_ep.dma_addr = 0;
2089            ep->dwc_ep.start_xfer_buff = 0;
2090            ep->dwc_ep.xfer_buff = 0;
2091            ep->dwc_ep.xfer_len = 0;
2092            ep->dwc_ep.xfer_count = 0;
2093            ep->dwc_ep.sent_zlp = 0;
2094            ep->dwc_ep.total_len = 0;
2095            ep->queue_sof = 0;
2096            ep->dwc_ep.desc_addr = 0;
2097            ep->dwc_ep.dma_desc_addr = 0;
2098
2099            /* Init the usb_ep structure. */
2100            ep->ep.name = names[i];
2101            ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
2102
2103            /**
2104             * @todo NGS: What should the max packet size be set to
2105             * here? Before EP type is set?
2106             */
2107            ep->ep.maxpacket = MAX_PACKET_SIZE;
2108
2109            list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
2110
2111            INIT_LIST_HEAD (&ep->queue);
2112        }
2113        hwcfg1 >>= 2;
2114    }
2115
2116    out_ep_cntr = 0;
2117    hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 2;
2118
2119    for (i = 1; out_ep_cntr < num_out_eps; i++)
2120    {
2121        if((hwcfg1 & 0x1) == 0) {
2122            dwc_otg_pcd_ep_t *ep = &pcd->out_ep[out_ep_cntr];
2123            out_ep_cntr++;
2124
2125            /* Init EP structure */
2126            ep->desc = 0;
2127            ep->pcd = pcd;
2128            ep->stopped = 1;
2129
2130            /* Init DWC ep structure */
2131            ep->dwc_ep.is_in = 0;
2132            ep->dwc_ep.num = i;
2133            ep->dwc_ep.active = 0;
2134            ep->dwc_ep.tx_fifo_num = 0;
2135            /* Control until ep is actvated */
2136            ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
2137            ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
2138            ep->dwc_ep.dma_addr = 0;
2139            ep->dwc_ep.start_xfer_buff = 0;
2140            ep->dwc_ep.xfer_buff = 0;
2141            ep->dwc_ep.xfer_len = 0;
2142            ep->dwc_ep.xfer_count = 0;
2143            ep->dwc_ep.sent_zlp = 0;
2144            ep->dwc_ep.total_len = 0;
2145            ep->queue_sof = 0;
2146
2147            /* Init the usb_ep structure. */
2148            ep->ep.name = names[15 + i];
2149            ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
2150            /**
2151             * @todo NGS: What should the max packet size be set to
2152             * here? Before EP type is set?
2153             */
2154            ep->ep.maxpacket = MAX_PACKET_SIZE;
2155
2156            list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
2157
2158            INIT_LIST_HEAD (&ep->queue);
2159        }
2160        hwcfg1 >>= 2;
2161    }
2162
2163    /* remove ep0 from the list. There is a ep0 pointer.*/
2164    list_del_init (&pcd->ep0.ep.ep_list);
2165
2166    pcd->ep0state = EP0_DISCONNECT;
2167    pcd->ep0.ep.maxpacket = MAX_EP0_SIZE;
2168    pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
2169    pcd->ep0.dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
2170}
2171
2172/**
2173 * This function releases the Gadget device.
2174 * required by device_unregister().
2175 *
2176 * @todo Should this do something? Should it free the PCD?
2177 */
2178static void dwc_otg_pcd_gadget_release(struct device *dev)
2179{
2180    DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, dev);
2181}
2182
2183
2184
2185/**
2186 * This function initialized the PCD portion of the driver.
2187 *
2188 */
2189
2190int dwc_otg_pcd_init(struct device *dev)
2191{
2192    static char pcd_name[] = "dwc_otg_pcd";
2193    dwc_otg_pcd_t *pcd;
2194    dwc_otg_core_if_t* core_if;
2195    dwc_otg_dev_if_t* dev_if;
2196    dwc_otg_device_t *otg_dev = dev_get_drvdata(dev);
2197    int retval = 0;
2198
2199
2200    DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n",__func__, dev);
2201    /*
2202     * Allocate PCD structure
2203     */
2204    pcd = kmalloc(sizeof(dwc_otg_pcd_t), GFP_KERNEL);
2205
2206    if (pcd == 0) {
2207        return -ENOMEM;
2208    }
2209
2210    memset(pcd, 0, sizeof(dwc_otg_pcd_t));
2211    spin_lock_init(&pcd->lock);
2212
2213    otg_dev->pcd = pcd;
2214    s_pcd = pcd;
2215    pcd->gadget.name = pcd_name;
2216#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
2217    strcpy(pcd->gadget.dev.bus_id, "gadget");
2218#else
2219    dev_set_name(&pcd->gadget.dev, "%s", "gadget");
2220#endif
2221
2222    pcd->otg_dev = dev_get_drvdata(dev);
2223
2224    pcd->gadget.dev.parent = dev;
2225    pcd->gadget.dev.release = dwc_otg_pcd_gadget_release;
2226    pcd->gadget.ops = &dwc_otg_pcd_ops;
2227
2228    core_if = GET_CORE_IF(pcd);
2229    dev_if = core_if->dev_if;
2230
2231    if(core_if->hwcfg4.b.ded_fifo_en) {
2232        DWC_PRINT("Dedicated Tx FIFOs mode\n");
2233    }
2234    else {
2235        DWC_PRINT("Shared Tx FIFO mode\n");
2236    }
2237
2238    /* If the module is set to FS or if the PHY_TYPE is FS then the gadget
2239     * should not report as dual-speed capable. replace the following line
2240     * with the block of code below it once the software is debugged for
2241     * this. If is_dualspeed = 0 then the gadget driver should not report
2242     * a device qualifier descriptor when queried. */
2243    if ((GET_CORE_IF(pcd)->core_params->speed == DWC_SPEED_PARAM_FULL) ||
2244        ((GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == 2) &&
2245         (GET_CORE_IF(pcd)->hwcfg2.b.fs_phy_type == 1) &&
2246         (GET_CORE_IF(pcd)->core_params->ulpi_fs_ls))) {
2247        pcd->gadget.is_dualspeed = 0;
2248    }
2249    else {
2250        pcd->gadget.is_dualspeed = 1;
2251    }
2252
2253    if ((otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE) ||
2254    (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST) ||
2255    (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
2256    (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
2257        pcd->gadget.is_otg = 0;
2258    }
2259    else {
2260        pcd->gadget.is_otg = 1;
2261    }
2262
2263
2264    pcd->driver = 0;
2265    /* Register the gadget device */
2266    retval = device_register(&pcd->gadget.dev);
2267    if (retval != 0) {
2268        kfree (pcd);
2269        return retval;
2270    }
2271
2272
2273    /*
2274     * Initialized the Core for Device mode.
2275     */
2276    if (dwc_otg_is_device_mode(core_if)) {
2277        dwc_otg_core_dev_init(core_if);
2278    }
2279
2280    /*
2281     * Initialize EP structures
2282     */
2283    dwc_otg_pcd_reinit(pcd);
2284
2285    /*
2286     * Register the PCD Callbacks.
2287     */
2288    dwc_otg_cil_register_pcd_callbacks(otg_dev->core_if, &pcd_callbacks,
2289                        pcd);
2290    /*
2291     * Setup interupt handler
2292     */
2293    DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", otg_dev->irq);
2294    retval = request_irq(otg_dev->irq, dwc_otg_pcd_irq,
2295                IRQF_SHARED, pcd->gadget.name, pcd);
2296    if (retval != 0) {
2297        DWC_ERROR("request of irq%d failed\n", otg_dev->irq);
2298        device_unregister(&pcd->gadget.dev);
2299        kfree (pcd);
2300        return -EBUSY;
2301    }
2302
2303    /*
2304     * Initialize the DMA buffer for SETUP packets
2305     */
2306    if (GET_CORE_IF(pcd)->dma_enable) {
2307        pcd->setup_pkt = dma_alloc_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, &pcd->setup_pkt_dma_handle, 0);
2308        if (pcd->setup_pkt == 0) {
2309            free_irq(otg_dev->irq, pcd);
2310            device_unregister(&pcd->gadget.dev);
2311            kfree (pcd);
2312            return -ENOMEM;
2313        }
2314
2315        pcd->status_buf = dma_alloc_coherent (NULL, sizeof (uint16_t), &pcd->status_buf_dma_handle, 0);
2316        if (pcd->status_buf == 0) {
2317            dma_free_coherent(NULL, sizeof(*pcd->setup_pkt), pcd->setup_pkt, pcd->setup_pkt_dma_handle);
2318            free_irq(otg_dev->irq, pcd);
2319            device_unregister(&pcd->gadget.dev);
2320            kfree (pcd);
2321            return -ENOMEM;
2322        }
2323
2324        if (GET_CORE_IF(pcd)->dma_desc_enable) {
2325            dev_if->setup_desc_addr[0] = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_setup_desc_addr[0], 1);
2326            dev_if->setup_desc_addr[1] = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_setup_desc_addr[1], 1);
2327            dev_if->in_desc_addr = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_in_desc_addr, 1);
2328            dev_if->out_desc_addr = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_out_desc_addr, 1);
2329
2330            if(dev_if->setup_desc_addr[0] == 0
2331            || dev_if->setup_desc_addr[1] == 0
2332            || dev_if->in_desc_addr == 0
2333            || dev_if->out_desc_addr == 0 ) {
2334
2335                if(dev_if->out_desc_addr)
2336                    dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, dev_if->dma_out_desc_addr, 1);
2337                if(dev_if->in_desc_addr)
2338                    dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, dev_if->dma_in_desc_addr, 1);
2339                if(dev_if->setup_desc_addr[1])
2340                    dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], dev_if->dma_setup_desc_addr[1], 1);
2341                if(dev_if->setup_desc_addr[0])
2342                    dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], dev_if->dma_setup_desc_addr[0], 1);
2343
2344
2345                dma_free_coherent(NULL, sizeof(*pcd->status_buf), pcd->status_buf, pcd->setup_pkt_dma_handle);
2346                dma_free_coherent(NULL, sizeof(*pcd->setup_pkt), pcd->setup_pkt, pcd->setup_pkt_dma_handle);
2347
2348                free_irq(otg_dev->irq, pcd);
2349                device_unregister(&pcd->gadget.dev);
2350                kfree (pcd);
2351
2352                return -ENOMEM;
2353            }
2354        }
2355    }
2356    else {
2357        pcd->setup_pkt = kmalloc (sizeof (*pcd->setup_pkt) * 5, GFP_KERNEL);
2358        if (pcd->setup_pkt == 0) {
2359            free_irq(otg_dev->irq, pcd);
2360            device_unregister(&pcd->gadget.dev);
2361            kfree (pcd);
2362            return -ENOMEM;
2363        }
2364
2365        pcd->status_buf = kmalloc (sizeof (uint16_t), GFP_KERNEL);
2366        if (pcd->status_buf == 0) {
2367            kfree(pcd->setup_pkt);
2368            free_irq(otg_dev->irq, pcd);
2369            device_unregister(&pcd->gadget.dev);
2370            kfree (pcd);
2371            return -ENOMEM;
2372        }
2373    }
2374
2375
2376    /* Initialize tasklet */
2377    start_xfer_tasklet.data = (unsigned long)pcd;
2378    pcd->start_xfer_tasklet = &start_xfer_tasklet;
2379
2380    return 0;
2381}
2382
2383/**
2384 * Cleanup the PCD.
2385 */
2386void dwc_otg_pcd_remove(struct device *dev)
2387{
2388    dwc_otg_device_t *otg_dev = dev_get_drvdata(dev);
2389    dwc_otg_pcd_t *pcd = otg_dev->pcd;
2390    dwc_otg_dev_if_t* dev_if = GET_CORE_IF(pcd)->dev_if;
2391
2392    DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
2393
2394    /*
2395     * Free the IRQ
2396     */
2397    free_irq(otg_dev->irq, pcd);
2398
2399     /* start with the driver above us */
2400    if (pcd->driver) {
2401        /* should have been done already by driver model core */
2402        DWC_WARN("driver '%s' is still registered\n",
2403                 pcd->driver->driver.name);
2404        usb_gadget_unregister_driver(pcd->driver);
2405    }
2406    device_unregister(&pcd->gadget.dev);
2407
2408    if (GET_CORE_IF(pcd)->dma_enable) {
2409        dma_free_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, pcd->setup_pkt, pcd->setup_pkt_dma_handle);
2410        dma_free_coherent (NULL, sizeof (uint16_t), pcd->status_buf, pcd->status_buf_dma_handle);
2411        if (GET_CORE_IF(pcd)->dma_desc_enable) {
2412            dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], dev_if->dma_setup_desc_addr[0], 1);
2413            dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], dev_if->dma_setup_desc_addr[1], 1);
2414            dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, dev_if->dma_in_desc_addr, 1);
2415            dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, dev_if->dma_out_desc_addr, 1);
2416        }
2417    }
2418    else {
2419        kfree (pcd->setup_pkt);
2420        kfree (pcd->status_buf);
2421    }
2422
2423    kfree(pcd);
2424    otg_dev->pcd = 0;
2425}
2426
2427/**
2428 * This function registers a gadget driver with the PCD.
2429 *
2430 * When a driver is successfully registered, it will receive control
2431 * requests including set_configuration(), which enables non-control
2432 * requests. then usb traffic follows until a disconnect is reported.
2433 * then a host may connect again, or the driver might get unbound.
2434 *
2435 * @param driver The driver being registered
2436 */
2437#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
2438int usb_gadget_probe_driver(struct usb_gadget_driver *driver, int (*bind)(struct usb_gadget *))
2439#else
2440int usb_gadget_register_driver(struct usb_gadget_driver *driver)
2441#endif
2442{
2443    int retval;
2444    int (*d_bind)(struct usb_gadget *);
2445#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
2446    d_bind = bind;
2447#else
2448    d_bind = driver->bind;
2449#endif
2450
2451    DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", driver->driver.name);
2452
2453    if (!driver || driver->speed == USB_SPEED_UNKNOWN ||
2454        !d_bind ||
2455        !driver->unbind ||
2456        !driver->disconnect ||
2457        !driver->setup) {
2458        DWC_DEBUGPL(DBG_PCDV,"EINVAL\n");
2459        return -EINVAL;
2460    }
2461    if (s_pcd == 0) {
2462        DWC_DEBUGPL(DBG_PCDV,"ENODEV\n");
2463        return -ENODEV;
2464    }
2465    if (s_pcd->driver != 0) {
2466        DWC_DEBUGPL(DBG_PCDV,"EBUSY (%p)\n", s_pcd->driver);
2467        return -EBUSY;
2468    }
2469
2470    /* hook up the driver */
2471    s_pcd->driver = driver;
2472    s_pcd->gadget.dev.driver = &driver->driver;
2473
2474    DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
2475    retval = d_bind(&s_pcd->gadget);
2476    if (retval) {
2477        DWC_ERROR("bind to driver %s --> error %d\n",
2478                    driver->driver.name, retval);
2479        s_pcd->driver = 0;
2480        s_pcd->gadget.dev.driver = 0;
2481        return retval;
2482    }
2483    DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
2484                    driver->driver.name);
2485    return 0;
2486}
2487
2488#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
2489EXPORT_SYMBOL(usb_gadget_probe_driver);
2490#else
2491EXPORT_SYMBOL(usb_gadget_register_driver);
2492#endif
2493
2494/**
2495 * This function unregisters a gadget driver
2496 *
2497 * @param driver The driver being unregistered
2498 */
2499int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
2500{
2501    //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
2502
2503    if (s_pcd == 0) {
2504        DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
2505                -ENODEV);
2506        return -ENODEV;
2507    }
2508    if (driver == 0 || driver != s_pcd->driver) {
2509        DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
2510                -EINVAL);
2511        return -EINVAL;
2512    }
2513
2514    driver->unbind(&s_pcd->gadget);
2515    s_pcd->driver = 0;
2516
2517    DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n",
2518            driver->driver.name);
2519    return 0;
2520}
2521EXPORT_SYMBOL(usb_gadget_unregister_driver);
2522
2523#endif /* DWC_HOST_ONLY */
2524

Archive Download this file



interactive