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

Archive Download this file



interactive