#include <linux/version.h>
#include <asm/io.h>
#include <linux/usb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
#include <../drivers/usb/core/hcd.h>
#else
#include <linux/usb/hcd.h>
/** @name Linux HC Driver API Functions */
/** @{ */
static int urb_enqueue(struct usb_hcd *hcd,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
struct usb_host_endpoint *ep,
#endif
struct urb *urb, gfp_t mem_flags);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
#else
static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
#endif
static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
#endif
static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
.flags = HCD_MEMORY | HCD_USB2,
- //.reset =
+ /* .reset = */
.start = hcd_start,
- //.suspend =
- //.resume =
+ /* .suspend = */
+ /* .resume = */
.stop = hcd_stop,
.urb_enqueue = urb_enqueue,
.urb_dequeue = urb_dequeue,
.endpoint_disable = endpoint_disable,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
.endpoint_reset = endpoint_reset,
#endif
.get_frame_number = get_frame_number,
.hub_status_data = hub_status_data,
.hub_control = hub_control,
- .bus_suspend = hcd_suspend ,
- .bus_resume = hcd_resume,
+ .bus_suspend = hcd_suspend,
+ .bus_resume = hcd_resume,
};
/** Gets the dwc_otg_hcd from a struct usb_hcd */
}
/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
-inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t * dwc_otg_hcd)
+static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd)
{
return dwc_otg_hcd_get_priv_data(dwc_otg_hcd);
}
-EXPORT_SYMBOL(dwc_otg_hcd_to_hcd);
/** Gets the usb_host_endpoint associated with an URB. */
inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
struct usb_device *dev = urb->dev;
int ep_num = usb_pipeendpoint(urb->pipe);
+ if (!dev)
+ return NULL;
+
if (usb_pipein(urb->pipe))
return dev->ep_in[ep_num];
else
return dev->ep_out[ep_num];
}
-static int _disconnect(dwc_otg_hcd_t * hcd)
+static int _disconnect(dwc_otg_hcd_t *hcd)
{
struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
return 0;
}
-static int _start(dwc_otg_hcd_t * hcd)
+static int _start(dwc_otg_hcd_t *hcd)
{
struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
return 0;
}
-static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr,
- uint32_t * port_addr)
+static int _hub_info(dwc_otg_hcd_t *hcd, void *urb_handle, uint32_t *hub_addr,
+ uint32_t *port_addr)
{
struct urb *urb = (struct urb *)urb_handle;
if (urb->dev->tt) {
return 0;
}
-static int _speed(dwc_otg_hcd_t * hcd, void *urb_handle)
+static int _speed(dwc_otg_hcd_t *hcd, void *urb_handle)
{
struct urb *urb = (struct urb *)urb_handle;
return urb->dev->speed;
}
-static int _get_b_hnp_enable(dwc_otg_hcd_t * hcd)
+static int _get_b_hnp_enable(dwc_otg_hcd_t *hcd)
{
struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
return usb_hcd->self.b_hnp_enable;
* Sets the final status of an URB and returns it to the device driver. Any
* required cleanup of the URB is performed.
*/
-static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
- dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
+static int _complete(dwc_otg_hcd_t *hcd, void *urb_handle,
+ dwc_otg_hcd_urb_t *dwc_otg_urb, int32_t status)
{
struct urb *urb = (struct urb *)urb_handle;
+ if (!urb)
+ return 0;
#ifdef DEBUG
if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n",
}
}
+ WARN((urb->actual_length > urb->transfer_buffer_length &&
+ usb_pipein(urb->pipe)),
+ "DWC_OTG Transfer buffer length less than actual buffer length"
+ "actual_length %d , buffer_length %d urb->complete %pF\n",
+ urb->actual_length, urb->transfer_buffer_length,
+ urb->complete);
+
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
int i;
if (ep) {
free_bus_bandwidth(dwc_otg_hcd_to_hcd(hcd),
dwc_otg_hcd_get_ep_bandwidth(hcd,
- ep->hcpriv),
+ ep->
+ hcpriv),
urb);
}
}
DWC_FREE(dwc_otg_urb);
+ usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
+
DWC_SPINUNLOCK(hcd->lock);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
#else
usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
{
struct dwc_otg_qh *_qh;
struct usb_host_endpoint *ep = dwc_urb_to_endpoint(_urb);
- if((ep)&&(ep->hcpriv))
- {
- _qh = (dwc_otg_qh_t *) ep->hcpriv;
+ if ((ep) && (ep->hcpriv)) {
+ _qh = (dwc_otg_qh_t *) ep->hcpriv;
_qh->data_toggle = 0;
}
}
.complete = _complete,
.get_b_hnp_enable = _get_b_hnp_enable,
};
+
static void dwc_otg_hcd_enable(struct work_struct *work)
{
dwc_otg_hcd_t *dwc_otg_hcd;
dwc_otg_hcd = container_of(work, dwc_otg_hcd_t, host_enable_work.work);
core_if = dwc_otg_hcd->core_if;
pldata = core_if->otg_dev->pldata;
- if(dwc_otg_hcd->host_enabled == dwc_otg_hcd->host_setenable){
-// DWC_PRINT("%s, enable flag %d\n", __func__, dwc_otg_hcd->host_setenable);
+ if (dwc_otg_hcd->host_enabled == dwc_otg_hcd->host_setenable) {
+ /* DWC_PRINT("%s, enable flag %d\n",
+ * __func__, dwc_otg_hcd->host_setenable); */
goto out;
}
-
- if(dwc_otg_hcd->host_setenable == 2){// enable -> disable
- if(pldata->get_status(USB_STATUS_DPDM)){// usb device connected
+
+ if (dwc_otg_hcd->host_setenable == 2) {/* enable -> disable */
+ if (pldata->get_status(USB_STATUS_DPDM)) {/* usb device connected */
dwc_otg_hcd->host_setenable = 1;
goto out;
}
DWC_PRINTF("%s, disable host controller\n", __func__);
#if 0
if (_core_if->hcd_cb && _core_if->hcd_cb->disconnect) {
- _core_if->hcd_cb->disconnect( _core_if->hcd_cb->p );
+ _core_if->hcd_cb->disconnect(_core_if->hcd_cb->p);
}
#endif
- pldata->soft_reset();
- dwc_otg_disable_host_interrupts( core_if );
- if(pldata->phy_suspend)
- pldata->phy_suspend( pldata, USB_PHY_SUSPEND);
+ pldata->soft_reset(pldata, RST_RECNT);
+ dwc_otg_disable_host_interrupts(core_if);
+ if (pldata->phy_suspend)
+ pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
udelay(3);
- pldata->clock_enable( pldata, 0);
- }else if(dwc_otg_hcd->host_setenable == 1){
+ pldata->clock_enable(pldata, 0);
+ } else if (dwc_otg_hcd->host_setenable == 1) {
DWC_PRINTF("%s, enable host controller\n", __func__);
- pldata->clock_enable( pldata, 1);
- if(pldata->phy_suspend)
- pldata->phy_suspend( pldata, USB_PHY_ENABLED);
+ pldata->clock_enable(pldata, 1);
+ if (pldata->phy_suspend)
+ pldata->phy_suspend(pldata, USB_PHY_ENABLED);
mdelay(5);
dwc_otg_core_init(core_if);
dwc_otg_enable_global_interrupts(core_if);
out:
return;
}
+
static void dwc_otg_hcd_connect_detect(unsigned long pdata)
{
- dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *)pdata;
+ dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *) pdata;
dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
unsigned long flags;
struct dwc_otg_platform_data *pldata;
pldata = core_if->otg_dev->pldata;
local_irq_save(flags);
- if(pldata->get_status(USB_STATUS_DPDM)) // usb device connected
- {
+ if (pldata->get_status(USB_STATUS_DPDM)) {
+ /* usb device connected */
dwc_otg_hcd->host_setenable = 1;
+ } else {
+ /* no device, suspend host */
+ if ((dwc_otg_read_hprt0(core_if) & 1) == 0)
+ dwc_otg_hcd->host_setenable = 2;
}
- else
- { // no device, suspend host
- if((dwc_otg_read_hprt0(core_if) & 1) == 0)
- dwc_otg_hcd->host_setenable = 2;
- }
- if((dwc_otg_hcd->host_enabled) && (dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled)){
+ if ((dwc_otg_hcd->host_enabled)
+ && (dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled)) {
schedule_delayed_work(&dwc_otg_hcd->host_enable_work, 1);
}
- mod_timer(&dwc_otg_hcd->connect_detect_timer,jiffies + (HZ<<1));
+ mod_timer(&dwc_otg_hcd->connect_detect_timer, jiffies + (HZ << 1));
local_irq_restore(flags);
return;
}
+static void otg20_hcd_connect_detect(struct work_struct *work)
+{
+ dwc_otg_hcd_t *dwc_otg_hcd =
+ container_of(work, dwc_otg_hcd_t, host_enable_work.work);
+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
+ struct dwc_otg_platform_data *pldata;
+ pldata = core_if->otg_dev->pldata;
+
+ if (pldata->phy_status == USB_PHY_SUSPEND) {
+ pldata->clock_enable(pldata, 1);
+ pldata->phy_suspend(pldata, USB_PHY_ENABLED);
+ }
+ dwc_otg_core_init(core_if);
+ dwc_otg_enable_global_interrupts(core_if);
+ cil_hcd_start(core_if);
+}
+
/**
* Initializes the HCD. This function allocates memory for and initializes the
* static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
* USB bus with the core and calls the hc_driver->start() function. It returns
* a negative error on failure.
*/
-int otg20_hcd_init( struct platform_device *_dev )
+int otg20_hcd_init(struct platform_device *_dev)
{
struct usb_hcd *hcd = NULL;
dwc_otg_hcd_t *dwc_otg_hcd = NULL;
dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
int retval = 0;
int irq;
- static u64 usb_dmamask = 0xffffffffUL;
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
- /* Set device flags indicating whether the HCD supports DMA. */
- if (dwc_otg_is_dma_enable(otg_dev->core_if)) {
-
- _dev->dev.dma_mask = &usb_dmamask;
- _dev->dev.coherent_dma_mask = ~0;
- } else {
-
- _dev->dev.dma_mask = (void *)0;
- _dev->dev.coherent_dma_mask = 0;
- }
-
/*
* Allocate memory for the base HCD plus the DWC OTG HCD.
* Initialize the base HCD.
*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, _dev->dev.bus_id);
#else
- hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, dev_name(&_dev->dev));
+ hcd =
+ usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev,
+ dev_name(&_dev->dev));
hcd->has_tt = 1;
-// hcd->uses_new_polling = 1;
-// hcd->poll_rh = 0;
+ /* hcd->uses_new_polling = 1; */
+ /* hcd->poll_rh = 0; */
#endif
if (!hcd) {
retval = -ENOMEM;
otg_dev->hcd->otg_dev = otg_dev;
hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
-#if 0//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) //don't support for LM(with 2.6.20.1 kernel)
+#if 0
+ /* #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) */
+ /* don't support for LM(with 2.6.20.1 kernel) */
hcd->self.otg_version = dwc_otg_get_otg_version(otg_dev->core_if);
/* Don't support SG list at this point */
hcd->self.sg_tablesize = 0;
#endif
-#if 0//LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+#if 0
+ /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) */
/* Do not to do HNP polling if not capable */
- //if (otg_dev->core_if->otg_ver)
- // hcd->self.is_hnp_cap = dwc_otg_get_hnpcapable(otg_dev->core_if);
+ /* if (otg_dev->core_if->otg_ver) */
+ /* hcd->self.is_hnp_cap = dwc_otg_get_hnpcapable(otg_dev->core_if); */
#endif
/*
* Finish generic HCD initialization and start the HCD. This function
* allocates the DMA buffer pool, registers the USB bus, requests the
* IRQ line, and calls hcd_start method.
*/
- irq = platform_get_irq(_dev,0);
+ irq = platform_get_irq(_dev, 0);
retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
if (retval < 0) {
goto error2;
dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
dwc_otg_hcd->host_enabled = 1;
-
+ if (dwc_otg_is_host_mode(otg_dev->core_if) ||
+ (otg_dev->core_if->usb_mode == USB_MODE_FORCE_HOST)) {
+ INIT_DELAYED_WORK(&dwc_otg_hcd->host_enable_work,
+ otg20_hcd_connect_detect);
+ schedule_delayed_work(&dwc_otg_hcd->host_enable_work, 0);
+ }
return 0;
error2:
return retval;
}
-
/**
* Initializes the HCD. This function allocates memory for and initializes the
* static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
* USB bus with the core and calls the hc_driver->start() function. It returns
* a negative error on failure.
*/
-int host20_hcd_init( struct platform_device *_dev )
+int host20_hcd_init(struct platform_device *_dev)
{
struct usb_hcd *hcd = NULL;
dwc_otg_hcd_t *dwc_otg_hcd = NULL;
dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
int retval = 0;
int irq;
- static u64 usb_dmamask = 0xffffffffUL;
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
- /* Set device flags indicating whether the HCD supports DMA. */
- if (dwc_otg_is_dma_enable(otg_dev->core_if)) {
-
- _dev->dev.dma_mask = &usb_dmamask;
- _dev->dev.coherent_dma_mask = ~0;
- } else {
-
- _dev->dev.dma_mask = (void *)0;
- _dev->dev.coherent_dma_mask = 0;
- }
-
/*
* Allocate memory for the base HCD plus the DWC OTG HCD.
* Initialize the base HCD.
*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, _dev->dev.bus_id);
#else
- hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, dev_name(&_dev->dev));
+ hcd =
+ usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev,
+ dev_name(&_dev->dev));
hcd->has_tt = 1;
-// hcd->uses_new_polling = 1;
-// hcd->poll_rh = 0;
+ /* hcd->uses_new_polling = 1; */
+ /* hcd->poll_rh = 0; */
#endif
if (!hcd) {
retval = -ENOMEM;
otg_dev->hcd->otg_dev = otg_dev;
hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
-#if 0//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) //don't support for LM(with 2.6.20.1 kernel)
+#if 0
+ /* #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) */
+ /* don't support for LM(with 2.6.20.1 kernel) */
hcd->self.otg_version = dwc_otg_get_otg_version(otg_dev->core_if);
/* Don't support SG list at this point */
hcd->self.sg_tablesize = 0;
#endif
-#if 0//LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+#if 0
+ /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) */
/* Do not to do HNP polling if not capable */
- //if (otg_dev->core_if->otg_ver)
- // hcd->self.is_hnp_cap = dwc_otg_get_hnpcapable(otg_dev->core_if);
+ /* if (otg_dev->core_if->otg_ver) */
+ /* hcd->self.is_hnp_cap = dwc_otg_get_hnpcapable(otg_dev->core_if);*/
#endif
/*
* Finish generic HCD initialization and start the HCD. This function
* allocates the DMA buffer pool, registers the USB bus, requests the
* IRQ line, and calls hcd_start method.
*/
- irq = platform_get_irq(_dev,0);
+ irq = platform_get_irq(_dev, 0);
retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
if (retval < 0) {
goto error2;
dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
- dwc_otg_hcd->host_enabled = 1;
- dwc_otg_hcd->host_setenable = 1;
+ dwc_otg_hcd->host_enabled = 2;
+ dwc_otg_hcd->host_setenable = 2;
dwc_otg_hcd->connect_detect_timer.function = dwc_otg_hcd_connect_detect;
dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd);
- init_timer( &dwc_otg_hcd->connect_detect_timer);
- mod_timer(&dwc_otg_hcd->connect_detect_timer, jiffies+(HZ<<3));
-
+ init_timer(&dwc_otg_hcd->connect_detect_timer);
+ mod_timer(&dwc_otg_hcd->connect_detect_timer, jiffies + (HZ << 1));
+
INIT_DELAYED_WORK(&dwc_otg_hcd->host_enable_work, dwc_otg_hcd_enable);
return 0;
* Removes the HCD.
* Frees memory and resources associated with the HCD and deregisters the bus.
*/
-void hcd_remove(
-
- struct platform_device *_dev
- )
+void hcd_remove(struct platform_device *_dev)
{
dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
dwc_otg_hcd_stop(dwc_otg_hcd);
}
-
static int dwc_otg_hcd_suspend(struct usb_hcd *hcd)
{
- dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd);
+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
hprt0_data_t hprt0;
pcgcctl_data_t pcgcctl;
struct dwc_otg_platform_data *pldata;
pldata = core_if->otg_dev->pldata;
- if(core_if->op_state == B_PERIPHERAL){
+ if (core_if->op_state == B_PERIPHERAL) {
DWC_PRINTF("%s, usb device mode\n", __func__);
return 0;
}
- if(!(dwc_otg_hcd->host_enabled&1))
+ if (!(dwc_otg_hcd->host_enabled & 1))
return 0;
hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
-#ifdef CONFIG_PM_RUNTIME
- if((!hprt0.b.prtena) && (!hprt0.b.prtpwr))
+#ifdef CONFIG_PM_RUNTIME
+ if ((!hprt0.b.prtena) && (!hprt0.b.prtpwr))
return 0;
-#endif
- DWC_PRINTF("%s suspend, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
+#endif
+ DWC_PRINTF("%s suspend, HPRT0:0x%x\n", hcd->self.bus_name, hprt0.d32);
- if(hprt0.b.prtconnsts){ // usb device connected
- if(!hprt0.b.prtsusp)
- {
+ if (hprt0.b.prtconnsts) { /* usb device connected */
+ if (!hprt0.b.prtsusp) {
hprt0.b.prtsusp = 1;
hprt0.b.prtena = 0;
DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
udelay(10);
hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
- if(!hprt0.b.prtsusp)
- {
+ if (!hprt0.b.prtsusp) {
hprt0.b.prtsusp = 1;
hprt0.b.prtena = 0;
DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
mdelay(5);
pcgcctl.d32 = DWC_READ_REG32(core_if->pcgcctl);
- //Partial Power-Down mode not enable
+ /* Partial Power-Down mode not enable */
pcgcctl.b.pwrclmp = 0;
DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
udelay(1);
- //pcgcctl.b.rstpdwnmodule = 1;//reset PDM
- pcgcctl.b.stoppclk = 1;//stop phy clk
+ /* reset PDM */
+ /* pcgcctl.b.rstpdwnmodule = 1; */
+ pcgcctl.b.stoppclk = 1; /* stop phy clk */
DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
- }
- else{ //no device connect
- if(!pldata->get_status(USB_REMOTE_WAKEUP)){
- if(pldata->phy_suspend)
+ } else {/* no device connect */
+ if (!pldata->get_status(USB_REMOTE_WAKEUP)) {
+ if (pldata->phy_suspend)
pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
+ udelay(3);
if (pldata->clock_enable)
- pldata->clock_enable(pldata, 0);
+ pldata->clock_enable(pldata, 0);
}
}
- udelay(3);
-
return 0;
}
-
static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
{
- dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd);
+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
hprt0_data_t hprt0;
pcgcctl_data_t pcgcctl;
gintmsk_data_t gintmsk;
struct dwc_otg_platform_data *pldata;
pldata = core_if->otg_dev->pldata;
-
- if(core_if->op_state == B_PERIPHERAL){
- DWC_PRINTF("%s, usb device mode\n", __func__);
+
+ if (core_if->op_state == B_PERIPHERAL) {
+ DWC_PRINTF("%s, usb device mode\n", __func__);
return 0;
}
-
-//#ifdef CONFIG_PM_RUNTIME
- if(!(dwc_otg_hcd->host_enabled&1))
+/* #ifdef CONFIG_PM_RUNTIME */
+ if (!(dwc_otg_hcd->host_enabled & 1))
return 0;
-//#endif
+/* #endif */
- if(!pldata->get_status(USB_REMOTE_WAKEUP)){
+ if (!pldata->get_status(USB_REMOTE_WAKEUP)) {
if (pldata->clock_enable)
- pldata->clock_enable( pldata, 1);
+ pldata->clock_enable(pldata, 1);
}
- hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
+ hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
#ifdef CONFIG_PM_RUNTIME
- //USB HCD already resumed by remote wakeup, return now
- if((!hprt0.b.prtsusp) && (hprt0.b.prtena))
+ /* USB HCD already resumed by remote wakeup, return now */
+ if ((!hprt0.b.prtsusp) && (hprt0.b.prtena))
return 0;
#endif
- //power on
+ /* power on */
pcgcctl.d32 = DWC_READ_REG32(core_if->pcgcctl);;
- pcgcctl.b.stoppclk = 0;//restart phy clk
+ pcgcctl.b.stoppclk = 0; /* restart phy clk */
DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
udelay(1);
- pcgcctl.b.pwrclmp = 0;//power clamp
+ pcgcctl.b.pwrclmp = 0; /* power clamp */
DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
udelay(2);
gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
gintmsk.b.portintr = 0;
DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
-
+
hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
#ifdef CONFIG_PM_RUNTIME
- if((!hprt0.b.prtena) && (!hprt0.b.prtpwr))
+ if ((!hprt0.b.prtena) && (!hprt0.b.prtpwr))
return 0;
#endif
- DWC_PRINTF("%s resume, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
-
- if(hprt0.b.prtconnsts){
- //hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
- //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
- hprt0.b.prtpwr = 1;
+ DWC_PRINTF("%s resume, HPRT0:0x%x\n", hcd->self.bus_name, hprt0.d32);
+
+ if (hprt0.b.prtconnsts) {
+ /* hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); */
+ /* DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32); */
+ hprt0.b.prtpwr = 1;
hprt0.b.prtres = 1;
hprt0.b.prtena = 0;
DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
mdelay(20);
- hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
- //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
- //hprt0.d32 = 0;
- hprt0.b.prtpwr = 1;
+ hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
+ /* DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32); */
+ /* hprt0.d32 = 0; */
+ hprt0.b.prtpwr = 1;
hprt0.b.prtres = 0;
hprt0.b.prtena = 0;
DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
hprt0.b.prtconndet = 1;
DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
- //hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
- //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
-
+ /* hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); */
+ /* DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32); */
+
mdelay(10);
- }
- else{
- if(!pldata->get_status(USB_REMOTE_WAKEUP)){
- if(pldata->phy_suspend)
- pldata->phy_suspend( pldata, USB_PHY_ENABLED);
+ } else {
+ if (!pldata->get_status(USB_REMOTE_WAKEUP)) {
+ if (pldata->phy_suspend)
+ pldata->phy_suspend(pldata, USB_PHY_ENABLED);
}
}
gintmsk.b.portintr = 1;
/** HCD Suspend */
int hcd_suspend(struct usb_hcd *hcd)
{
- //dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
+ /* dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); */
DWC_DEBUGPL(DBG_HCD, "HCD SUSPEND\n");
/** HCD resume */
int hcd_resume(struct usb_hcd *hcd)
{
- //dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
+ /* dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); */
DWC_DEBUGPL(DBG_HCD, "HCD RESUME\n");
-
+
dwc_otg_hcd_resume(hcd);
return 0;
}
-
/** Returns the current frame number. */
static int get_frame_number(struct usb_hcd *hcd)
{
DWC_PRINTF(" Device address: %d\n", usb_pipedevice(urb->pipe));
DWC_PRINTF(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
(usb_pipein(urb->pipe) ? "IN" : "OUT"));
- DWC_PRINTF(" Endpoint type: %s\n", ( {
+ DWC_PRINTF(" Endpoint type: %s\n", ({
char *pipetype;
switch (usb_pipetype(urb->pipe)) {
-case PIPE_CONTROL:
-pipetype = "CONTROL"; break; case PIPE_BULK:
-pipetype = "BULK"; break; case PIPE_INTERRUPT:
-pipetype = "INTERRUPT"; break; case PIPE_ISOCHRONOUS:
-pipetype = "ISOCHRONOUS"; break; default:
- pipetype = "UNKNOWN"; break;};
- pipetype;}
- )) ;
- DWC_PRINTF(" Speed: %s\n", ( {
- char *speed; switch (urb->dev->speed) {
-case USB_SPEED_HIGH:
-speed = "HIGH"; break; case USB_SPEED_FULL:
-speed = "FULL"; break; case USB_SPEED_LOW:
-speed = "LOW"; break; default:
- speed = "UNKNOWN"; break;};
- speed;}
- )) ;
+ case PIPE_CONTROL:
+ pipetype = "CONTROL";
+ break;
+ case PIPE_BULK:
+ pipetype = "BULK";
+ break;
+ case PIPE_INTERRUPT:
+ pipetype = "INTERRUPT";
+ break;
+ case PIPE_ISOCHRONOUS:
+ pipetype = "ISOCHRONOUS";
+ break;
+ default:
+ pipetype = "UNKNOWN";
+ break; };
+ pipetype; }
+ )) ;
+ DWC_PRINTF(" Speed: %s\n", ({
+ char *speed;
+ switch (urb->dev->speed) {
+ case USB_SPEED_HIGH:
+ speed = "HIGH";
+ break;
+ case USB_SPEED_FULL:
+ speed = "FULL";
+ break;
+ case USB_SPEED_LOW:
+ speed = "LOW";
+ break;
+ default:
+ speed = "UNKNOWN";
+ break; };
+ speed; }
+ )) ;
DWC_PRINTF(" Max packet size: %d\n",
usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
DWC_PRINTF(" Data buffer length: %d\n", urb->transfer_buffer_length);
* (URB). mem_flags indicates the type of memory allocation to use while
* processing this URB. */
static int urb_enqueue(struct usb_hcd *hcd,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
struct usb_host_endpoint *ep,
#endif
struct urb *urb, gfp_t mem_flags)
{
int retval = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
struct usb_host_endpoint *ep = urb->ep;
#endif
dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
int alloc_bandwidth = 0;
uint8_t ep_type = 0;
uint32_t flags = 0;
+ dwc_irqflags_t irq_flags;
void *buf;
#ifdef DEBUG
}
#endif
- if(atomic_read(&urb->use_count)>1){
+ if (unlikely(atomic_read(&urb->use_count) > 1)) {
+ retval = -EPERM;
+ printk("%s urb %p already in queue, qtd %p, use_count %d\n",
+ __func__, urb, urb->hcpriv,
+ atomic_read(&urb->use_count));
+ return retval;
+ }
+
+ if (unlikely(atomic_read(&urb->reject))) {
retval = -EPERM;
- printk("%s urb %p already in queue, qtd %p, count%d\n",
- __func__, urb, urb->hcpriv, atomic_read(&urb->use_count));
- return retval;
+ DWC_DEBUGPL(DBG_HCD,
+ "%s urb %p submissions will fail,reject %d,count %d\n",
+ __func__, urb, atomic_read(&urb->reject),
+ atomic_read(&urb->use_count));
+ return retval;
}
if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
usb_maxpacket(urb->dev, urb->pipe,
!(usb_pipein(urb->pipe))));
- if((uint32_t)urb->transfer_buffer & 3){
- DWC_PRINTF("%s urb->transfer_buffer address not align to 4-byte 0x%x\n",
- __func__, (uint32_t)urb->transfer_buffer);
+#ifdef DEBUG
+ if ((uint32_t) urb->transfer_buffer & 3) {
+ DWC_PRINTF
+ ("%s urb->transfer_buffer address not align to 4-byte 0x%x\n",
+ __func__, (uint32_t) urb->transfer_buffer);
}
+#endif
buf = urb->transfer_buffer;
for (i = 0; i < urb->number_of_packets; ++i) {
dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_urb, i,
- urb->
- iso_frame_desc[i].offset,
- urb->
- iso_frame_desc[i].length);
+ urb->iso_frame_desc[i].
+ offset,
+ urb->iso_frame_desc[i].
+ length);
}
urb->hcpriv = dwc_otg_urb;
+
+ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irq_flags);
+ retval = usb_hcd_link_urb_to_ep(hcd, urb);
+ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irq_flags);
+ if (retval)
+ goto fail1;
+
retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb, &ep->hcpriv,
mem_flags == GFP_ATOMIC ? 1 : 0);
- if (!retval) {
- if (alloc_bandwidth) {
- allocate_bus_bandwidth(hcd,
- dwc_otg_hcd_get_ep_bandwidth
- (dwc_otg_hcd, ep->hcpriv), urb);
- }
- } else {
- if (retval == -DWC_E_NO_DEVICE) {
+ if (retval) {
+ if (retval == -DWC_E_NO_DEVICE)
retval = -ENODEV;
- }
+ goto fail2;
+ }
+
+ if (alloc_bandwidth) {
+ allocate_bus_bandwidth(hcd, dwc_otg_hcd_get_ep_bandwidth
+ (dwc_otg_hcd, ep->hcpriv), urb);
}
+ return 0;
+fail2:
+ /* */
+ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irq_flags);
+ dwc_otg_urb->priv = NULL;
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irq_flags);
+fail1:
+ urb->hcpriv = NULL;
+ DWC_FREE(dwc_otg_urb);
return retval;
}
/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
* success. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
#else
static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
#endif
{
+ int rc;
dwc_irqflags_t flags;
dwc_otg_hcd_t *dwc_otg_hcd;
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
}
#endif
- DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
-
- if(((uint32_t)urb&0xf0000000)==0){
+ if (!urb) {
DWC_PRINTF("%s error: urb is %p!!!\n", __func__, urb);
- goto out1;
+ return 0;
}
-
- if(((uint32_t)urb->hcpriv&0xf0000000) == 0){
- DWC_PRINTF("%s error: urb->hcpriv %p urb %p, count %d!!!\n",__func__,
- urb->hcpriv, urb, atomic_read(&urb->use_count));
- if((atomic_read(&urb->use_count)) == 1)
- goto out2;
- else{
- DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
- return 0;
- }
+
+ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
+ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (rc) {
+ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
+ return rc;
}
-
- dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, urb->hcpriv);
-out2:
+ dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, urb->hcpriv);
DWC_FREE(urb->hcpriv);
urb->hcpriv = NULL;
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
/* Higher layer software sets URB status. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
usb_hcd_giveback_urb(hcd, urb);
#else
usb_hcd_giveback_urb(hcd, urb, status);
DWC_PRINTF("Called usb_hcd_giveback_urb()\n");
DWC_PRINTF(" urb->status = %d\n", urb->status);
}
-out1:
+
return 0;
}
ep->hcpriv = NULL;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
-/* Resets endpoint specific parameter values, in current version used to reset
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+/* Resets endpoint specific parameter values, in current version used to reset
* the data toggle(as a WA). This function can be called from usb_clear_halt routine */
static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
{
else
return;
- DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n", epnum);
+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n",
+ epnum);
DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
usb_settoggle(udev, epnum, is_out, 0);
dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
int32_t retval = dwc_otg_hcd_handle_intr(dwc_otg_hcd);
if (retval != 0) {
- //S3C2410X_CLEAR_EINTPEND();
+ /* S3C2410X_CLEAR_EINTPEND(); */
}
return IRQ_RETVAL(retval);
}