OpenProtocol() giving me EFI_INVALID_PARAMETER


Ethin Probst
 

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;
}
```
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


Andrew Fish
 

On Jul 17, 2021, at 9:41 AM, Ethin Probst <harlydavidsen@gmail.com> 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 <handleNum> it will show the <handleNum> 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


Ethin Probst
 

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 <afish@apple.com> wrote:


On Jul 17, 2021, at 9:41 AM, Ethin Probst <harlydavidsen@gmail.com>
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 <handleNum> it will show the <handleNum>
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


Ethin Probst
 

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?

On 7/17/21, Ethin Probst <harlydavidsen@gmail.com> 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 <afish@apple.com> wrote:


On Jul 17, 2021, at 9:41 AM, Ethin Probst <harlydavidsen@gmail.com>
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 <handleNum> it will show the <handleNum>
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


Andrew Fish
 



On Jul 17, 2021, at 10:06 AM, Ethin Probst <harlydavidsen@...> 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 <harlydavidsen@...> 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 <afish@...> wrote:


On Jul 17, 2021, at 9:41 AM, Ethin Probst <harlydavidsen@...>
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 <handleNum> it will show the <handleNum>
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







Ethin Probst
 

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 <afish@apple.com> wrote:


On Jul 17, 2021, at 10:06 AM, Ethin Probst <harlydavidsen@gmail.com>
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 <harlydavidsen@gmail.com> 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 <afish@apple.com> wrote:


On Jul 17, 2021, at 9:41 AM, Ethin Probst <harlydavidsen@gmail.com>
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 <handleNum> it will show the
<handleNum>
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


Andrew Fish
 

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 <harlydavidsen@...> 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 <afish@...> wrote:


On Jul 17, 2021, at 10:06 AM, Ethin Probst <harlydavidsen@...>
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 <harlydavidsen@...> 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 <afish@...> wrote:


On Jul 17, 2021, at 9:41 AM, Ethin Probst <harlydavidsen@...>
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 <handleNum> it will show the
<handleNum>
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




Ethin Probst
 

Tried this and I still get that invalid handle. Definitely confused
where that's coming from.

On 7/17/21, Andrew Fish <afish@apple.com> wrote:
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 <harlydavidsen@gmail.com>
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 <afish@apple.com <mailto:afish@apple.com>> wrote:


On Jul 17, 2021, at 10:06 AM, Ethin Probst <harlydavidsen@gmail.com>
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 <harlydavidsen@gmail.com> 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 <afish@apple.com> wrote:


On Jul 17, 2021, at 9:41 AM, Ethin Probst <harlydavidsen@gmail.com>
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 <handleNum> it will show the
<handleNum>
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


--
Signed,
Ethin D. Probst