The various USB specifications all use one-based numbering for ports.
This scheme is applied consistently across the various relevant
specifications, covering both port numbers that appear on the wire
(i.e. downstream hub port numbers) and port numbers that exist only
logically (i.e. root hub port numbers).
The UEFI specification is ambiguous about the port numbers as used for
the ParentPortNumber field within a USB_DEVICE_PATH structure. As of
UEFI specification version 2.8 errata B:
- section 10.3.4.5 just states "USB Parent Port Number" with no
indication of being zero-based or one-based
- section 17.1.1 notes that for the EFI_USB2_HC_PROTOCOL, references
to PortNumber parameters are zero-based for root hub ports
- section 17.1.1 also mentions a TranslatorPortNumber used by
EFI_USB2_HC_PROTOCOL, with no indication of being zero-based or
one-based
- there are no other mentions of USB port numbering schemes.
Experimentation and inspection of the EDK2 codebase reveals that at
least the EDK2 reference implementation will use zero-based numbering
for both root and non-root hub ports when populating a USB_DEVICE_PATH
structure (though will inconsistently use one-based numbering for the
TranslatorPortNumber parameter).
Use zero-based numbering for both root and non-root hub ports when
constructing a USB_DEVICE_PATH in order to match the behaviour of the
EDK2 implementation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As noted in the comments, UEFI manages to combines the all of the
worst aspects of both a polling design (inefficiency and inability to
sleep until something interesting happens) and of an interrupt-driven
design (the complexity of code that could be preempted at any time,
thanks to UEFI timers).
This causes problems in particular for UEFI USB keyboards: the
keyboard driver calls UsbAsyncInterruptTransfer() to set up a periodic
timer which is used to poll the USB bus. This poll may interrupt a
critical section within iPXE, typically resulting in list corruption
and either a hang or reboot.
Work around this problem by mirroring the BIOS design, in which we run
with interrupts disabled almost all of the time.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the UEFI platform firmware to provide drivers for unrecognised
devices, by exposing our own implementation of EFI_USB_IO_PROTOCOL.
Signed-off-by: Michael Brown <mcb30@ipxe.org>