If I `OvmfPkg/builds.sh qemu -usb -device usb-audio -device qemu-xhci` I see 2 USB handle? When you open EXCLUSIVE you are kicking other people off the handles. I’m not sure that is a good idea for you to do that to every USB handle in the system. If there was a handle that represented a USB to USB bridge seems like you could kick all the children off…. So when you are probing try using GET_PROTOCOL, and only use EXCLUSIVE after you find the device you want to manage. Thanks, Andrew Fish > On Jul 17, 2021, at 11:10 AM, Ethin Probst wrote: > > Thanks, Andrew. So it appears as though only a single handle exists > ("AF: DevicePath(..)/Pci(0x1D,0x0)/USB(0x0,0x0)) USBIO") but my app is > getting two handles, one of which doesn't actually exist. I still am > unsure why though. Getting verbose info about handle AF yields an > interface with class 0x01, subclass 0x01, and protocol 0x04, so this > appears to match the USB audio control interface. However, no audio > streaming device is available, as I would expect. Attempting to set > the interface to `1` also fails on the UAC device (though the USB > specification does note that this is not necessarily an error and may > just indicate that that interface setting is not supported so my app > currently just continues on regardless). I am running with qemu args > `-usb -device usb-audio,... -audiodev ...`. I've tried with `-device > qemu-xhci ...` but I get the same result. > > On 7/17/21, Andrew Fish > wrote: >> >> >>> On Jul 17, 2021, at 10:06 AM, Ethin Probst >>> wrote: >>> >>> Okay, so I just tried dh -v 7EDE4C18 (that was the handle that I'm >>> getting from `HandleBuffer()`) and it says "dh: Handle - '7EDE4C18' >>> not found". So I'm definitely confused because that's what >>> `HandleBuffer()` is getting me. Should I pre-allocate the buffer? >>> >> >> Ethin, >> >> The UEFI Shell `dh` command UI uses handle numbers from 0 - N as hex >> digits. You have use these abstract values with the `dh` command. For >> example: use `dh -v A1` to see the actual handle value for A1 (7EBA9598). >> You can search handles that contain a specific protocol... >> >> Shell> dh -p PciIo >> Handle dump by protocol 'PCIIO' >> A1: PCIIO DevicePath(PciRoot(0x0)/Pci(0x0,0x0)) >> A2: PCIIO DevicePath(PciRoot(0x0)/Pci(0x1,0x0)) >> A3: PCIIO DevicePath(PciRoot(0x0)/Pci(0x2,0x0)) >> A4: PCIIO DevicePath(..0)/Pci(0x2,0x0)/Pci(0x0,0x0)) >> A5: PCIIO DevicePath(..0)/Pci(0x2,0x0)/Pci(0x1,0x0)) >> A6: PCIIO DevicePath(..0)/Pci(0x2,0x0)/Pci(0x2,0x0)) >> A7: PCIIO DevicePath(..0)/Pci(0x2,0x0)/Pci(0x3,0x0)) >> A8: PCIIO DevicePath(..0)/Pci(0x2,0x0)/Pci(0x4,0x0)) >> A9: PCIIO DevicePath(..0)/Pci(0x2,0x0)/Pci(0x5,0x0)) >> AA: PCIIO DevicePath(PciRoot(0x0)/Pci(0x1E,0x0)) >> AB: DiskIO BlockIO FA920010-6785-4941-B6EC-498C579F160A PCIIO >> DevicePath(..)/Pci(0x1E,0x0)/Pci(0x0,0x0)) >> AC: ISAACPI PCIIO DevicePath(PciRoot(0x0)/Pci(0x1F,0x0)) >> AD: PCIIO DevicePath(PciRoot(0x0)/Pci(0x1F,0x3)) >> Shell> dh -v A1 >> A1: 7EBA9598 >> PCIIO(7EBA8AA8) >> Segment #.....: 00 >> Bus #.........: 00 >> Device #......: 00 >> Function #....: 00 >> ROM Size......: 0 >> ROM Location..: 00000000 >> Vendor ID.....: 8086 >> Device ID.....: 29C0 >> Class Code....: 00 00 06 >> Configuration Header : >> 8680C029070000000000000600000000 >> 00000000000000000000000000000000 >> 000000000000000000000000F41A0011 >> 000000000000000000000000FF000000 >> DevicePath(7EBA9E18) >> PciRoot(0x0)/Pci(0x0,0x0) >> >> Thanks, >> >> Andrew Fish >> >>> On 7/17/21, Ethin Probst wrote: >>>> I mean, possible... The code I'm using to initialize the handle buffer >>>> is >>>> this: >>>> >>>> ```C >>>> EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imageHandle, IN >>>> EFI_SYSTEM_TABLE* >>>> st) { >>>> Print(L"Attempting to find USB IO protocol\n"); >>>> UINTN numHandles = 0; >>>> UINTN i = 0; >>>> UINT32 UsbStatus = 0; >>>> EFI_HANDLE* handles = NULL; >>>> EFI_USB_IO_PROTOCOL* UsbIo = NULL; >>>> EFI_STATUS status = st->BootServices->LocateHandleBuffer(ByProtocol, >>>> &gEfiUsbIoProtocolGuid, NULL, &numHandles, &handles); >>>> if (EFI_ERROR(status)) { >>>> Print(L"Cannot find any handles for USB devices, reason: %r\n", >>>> status); >>>> return EFI_ABORTED; >>>> } >>>> Print(L"Found %d USB devices; enumerating\n", numHandles); >>>> for (; i < numHandles; ++i) { >>>> Print(L"Trying to open handle %d (%x)... ", i, handles[i]); >>>> status = st->BootServices->OpenProtocol(handles[i], >>>> &gEfiUsbIoProtocolGuid, (void**)&UsbIo, imageHandle, NULL, >>>> EFI_OPEN_PROTOCOL_EXCLUSIVE); >>>> if (EFI_ERROR(status)) { >>>> Print(L"%r, skipping\n", status); >>>> continue; >>>> } >>>> // ... >>>> ``` >>>> I've done my best to follow SEI secure C coding standards, like >>>> initializing all variables, regardless of type -- e.g. initializing >>>> pointers to 0/NULL. But I will definitely try that idea. >>>> >>>> On 7/17/21, Andrew Fish wrote: >>>>> >>>>> >>>>>> On Jul 17, 2021, at 9:41 AM, Ethin Probst >>>>>> wrote: >>>>>> >>>>>> Hey all, >>>>>> >>>>>> So my UsbAudio.efi app has hit a bit of a roadblock. This code: >>>>>> >>>>>> ```C >>>>>> status = st->BootServices->OpenProtocol(handles[i], >>>>>> &gEfiUsbIoProtocolGuid, (void**)&UsbIo, imageHandle, NULL, >>>>>> EFI_OPEN_PROTOCOL_EXCLUSIVE); >>>>>> if (EFI_ERROR(status)) { >>>>>> Print(L"%r, skipping\n", status); >>>>>> continue; >>>>>> } >>>>>> ``` >>>>> >>>>> How are you constructing handle[]? Could it have gotten stale? You >>>>> could >>>>> print out the value of handle[I] on the failure. >>>>> >>>>> The contents of a handle are not defined, but the current >>>>> implementation >>>>> is >>>>> a pointer to an IHANDLE internal data structure in the DXE Core. If you >>>>> are >>>>> at the UEFI Shell and you `dh -v it will show the >>>>> >>>>> and the value. >>>>> >>>>> Shell> dh -v 98 >>>>> 98: 6d5CF18 >>>>> …. >>>>> >>>>> I think you can `dh -p UsbIo’ to get the list of the UsbIo handles. >>>>> >>>>> So you can poke around and see what is happening on that handle. >>>>> >>>>> I guess the handle[] array could be getting corrupted? So you could >>>>> check >>>>> for that? >>>>> >>>>> Thanks, >>>>> >>>>> Andrew Fish >>>>> >>>>>> Is giving me EFI_INVALID_PARAMETER and I don’t know why. I don't think >>>>>> I'm violating any of its constraints, according to the specification, >>>>>> and I haven't touched this code since it was written. It also happens >>>>>> irregularly: sometimes it happens on the USB audio streaming device, >>>>>> or if I have a device plugged in it might happen on that device, you >>>>>> get the idea. But it doesn't consistently fail. Does anybody have any >>>>>> idea what's going on? >>>>>> >>>>>> -- >>>>>> Signed, >>>>>> Ethin D. Probst >>>>> >>>>> >>>> >>>> >>>> -- >>>> Signed, >>>> Ethin D. Probst >>>> >>> >>> >>> -- >>> Signed, >>> Ethin D. Probst >>> >>> >>> >>> >>> >> >> > > > -- > Signed, > Ethin D. Probst > > >