*
* @param _core_if Programming view of DWC_otg controller.
*/
+#ifdef DWC_BOTH_HOST_SLAVE
+extern void dwc_otg_force_device(dwc_otg_core_if_t *core_if);
+extern void dwc_otg_force_host(dwc_otg_core_if_t *core_if);
+extern int rk28_usb_suspend( int exitsuspend );
+#endif
int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *_core_if)
{
gintsts_data_t gintsts = { .d32 = 0 };
+ #ifdef DWC_BOTH_HOST_SLAVE
+ uint32_t count = 0;
+ dwc_otg_pcd_t *pcd = _core_if->otg_dev->pcd;
+ gintmsk_data_t gintmsk = { .d32 = 0 };
+ gotgctl_data_t gotgctl = { .d32 = 0 };
+ if(pcd &&(pcd->phy_suspend == 1))
+ {
+ rk28_usb_suspend( 1 );
+ }
+
+ /*
+ * yangkai@rk, 20100331
+ * ³äµçÆ÷½ÓÈëʱÓпÉÄÜUSB IDΪµÍ, ´ËÊ±Ó¦ÌØ±ð´¦Àí£¬²»Çл»³ÉHOST£»
+ * ×¢Òâ,Èç¹ûhostÉ豸Èç¹û¿ìËٰβ壬»áµ±³ÉUSB_IDΪµÍµÄ³äµçÆ÷´¦Àí
+ */
+ gotgctl.d32 = dwc_read_reg32( &_core_if->core_global_regs->gotgctl );
+ #if 1
+ if((!gotgctl.b.conidsts)&&( gotgctl.b.bsesvld ))
+ {
+ if(pcd &&(pcd->vbus_status == 0))
+ pcd->vbus_status = 1;
+ gintsts.b.conidstschng = 1;
+ dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
+ return 1;
+ }
+ #endif
+// cmy: Ö»Óе±usb´¦ÓÚÕý³£Ä£Ê½Ê±£¬²Å´¦Àí¸ÃÖжϽøÐÐÇл»
+ if(_core_if->usb_mode != USB_MODE_NORMAL)
+ {
+ DWC_PRINT("_core_if->usb_mode=%d\n", _core_if->usb_mode);
+ gintsts.b.conidstschng = 1;
+ dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
+ return 1;
+ }
+ DWC_DEBUGPL(DBG_CIL, "switch\n");
+
+ /*
+ * Need to disable SOF interrupt immediately. If switching from device
+ * to host, the PCD interrupt handler won't handle the interrupt if
+ * host mode is already set. The HCD interrupt handler won't get
+ * called if the HCD state is HALT. This means that the interrupt does
+ * not get handled and Linux complains loudly.
+ */
+ gintmsk.b.sofintr = 1;
+ dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
+
+ DWC_DEBUGPL(DBG_CIL, " ++Connector ID Status Change Interrupt++ (%s)\n",
+ (dwc_otg_is_host_mode(_core_if)?"Host":"Device"));
+ gotgctl.d32 = dwc_read_reg32(&_core_if->core_global_regs->gotgctl);
+ DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
+ DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
+
+ /* B-Device connector (Device Mode) */
+ if (gotgctl.b.conidsts) {
+ /* Wait for switch to device mode. */
+ while (!dwc_otg_is_device_mode(_core_if) ){
+ DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n",
+ (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral"));
+ MDELAY(100);
+ if (++count > 10000) *(uint32_t*)NULL=0;
+ }
+ hcd_stop(_core_if);
+ _core_if->op_state = B_PERIPHERAL;
+ //pcd->phy_suspend = 1;
+ pcd->vbus_status = 0;
+ dwc_otg_pcd_start_vbus_timer( pcd );
+ } else {
+ /* A-Device connector (Host Mode) */
+ while (!dwc_otg_is_host_mode(_core_if) ) {
+ DWC_PRINT("Waiting for Host Mode, Mode=%s\n",
+ (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral"));
+ MDELAY(100);
+ if (++count > 10000) *(uint32_t*)NULL=0;
+ }
+ dwc_otg_force_host(_core_if);
+ }
+ #endif
/* Set flag and clear interrupt */
gintsts.b.conidstschng = 1;
dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
}
static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store);
#ifdef CONFIG_USB
+
+extern struct usb_hub *g_root_hub20;
+#ifdef DWC_BOTH_HOST_SLAVE
+extern void hcd_start( dwc_otg_core_if_t *_core_if );
+
+extern int rk28_usb_suspend( int exitsuspend );
+extern void hub_disconnect_device(struct usb_hub *hub);
+
+static ssize_t force_usb_mode_show(struct device_driver *_drv, char *_buf)
+{
+ dwc_otg_device_t *otg_dev = g_otgdev;
+ dwc_otg_core_if_t *core_if = otg_dev->core_if;
+#if 1
+ return sprintf (_buf, "%d\n", core_if->usb_mode);
+#else
+ dwc_otg_device_t *otg_dev = lm_get_drvdata(g_lmdev);
+ dwc_otg_core_if_t *core_if = otg_dev->core_if;
+ gotgctl_data_t gctrl;
+ gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl );
+ printk("OTGCTL=0x%08X\n", gctrl.d32);
+
+ if(g_usb_mode == USB_NORMAL_MODE)
+ return sprintf (_buf, "Current usb mode: Normal Mode\n");
+ else if(g_usb_mode == FORCE_HOST_MODE)
+ return sprintf (_buf, "Current usb mode: Force Host\n");
+ else if(g_usb_mode == FORCE_DEVICE_MODE)
+ return sprintf (_buf, "Current usb mode: Force Device\n");
+ else
+ return sprintf (_buf, "Current usb mode: Unknown\n");
+#endif
+}
+
+void dwc_otg_force_host(dwc_otg_core_if_t *core_if)
+{
+ dwc_otg_device_t *otg_dev = g_otgdev;
+ dctl_data_t dctl = {.d32=0};
+ if(core_if->op_state == A_HOST)
+ {
+ printk("dwc_otg_force_host,already in A_HOST mode,everest\n");
+ return;
+ }
+ if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1))
+ {
+ rk28_usb_suspend( 1 );
+ }
+ del_timer(&otg_dev->pcd->check_vbus_timer);
+ // force disconnect
+ /* soft disconnect */
+ dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
+ dctl.b.sftdiscon = 1;
+ dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
+
+ if (core_if->pcd_cb && core_if->pcd_cb->stop ) {
+ core_if->pcd_cb->stop( core_if->pcd_cb->p );
+ }
+
+ //core_if->op_state = A_HOST;
+ /*
+ * Initialize the Core for Host mode.
+ */
+ dwc_otg_core_init(core_if);
+ dwc_otg_enable_global_interrupts(core_if);
+ hcd_start( core_if );
+
+}
+void dwc_otg_force_device(dwc_otg_core_if_t *core_if)
+{
+ dwc_otg_device_t *otg_dev = g_otgdev;
+ dwc_otg_disable_global_interrupts( core_if );
+ if (core_if->hcd_cb && core_if->hcd_cb->stop) {
+ core_if->hcd_cb->stop( core_if->hcd_cb->p );
+ }
+ if(core_if->op_state == B_PERIPHERAL)
+ {
+ printk("dwc_otg_force_device,already in B_PERIPHERAL,everest\n");
+ return;
+ }
+ hub_disconnect_device(g_root_hub20);
+ otg_dev->core_if->op_state = B_PERIPHERAL;
+ /* Reset the Controller */
+ dwc_otg_core_reset( core_if );
+ //otg_dev->pcd->phy_suspend = 1;
+ otg_dev->pcd->vbus_status = 0;
+ dwc_otg_pcd_start_vbus_timer( otg_dev->pcd );
+
+}
+static void dwc_otg_set_gusbcfg(dwc_otg_core_if_t *core_if, int mode)
+{
+ gusbcfg_data_t usbcfg = { .d32 = 0 };
+
+ usbcfg.d32 = dwc_read_reg32( &core_if->core_global_regs->gusbcfg);
+ switch(mode)
+ {
+ case USB_MODE_FORCE_HOST:
+ usbcfg.b.force_hst_mode = 1;
+ usbcfg.b.force_dev_mode = 0;
+ break;
+ case USB_MODE_FORCE_DEVICE:
+ usbcfg.b.force_hst_mode = 0;
+ usbcfg.b.force_dev_mode = 1;
+ break;
+ case USB_MODE_NORMAL:
+ usbcfg.b.force_hst_mode = 0;
+ usbcfg.b.force_dev_mode = 0;
+ break;
+ }
+ dwc_write_reg32( &core_if->core_global_regs->gusbcfg, usbcfg.d32 );
+}
+
+static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf,
+ size_t _count )
+{
+ int new_mode = simple_strtoul(_buf, NULL, 16);
+ dwc_otg_device_t *otg_dev = g_otgdev;
+ dwc_otg_core_if_t *core_if = otg_dev->core_if;
+ DWC_PRINT("%s %d->%d\n",__func__, core_if->usb_mode, new_mode);
+ if(core_if->usb_mode == new_mode)
+ {
+ return _count;
+ }
+
+ switch(new_mode)
+ {
+ case USB_MODE_FORCE_HOST:
+ if(USB_MODE_FORCE_DEVICE == core_if->usb_mode)
+ {/* device-->host */
+ core_if->usb_mode = new_mode;
+ dwc_otg_force_host(core_if);
+ }
+ else if(USB_MODE_NORMAL == core_if->usb_mode)
+ {
+ core_if->usb_mode = new_mode;
+ if(dwc_otg_is_host_mode(core_if))
+ {
+ dwc_otg_set_gusbcfg(core_if, new_mode);
+ }
+ else
+ {
+ dwc_otg_force_host(core_if);
+ }
+ }
+ else
+ core_if->usb_mode = new_mode;
+ break;
+ case USB_MODE_FORCE_DEVICE:
+ if(USB_MODE_FORCE_HOST == core_if->usb_mode)
+ {
+ core_if->usb_mode = new_mode;
+ dwc_otg_force_device(core_if);
+ }
+ else if(USB_MODE_NORMAL == core_if->usb_mode)
+ {
+ core_if->usb_mode = new_mode;
+ if(dwc_otg_is_device_mode(core_if))
+ {
+ dwc_otg_set_gusbcfg(core_if, new_mode);
+ }
+ else
+ {
+ dwc_otg_force_device(core_if);
+ }
+ }
+ break;
+ case USB_MODE_NORMAL:
+ #if 1
+ if(USB_MODE_FORCE_DEVICE == core_if->usb_mode)
+ {
+ core_if->usb_mode = new_mode;
+ if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1))
+ {
+ rk28_usb_suspend( 1 );
+ }
+ del_timer(&otg_dev->pcd->check_vbus_timer);
+ dwc_otg_set_gusbcfg(core_if, new_mode);
+ msleep(50);
+ if(dwc_otg_is_host_mode(core_if))
+ {
+ dwc_otg_force_host(core_if);
+ }
+ else
+ {
+ dwc_otg_pcd_start_vbus_timer( otg_dev->pcd );
+ }
+ //mdelay(10);
+ //core_if->usb_mode = new_mode;
+ //if(!dwc_otg_connid(core_if))
+ // dwc_otg_force_host(core_if);
+ }
+ else if(USB_MODE_FORCE_HOST == core_if->usb_mode)
+ {
+ if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1))
+ {
+ rk28_usb_suspend( 1 );
+ }
+ core_if->usb_mode = new_mode;
+ dwc_otg_set_gusbcfg(core_if, new_mode);
+ msleep(100);
+ if(dwc_otg_is_device_mode(core_if))
+ {
+ dwc_otg_force_device(core_if);
+ }
+ //if(dwc_otg_connid(core_if))
+ // hub_disconnect_device();
+ //core_if->usb_mode = new_mode;
+ // dwc_otg_force_device(core_if);
+ }
+ #endif
+ break;
+ default:
+ break;
+ }
+ return _count;
+}
+static DRIVER_ATTR(force_usb_mode, 0666/*S_IRUGO|S_IWUSR*/, force_usb_mode_show, force_usb_mode_store);
+#endif
static ssize_t dwc_otg_enable_show( struct device *_dev,
struct device_attribute *attr, char *buf)
{
#endif
static ssize_t dwc_otg_conn_en_show(struct device_driver *_drv, char *_buf)
{
-#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
dwc_otg_device_t *otg_dev = g_otgdev;
dwc_otg_pcd_t *_pcd = otg_dev->pcd;
return sprintf (_buf, "%d\n", _pcd->conn_en);
static ssize_t dwc_otg_conn_en_store(struct device_driver *_drv, const char *_buf,
size_t _count)
{
-#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
int enable = simple_strtoul(_buf, NULL, 10);
dwc_otg_device_t *otg_dev = g_otgdev;
dwc_otg_pcd_t *_pcd = otg_dev->pcd;
return _count;
}
static DRIVER_ATTR(dwc_otg_conn_en, S_IRUGO|S_IWUSR, dwc_otg_conn_en_show, dwc_otg_conn_en_store);
-#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
static ssize_t vbus_status_show(struct device_driver *_drv, char *_buf)
{
dwc_otg_device_t *otg_dev = g_otgdev;
}
static DRIVER_ATTR(vbus_status, S_IRUGO|S_IWUSR, vbus_status_show, NULL);
#endif
+volatile depctl_data_t depctl_ep0 = {.d32 = 0};
+volatile depctl_data_t depctl_ep2 = {.d32 = 0};
+volatile depctl_data_t depctl_ep4 = {.d32 = 0};
+void dwc_otg_epout_save(void)
+{
+ dwc_otg_device_t *otg_dev = g_otgdev;
+ dwc_otg_dev_if_t *dev_if = otg_dev->core_if->dev_if;
+ volatile depctl_data_t depctl = {.d32 = 0};
+ volatile grstctl_t grstctl = {.d32 = 0};
+ grstctl.d32 = dwc_read_reg32(&otg_dev->core_if->core_global_regs->grstctl);
+
+ while(grstctl.b.ahbidle != 1)
+ {
+ grstctl.d32 = dwc_read_reg32(&otg_dev->core_if->core_global_regs->grstctl);
+ }
+ depctl_ep0.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
+ depctl.d32 = depctl_ep0.d32;
+ if(depctl.b.epena)
+ {
+ depctl.b.epena = 0;
+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, depctl.d32);
+ }
+ depctl_ep2.d32 = dwc_read_reg32(&dev_if->out_ep_regs[2]->doepctl);
+ depctl.d32 = depctl_ep2.d32;
+ if(depctl.b.epena)
+ {
+ depctl.b.epena = 0;
+ dwc_write_reg32(&dev_if->out_ep_regs[2]->doepctl, depctl.d32);
+ }
+ depctl_ep4.d32 = dwc_read_reg32(&dev_if->out_ep_regs[4]->doepctl);
+ depctl.d32 = depctl_ep4.d32;
+ if(depctl.b.epena)
+ {
+ depctl.b.epena = 0;
+ dwc_write_reg32(&dev_if->out_ep_regs[4]->doepctl, depctl.d32);
+ }
+}
+void dwc_otg_epout_restore(void)
+{
+ dwc_otg_device_t *otg_dev = g_otgdev;
+ dwc_otg_dev_if_t *dev_if = otg_dev->core_if->dev_if;
+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, depctl_ep0.d32);
+ dwc_write_reg32(&dev_if->out_ep_regs[2]->doepctl, depctl_ep2.d32);
+ dwc_write_reg32(&dev_if->out_ep_regs[4]->doepctl, depctl_ep4.d32);
+}
/**
* This function is called during module intialization to verify that
free_irq( platform_get_irq(to_platform_device(dev),0), otg_dev );
}
-#ifdef CONFIG_DWC_OTG_HOST_ONLY
+#ifndef CONFIG_DWC_OTG_DEVICE_ONLY
if (otg_dev->hcd != NULL)
{
dwc_otg_hcd_remove(dev);
}
#endif
-#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
if (otg_dev->pcd != NULL)
{
dwc_otg_pcd_remove(dev);
* Create Device Attributes in sysfs
*/
dwc_otg_attr_create(dev);
-#ifdef CONFIG_DWC_OTG_HOST_ONLY
+#ifndef CONFIG_DWC_OTG_DEVICE_ONLY
retval |= device_create_file(dev, &dev_attr_enable);
#endif
#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_DEVICE;
+#else
+#ifdef CONFIG_DWC_OTG_HOST_ONLY
+ dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_HOST;
#else
+
+#ifdef CONFIG_DWC_OTG_DEFAULT_HOST
dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_HOST;
+#else
+ dwc_otg_device->core_if->usb_mode = USB_MODE_NORMAL;
+#endif
+
+#endif
#endif
/*
/* Initialize the bus state. If the core is in Device Mode
* HALT the USB bus and return. */
-#ifdef CONFIG_DWC_OTG_HOST_ONLY
+#ifndef CONFIG_DWC_OTG_DEVICE_ONLY
USB_IOMUX_INIT(GPIO4A5_OTG0DRVVBUS_NAME, GPIO4L_OTG0_DRV_VBUS);
/*
* Initialize the HCD
goto fail;
}
#endif
-#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
/*
* Initialize the PCD
*/
* handlers are installed.
*/
dwc_otg_enable_global_interrupts( dwc_otg_device->core_if );
-#ifdef CONFIG_DWC_OTG_HOST_ONLY
-#ifndef CONFIG_USB20_OTG_EN
- clk_disable(dwc_otg_device->phyclk);
- clk_disable(dwc_otg_device->ahbclk);
- *otg_phy_con1 |= (0x01<<2);
- *otg_phy_con1 &= ~(0x01<<3); // enter suspend.
-#endif
+#ifndef CONFIG_DWC_OTG_DEVICE_ONLY
+ if(dwc_otg_device->hcd->host_enabled == 0)
+ {
+ clk_disable(dwc_otg_device->phyclk);
+ clk_disable(dwc_otg_device->ahbclk);
+ *otg_phy_con1 |= (0x01<<2);
+ *otg_phy_con1 &= ~(0x01<<3); // enter suspend.
+ }
#endif
DWC_PRINT("dwc_otg_driver_probe end, everest\n");
return 0;
return retval;
}
-#ifndef DWC_HOST_ONLY
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
extern int rk28_usb_suspend( int exitsuspend );
static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t state )
{
DWC_PRINT("%s,A_HOST mode\n", __func__);
return 0;
}
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
+
+ rk28_usb_suspend(1);
/* soft disconnect */
/* 20100226,HSL@RK,if not disconnect,when usb cable in,will auto reconnect
/* Clear any pending interrupts */
dwc_write_reg32( &global_regs->gintsts, 0xeFFFFFFF);
+
dwc_otg_enable_global_interrupts(core_if);
mod_timer(&otg_dev->pcd->check_vbus_timer , jiffies + (HZ<<2));
{
core_if->usb_wakeup = 0;
}
+ DWC_PRINT("%s gahbcfg:0x%x\n", __func__, global_regs->gahbcfg);
+#endif
return 0;
}
pr_warning("DWC_OTG: Failed to create driver version file\n");
if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_debuglevel))
pr_warning("DWC_OTG: Failed to create driver debug level file\n");
-
-#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_conn_en))
pr_warning("DWC_OTG: Failed to create driver dwc_otg_conn_en file");
+#endif
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_vbus_status))
pr_warning("DWC_OTG: Failed to create driver vbus status file");
#endif
+#ifdef DWC_BOTH_HOST_SLAVE
+ if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode))
+ pr_warning("DWC_OTG: Failed to create driver force usb mode file\n");
+#endif
/*
* USB1.1 host controller
driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel);
-#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+#ifdef DWC_BOTH_HOST_SLAVE
+ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode);
+#endif
+#ifndef CONFIG_DWC_OTG_HOST_ONLY
driver_remove_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_conn_en);
#endif
+#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_vbus_status);
+#endif
platform_driver_unregister(&dwc_otg_driver);
dwc_otg_qh_t *qh;
struct list_head *qtd_item;
dwc_otg_qtd_t *qtd;
+ struct urb *urb;
+ struct usb_host_endpoint *ep;
list_for_each(qh_item, _qh_list) {
qh = list_entry(qh_item, dwc_otg_qh_t, qh_list_entry);
qtd_item = qh->qtd_list.next) {
qtd = list_entry(qtd_item, dwc_otg_qtd_t, qtd_list_entry);
if (qtd->urb != NULL) {
+ urb = qtd->urb;
+ ep = qtd->urb->ep;
+ // 20110415 yk
+ // urb will be re entry to ep->urb_list if use ETIMEOUT
dwc_otg_hcd_complete_urb(_hcd, qtd->urb,
- -ETIMEDOUT);
+ -ETIMEDOUT);//ESHUTDOWN
+
+ //if(!list_empty(&ep->urb_list))
+ DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
+ __func__, urb, usb_pipedevice(urb->pipe),
+ usb_pipeendpoint(urb->pipe),
+ usb_pipein(urb->pipe) ? "IN" : "OUT", urb->unlinked);
+
+ if (!urb->unlinked)
+ urb->unlinked = -ESHUTDOWN;
+
}
dwc_otg_hcd_qtd_remove_and_free(qtd);
}
static int32_t dwc_otg_hcd_disconnect_cb( void *_p )
{
gintsts_data_t intr;
- dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p);
+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p);
- //DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
+ //DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
- /*
- * Set status flags for the hub driver.
- */
-// DWC_PRINT("dwc_otg_hcd_disconnect_cb");
- dwc_otg_hcd->flags.b.port_connect_status_change = 1;
+ /*
+ * Set status flags for the hub driver.
+ */
+ dwc_otg_hcd->flags.b.port_connect_status_change = 1;
dwc_otg_hcd->flags.b.port_connect_status = 0;
- /*
- * Shutdown any transfers in process by clearing the Tx FIFO Empty
- * interrupt mask and status bits and disabling subsequent host
- * channel interrupts.
- */
- intr.d32 = 0;
- intr.b.nptxfempty = 1;
- intr.b.ptxfempty = 1;
+ /*
+ * Shutdown any transfers in process by clearing the Tx FIFO Empty
+ * interrupt mask and status bits and disabling subsequent host
+ * channel interrupts.
+ */
+ intr.d32 = 0;
+ intr.b.nptxfempty = 1;
+ intr.b.ptxfempty = 1;
intr.b.hcintr = 1;
- dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintmsk, intr.d32, 0);
- dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintsts, intr.d32, 0);
+ dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintmsk, intr.d32, 0);
+ dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintsts, intr.d32, 0);
del_timers(dwc_otg_hcd);
}
}
- /* A disconnect will end the session so the B-Device is no
- * longer a B-host. */
- ((struct usb_hcd *)_p)->self.is_b_host = 0;
- return 1;
+ /* A disconnect will end the session so the B-Device is no
+ * longer a B-host. */
+ ((struct usb_hcd *)_p)->self.is_b_host = 0;
+ return 1;
}
/**
dwc_otg_qtd_t * urb_qtd;
dwc_otg_qh_t * qh;
struct usb_host_endpoint *_ep = _urb->ep;//dwc_urb_to_endpoint(_urb);
- int retval;
+ //int retval;
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
urb_qtd = (dwc_otg_qtd_t *) _urb->hcpriv;
spin_lock(&_hcd->lock);
}
-
+void dwc_otg_clear_halt(struct urb *_urb)
+{
+ 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;
+ _qh->data_toggle = 0;
+ }
+}
/*
* Returns the Queue Head for an URB.
*/