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_DEVICE_ONLY
00034
00041 #include <linux/kernel.h>
00042 #include <linux/module.h>
00043 #include <linux/moduleparam.h>
00044 #include <linux/init.h>
00045 #include <linux/device.h>
00046 #include <linux/errno.h>
00047 #include <linux/list.h>
00048 #include <linux/interrupt.h>
00049 #include <linux/string.h>
00050 #include <linux/dma-mapping.h>
00051 #include <linux/version.h>
00052 #include <asm/io.h>
00053
00054 #ifdef LM_INTERFACE
00055 #include <asm/arch/regs-irq.h>
00056 #include <asm/arch/lm.h>
00057 #include <asm/arch/irqs.h>
00058 #endif
00059
00060 #include <linux/usb.h>
00061 #include <../drivers/usb/core/hcd.h>
00062
00063 #include "dwc_otg_hcd_if.h"
00064 #include "dwc_otg_dbg.h"
00065 #include "dwc_otg_driver.h"
00066
00071 #define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
00072 ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
00073
00074 static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
00075
00078 static int urb_enqueue(struct usb_hcd *hcd,
00079 struct usb_host_endpoint *ep,
00080 struct urb *urb, gfp_t mem_flags);
00081
00082 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
00083
00084 static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
00085
00086 static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
00087 extern int hcd_start(struct usb_hcd *hcd);
00088 extern void hcd_stop(struct usb_hcd *hcd);
00089 static int get_frame_number(struct usb_hcd *hcd);
00090 extern int hub_status_data(struct usb_hcd *hcd, char *buf);
00091 extern int hub_control(struct usb_hcd *hcd,
00092 u16 typeReq,
00093 u16 wValue, u16 wIndex, char *buf, u16 wLength);
00094
00095 struct wrapper_priv_data {
00096 dwc_otg_hcd_t *dwc_otg_hcd;
00097 };
00098
00101 static struct hc_driver dwc_otg_hc_driver = {
00102
00103 .description = dwc_otg_hcd_name,
00104 .product_desc = "DWC OTG Controller",
00105 .hcd_priv_size = sizeof(struct wrapper_priv_data),
00106
00107 .irq = dwc_otg_hcd_irq,
00108
00109 .flags = HCD_MEMORY | HCD_USB2,
00110
00111
00112 .start = hcd_start,
00113
00114
00115 .stop = hcd_stop,
00116
00117 .urb_enqueue = urb_enqueue,
00118 .urb_dequeue = urb_dequeue,
00119 .endpoint_disable = endpoint_disable,
00120
00121 .get_frame_number = get_frame_number,
00122
00123 .hub_status_data = hub_status_data,
00124 .hub_control = hub_control,
00125
00126
00127 };
00128
00130 static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
00131 {
00132 struct wrapper_priv_data *p;
00133 p = (struct wrapper_priv_data *)(hcd->hcd_priv);
00134 return p->dwc_otg_hcd;
00135 }
00136
00138 static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t * dwc_otg_hcd)
00139 {
00140 return dwc_otg_hcd_get_priv_data(dwc_otg_hcd);
00141 }
00142
00144 inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
00145 {
00146 struct usb_device *dev = urb->dev;
00147 int ep_num = usb_pipeendpoint(urb->pipe);
00148
00149 if (usb_pipein(urb->pipe))
00150 return dev->ep_in[ep_num];
00151 else
00152 return dev->ep_out[ep_num];
00153 }
00154
00155 static int _disconnect(dwc_otg_hcd_t * hcd)
00156 {
00157 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
00158
00159 usb_hcd->self.is_b_host = 0;
00160 return 0;
00161 }
00162
00163 static int _start(dwc_otg_hcd_t * hcd)
00164 {
00165 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
00166
00167 usb_hcd->self.is_b_host = dwc_otg_hcd_is_b_host(hcd);
00168 hcd_start(usb_hcd);
00169
00170 return 0;
00171 }
00172
00173 static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr,
00174 uint32_t * port_addr)
00175 {
00176 struct urb *urb = (struct urb *)urb_handle;
00177 if (urb->dev->tt) {
00178 *hub_addr = urb->dev->tt->hub->devnum;
00179 } else {
00180 *hub_addr = 0;
00181 }
00182 *port_addr = urb->dev->ttport;
00183 return 0;
00184 }
00185
00186 static int _speed(dwc_otg_hcd_t * hcd, void *urb_handle)
00187 {
00188 struct urb *urb = (struct urb *)urb_handle;
00189 return urb->dev->speed;
00190 }
00191
00192 static int _get_b_hnp_enable(dwc_otg_hcd_t * hcd)
00193 {
00194 struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
00195 return usb_hcd->self.b_hnp_enable;
00196 }
00197
00198 static void allocate_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
00199 struct urb *urb)
00200 {
00201 hcd_to_bus(hcd)->bandwidth_allocated += bw / urb->interval;
00202 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
00203 hcd_to_bus(hcd)->bandwidth_isoc_reqs++;
00204 } else {
00205 hcd_to_bus(hcd)->bandwidth_int_reqs++;
00206 }
00207 }
00208
00209 static void free_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
00210 struct urb *urb)
00211 {
00212 hcd_to_bus(hcd)->bandwidth_allocated -= bw / urb->interval;
00213 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
00214 hcd_to_bus(hcd)->bandwidth_isoc_reqs--;
00215 } else {
00216 hcd_to_bus(hcd)->bandwidth_int_reqs--;
00217 }
00218 }
00219
00224 static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
00225 dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
00226 {
00227 struct urb *urb = (struct urb *)urb_handle;
00228 #ifdef DEBUG
00229 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
00230 DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n",
00231 __func__, urb, usb_pipedevice(urb->pipe),
00232 usb_pipeendpoint(urb->pipe),
00233 usb_pipein(urb->pipe) ? "IN" : "OUT", status);
00234 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
00235 int i;
00236 for (i = 0; i < urb->number_of_packets; i++) {
00237 DWC_PRINTF(" ISO Desc %d status: %d\n",
00238 i, urb->iso_frame_desc[i].status);
00239 }
00240 }
00241 }
00242 #endif
00243
00244 urb->actual_length = dwc_otg_hcd_urb_get_actual_length(dwc_otg_urb);
00245
00246 switch (status) {
00247 case -DWC_E_PROTOCOL:
00248 status = -EPROTO;
00249 break;
00250 case -DWC_E_IN_PROGRESS:
00251 status = -EINPROGRESS;
00252 break;
00253 case -DWC_E_PIPE:
00254 status = -EPIPE;
00255 break;
00256 case -DWC_E_IO:
00257 status = -EIO;
00258 break;
00259 case -DWC_E_TIMEOUT:
00260 status = -ETIMEDOUT;
00261 break;
00262 case -DWC_E_OVERFLOW:
00263 status = -EOVERFLOW;
00264 break;
00265 default:
00266 if (status) {
00267 DWC_PRINTF("Uknown urb status %d\n", status);
00268
00269 }
00270 }
00271
00272 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
00273 int i;
00274
00275 urb->error_count = dwc_otg_hcd_urb_get_error_count(dwc_otg_urb);
00276 for (i = 0; i < urb->number_of_packets; ++i) {
00277 urb->iso_frame_desc[i].actual_length =
00278 dwc_otg_hcd_urb_get_iso_desc_actual_length
00279 (dwc_otg_urb, i);
00280 urb->iso_frame_desc[i].status =
00281 dwc_otg_hcd_urb_get_iso_desc_status
00282 (dwc_otg_urb, i);
00283 }
00284 }
00285
00286 urb->status = status;
00287 urb->hcpriv = NULL;
00288 if (!status) {
00289 if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
00290 (urb->actual_length < urb->transfer_buffer_length)) {
00291 urb->status = -EREMOTEIO;
00292 }
00293 }
00294
00295 if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ||
00296 (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
00297 struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
00298 if (ep) {
00299 free_bus_bandwidth(dwc_otg_hcd_to_hcd(hcd),
00300 dwc_otg_hcd_get_ep_bandwidth(hcd,
00301 ep->
00302 hcpriv),
00303 urb);
00304 }
00305 }
00306
00307 dwc_free(dwc_otg_urb);
00308 usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
00309 return 0;
00310 }
00311
00312 static struct dwc_otg_hcd_function_ops hcd_fops = {
00313 .start = _start,
00314 .disconnect = _disconnect,
00315 .hub_info = _hub_info,
00316 .speed = _speed,
00317 .complete = _complete,
00318 .get_b_hnp_enable = _get_b_hnp_enable,
00319 };
00320
00327 int hcd_init(
00328 #ifdef LM_INTERFACE
00329 struct lm_device *_dev
00330 #elif PCI_INTERFACE
00331 struct pci_dev *_dev
00332 #endif
00333 )
00334 {
00335 struct usb_hcd *hcd = NULL;
00336 dwc_otg_hcd_t *dwc_otg_hcd = NULL;
00337 #ifdef LM_INTERFACE
00338 dwc_otg_device_t *otg_dev = lm_get_drvdata(_dev);
00339 #elif PCI_INTERFACE
00340 dwc_otg_device_t *otg_dev = pci_get_drvdata(_dev);
00341 #endif
00342
00343 int retval = 0;
00344
00345 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
00346
00347
00348 if (dwc_otg_is_dma_enable(otg_dev->core_if)) {
00349 #ifdef LM_INTERFACE
00350 _dev->dev.dma_mask = (void *)~0;
00351 _dev->dev.coherent_dma_mask = ~0;
00352 #elif PCI_INTERFACE
00353 pci_set_dma_mask(_dev,DMA_32BIT_MASK);
00354 pci_set_consistent_dma_mask(_dev,DMA_32BIT_MASK);
00355 #endif
00356
00357 } else {
00358 #ifdef LM_INTERFACE
00359 _dev->dev.dma_mask = (void *)0;
00360 _dev->dev.coherent_dma_mask = 0;
00361 #elif PCI_INTERFACE
00362 pci_set_dma_mask(_dev,0);
00363 pci_set_consistent_dma_mask(_dev,0);
00364 #endif
00365 }
00366
00367
00368
00369
00370
00371 hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, _dev->dev.bus_id);
00372 if (!hcd) {
00373 retval = -ENOMEM;
00374 goto error1;
00375 }
00376
00377 hcd->regs = otg_dev->base;
00378
00379
00380 dwc_otg_hcd = dwc_otg_hcd_alloc_hcd();
00381 if (!dwc_otg_hcd) {
00382 goto error2;
00383 }
00384 ((struct wrapper_priv_data *)(hcd->hcd_priv))->dwc_otg_hcd =
00385 dwc_otg_hcd;
00386 otg_dev->hcd = dwc_otg_hcd;
00387
00388 if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if)) {
00389 goto error2;
00390 }
00391
00392 hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
00393
00394
00395
00396
00397
00398
00399 retval = usb_add_hcd(hcd, _dev->irq, SA_SHIRQ);
00400 if (retval < 0) {
00401 goto error2;
00402 }
00403
00404 dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
00405 return 0;
00406
00407 error2:
00408 usb_put_hcd(hcd);
00409 error1:
00410 return retval;
00411 }
00412
00417 void hcd_remove(
00418 #ifdef LM_INTERFACE
00419 struct lm_device *_dev
00420 #elif PCI_INTERFACE
00421 struct pci_dev *_dev
00422 #endif
00423 )
00424 {
00425 #ifdef LM_INTERFACE
00426 dwc_otg_device_t *otg_dev = lm_get_drvdata(_dev);
00427 #elif PCI_INTERFACE
00428 dwc_otg_device_t *otg_dev = pci_get_drvdata(_dev);
00429 #endif
00430
00431 dwc_otg_hcd_t *dwc_otg_hcd;
00432 struct usb_hcd *hcd;
00433
00434 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
00435
00436 if (!otg_dev) {
00437 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
00438 return;
00439 }
00440
00441 dwc_otg_hcd = otg_dev->hcd;
00442
00443 if (!dwc_otg_hcd) {
00444 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
00445 return;
00446 }
00447
00448 hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
00449
00450 if (!hcd) {
00451 DWC_DEBUGPL(DBG_ANY,
00452 "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n",
00453 __func__);
00454 return;
00455 }
00456 usb_remove_hcd(hcd);
00457 dwc_otg_hcd_set_priv_data(dwc_otg_hcd, NULL);
00458 dwc_otg_hcd_remove(dwc_otg_hcd);
00459 usb_put_hcd(hcd);
00460 }
00461
00462
00463
00464
00465
00469 int hcd_start(struct usb_hcd *hcd)
00470 {
00471 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
00472 struct usb_bus *bus;
00473
00474 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
00475 bus = hcd_to_bus(hcd);
00476
00477 hcd->state = HC_STATE_RUNNING;
00478 if (dwc_otg_hcd_start(dwc_otg_hcd, &hcd_fops)) {
00479 return 0;
00480 }
00481
00482
00483 if (bus->root_hub) {
00484 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
00485
00486 usb_hcd_resume_root_hub(hcd);
00487 }
00488
00489 return 0;
00490 }
00491
00496 void hcd_stop(struct usb_hcd *hcd)
00497 {
00498 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
00499
00500 dwc_otg_hcd_stop(dwc_otg_hcd);
00501 }
00502
00504 static int get_frame_number(struct usb_hcd *hcd)
00505 {
00506 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
00507
00508 return dwc_otg_hcd_get_frame_number(dwc_otg_hcd);
00509 }
00510
00511 #ifdef DEBUG
00512 static void dump_urb_info(struct urb *urb, char *fn_name)
00513 {
00514 DWC_PRINTF("%s, urb %p\n", fn_name, urb);
00515 DWC_PRINTF(" Device address: %d\n", usb_pipedevice(urb->pipe));
00516 DWC_PRINTF(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
00517 (usb_pipein(urb->pipe) ? "IN" : "OUT"));
00518 DWC_PRINTF(" Endpoint type: %s\n", ( {
00519 char *pipetype;
00520 switch (usb_pipetype(urb->pipe)) {
00521 case PIPE_CONTROL:
00522 pipetype = "CONTROL"; break; case PIPE_BULK:
00523 pipetype = "BULK"; break; case PIPE_INTERRUPT:
00524 pipetype = "INTERRUPT"; break; case PIPE_ISOCHRONOUS:
00525 pipetype = "ISOCHRONOUS"; break; default:
00526 pipetype = "UNKNOWN"; break;};
00527 pipetype;}
00528 )) ;
00529 DWC_PRINTF(" Speed: %s\n", ( {
00530 char *speed; switch (urb->dev->speed) {
00531 case USB_SPEED_HIGH:
00532 speed = "HIGH"; break; case USB_SPEED_FULL:
00533 speed = "FULL"; break; case USB_SPEED_LOW:
00534 speed = "LOW"; break; default:
00535 speed = "UNKNOWN"; break;};
00536 speed;}
00537 )) ;
00538 DWC_PRINTF(" Max packet size: %d\n",
00539 usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
00540 DWC_PRINTF(" Data buffer length: %d\n", urb->transfer_buffer_length);
00541 DWC_PRINTF(" Transfer buffer: %p, Transfer DMA: %p\n",
00542 urb->transfer_buffer, (void *)urb->transfer_dma);
00543 DWC_PRINTF(" Setup buffer: %p, Setup DMA: %p\n",
00544 urb->setup_packet, (void *)urb->setup_dma);
00545 DWC_PRINTF(" Interval: %d\n", urb->interval);
00546 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
00547 int i;
00548 for (i = 0; i < urb->number_of_packets; i++) {
00549 DWC_PRINTF(" ISO Desc %d:\n", i);
00550 DWC_PRINTF(" offset: %d, length %d\n",
00551 urb->iso_frame_desc[i].offset,
00552 urb->iso_frame_desc[i].length);
00553 }
00554 }
00555 }
00556
00557 #endif
00558
00562 static int urb_enqueue(struct usb_hcd *hcd,
00563 struct usb_host_endpoint *ep,
00564 struct urb *urb, gfp_t mem_flags)
00565 {
00566 int retval = 0;
00567 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
00568 dwc_otg_hcd_urb_t *dwc_otg_urb;
00569 int i;
00570 int alloc_bandwidth = 0;
00571 uint8_t ep_type = 0;
00572 uint32_t flags = 0;
00573 void *buf;
00574
00575 #ifdef DEBUG
00576 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
00577 dump_urb_info(urb, "urb_enqueue");
00578 }
00579 #endif
00580
00581 if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
00582 || (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
00583 if (!dwc_otg_hcd_is_bandwidth_allocated
00584 (dwc_otg_hcd, &ep->hcpriv)) {
00585 alloc_bandwidth = 1;
00586 }
00587 }
00588
00589 switch (usb_pipetype(urb->pipe)) {
00590 case PIPE_CONTROL:
00591 ep_type = USB_ENDPOINT_XFER_CONTROL;
00592 break;
00593 case PIPE_ISOCHRONOUS:
00594 ep_type = USB_ENDPOINT_XFER_ISOC;
00595 break;
00596 case PIPE_BULK:
00597 ep_type = USB_ENDPOINT_XFER_BULK;
00598 break;
00599 case PIPE_INTERRUPT:
00600 ep_type = USB_ENDPOINT_XFER_INT;
00601 break;
00602 default:
00603 DWC_WARN("Wrong ep type\n");
00604 }
00605
00606 dwc_otg_urb = dwc_otg_hcd_urb_alloc(dwc_otg_hcd,
00607 urb->number_of_packets,
00608 mem_flags == GFP_ATOMIC ? 1 : 0);
00609
00610 dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_urb, usb_pipedevice(urb->pipe),
00611 usb_pipeendpoint(urb->pipe), ep_type,
00612 usb_pipein(urb->pipe),
00613 usb_maxpacket(urb->dev, urb->pipe,
00614 !(usb_pipein(urb->pipe))));
00615
00616 buf = urb->transfer_buffer;
00617 if (hcd->self.uses_dma) {
00618
00619
00620
00621
00622
00623
00624 buf = phys_to_virt(urb->transfer_dma);
00625 }
00626
00627 if (!(urb->transfer_flags & URB_NO_INTERRUPT))
00628 flags |= URB_GIVEBACK_ASAP;
00629 if (urb->transfer_flags & URB_ZERO_PACKET)
00630 flags |= URB_SEND_ZERO_PACKET;
00631
00632 dwc_otg_hcd_urb_set_params(dwc_otg_urb, urb, buf,
00633 urb->transfer_dma,
00634 urb->transfer_buffer_length,
00635 urb->setup_packet,
00636 urb->setup_dma,
00637 flags,
00638 urb->interval);
00639
00640 for (i = 0; i < urb->number_of_packets; ++i) {
00641 dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_urb, i,
00642 urb->iso_frame_desc[i].
00643 offset,
00644 urb->iso_frame_desc[i].
00645 length);
00646 }
00647
00648 urb->hcpriv = dwc_otg_urb;
00649 retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb, &ep->hcpriv);
00650 if (!retval) {
00651 if (alloc_bandwidth) {
00652 allocate_bus_bandwidth(hcd,
00653 dwc_otg_hcd_get_ep_bandwidth
00654 (dwc_otg_hcd, ep->hcpriv), urb);
00655 }
00656 } else {
00657 if (retval == -DWC_E_NO_DEVICE) {
00658 retval = -ENODEV;
00659 }
00660 }
00661
00662 return retval;
00663 }
00664
00667 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
00668 {
00669 dwc_otg_hcd_t *dwc_otg_hcd;
00670 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
00671
00672 dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
00673
00674 #ifdef DEBUG
00675 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
00676 dump_urb_info(urb, "urb_dequeue");
00677 }
00678 #endif
00679 dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, urb->hcpriv);
00680
00681 dwc_free(urb->hcpriv);
00682 urb->hcpriv = NULL;
00683
00684
00685 usb_hcd_giveback_urb(hcd, urb);
00686 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
00687 DWC_PRINTF("Called usb_hcd_giveback_urb()\n");
00688 DWC_PRINTF(" urb->status = %d\n", urb->status);
00689 }
00690
00691 return 0;
00692 }
00693
00694
00695
00696
00697 static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
00698 {
00699 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
00700
00701 DWC_DEBUGPL(DBG_HCD,
00702 "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
00703 "endpoint=%d\n", ep->desc.bEndpointAddress,
00704 dwc_ep_addr_to_endpoint(ep->desc.bEndpointAddress));
00705 dwc_otg_hcd_endpoint_disable(dwc_otg_hcd, ep->hcpriv, 250);
00706 ep->hcpriv = NULL;
00707 }
00708
00714 static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd)
00715 {
00716 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
00717 int32_t retval = dwc_otg_hcd_handle_intr(dwc_otg_hcd);
00718 if (retval != 0) {
00719 S3C2410X_CLEAR_EINTPEND();
00720 }
00721 return IRQ_RETVAL(retval);
00722 }
00723
00728 int hub_status_data(struct usb_hcd *hcd, char *buf)
00729 {
00730 dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
00731
00732 buf[0] = 0;
00733 buf[0] |= (dwc_otg_hcd_is_status_changed(dwc_otg_hcd, 1)) << 1;
00734
00735 return (buf[0] != 0);
00736 }
00737
00739 int hub_control(struct usb_hcd *hcd,
00740 u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
00741 {
00742 int retval;
00743
00744 retval = dwc_otg_hcd_hub_control(hcd_to_dwc_otg_hcd(hcd),
00745 typeReq, wValue, wIndex, buf, wLength);
00746
00747 switch (retval) {
00748 case -DWC_E_INVALID:
00749 retval = -EINVAL;
00750 break;
00751 }
00752
00753 return retval;
00754 }
00755
00756 #endif