+2009-12-22 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * bus/usb/uhci.c (grub_uhci_transfer): Set a limit transaction time.
+ (grub_uhci_portstatus): Likewise.
+ (grub_uhci_portstatus): Add necessary delay.
+
2009-12-21 Carles Pina i Estany <carles@pina.cat>
-
+
* commands/acpi.c (options): Fix capitalizations and/or full stops.
(GRUB_MOD_INIT): Likewise.
* commands/boot.c (GRUB_MOD_INIT): Likewise.
#include <grub/usb.h>
#include <grub/usbtrans.h>
#include <grub/pci.h>
-#include <grub/cpu/pci.h>
#include <grub/i386/io.h>
#include <grub/time.h>
grub_uhci_td_t td_prev = NULL;
grub_usb_err_t err = GRUB_USB_ERR_NONE;
int i;
+ grub_uint64_t endtime;
/* Allocate a queue head for the transfer queue. */
qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
/* Wait until either the transaction completed or an error
occurred. */
+ endtime = grub_get_time_ms () + 1000;
for (;;)
{
grub_uhci_td_t errtd;
updated. */
grub_dprintf ("uhci", "transaction fallthrough\n");
}
+ if (grub_get_time_ms () > endtime)
+ {
+ err = GRUB_USB_ERR_STALL;
+ grub_dprintf ("uhci", "transaction timed out\n");
+ goto fail;
+ }
+ grub_cpu_idle ();
}
grub_dprintf ("uhci", "transaction complete\n");
struct grub_uhci *u = (struct grub_uhci *) dev->data;
int reg;
unsigned int status;
+ grub_uint64_t endtime;
grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port);
status = grub_uhci_readreg16 (u, reg);
grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
grub_dprintf ("uhci", "reset completed\n");
+ grub_millisleep (10);
/* Enable the port. */
grub_uhci_writereg16 (u, reg, enable << 2);
grub_dprintf ("uhci", "waiting for the port to be enabled\n");
- while (! (grub_uhci_readreg16 (u, reg) & (1 << 2)));
+ endtime = grub_get_time_ms () + 1000;
+ while (! (grub_uhci_readreg16 (u, reg) & (1 << 2)))
+ if (grub_get_time_ms () > endtime)
+ return grub_error (GRUB_ERR_IO, "UHCI Timed out");
status = grub_uhci_readreg16 (u, reg);
grub_dprintf ("uhci", ">3detect=0x%02x\n", status);