268 lines
8.7 KiB
Diff
268 lines
8.7 KiB
Diff
|
From e8bff0306f0d095082eea159133007f1de62b169 Mon Sep 17 00:00:00 2001
|
||
|
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
|
||
|
Date: Tue, 19 Mar 2013 20:35:21 +0100
|
||
|
Subject: [PATCH 213/364] Fix USB devices not being detected when
|
||
|
requested due to delayed attach.
|
||
|
|
||
|
---
|
||
|
ChangeLog | 5 +++++
|
||
|
grub-core/bus/usb/usbhub.c | 29 ++++++++++++++++++++++++-----
|
||
|
grub-core/commands/keystatus.c | 2 +-
|
||
|
grub-core/commands/terminal.c | 12 ++++++++++--
|
||
|
grub-core/commands/usbtest.c | 2 +-
|
||
|
grub-core/disk/usbms.c | 5 +++--
|
||
|
grub-core/kern/term.c | 4 ++--
|
||
|
include/grub/term.h | 2 +-
|
||
|
include/grub/usb.h | 2 +-
|
||
|
9 files changed, 48 insertions(+), 15 deletions(-)
|
||
|
|
||
|
diff --git a/ChangeLog b/ChangeLog
|
||
|
index 94dd5bb..725fbe2 100644
|
||
|
--- a/ChangeLog
|
||
|
+++ b/ChangeLog
|
||
|
@@ -1,5 +1,10 @@
|
||
|
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.
|
||
|
|
||
|
2013-03-19 Vladimir Serbinenko <phcoder@gmail.com>
|
||
|
diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
|
||
|
index f95a567..253e49f 100644
|
||
|
--- a/grub-core/bus/usb/usbhub.c
|
||
|
+++ b/grub-core/bus/usb/usbhub.c
|
||
|
@@ -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);
|
||
|
}
|
||
|
diff --git a/grub-core/commands/keystatus.c b/grub-core/commands/keystatus.c
|
||
|
index 0925c6a..460cf4e 100644
|
||
|
--- a/grub-core/commands/keystatus.c
|
||
|
+++ b/grub-core/commands/keystatus.c
|
||
|
@@ -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)
|
||
|
{
|
||
|
diff --git a/grub-core/commands/terminal.c b/grub-core/commands/terminal.c
|
||
|
index 425a411..3002186 100644
|
||
|
--- a/grub-core/commands/terminal.c
|
||
|
+++ b/grub-core/commands/terminal.c
|
||
|
@@ -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"),
|
||
|
diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c
|
||
|
index af35b8c..01cdca9 100644
|
||
|
--- a/grub-core/commands/usbtest.c
|
||
|
+++ b/grub-core/commands/usbtest.c
|
||
|
@@ -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);
|
||
|
diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c
|
||
|
index 2cfc537..da01be3 100644
|
||
|
--- a/grub-core/disk/usbms.c
|
||
|
+++ b/grub-core/disk/usbms.c
|
||
|
@@ -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,
|
||
|
diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c
|
||
|
index 44ada25..66c5971 100644
|
||
|
--- a/grub-core/kern/term.c
|
||
|
+++ b/grub-core/kern/term.c
|
||
|
@@ -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 ();
|
||
|
diff --git a/include/grub/term.h b/include/grub/term.h
|
||
|
index 84f5766..655a5e3 100644
|
||
|
--- a/include/grub/term.h
|
||
|
+++ b/include/grub/term.h
|
||
|
@@ -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
|
||
|
diff --git a/include/grub/usb.h b/include/grub/usb.h
|
||
|
index 32f0ecd..7164dd5 100644
|
||
|
--- a/include/grub/usb.h
|
||
|
+++ b/include/grub/usb.h
|
||
|
@@ -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
|
||
|
--
|
||
|
1.8.1.4
|
||
|
|