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