00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef DWC_HOST_ONLY
00034
00056 #include <linux/kernel.h>
00057 #include <linux/module.h>
00058 #include <linux/moduleparam.h>
00059 #include <linux/init.h>
00060 #include <linux/device.h>
00061 #include <linux/errno.h>
00062 #include <linux/list.h>
00063 #include <linux/interrupt.h>
00064 #include <linux/string.h>
00065 #include <linux/dma-mapping.h>
00066 #include <linux/version.h>
00067
00068 #ifdef LM_INTERFACE
00069 # include <asm/arch/regs-irq.h>
00070 # include <asm/arch/lm.h>
00071 # include <asm/arch/irqs.h>
00072 #endif
00073
00074 #include <asm/io.h>
00075 # include <linux/usb_ch9.h>
00076 #include <linux/usb_gadget.h>
00077
00078 #include "dwc_otg_pcd_if.h"
00079 #include "dwc_otg_driver.h"
00080 #include "dwc_otg_dbg.h"
00081
00082 static struct gadget_wrapper {
00083 dwc_otg_pcd_t *pcd;
00084
00085 struct usb_gadget gadget;
00086 struct usb_gadget_driver *driver;
00087
00088 struct usb_ep ep0;
00089 struct usb_ep in_ep[16];
00090 struct usb_ep out_ep[16];
00091
00092 } *gadget_wrapper;
00093
00094
00095 extern void dump_msg(const u8 * buf, unsigned int length);
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00121 static int ep_enable(struct usb_ep *usb_ep,
00122 const struct usb_endpoint_descriptor *ep_desc)
00123 {
00124 int retval;
00125
00126 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, ep_desc);
00127
00128 if (!usb_ep || !ep_desc || ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
00129 DWC_WARN("%s, bad ep or descriptor\n", __func__);
00130 return -EINVAL;
00131 }
00132 if (usb_ep == &gadget_wrapper->ep0) {
00133 DWC_WARN("%s, bad ep(0)\n", __func__);
00134 return -EINVAL;
00135 }
00136
00137
00138 if (!ep_desc->wMaxPacketSize) {
00139 DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
00140 return -ERANGE;
00141 }
00142
00143 if (!gadget_wrapper->driver ||
00144 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
00145 DWC_WARN("%s, bogus device state\n", __func__);
00146 return -ESHUTDOWN;
00147 }
00148
00149 retval = dwc_otg_pcd_ep_enable(gadget_wrapper->pcd,
00150 (const uint8_t *)ep_desc,
00151 (void *)usb_ep);
00152 if (retval) {
00153 DWC_WARN("dwc_otg_pcd_ep_enable failed\n");
00154 return -EINVAL;
00155 }
00156
00157 usb_ep->maxpacket = le16_to_cpu(ep_desc->wMaxPacketSize);
00158
00159 return 0;
00160 }
00161
00170 static int ep_disable(struct usb_ep *usb_ep)
00171 {
00172 int retval;
00173
00174 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, usb_ep);
00175 if (!usb_ep) {
00176 DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
00177 usb_ep ? usb_ep->name : NULL);
00178 return -EINVAL;
00179 }
00180
00181 retval = dwc_otg_pcd_ep_disable(gadget_wrapper->pcd, usb_ep);
00182 if (retval) {
00183 retval = -EINVAL;
00184 }
00185
00186 return retval;
00187 }
00188
00196 static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
00197 gfp_t gfp_flags)
00198 {
00199 struct usb_request *usb_req;
00200
00201 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d)\n", __func__, ep, gfp_flags);
00202 if (0 == ep) {
00203 DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
00204 return 0;
00205 }
00206 usb_req = kmalloc(sizeof(*usb_req), gfp_flags);
00207 if (0 == usb_req) {
00208 DWC_WARN("%s() %s\n", __func__, "request allocation failed!\n");
00209 return 0;
00210 }
00211 memset(usb_req, 0, sizeof(*usb_req));
00212 usb_req->dma = DWC_INVALID_DMA_ADDR;
00213
00214 return usb_req;
00215 }
00216
00223 static void dwc_otg_pcd_free_request(struct usb_ep *ep, struct usb_request *req)
00224 {
00225 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, ep, req);
00226
00227 if (0 == ep || 0 == req) {
00228 DWC_WARN("%s() %s\n", __func__,
00229 "Invalid ep or req argument!\n");
00230 return;
00231 }
00232
00233 kfree(req);
00234 }
00235
00246 static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes,
00247 dma_addr_t * dma, gfp_t gfp_flags)
00248 {
00249 void *buf;
00250 dwc_otg_pcd_t *pcd = 0;
00251
00252 pcd = gadget_wrapper->pcd;
00253
00254 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes,
00255 dma, gfp_flags);
00256
00257
00258 if ((bytes & 0x3UL) != 0) {
00259 DWC_WARN("%s() Buffer size is not a multiple of"
00260 "DWORD size (%d)", __func__, bytes);
00261 }
00262
00263 buf = dma_alloc_coherent(NULL, bytes, dma, gfp_flags);
00264
00265
00266 if (((int)buf & 0x3UL) != 0) {
00267 DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
00268 __func__, buf);
00269 }
00270
00271 return buf;
00272 }
00273
00282 static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf,
00283 dma_addr_t dma, unsigned bytes)
00284 {
00285 dwc_otg_pcd_t *pcd = 0;
00286
00287 pcd = gadget_wrapper->pcd;
00288
00289 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%0x,%d)\n", __func__, buf, dma, bytes);
00290
00291 dma_free_coherent(NULL, bytes, buf, dma);
00292 }
00293
00308 static int ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req,
00309 gfp_t gfp_flags)
00310 {
00311 dwc_otg_pcd_t *pcd;
00312 int retval;
00313
00314 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p,%d)\n",
00315 __func__, usb_ep, usb_req, gfp_flags);
00316
00317 if (!usb_req || !usb_req->complete || !usb_req->buf) {
00318 DWC_WARN("bad params\n");
00319 return -EINVAL;
00320 }
00321
00322 if (!usb_ep) {
00323 DWC_WARN("bad ep\n");
00324 return -EINVAL;
00325 }
00326
00327 pcd = gadget_wrapper->pcd;
00328 if (!gadget_wrapper->driver ||
00329 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
00330 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
00331 gadget_wrapper->gadget.speed);
00332 DWC_WARN("bogus device state\n");
00333 return -ESHUTDOWN;
00334 }
00335
00336 DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
00337 usb_ep->name, usb_req, usb_req->length, usb_req->buf);
00338
00339 usb_req->status = -EINPROGRESS;
00340 usb_req->actual = 0;
00341
00342 retval = dwc_otg_pcd_ep_queue(pcd, usb_ep, usb_req->buf, usb_req->dma,
00343 usb_req->length, usb_req->zero, usb_req,
00344 gfp_flags == GFP_ATOMIC ? 1 : 0);
00345 if (retval) {
00346 return -EINVAL;
00347 }
00348
00349 return 0;
00350 }
00351
00355 static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req)
00356 {
00357 DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, usb_req);
00358
00359 if (!usb_ep || !usb_req) {
00360 DWC_WARN("bad argument\n");
00361 return -EINVAL;
00362 }
00363 if (!gadget_wrapper->driver ||
00364 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
00365 DWC_WARN("bogus device state\n");
00366 return -ESHUTDOWN;
00367 }
00368 if (dwc_otg_pcd_ep_dequeue(gadget_wrapper->pcd, usb_ep, usb_req)) {
00369 return -EINVAL;
00370 }
00371
00372 return 0;
00373 }
00374
00391 static int ep_halt(struct usb_ep *usb_ep, int value)
00392 {
00393 int retval = 0;
00394
00395 DWC_DEBUGPL(DBG_PCD, "HALT %s %d\n", usb_ep->name, value);
00396
00397 if (!usb_ep) {
00398 DWC_WARN("bad ep\n");
00399 return -EINVAL;
00400 }
00401
00402 retval = dwc_otg_pcd_ep_halt(gadget_wrapper->pcd, usb_ep, value);
00403 if (retval == -DWC_E_AGAIN) {
00404 return -EAGAIN;
00405 } else if (retval) {
00406 retval = -EINVAL;
00407 }
00408
00409 return retval;
00410 }
00411
00412 #ifdef DWC_EN_ISOC
00413
00422 static int iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
00423 gfp_t gfp_flags)
00424 {
00425 int retval = 0;
00426
00427 if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
00428 DWC_WARN("bad params\n");
00429 return -EINVAL;
00430 }
00431
00432 if (!usb_ep) {
00433 DWC_PRINTF("bad params\n");
00434 return -EINVAL;
00435 }
00436
00437 req->status = -EINPROGRESS;
00438
00439 retval =
00440 dwc_otg_pcd_iso_ep_start(gadget_wrapper->pcd, usb_ep, req->buf0,
00441 req->buf1, req->dma0, req->dma1,
00442 req->sync_frame, req->data_pattern_frame,
00443 req->data_per_frame,
00444 req->flags & USB_REQ_ISO_ASAP ? -1 : req->
00445 start_frame, req->buf_proc_intrvl, req,
00446 gfp_flags == GFP_ATOMIC ? 1 : 0);
00447
00448 if (retval) {
00449 return -EINVAL;
00450 }
00451
00452 return retval;
00453 }
00454
00458 static int iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
00459 {
00460 int retval = 0;
00461 if (!usb_ep) {
00462 DWC_WARN("bad ep\n");
00463 }
00464
00465 if (!gadget_wrapper->driver ||
00466 gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
00467 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
00468 gadget_wrapper->gadget.speed);
00469 DWC_WARN("bogus device state\n");
00470 }
00471
00472 dwc_otg_pcd_iso_ep_stop(gadget_wrapper->pcd, usb_ep, req);
00473 if (retval) {
00474 retval = -EINVAL;
00475 }
00476
00477 return retval;
00478 }
00479
00480 static struct usb_iso_request *alloc_iso_request(struct usb_ep *ep,
00481 int packets, gfp_t gfp_flags)
00482 {
00483 struct usb_iso_request *pReq = NULL;
00484 uint32_t req_size;
00485
00486 req_size = sizeof(struct usb_iso_request);
00487 req_size +=
00488 (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
00489
00490 pReq = kmalloc(req_size, gfp_flags);
00491 if (!pReq) {
00492 DWC_WARN("Can't allocate Iso Request\n");
00493 return 0;
00494 }
00495 pReq->iso_packet_desc0 = (void *)(pReq + 1);
00496
00497 pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
00498
00499 return pReq;
00500 }
00501
00502 static void free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
00503 {
00504 kfree(req);
00505 }
00506
00507 static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops = {
00508 .ep_ops = {
00509 .enable = ep_enable,
00510 .disable = ep_disable,
00511
00512 .alloc_request = dwc_otg_pcd_alloc_request,
00513 .free_request = dwc_otg_pcd_free_request,
00514
00515 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
00516 .free_buffer = dwc_otg_pcd_free_buffer,
00517
00518 .queue = ep_queue,
00519 .dequeue = ep_dequeue,
00520
00521 .set_halt = ep_halt,
00522 .fifo_status = 0,
00523 .fifo_flush = 0,
00524 },
00525 .iso_ep_start = iso_ep_start,
00526 .iso_ep_stop = iso_ep_stop,
00527 .alloc_iso_request = alloc_iso_request,
00528 .free_iso_request = free_iso_request,
00529 };
00530
00531 #else
00532
00533 static struct usb_ep_ops dwc_otg_pcd_ep_ops = {
00534 .enable = ep_enable,
00535 .disable = ep_disable,
00536
00537 .alloc_request = dwc_otg_pcd_alloc_request,
00538 .free_request = dwc_otg_pcd_free_request,
00539
00540 .alloc_buffer = dwc_otg_pcd_alloc_buffer,
00541 .free_buffer = dwc_otg_pcd_free_buffer,
00542
00543 .queue = ep_queue,
00544 .dequeue = ep_dequeue,
00545
00546 .set_halt = ep_halt,
00547 .fifo_status = 0,
00548 .fifo_flush = 0,
00549
00550 };
00551
00552 #endif
00553
00572 static int get_frame_number(struct usb_gadget *gadget)
00573 {
00574 struct gadget_wrapper *d;
00575
00576 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
00577
00578 if (gadget == 0) {
00579 return -ENODEV;
00580 }
00581
00582 d = container_of(gadget, struct gadget_wrapper, gadget);
00583 return dwc_otg_pcd_get_frame_number(d->pcd);
00584 }
00585
00586 #ifdef CONFIG_USB_DWC_OTG_LPM
00587 static int test_lpm_enabled(struct usb_gadget *gadget)
00588 {
00589 struct gadget_wrapper *d;
00590
00591 d = container_of(gadget, struct gadget_wrapper, gadget);
00592
00593 return dwc_otg_pcd_is_lpm_enabled(d->pcd);
00594 }
00595 #endif
00596
00603 static int wakeup(struct usb_gadget *gadget)
00604 {
00605 struct gadget_wrapper *d;
00606
00607 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
00608
00609 if (gadget == 0) {
00610 return -ENODEV;
00611 } else {
00612 d = container_of(gadget, struct gadget_wrapper, gadget);
00613 }
00614 dwc_otg_pcd_wakeup(d->pcd);
00615 return 0;
00616 }
00617
00618 static const struct usb_gadget_ops dwc_otg_pcd_ops = {
00619 .get_frame = get_frame_number,
00620 .wakeup = wakeup,
00621 #ifdef CONFIG_USB_DWC_OTG_LPM
00622 .lpm_support = test_lpm_enabled,
00623 #endif
00624
00625 };
00626
00627 static int _setup(dwc_otg_pcd_t * pcd, uint8_t * bytes)
00628 {
00629 int retval = -DWC_E_NOT_SUPPORTED;
00630 if (gadget_wrapper->driver && gadget_wrapper->driver->setup) {
00631 retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget,
00632 (struct usb_ctrlrequest
00633 *)bytes);
00634 }
00635
00636 if (retval == -ENOTSUPP) {
00637 retval = -DWC_E_NOT_SUPPORTED;
00638 } else if (retval < 0) {
00639 retval = -DWC_E_INVALID;
00640 }
00641
00642 return retval;
00643 }
00644
00645 #ifdef DWC_EN_ISOC
00646 static int _isoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
00647 void *req_handle, int proc_buf_num)
00648 {
00649 int i, packet_count;
00650 struct usb_gadget_iso_packet_descriptor *iso_packet = 0;
00651 struct usb_iso_request *iso_req = req_handle;
00652
00653 if (proc_buf_num) {
00654 iso_packet = iso_req->iso_packet_desc1;
00655 } else {
00656 iso_packet = iso_req->iso_packet_desc0;
00657 }
00658 packet_count =
00659 dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle);
00660 for (i = 0; i < packet_count; ++i) {
00661 int status;
00662 int actual;
00663 int offset;
00664 dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle,
00665 i, &status, &actual, &offset);
00666 switch (status) {
00667 case -DWC_E_NO_DATA:
00668 status = -ENODATA;
00669 break;
00670 default:
00671 if (status) {
00672 DWC_PRINTF("unknown status in isoc packet\n");
00673 }
00674
00675 }
00676 iso_packet[i].status = status;
00677 iso_packet[i].offset = offset;
00678 iso_packet[i].actual_length = actual;
00679 }
00680
00681 iso_req->status = 0;
00682 iso_req->process_buffer(ep_handle, iso_req);
00683
00684 return 0;
00685 }
00686 #endif
00687
00688 static int _complete(dwc_otg_pcd_t * pcd, void *ep_handle,
00689 void *req_handle, int32_t status, uint32_t actual)
00690 {
00691 struct usb_request *req = (struct usb_request *)req_handle;
00692
00693 if (req && req->complete) {
00694 switch (status) {
00695 case -DWC_E_SHUTDOWN:
00696 req->status = -ESHUTDOWN;
00697 break;
00698 case -DWC_E_RESTART:
00699 req->status = -ECONNRESET;
00700 break;
00701 case -DWC_E_INVALID:
00702 req->status = -EINVAL;
00703 break;
00704 case -DWC_E_TIMEOUT:
00705 req->status = -ETIMEDOUT;
00706 break;
00707 default:
00708 req->status = status;
00709
00710 }
00711 req->actual = actual;
00712 req->complete(ep_handle, req);
00713 }
00714
00715 return 0;
00716 }
00717
00718 static int _connect(dwc_otg_pcd_t * pcd, int speed)
00719 {
00720 gadget_wrapper->gadget.speed = speed;
00721 return 0;
00722 }
00723
00724 static int _disconnect(dwc_otg_pcd_t * pcd)
00725 {
00726 if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) {
00727 gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget);
00728 }
00729 return 0;
00730 }
00731
00732 static int _resume(dwc_otg_pcd_t * pcd)
00733 {
00734 if (gadget_wrapper->driver && gadget_wrapper->driver->resume) {
00735 gadget_wrapper->driver->resume(&gadget_wrapper->gadget);
00736 }
00737
00738 return 0;
00739 }
00740
00741 static int _suspend(dwc_otg_pcd_t * pcd)
00742 {
00743 if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) {
00744 gadget_wrapper->driver->suspend(&gadget_wrapper->gadget);
00745 }
00746 return 0;
00747 }
00748
00752 static int _hnp_changed(dwc_otg_pcd_t * pcd)
00753 {
00754
00755 if (!gadget_wrapper->gadget.is_otg)
00756 return 0;
00757
00758 gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd);
00759 gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd);
00760 gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd);
00761 return 0;
00762 }
00763
00764 static int _reset(dwc_otg_pcd_t * pcd)
00765 {
00766 return 0;
00767 }
00768
00769 #ifdef DWC_UTE_CFI
00770 static int _cfi_setup(dwc_otg_pcd_t * pcd, void *cfi_req)
00771 {
00772 int retval = -DWC_E_INVALID;
00773 if (gadget_wrapper->driver->cfi_feature_setup) {
00774 retval =
00775 gadget_wrapper->driver->cfi_feature_setup(&gadget_wrapper->
00776 gadget,
00777 (struct
00778 cfi_usb_ctrlrequest
00779 *)cfi_req);
00780 }
00781
00782 return retval;
00783 }
00784 #endif
00785
00786 static const struct dwc_otg_pcd_function_ops fops = {
00787 .complete = _complete,
00788 #ifdef DWC_EN_ISOC
00789 .isoc_complete = _isoc_complete,
00790 #endif
00791 .setup = _setup,
00792 .disconnect = _disconnect,
00793 .connect = _connect,
00794 .resume = _resume,
00795 .suspend = _suspend,
00796 .hnp_changed = _hnp_changed,
00797 .reset = _reset,
00798 #ifdef DWC_UTE_CFI
00799 .cfi_setup = _cfi_setup,
00800 #endif
00801 };
00802
00806 static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev)
00807 {
00808 dwc_otg_pcd_t *pcd = dev;
00809 int32_t retval = IRQ_NONE;
00810
00811 retval = dwc_otg_pcd_handle_intr(pcd);
00812 if (retval != 0) {
00813 S3C2410X_CLEAR_EINTPEND();
00814 }
00815 return IRQ_RETVAL(retval);
00816 }
00817
00824 void gadget_add_eps(struct gadget_wrapper *d)
00825 {
00826 static const char *names[] = {
00827
00828 "ep0",
00829 "ep1in",
00830 "ep2in",
00831 "ep3in",
00832 "ep4in",
00833 "ep5in",
00834 "ep6in",
00835 "ep7in",
00836 "ep8in",
00837 "ep9in",
00838 "ep10in",
00839 "ep11in",
00840 "ep12in",
00841 "ep13in",
00842 "ep14in",
00843 "ep15in",
00844 "ep1out",
00845 "ep2out",
00846 "ep3out",
00847 "ep4out",
00848 "ep5out",
00849 "ep6out",
00850 "ep7out",
00851 "ep8out",
00852 "ep9out",
00853 "ep10out",
00854 "ep11out",
00855 "ep12out",
00856 "ep13out",
00857 "ep14out",
00858 "ep15out"
00859 };
00860
00861 int i;
00862 struct usb_ep *ep;
00863
00864 DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__);
00865
00866 INIT_LIST_HEAD(&d->gadget.ep_list);
00867 d->gadget.ep0 = &d->ep0;
00868 d->gadget.speed = USB_SPEED_UNKNOWN;
00869
00870 INIT_LIST_HEAD(&d->gadget.ep0->ep_list);
00871
00875 ep = &d->ep0;
00876
00877
00878 ep->name = names[0];
00879 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
00880
00885 ep->maxpacket = MAX_PACKET_SIZE;
00886 dwc_otg_pcd_ep_enable(d->pcd, NULL, ep);
00887
00888 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
00889
00894 for (i = 0; i < 15; i++) {
00895 ep = &d->in_ep[i];
00896
00897
00898 ep->name = names[i + 1];
00899 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
00900
00905 ep->maxpacket = MAX_PACKET_SIZE;
00906 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
00907 }
00908
00909 for (i = 0; i < 15; i++) {
00910 ep = &d->out_ep[i];
00911
00912
00913 ep->name = names[15 + i + 1];
00914 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
00915
00920 ep->maxpacket = MAX_PACKET_SIZE;
00921
00922 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
00923 }
00924
00925
00926 list_del_init(&d->ep0.ep_list);
00927
00928 d->ep0.maxpacket = MAX_EP0_SIZE;
00929 }
00930
00937 static void dwc_otg_pcd_gadget_release(struct device *dev)
00938 {
00939 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
00940 }
00941
00942 static struct gadget_wrapper *alloc_wrapper(
00943 #ifdef LM_INTERFACE
00944 struct lm_device *_dev
00945 #elif PCI_INTERFACE
00946 struct pci_dev *_dev
00947 #endif
00948 )
00949 {
00950 static char pcd_name[] = "dwc_otg_pcd";
00951 #ifdef LM_INTERFACE
00952 dwc_otg_device_t *otg_dev = lm_get_drvdata(_dev);
00953 #elif PCI_INTERFACE
00954 dwc_otg_device_t *otg_dev = pci_get_drvdata(_dev);
00955 #endif
00956
00957 struct gadget_wrapper *d;
00958 int retval;
00959
00960 d = dwc_alloc(sizeof(*d));
00961 if (d == NULL) {
00962 return NULL;
00963 }
00964
00965 memset(d, 0, sizeof(*d));
00966
00967 d->gadget.name = pcd_name;
00968 d->pcd = otg_dev->pcd;
00969 strcpy(d->gadget.dev.bus_id, "gadget");
00970
00971 d->gadget.dev.parent = &_dev->dev;
00972 d->gadget.dev.release = dwc_otg_pcd_gadget_release;
00973 d->gadget.ops = &dwc_otg_pcd_ops;
00974 d->gadget.is_dualspeed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd);
00975 d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
00976
00977 d->driver = 0;
00978
00979 retval = device_register(&d->gadget.dev);
00980 if (retval != 0) {
00981 DWC_ERROR("device_register failed\n");
00982 dwc_free(d);
00983 return NULL;
00984 }
00985
00986 return d;
00987 }
00988
00989 static void free_wrapper(struct gadget_wrapper *d)
00990 {
00991 if (d->driver) {
00992
00993 DWC_WARN("driver '%s' is still registered\n",
00994 d->driver->driver.name);
00995 usb_gadget_unregister_driver(d->driver);
00996 }
00997
00998 device_unregister(&d->gadget.dev);
00999 dwc_free(d);
01000 }
01001
01006 int pcd_init(
01007 #ifdef LM_INTERFACE
01008 struct lm_device *_dev
01009 #elif PCI_INTERFACE
01010 struct pci_dev *_dev
01011 #endif
01012 )
01013
01014 {
01015 #ifdef LM_INTERFACE
01016 dwc_otg_device_t *otg_dev = lm_get_drvdata(_dev);
01017 #elif PCI_INTERFACE
01018 dwc_otg_device_t *otg_dev = pci_get_drvdata(_dev);
01019 #endif
01020
01021 int retval = 0;
01022
01023 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
01024
01025 otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if);
01026
01027 if (!otg_dev->pcd) {
01028 DWC_ERROR("dwc_otg_pcd_init failed\n");
01029 return -ENOMEM;
01030 }
01031
01032 gadget_wrapper = alloc_wrapper(_dev);
01033
01034
01035
01036
01037 gadget_add_eps(gadget_wrapper);
01038
01039
01040
01041
01042 DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", _dev->irq);
01043 retval = request_irq(_dev->irq, dwc_otg_pcd_irq,
01044 SA_SHIRQ, gadget_wrapper->gadget.name,
01045 otg_dev->pcd);
01046 if (retval != 0) {
01047 DWC_ERROR("request of irq%d failed\n", _dev->irq);
01048 free_wrapper(gadget_wrapper);
01049 return -EBUSY;
01050 }
01051
01052 dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
01053
01054 return retval;
01055 }
01056
01060 void pcd_remove(
01061 #ifdef LM_INTERFACE
01062 struct lm_device *_dev
01063 #elif PCI_INTERFACE
01064 struct pci_dev *_dev
01065 #endif
01066 )
01067 {
01068 #ifdef LM_INTERFACE
01069 dwc_otg_device_t *otg_dev = lm_get_drvdata(_dev);
01070 #elif PCI_INTERFACE
01071 dwc_otg_device_t *otg_dev = pci_get_drvdata(_dev);
01072 #endif
01073 dwc_otg_pcd_t *pcd = otg_dev->pcd;
01074
01075 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
01076
01077
01078
01079
01080 free_irq(_dev->irq, pcd);
01081 dwc_otg_pcd_remove(otg_dev->pcd);
01082 free_wrapper(gadget_wrapper);
01083 otg_dev->pcd = 0;
01084 }
01085
01096 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
01097 {
01098 int retval;
01099
01100 DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n",
01101 driver->driver.name);
01102
01103 if (!driver || driver->speed == USB_SPEED_UNKNOWN ||
01104 !driver->bind ||
01105 !driver->unbind || !driver->disconnect || !driver->setup) {
01106 DWC_DEBUGPL(DBG_PCDV, "EINVAL\n");
01107 return -EINVAL;
01108 }
01109 if (gadget_wrapper == 0) {
01110 DWC_DEBUGPL(DBG_PCDV, "ENODEV\n");
01111 return -ENODEV;
01112 }
01113 if (gadget_wrapper->driver != 0) {
01114 DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver);
01115 return -EBUSY;
01116 }
01117
01118
01119 gadget_wrapper->driver = driver;
01120 gadget_wrapper->gadget.dev.driver = &driver->driver;
01121
01122 DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
01123 retval = driver->bind(&gadget_wrapper->gadget);
01124 if (retval) {
01125 DWC_ERROR("bind to driver %s --> error %d\n",
01126 driver->driver.name, retval);
01127 gadget_wrapper->driver = 0;
01128 gadget_wrapper->gadget.dev.driver = 0;
01129 return retval;
01130 }
01131 DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
01132 driver->driver.name);
01133 return 0;
01134 }
01135
01136 EXPORT_SYMBOL(usb_gadget_register_driver);
01137
01143 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
01144 {
01145
01146
01147 if (gadget_wrapper == 0) {
01148 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
01149 -ENODEV);
01150 return -ENODEV;
01151 }
01152 if (driver == 0 || driver != gadget_wrapper->driver) {
01153 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
01154 -EINVAL);
01155 return -EINVAL;
01156 }
01157
01158 driver->unbind(&gadget_wrapper->gadget);
01159 gadget_wrapper->driver = 0;
01160
01161 DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", driver->driver.name);
01162 return 0;
01163 }
01164
01165 EXPORT_SYMBOL(usb_gadget_unregister_driver);
01166
01167 #endif