if ((revision & 0xFF) != 0x10)
goto fail;
- grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA,
- (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA)
- & ~GRUB_OHCI_RHUB_PORT_POWER_MASK)
- | GRUB_OHCI_RHUB_PORT_ALL_POWERED);
-
+ {
+ grub_uint32_t control;
+ /* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */
+ control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+ if ((control & 0x100) != 0)
+ {
+ unsigned i;
+ grub_dprintf("ohci", "OHCI is owned by SMM\n");
+ /* Do change of ownership */
+ /* Ownership change request */
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, (1<<3)); /* XXX: Magic. */
+ /* Waiting for SMM deactivation */
+ for (i=0; i < 10; i++)
+ {
+ if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & 0x100) == 0)
+ {
+ grub_dprintf("ohci", "Ownership changed normally.\n");
+ break;
+ }
+ grub_millisleep (100);
+ }
+ if (i >= 10)
+ {
+ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
+ grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~0x100);
+ grub_dprintf("ohci", "Ownership changing timeout, change forced !\n");
+ }
+ }
+ else if (((control & 0x100) == 0) &&
+ ((control & 0xc0) != 0)) /* Not owned by SMM nor reset */
+ {
+ grub_dprintf("ohci", "OHCI is owned by BIOS\n");
+ /* Do change of ownership - not implemented yet... */
+ /* In fact we probably need to do nothing ...? */
+ }
+ else
+ {
+ grub_dprintf("ohci", "OHCI is not owned by SMM nor BIOS\n");
+ /* We can setup OHCI. */
+ }
+ }
/* Suspend the OHCI by issuing a reset. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */