1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_linux.c $
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.
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.
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
32 * ========================================================================== */
36 * This file implements the Peripheral Controller Driver.
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
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.)
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>.
56 #include "dwc_otg_os_dep.h"
57 #include "dwc_otg_pcd_if.h"
58 #include "dwc_otg_pcd.h"
59 #include "dwc_otg_driver.h"
60 #include "dwc_otg_dbg.h"
62 extern bool fiq_enable;
64 static struct gadget_wrapper {
67 struct usb_gadget gadget;
68 struct usb_gadget_driver *driver;
71 struct usb_ep in_ep[16];
72 struct usb_ep out_ep[16];
76 /* Display the contents of the buffer */
77 extern void dump_msg(const u8 * buf, unsigned int length);
79 * Get the dwc_otg_pcd_ep_t* from usb_ep* pointer - NULL in case
80 * if the endpoint is not found
82 static struct dwc_otg_pcd_ep *ep_from_handle(dwc_otg_pcd_t * pcd, void *handle)
85 if (pcd->ep0.priv == handle) {
89 for (i = 0; i < MAX_EPS_CHANNELS - 1; i++) {
90 if (pcd->in_ep[i].priv == handle)
91 return &pcd->in_ep[i];
92 if (pcd->out_ep[i].priv == handle)
93 return &pcd->out_ep[i];
99 /* USB Endpoint Operations */
101 * The following sections briefly describe the behavior of the Gadget
102 * API endpoint operations implemented in the DWC_otg driver
103 * software. Detailed descriptions of the generic behavior of each of
104 * these functions can be found in the Linux header file
105 * include/linux/usb_gadget.h.
107 * The Gadget API provides wrapper functions for each of the function
108 * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
109 * function, which then calls the underlying PCD function. The
110 * following sections are named according to the wrapper
111 * functions. Within each section, the corresponding DWC_otg PCD
112 * function name is specified.
117 * This function is called by the Gadget Driver for each EP to be
118 * configured for the current configuration (SET_CONFIGURATION).
120 * This function initializes the dwc_otg_ep_t data structure, and then
121 * calls dwc_otg_ep_activate.
123 static int ep_enable(struct usb_ep *usb_ep,
124 const struct usb_endpoint_descriptor *ep_desc)
128 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, ep_desc);
130 if (!usb_ep || !ep_desc || ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
131 DWC_WARN("%s, bad ep or descriptor\n", __func__);
134 if (usb_ep == &gadget_wrapper->ep0) {
135 DWC_WARN("%s, bad ep(0)\n", __func__);
139 /* Check FIFO size? */
140 if (!ep_desc->wMaxPacketSize) {
141 DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
145 if (!gadget_wrapper->driver ||
146 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
147 DWC_WARN("%s, bogus device state\n", __func__);
151 /* Delete after check - MAS */
153 nat = (uint32_t) ep_desc->wMaxPacketSize;
154 printk(KERN_ALERT "%s: nat (before) =%d\n", __func__, nat);
155 nat = (nat >> 11) & 0x03;
156 printk(KERN_ALERT "%s: nat (after) =%d\n", __func__, nat);
158 retval = dwc_otg_pcd_ep_enable(gadget_wrapper->pcd,
159 (const uint8_t *)ep_desc,
162 DWC_WARN("dwc_otg_pcd_ep_enable failed\n");
166 usb_ep->maxpacket = le16_to_cpu(ep_desc->wMaxPacketSize);
172 * This function is called when an EP is disabled due to disconnect or
173 * change in configuration. Any pending requests will terminate with a
174 * status of -ESHUTDOWN.
176 * This function modifies the dwc_otg_ep_t data structure for this EP,
177 * and then calls dwc_otg_ep_deactivate.
179 static int ep_disable(struct usb_ep *usb_ep)
183 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, usb_ep);
185 DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
186 usb_ep ? usb_ep->name : NULL);
190 retval = dwc_otg_pcd_ep_disable(gadget_wrapper->pcd, usb_ep);
199 * This function allocates a request object to use with the specified
202 * @param ep The endpoint to be used with with the request
203 * @param gfp_flags the GFP_* flags to use.
205 static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
208 struct usb_request *usb_req;
210 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d)\n", __func__, ep, gfp_flags);
212 DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
215 usb_req = kzalloc(sizeof(*usb_req), gfp_flags);
217 DWC_WARN("%s() %s\n", __func__, "request allocation failed!\n");
220 usb_req->dma = DWC_DMA_ADDR_INVALID;
226 * This function frees a request object.
228 * @param ep The endpoint associated with the request
229 * @param req The request being freed
231 static void dwc_otg_pcd_free_request(struct usb_ep *ep, struct usb_request *req)
233 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, ep, req);
235 if (0 == ep || 0 == req) {
236 DWC_WARN("%s() %s\n", __func__,
237 "Invalid ep or req argument!\n");
244 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
246 * This function allocates an I/O buffer to be used for a transfer
247 * to/from the specified endpoint.
249 * @param usb_ep The endpoint to be used with with the request
250 * @param bytes The desired number of bytes for the buffer
251 * @param dma Pointer to the buffer's DMA address; must be valid
252 * @param gfp_flags the GFP_* flags to use.
253 * @return address of a new buffer or null is buffer could not be allocated.
255 static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes,
256 dma_addr_t * dma, gfp_t gfp_flags)
259 dwc_otg_pcd_t *pcd = 0;
261 pcd = gadget_wrapper->pcd;
263 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes,
266 /* Check dword alignment */
267 if ((bytes & 0x3UL) != 0) {
268 DWC_WARN("%s() Buffer size is not a multiple of"
269 "DWORD size (%d)", __func__, bytes);
272 buf = dma_alloc_coherent(NULL, bytes, dma, gfp_flags);
275 /* Check dword alignment */
276 if (((int)buf & 0x3UL) != 0) {
277 DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
285 * This function frees an I/O buffer that was allocated by alloc_buffer.
287 * @param usb_ep the endpoint associated with the buffer
288 * @param buf address of the buffer
289 * @param dma The buffer's DMA address
290 * @param bytes The number of bytes of the buffer
292 static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf,
293 dma_addr_t dma, unsigned bytes)
295 dwc_otg_pcd_t *pcd = 0;
297 pcd = gadget_wrapper->pcd;
299 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%0x,%d)\n", __func__, buf, dma, bytes);
301 dma_free_coherent(NULL, bytes, buf, dma);
306 * This function is used to submit an I/O Request to an EP.
308 * - When the request completes the request's completion callback
309 * is called to return the request to the driver.
310 * - An EP, except control EPs, may have multiple requests
312 * - Once submitted the request cannot be examined or modified.
313 * - Each request is turned into one or more packets.
314 * - A BULK EP can queue any amount of data; the transfer is
316 * - Zero length Packets are specified with the request 'zero'
319 static int ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req,
323 struct dwc_otg_pcd_ep *ep = NULL;
324 int retval = 0, is_isoc_ep = 0;
325 dma_addr_t dma_addr = DWC_DMA_ADDR_INVALID;
327 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p,%d)\n",
328 __func__, usb_ep, usb_req, gfp_flags);
330 if (!usb_req || !usb_req->complete || !usb_req->buf) {
331 DWC_WARN("bad params\n");
336 DWC_WARN("bad ep\n");
340 pcd = gadget_wrapper->pcd;
341 if (!gadget_wrapper->driver ||
342 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
343 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
344 gadget_wrapper->gadget.speed);
345 DWC_WARN("bogus device state\n");
349 DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
350 usb_ep->name, usb_req, usb_req->length, usb_req->buf);
352 usb_req->status = -EINPROGRESS;
355 ep = ep_from_handle(pcd, usb_ep);
359 is_isoc_ep = (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) ? 1 : 0;
360 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
361 dma_addr = usb_req->dma;
363 if (GET_CORE_IF(pcd)->dma_enable) {
364 dwc_otg_device_t *otg_dev = gadget_wrapper->pcd->otg_dev;
365 struct device *dev = NULL;
368 dev = DWC_OTG_OS_GETDEV(otg_dev->os_dep);
370 if (usb_req->length != 0 &&
371 usb_req->dma == DWC_DMA_ADDR_INVALID) {
372 dma_addr = dma_map_single(dev, usb_req->buf,
381 #ifdef DWC_UTE_PER_IO
382 if (is_isoc_ep == 1) {
383 retval = dwc_otg_pcd_xiso_ep_queue(pcd, usb_ep, usb_req->buf, dma_addr,
384 usb_req->length, usb_req->zero, usb_req,
385 gfp_flags == GFP_ATOMIC ? 1 : 0, &usb_req->ext_req);
392 retval = dwc_otg_pcd_ep_queue(pcd, usb_ep, usb_req->buf, dma_addr,
393 usb_req->length, usb_req->zero, usb_req,
394 gfp_flags == GFP_ATOMIC ? 1 : 0);
403 * This function cancels an I/O request from an EP.
405 static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req)
407 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, usb_req);
409 if (!usb_ep || !usb_req) {
410 DWC_WARN("bad argument\n");
413 if (!gadget_wrapper->driver ||
414 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
415 DWC_WARN("bogus device state\n");
418 if (dwc_otg_pcd_ep_dequeue(gadget_wrapper->pcd, usb_ep, usb_req)) {
426 * usb_ep_set_halt stalls an endpoint.
428 * usb_ep_clear_halt clears an endpoint halt and resets its data
431 * Both of these functions are implemented with the same underlying
432 * function. The behavior depends on the value argument.
434 * @param[in] usb_ep the Endpoint to halt or clear halt.
436 * - 0 means clear_halt.
437 * - 1 means set_halt,
438 * - 2 means clear stall lock flag.
439 * - 3 means set stall lock flag.
441 static int ep_halt(struct usb_ep *usb_ep, int value)
445 DWC_DEBUGPL(DBG_PCD, "HALT %s %d\n", usb_ep->name, value);
448 DWC_WARN("bad ep\n");
452 retval = dwc_otg_pcd_ep_halt(gadget_wrapper->pcd, usb_ep, value);
453 if (retval == -DWC_E_AGAIN) {
462 //#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
465 * ep_wedge: sets the halt feature and ignores clear requests
467 * @usb_ep: the endpoint being wedged
469 * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT)
470 * requests. If the gadget driver clears the halt status, it will
471 * automatically unwedge the endpoint.
473 * Returns zero on success, else negative errno. *
474 * Check usb_ep_set_wedge() at "usb_gadget.h" for details
476 static int ep_wedge(struct usb_ep *usb_ep)
480 DWC_DEBUGPL(DBG_PCD, "WEDGE %s\n", usb_ep->name);
483 DWC_WARN("bad ep\n");
487 retval = dwc_otg_pcd_ep_wedge(gadget_wrapper->pcd, usb_ep);
488 if (retval == -DWC_E_AGAIN) {
500 * This function is used to submit an ISOC Transfer Request to an EP.
502 * - Every time a sync period completes the request's completion callback
503 * is called to provide data to the gadget driver.
504 * - Once submitted the request cannot be modified.
505 * - Each request is turned into periodic data packets untill ISO
506 * Transfer is stopped..
508 static int iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
513 if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
514 DWC_WARN("bad params\n");
519 DWC_PRINTF("bad params\n");
523 req->status = -EINPROGRESS;
526 dwc_otg_pcd_iso_ep_start(gadget_wrapper->pcd, usb_ep, req->buf0,
527 req->buf1, req->dma0, req->dma1,
528 req->sync_frame, req->data_pattern_frame,
531 flags & USB_REQ_ISO_ASAP ? -1 :
532 req->start_frame, req->buf_proc_intrvl,
533 req, gfp_flags == GFP_ATOMIC ? 1 : 0);
543 * This function stops ISO EP Periodic Data Transfer.
545 static int iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
549 DWC_WARN("bad ep\n");
552 if (!gadget_wrapper->driver ||
553 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
554 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
555 gadget_wrapper->gadget.speed);
556 DWC_WARN("bogus device state\n");
559 dwc_otg_pcd_iso_ep_stop(gadget_wrapper->pcd, usb_ep, req);
567 static struct usb_iso_request *alloc_iso_request(struct usb_ep *ep,
568 int packets, gfp_t gfp_flags)
570 struct usb_iso_request *pReq = NULL;
573 req_size = sizeof(struct usb_iso_request);
575 (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
577 pReq = kmalloc(req_size, gfp_flags);
579 DWC_WARN("Can't allocate Iso Request\n");
582 pReq->iso_packet_desc0 = (void *)(pReq + 1);
584 pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
589 static void free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
594 static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops = {
597 .disable = ep_disable,
599 .alloc_request = dwc_otg_pcd_alloc_request,
600 .free_request = dwc_otg_pcd_free_request,
602 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
603 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
604 .free_buffer = dwc_otg_pcd_free_buffer,
608 .dequeue = ep_dequeue,
614 .iso_ep_start = iso_ep_start,
615 .iso_ep_stop = iso_ep_stop,
616 .alloc_iso_request = alloc_iso_request,
617 .free_iso_request = free_iso_request,
622 int (*enable) (struct usb_ep *ep,
623 const struct usb_endpoint_descriptor *desc);
624 int (*disable) (struct usb_ep *ep);
626 struct usb_request *(*alloc_request) (struct usb_ep *ep,
628 void (*free_request) (struct usb_ep *ep, struct usb_request *req);
630 int (*queue) (struct usb_ep *ep, struct usb_request *req,
632 int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
634 int (*set_halt) (struct usb_ep *ep, int value);
635 int (*set_wedge) (struct usb_ep *ep);
637 int (*fifo_status) (struct usb_ep *ep);
638 void (*fifo_flush) (struct usb_ep *ep);
639 static struct usb_ep_ops dwc_otg_pcd_ep_ops = {
641 .disable = ep_disable,
643 .alloc_request = dwc_otg_pcd_alloc_request,
644 .free_request = dwc_otg_pcd_free_request,
646 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
647 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
648 .free_buffer = dwc_otg_pcd_free_buffer,
650 /* .set_wedge = ep_wedge, */
651 .set_wedge = NULL, /* uses set_halt instead */
655 .dequeue = ep_dequeue,
663 #endif /* _EN_ISOC_ */
664 /* Gadget Operations */
666 * The following gadget operations will be implemented in the DWC_otg
667 * PCD. Functions in the API that are not described below are not
670 * The Gadget API provides wrapper functions for each of the function
671 * pointers defined in usb_gadget_ops. The Gadget Driver calls the
672 * wrapper function, which then calls the underlying PCD function. The
673 * following sections are named according to the wrapper functions
674 * (except for ioctl, which doesn't have a wrapper function). Within
675 * each section, the corresponding DWC_otg PCD function name is
681 *Gets the USB Frame number of the last SOF.
683 static int get_frame_number(struct usb_gadget *gadget)
685 struct gadget_wrapper *d;
687 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
693 d = container_of(gadget, struct gadget_wrapper, gadget);
694 return dwc_otg_pcd_get_frame_number(d->pcd);
697 #ifdef CONFIG_USB_DWC_OTG_LPM
698 static int test_lpm_enabled(struct usb_gadget *gadget)
700 struct gadget_wrapper *d;
702 d = container_of(gadget, struct gadget_wrapper, gadget);
704 return dwc_otg_pcd_is_lpm_enabled(d->pcd);
709 * Initiates Session Request Protocol (SRP) to wakeup the host if no
710 * session is in progress. If a session is already in progress, but
711 * the device is suspended, remote wakeup signaling is started.
714 static int wakeup(struct usb_gadget *gadget)
716 struct gadget_wrapper *d;
718 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
723 d = container_of(gadget, struct gadget_wrapper, gadget);
725 dwc_otg_pcd_wakeup(d->pcd);
729 static const struct usb_gadget_ops dwc_otg_pcd_ops = {
730 .get_frame = get_frame_number,
732 #ifdef CONFIG_USB_DWC_OTG_LPM
733 .lpm_support = test_lpm_enabled,
735 // current versions must always be self-powered
738 static int _setup(dwc_otg_pcd_t * pcd, uint8_t * bytes)
740 int retval = -DWC_E_NOT_SUPPORTED;
741 if (gadget_wrapper->driver && gadget_wrapper->driver->setup) {
742 retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget,
743 (struct usb_ctrlrequest
747 if (retval == -ENOTSUPP) {
748 retval = -DWC_E_NOT_SUPPORTED;
749 } else if (retval < 0) {
750 retval = -DWC_E_INVALID;
757 static int _isoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
758 void *req_handle, int proc_buf_num)
761 struct usb_gadget_iso_packet_descriptor *iso_packet = 0;
762 struct usb_iso_request *iso_req = req_handle;
765 iso_packet = iso_req->iso_packet_desc1;
767 iso_packet = iso_req->iso_packet_desc0;
770 dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle);
771 for (i = 0; i < packet_count; ++i) {
775 dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle,
776 i, &status, &actual, &offset);
783 DWC_PRINTF("unknown status in isoc packet\n");
787 iso_packet[i].status = status;
788 iso_packet[i].offset = offset;
789 iso_packet[i].actual_length = actual;
793 iso_req->process_buffer(ep_handle, iso_req);
797 #endif /* DWC_EN_ISOC */
799 #ifdef DWC_UTE_PER_IO
801 * Copy the contents of the extended request to the Linux usb_request's
802 * extended part and call the gadget's completion.
804 * @param pcd Pointer to the pcd structure
805 * @param ep_handle Void pointer to the usb_ep structure
806 * @param req_handle Void pointer to the usb_request structure
807 * @param status Request status returned from the portable logic
808 * @param ereq_port Void pointer to the extended request structure
809 * created in the the portable part that contains the
810 * results of the processed iso packets.
812 static int _xisoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
813 void *req_handle, int32_t status, void *ereq_port)
815 struct dwc_ute_iso_req_ext *ereqorg = NULL;
816 struct dwc_iso_xreq_port *ereqport = NULL;
817 struct dwc_ute_iso_packet_descriptor *desc_org = NULL;
819 struct usb_request *req;
820 //struct dwc_ute_iso_packet_descriptor *
823 req = (struct usb_request *)req_handle;
824 ereqorg = &req->ext_req;
825 ereqport = (struct dwc_iso_xreq_port *)ereq_port;
826 desc_org = ereqorg->per_io_frame_descs;
828 if (req && req->complete) {
829 /* Copy the request data from the portable logic to our request */
830 for (i = 0; i < ereqport->pio_pkt_count; i++) {
831 desc_org[i].actual_length =
832 ereqport->per_io_frame_descs[i].actual_length;
834 ereqport->per_io_frame_descs[i].status;
838 case -DWC_E_SHUTDOWN:
839 req->status = -ESHUTDOWN;
842 req->status = -ECONNRESET;
845 req->status = -EINVAL;
848 req->status = -ETIMEDOUT;
851 req->status = status;
854 /* And call the gadget's completion */
855 req->complete(ep_handle, req);
860 #endif /* DWC_UTE_PER_IO */
862 static int _complete(dwc_otg_pcd_t * pcd, void *ep_handle,
863 void *req_handle, int32_t status, uint32_t actual)
865 struct usb_request *req = (struct usb_request *)req_handle;
866 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)
867 struct dwc_otg_pcd_ep *ep = NULL;
870 if (req && req->complete) {
872 case -DWC_E_SHUTDOWN:
873 req->status = -ESHUTDOWN;
876 req->status = -ECONNRESET;
879 req->status = -EINVAL;
882 req->status = -ETIMEDOUT;
885 req->status = status;
889 req->actual = actual;
890 DWC_SPINUNLOCK(pcd->lock);
891 req->complete(ep_handle, req);
892 DWC_SPINLOCK(pcd->lock);
894 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)
895 ep = ep_from_handle(pcd, ep_handle);
896 if (GET_CORE_IF(pcd)->dma_enable) {
897 if (req->length != 0) {
898 dwc_otg_device_t *otg_dev = gadget_wrapper->pcd->otg_dev;
899 struct device *dev = NULL;
902 dev = DWC_OTG_OS_GETDEV(otg_dev->os_dep);
904 dma_unmap_single(dev, req->dma, req->length,
906 DMA_TO_DEVICE: DMA_FROM_DEVICE);
914 static int _connect(dwc_otg_pcd_t * pcd, int speed)
916 gadget_wrapper->gadget.speed = speed;
920 static int _disconnect(dwc_otg_pcd_t * pcd)
922 if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) {
923 gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget);
928 static int _resume(dwc_otg_pcd_t * pcd)
930 if (gadget_wrapper->driver && gadget_wrapper->driver->resume) {
931 gadget_wrapper->driver->resume(&gadget_wrapper->gadget);
937 static int _suspend(dwc_otg_pcd_t * pcd)
939 if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) {
940 gadget_wrapper->driver->suspend(&gadget_wrapper->gadget);
946 * This function updates the otg values in the gadget structure.
948 static int _hnp_changed(dwc_otg_pcd_t * pcd)
951 if (!gadget_wrapper->gadget.is_otg)
954 gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd);
955 gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd);
956 gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd);
960 static int _reset(dwc_otg_pcd_t * pcd)
966 static int _cfi_setup(dwc_otg_pcd_t * pcd, void *cfi_req)
968 int retval = -DWC_E_INVALID;
969 if (gadget_wrapper->driver->cfi_feature_setup) {
971 gadget_wrapper->driver->
972 cfi_feature_setup(&gadget_wrapper->gadget,
973 (struct cfi_usb_ctrlrequest *)cfi_req);
980 static const struct dwc_otg_pcd_function_ops fops = {
981 .complete = _complete,
983 .isoc_complete = _isoc_complete,
986 .disconnect = _disconnect,
990 .hnp_changed = _hnp_changed,
993 .cfi_setup = _cfi_setup,
995 #ifdef DWC_UTE_PER_IO
996 .xisoc_complete = _xisoc_complete,
1001 * This function is the top level PCD interrupt handler.
1003 static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev)
1005 dwc_otg_pcd_t *pcd = dev;
1006 int32_t retval = IRQ_NONE;
1008 retval = dwc_otg_pcd_handle_intr(pcd);
1010 S3C2410X_CLEAR_EINTPEND();
1012 return IRQ_RETVAL(retval);
1016 * This function initialized the usb_ep structures to there default
1019 * @param d Pointer on gadget_wrapper.
1021 void gadget_add_eps(struct gadget_wrapper *d)
1023 static const char *names[] = {
1060 int8_t dev_endpoints;
1062 DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__);
1064 INIT_LIST_HEAD(&d->gadget.ep_list);
1065 d->gadget.ep0 = &d->ep0;
1066 d->gadget.speed = USB_SPEED_UNKNOWN;
1068 INIT_LIST_HEAD(&d->gadget.ep0->ep_list);
1071 * Initialize the EP0 structure.
1075 /* Init the usb_ep structure. */
1076 ep->name = names[0];
1077 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1080 * @todo NGS: What should the max packet size be set to
1081 * here? Before EP type is set?
1083 ep->maxpacket = MAX_PACKET_SIZE;
1084 dwc_otg_pcd_ep_enable(d->pcd, NULL, ep);
1086 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1089 * Initialize the EP structures.
1091 dev_endpoints = d->pcd->core_if->dev_if->num_in_eps;
1093 for (i = 0; i < dev_endpoints; i++) {
1096 /* Init the usb_ep structure. */
1097 ep->name = names[d->pcd->in_ep[i].dwc_ep.num];
1098 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1101 * @todo NGS: What should the max packet size be set to
1102 * here? Before EP type is set?
1104 ep->maxpacket = MAX_PACKET_SIZE;
1105 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1108 dev_endpoints = d->pcd->core_if->dev_if->num_out_eps;
1110 for (i = 0; i < dev_endpoints; i++) {
1113 /* Init the usb_ep structure. */
1114 ep->name = names[15 + d->pcd->out_ep[i].dwc_ep.num];
1115 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
1118 * @todo NGS: What should the max packet size be set to
1119 * here? Before EP type is set?
1121 ep->maxpacket = MAX_PACKET_SIZE;
1123 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
1126 /* remove ep0 from the list. There is a ep0 pointer. */
1127 list_del_init(&d->ep0.ep_list);
1129 d->ep0.maxpacket = MAX_EP0_SIZE;
1133 * This function releases the Gadget device.
1134 * required by device_unregister().
1136 * @todo Should this do something? Should it free the PCD?
1138 static void dwc_otg_pcd_gadget_release(struct device *dev)
1140 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
1143 static struct gadget_wrapper *alloc_wrapper(dwc_bus_dev_t *_dev)
1145 static char pcd_name[] = "dwc_otg_pcd";
1146 dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
1147 struct gadget_wrapper *d;
1150 d = DWC_ALLOC(sizeof(*d));
1155 memset(d, 0, sizeof(*d));
1157 d->gadget.name = pcd_name;
1158 d->pcd = otg_dev->pcd;
1160 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
1161 strcpy(d->gadget.dev.bus_id, "gadget");
1163 dev_set_name(&d->gadget.dev, "%s", "gadget");
1166 d->gadget.dev.parent = &_dev->dev;
1167 d->gadget.dev.release = dwc_otg_pcd_gadget_release;
1168 d->gadget.ops = &dwc_otg_pcd_ops;
1169 d->gadget.max_speed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd) ? USB_SPEED_HIGH:USB_SPEED_FULL;
1170 d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
1173 /* Register the gadget device */
1174 retval = device_register(&d->gadget.dev);
1176 DWC_ERROR("device_register failed\n");
1184 static void free_wrapper(struct gadget_wrapper *d)
1187 /* should have been done already by driver model core */
1188 DWC_WARN("driver '%s' is still registered\n",
1189 d->driver->driver.name);
1190 #ifdef CONFIG_USB_GADGET
1191 usb_gadget_unregister_driver(d->driver);
1195 device_unregister(&d->gadget.dev);
1200 * This function initialized the PCD portion of the driver.
1203 int pcd_init(dwc_bus_dev_t *_dev)
1205 dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
1208 DWC_DEBUGPL(DBG_PCDV, "%s(%p) otg_dev=%p\n", __func__, _dev, otg_dev);
1210 otg_dev->pcd = dwc_otg_pcd_init(otg_dev);
1212 if (!otg_dev->pcd) {
1213 DWC_ERROR("dwc_otg_pcd_init failed\n");
1217 otg_dev->pcd->otg_dev = otg_dev;
1218 gadget_wrapper = alloc_wrapper(_dev);
1221 * Initialize EP structures
1223 gadget_add_eps(gadget_wrapper);
1225 * Setup interupt handler
1227 DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n",
1228 otg_dev->os_dep.irq_num);
1229 retval = request_irq(otg_dev->os_dep.irq_num, dwc_otg_pcd_irq,
1230 IRQF_SHARED, gadget_wrapper->gadget.name,
1233 DWC_ERROR("request of irq%d failed\n", otg_dev->os_dep.irq_num);
1234 free_wrapper(gadget_wrapper);
1238 dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
1246 void pcd_remove(dwc_bus_dev_t *_dev)
1248 dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
1249 dwc_otg_pcd_t *pcd = otg_dev->pcd;
1251 DWC_DEBUGPL(DBG_PCDV, "%s(%p) otg_dev %p\n", __func__, _dev, otg_dev);
1256 free_irq(otg_dev->os_dep.irq_num, pcd);
1257 dwc_otg_pcd_remove(otg_dev->pcd);
1258 free_wrapper(gadget_wrapper);
1262 #endif /* DWC_HOST_ONLY */