musb: output an error when wrong speed is selected for the hostmode paul-manual
authorPaul Fertser <fercerpav@gmail.com>
Wed, 10 Nov 2010 14:08:13 +0000 (17:08 +0300)
committerPaul Fertser <fercerpav@gmail.com>
Wed, 10 Nov 2010 14:08:13 +0000 (17:08 +0300)
By monitoring kernel log the userspace will be able to detect improper
speed setting and warn the user or try to automatically readjust (by
disabling internal vbus and reentering the hostmode with the proper
speed).

Bump API to 20101110.

drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_procfs.c
drivers/usb/musb/musb_virthub.c

index 00dcc94..cd359c1 100644 (file)
@@ -65,7 +65,7 @@ struct musb_ep;
 
 /* This is the version of forced hostmode userspace<->kernelspace API.
  * Do not update to the build date, bump only on API changes */
-#define MUSB_VERSION_HOSTMODE  "20101104"
+#define MUSB_VERSION_HOSTMODE  "20101110"
 
 #ifdef CONFIG_USB_MUSB_OTG
 
index 8480b56..e8e0b27 100644 (file)
@@ -662,7 +662,7 @@ static int musb_proc_write(struct file *file, const char __user *buffer,
                /* Connect request */
                {
                struct usb_hcd *hcd = musb_to_hcd(musb);
-               u8 testmode;
+               u8 testmode, line;
 
                musb->is_active = 1;
                set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
@@ -685,7 +685,22 @@ static int musb_proc_write(struct file *file, const char __user *buffer,
                musb->port1_status |= USB_PORT_STAT_CONNECTION
                                        |(USB_PORT_STAT_C_CONNECTION << 16);
 
+               line = musb_ulpi_readb(mbase, ISP1704_DEBUG);
                testmode = musb_readb(mbase, MUSB_TESTMODE);
+
+               switch (line) {
+               case 1: /* pullup indicates a full/high-speed device */
+                       if (!(testmode & (MUSB_TEST_FORCE_FS | MUSB_TEST_FORCE_HS)))
+                               pr_err("Forced hostmode error: a full/high-speed device attached but low-speed mode selected\n"); 
+                       break;
+               case 2: /* pullup indicates a low-speed device */
+                       if (testmode & (MUSB_TEST_FORCE_FS | MUSB_TEST_FORCE_HS))
+                               pr_err("Forced hostmode error: a low-speed device attached but full/high-speed mode selected\n"); 
+                       break;
+               default:
+                       pr_err("Forced hostmode error: no device attached\n");
+               }
                if (!(testmode & (MUSB_TEST_FORCE_FS | MUSB_TEST_FORCE_HS)))
                        musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
 
index 7e7900f..bd033e5 100644 (file)
@@ -112,7 +112,7 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend)
 
 static void musb_port_reset(struct musb *musb, bool do_reset)
 {
-       u8              power;
+       u8              power, testmode;
        void __iomem    *mbase = musb->mregs;
 
 #ifdef CONFIG_USB_MUSB_OTG
@@ -162,10 +162,16 @@ static void musb_port_reset(struct musb *musb, bool do_reset)
 
                musb->ignore_disconnect = false;
 
+               testmode = musb_readb(mbase, MUSB_TESTMODE);
                power = musb_readb(mbase, MUSB_POWER);
                if (power & MUSB_POWER_HSMODE) {
                        DBG(4, "high-speed device connected\n");
                        musb->port1_status |= USB_PORT_STAT_HIGH_SPEED;
+                       if (!(testmode & MUSB_TEST_FORCE_HS))
+                               pr_err("Forced hostmode error: a high-speed device attached but not high-speed mode selected\n"); 
+               } else {
+                       if (testmode & MUSB_TEST_FORCE_HS)
+                               pr_err("Forced hostmode error: a full/low-speed device attached but high-speed mode selected\n"); 
                }
 
                musb->port1_status &= ~USB_PORT_STAT_RESET;