due to delayed attach.
+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.
static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES];
static int rescan = 0;
+static int npending = 0;
struct grub_usb_hub
{
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;
* 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;
}
}
/* 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;
}
void
-grub_usb_poll_devices (void)
+grub_usb_poll_devices (int wait_for_completion)
{
struct grub_usb_hub *hub;
int i;
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)
/* 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);
}
if (dev && dev->descdev.class == 0x09)
poll_nonroot_hub (dev);
}
- if (!rescan)
+ if (!(rescan || (npending && wait_for_completion)))
break;
grub_millisleep (50);
}
grub_term_input_t term;
if (grub_term_poll_usb)
- grub_term_poll_usb ();
+ grub_term_poll_usb (0);
FOR_ACTIVE_TERM_INPUTS(term)
{
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
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"),
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);
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])
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,
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. */
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 ();
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
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