]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Fix USB devices not being detected when requested
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 19 Mar 2013 19:35:21 +0000 (20:35 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 19 Mar 2013 19:35:21 +0000 (20:35 +0100)
due to delayed attach.

ChangeLog
grub-core/bus/usb/usbhub.c
grub-core/commands/keystatus.c
grub-core/commands/terminal.c
grub-core/commands/usbtest.c
grub-core/disk/usbms.c
grub-core/kern/term.c
include/grub/term.h
include/grub/usb.h

index 94dd5bb6f1d19dca436c59aee9543f4ae84350c3..725fbe29a976eb149191a2581d8d235d0669e076 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-19  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Fix USB devices not being detected when requested
+       due to delayed attach.
+
 2013-03-19  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Implement boot time analysis framework.
index f95a567883a23860a1f20b7232f443fec42ddb8b..253e49f9245e908c395ce1a9488215a35a55fac1 100644 (file)
@@ -29,6 +29,7 @@
 static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES];
 
 static int rescan = 0;
+static int npending = 0;
 
 struct grub_usb_hub
 {
@@ -227,21 +228,33 @@ attach_root_port (struct grub_usb_hub *hub, int portno,
       if (current_speed == GRUB_USB_SPEED_NONE)
         i = 0;
     }
+
+  grub_boot_time ("After the stable power wait portno=%d", portno);
+
   grub_dprintf ("usb", "total=%d\n", total);
   if (total >= 2000)
-    return;
+    {
+      grub_boot_time ("Root port timeout");
+      return;
+    }
+
+  grub_boot_time ("After detect_dev");
 
   /* Enable the port.  */
   err = hub->controller->dev->portstatus (hub->controller, portno, 1);
   if (err)
     return;
   hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
+  npending++;
 
   grub_millisleep (10);
 
+  grub_boot_time ("Port enabled");
+
   /* Enable the port and create a device.  */
   dev = grub_usb_hub_add_dev (hub->controller, speed, portno, 0);
   hub->controller->dev->pending_reset = 0;
+  npending--;
   if (! dev)
     return;
 
@@ -475,6 +488,7 @@ poll_nonroot_hub (grub_usb_device_t dev)
               * anywhere on the same OHCI controller until
               * we will finish addressing of reseted device ! */
               dev->controller.dev->pending_reset = grub_get_time_ms () + 5000;
+             npending++;
               return;
            }
        }
@@ -510,7 +524,11 @@ poll_nonroot_hub (grub_usb_device_t dev)
 
              /* Add the device and assign a device address to it.  */
              next_dev = grub_usb_hub_add_dev (&dev->controller, speed, i, dev->addr);
-             dev->controller.dev->pending_reset = 0;
+             if (dev->controller.dev->pending_reset)
+               {
+                 dev->controller.dev->pending_reset = 0;
+                 npending--;
+               }
              if (! next_dev)
                continue;
 
@@ -525,7 +543,7 @@ poll_nonroot_hub (grub_usb_device_t dev)
 }
 
 void
-grub_usb_poll_devices (void)
+grub_usb_poll_devices (int wait_for_completion)
 {
   struct grub_usb_hub *hub;
   int i;
@@ -539,7 +557,7 @@ grub_usb_poll_devices (void)
          grub_usb_speed_t speed = GRUB_USB_SPEED_NONE;
          int changed = 0;
 
-          if (!hub->controller->dev->pending_reset)
+          if (hub->controller->dev->pending_reset)
             {
               /* Check for possible timeout */
               if (grub_get_time_ms () > hub->controller->dev->pending_reset)
@@ -547,6 +565,7 @@ grub_usb_poll_devices (void)
                   /* Something went wrong, reset device was not
                    * addressed properly, timeout happened */
                  hub->controller->dev->pending_reset = 0;
+                 npending--;
                  speed = hub->controller->dev->detect_dev (hub->controller,
                                                             i, &changed);
                 }
@@ -573,7 +592,7 @@ grub_usb_poll_devices (void)
          if (dev && dev->descdev.class == 0x09)
            poll_nonroot_hub (dev);
        }
-      if (!rescan)
+      if (!(rescan || (npending && wait_for_completion)))
        break;
       grub_millisleep (50);
     }
index 0925c6a0f9e3ddbc35690983befa0b0045d1da07..460cf4e7e50c0ee95b4c938853dda4a99b1b51e0 100644 (file)
@@ -42,7 +42,7 @@ grub_getkeystatus (void)
   grub_term_input_t term;
 
   if (grub_term_poll_usb)
-    grub_term_poll_usb ();
+    grub_term_poll_usb (0);
 
   FOR_ACTIVE_TERM_INPUTS(term)
   {
index 425a41126e754c05b6d444da7976585157327018..3002186d266252ecb6f454a3b41525c789d47a12 100644 (file)
@@ -108,9 +108,9 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
          if (term)
            break;
          if (again)
-           return grub_error (GRUB_ERR_BAD_ARGUMENT,
+          return grub_error (GRUB_ERR_BAD_ARGUMENT,
                              N_("terminal `%s' isn't found"),
-                              args[i]);
+                             args[i]);
          for (aut = autoloads; aut; aut = aut->next)
            if (grub_strcmp (args[i], aut->name) == 0
               || (grub_strcmp (args[i], "ofconsole") == 0
@@ -126,6 +126,14 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
                grub_errno = GRUB_ERR_NONE;
                break;
              }
+        if (grub_memcmp (args[i], "serial_usb",
+                                 sizeof ("serial_usb") - 1) == 0
+            && grub_term_poll_usb)
+          {
+            grub_term_poll_usb (1);
+            again = 1;
+            continue;
+          }
          if (!aut)
            return grub_error (GRUB_ERR_BAD_ARGUMENT,
                              N_("terminal `%s' isn't found"),
index af35b8c194659d1d0f2f977fedaa8d908d8e693c..01cdca93466863cc20597f2a0db373e5fd2c71fd 100644 (file)
@@ -196,7 +196,7 @@ grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)),
                  int argc __attribute__ ((unused)),
                  char **args __attribute__ ((unused)))
 {
-  grub_usb_poll_devices ();
+  grub_usb_poll_devices (1);
 
   grub_printf ("USB devices:\n\n");
   grub_usb_iterate (usb_iterate, NULL);
index 2cfc537112d5fbca9881a68fc8c59ea763c0e092..da01be3bd2cc9f0302440efd1687691dbd9aab9b 100644 (file)
@@ -277,7 +277,7 @@ grub_usbms_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
   if (pull != GRUB_DISK_PULL_NONE)
     return 0;
 
-  grub_usb_poll_devices ();
+  grub_usb_poll_devices (1);
 
   for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
     if (grub_usbms_devices[i])
@@ -611,7 +611,8 @@ grub_usbms_open (int id, int devnum, struct grub_scsi *scsi)
     return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
                       "not USB Mass Storage device");
 
-  grub_usb_poll_devices ();
+  if (!grub_usbms_devices[devnum])
+    grub_usb_poll_devices (1);
 
   if (!grub_usbms_devices[devnum])
     return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
index 44ada252488845cf5db4906528205d4c9c2e3e31..66c597130a76c1688b860c20e1471bca7c6e6f8b 100644 (file)
@@ -32,7 +32,7 @@ struct grub_term_input *grub_term_inputs;
 grub_uint8_t grub_term_normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR;
 grub_uint8_t grub_term_highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR;
 
-void (*grub_term_poll_usb) (void) = NULL;
+void (*grub_term_poll_usb) (int wait_for_completion) = NULL;
 void (*grub_net_poll_cards_idle) (void) = NULL;
 
 /* Put a Unicode character.  */
@@ -90,7 +90,7 @@ grub_getkey_noblock (void)
   grub_term_input_t term;
 
   if (grub_term_poll_usb)
-    grub_term_poll_usb ();
+    grub_term_poll_usb (0);
 
   if (grub_net_poll_cards_idle)
     grub_net_poll_cards_idle ();
index 84f576685cdda05679b2c7622d18067fbb34763b..655a5e33b9debce0f880943500565723bdb247e5 100644 (file)
@@ -467,7 +467,7 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces)
     grub_putcode (' ', term);
 }
 
-extern void (*EXPORT_VAR (grub_term_poll_usb)) (void);
+extern void (*EXPORT_VAR (grub_term_poll_usb)) (int wait_for_completion);
 
 #define GRUB_TERM_REPEAT_PRE_INTERVAL 400
 #define GRUB_TERM_REPEAT_INTERVAL 50
index 32f0ecdbb55de71fb16a491cea893af154cea3f2..7164dd5a441a31390a58f117b4efb02f69e4d66b 100644 (file)
@@ -291,7 +291,7 @@ struct grub_usb_attach_desc
 void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc);
 void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc);
 
-void grub_usb_poll_devices (void);
+void grub_usb_poll_devices (int wait_for_completion);
 
 void grub_usb_device_attach (grub_usb_device_t dev);
 grub_usb_err_t