Explorar o código

1.修改U盘升级慢的问题; 2.修改cable is bad导致的后续U盘不识别问题

huangliang hai 1 ano
pai
achega
032352b945

+ 7 - 1
linux/drivers/usb/core/hub.c

@@ -2929,7 +2929,13 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
 		delay = HUB_LONG_RESET_TIME;
 	}
 	
-	hub_port_error_notify(udev);
+	{
+		struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+		if (hcd->driver->reset_usb_controller)
+			hcd->driver->reset_usb_controller(hcd, 0);
+		else
+			hub_port_error_notify(udev);
+	}
 	dev_err(&port_dev->dev, "Cannot enable. Maybe the USB cable is bad?\n");
 
 done:

+ 39 - 1
linux/drivers/usb/musb/musb_core.c

@@ -2313,8 +2313,11 @@ static void musb_irq_work(struct work_struct *data)
 			musb_platform_try_idle(musb, jiffies
 				+ msecs_to_jiffies(musb->a_wait_bcon));
 
-		if (musb->ops->set_mode)
+		if (musb->ops->set_mode) {
+			musb->ops->set_mode(musb, MUSB_PERIPHERAL);
+			msleep(1000);
 			musb->ops->set_mode(musb, MUSB_OTG);
+		}
 	}
 
 	error = pm_runtime_get_sync(musb->controller);
@@ -2543,6 +2546,38 @@ static void musb_deassert_reset(struct work_struct *work)
 	spin_unlock_irqrestore(&musb->lock, flags);
 }
 
+static void musb_recovery_usb_proc(struct work_struct *work)
+{
+	struct musb *musb = NULL;
+
+	if (NULL == work)
+		return;
+
+	musb = container_of(work, struct musb, recovery_usb_work);
+	if (NULL == musb)
+		return;
+
+	if (musb->ops->set_mode)
+		musb->ops->set_mode(musb, MUSB_PERIPHERAL);
+	msleep(1000);
+	if (musb->ops->set_mode)
+		musb->ops->set_mode(musb, MUSB_OTG);
+}
+
+static void musb_reset_timer_handler(struct timer_list *t)
+{
+	struct musb *musb = NULL;
+
+	if (NULL == t)
+		return;
+
+	musb = container_of(t, struct musb, musb_reset_timer);
+	if (NULL == musb)
+		return;
+
+	schedule_work(&musb->recovery_usb_work);
+}
+
 /*
  * Perform generic per-controller initialization.
  *
@@ -2721,6 +2756,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	INIT_DELAYED_WORK(&musb->irq_work, musb_irq_work);
 	INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset);
 	INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume);
+	INIT_WORK(&musb->recovery_usb_work, musb_recovery_usb_proc);
+
+	timer_setup(&musb->musb_reset_timer, musb_reset_timer_handler, 0);
 
 	/* setup musb parts of the core (especially endpoints) */
 	status = musb_core_init(plat->config->multipoint

+ 2 - 0
linux/drivers/usb/musb/musb_core.h

@@ -281,6 +281,8 @@ struct musb {
 	struct delayed_work	deassert_reset_work;
 	struct delayed_work	finish_resume_work;
 	struct delayed_work	gadget_work;
+	struct work_struct recovery_usb_work;
+	struct timer_list musb_reset_timer;
 	u16			hwvers;
 
 	u16			intrrxe;

+ 22 - 0
linux/drivers/usb/musb/musb_host.c

@@ -2869,6 +2869,27 @@ static void musb_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 }
 #endif /* !CONFIG_MUSB_PIO_ONLY */
 
+static int musb_reset_usb_controller(struct usb_hcd *hcd, int mode)
+{
+	struct musb	*musb = NULL;
+	int ret = -1;
+
+	(void)mode;
+	if (NULL == hcd)
+		return ret;
+
+	musb = hcd_to_musb(hcd);
+	if (NULL == musb) {
+		return ret;
+	}
+
+	//printk("\n######### %s start at line:%d musb:%x\n\n", __func__, __LINE__, (int)musb);
+
+	mod_timer(&musb->musb_reset_timer, jiffies + msecs_to_jiffies(3000));
+
+	return 0;
+}
+
 static const struct hc_driver musb_hc_driver = {
 	.description		= "musb-hcd",
 	.product_desc		= "MUSB HDRC host driver",
@@ -2897,6 +2918,7 @@ static const struct hc_driver musb_hc_driver = {
 	.hub_control		= musb_hub_control,
 	.bus_suspend		= musb_bus_suspend,
 	.bus_resume		= musb_bus_resume,
+	.reset_usb_controller  = musb_reset_usb_controller
 	/* .start_port_reset	= NULL, */
 	/* .hub_irq_enable	= NULL, */
 };

+ 1 - 0
linux/include/linux/usb/hcd.h

@@ -407,6 +407,7 @@ struct hc_driver {
 	/* Call for power on/off the port if necessary */
 	int	(*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
 
+	int (*reset_usb_controller)(struct usb_hcd *hcd, int mode);
 };
 
 static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)

+ 6 - 0
u-boot/common/usb_storage.c

@@ -50,6 +50,8 @@
 #undef BBB_COMDAT_TRACE
 #undef BBB_XPORT_TRACE
 
+#define ARK_USB_MAX_XFER_BLK	1024
+
 #include <scsi.h>
 /* direction table -- this indicates the direction of the data
  * transfer for each command code -- a 1 indicates input
@@ -953,9 +955,13 @@ static void usb_stor_set_max_xfer_blk(struct usb_device *udev,
 	 * WRITE(10) commands are limited to 65535 blocks.
 	 */
 	blk = USHRT_MAX;
+#else
+#ifdef ARK_USB_MAX_XFER_BLK
+	blk = ARK_USB_MAX_XFER_BLK;
 #else
 	blk = 20;
 #endif
+#endif
 #else
 	ret = usb_get_max_xfer_size(udev, (size_t *)&size);
 	if (ret < 0) {