/dev/usb/hid (v5)

From WiiBrew
< /dev‎ | usb
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

/dev/usb/hid is used to interact with USB HIDs in IOS57, 58 and 59.

It is very similar to /dev/usb/ven and other v5 interfaces. Some ioctl handlers are identical to USB_VEN. Both rely on /dev/usb/usb for most actions.

Handles

Handles for USB_HID function exactly the same as for USB_VEN.

Transfers

Compared to VEN, HID has an additional member at the end of the device structure that seems to be used for keeping track of ongoing transfers.

There can be up to 32 ongoing transfers (in total, for all devices) at the same time. IPC_ERROR_MAX (-5) will be returned by the transfer submission ioctlvs (0x12 and 0x13) if the limit is exceeded (unlike VEN, which returns IPC_EINVAL).

It appears that transfers can be queued. If a transfer is already in progress, any new transfer request will be added to a queue and only processed after some amount of time depending on the data length of the previous transfer. [check]

When a device is unplugged, all of the queued transfer requests are replied to with return code USB_ECANCELED (-7022), their associated IOS timers are stopped and destroyed.

Ioctls

Ioctl Name Input Output Notes
0 GetVersion Identical to VEN
1 GetDeviceChange None

Entry[32] (0x180 bytes)

For each entry:

0-1: Interface number
1-2: Device index (0 to 31)
2-4: Device number
4-6: VID
6-8: PID
8-10: Device number
10-11: Interface number
11-12: Number of alternate settings

Set up a device insertion/removal callback. Returns the number of entries.

Note that this ioctl immediately returns on the first call.

Behind the scenes, HID keeps track of the device list (which can handle up to 32 devices) by issuing (async) ioctl 1 to /dev/usb/usb and updating its internal list on reply.

This is very similar to VEN, but there is a critical difference: the first byte is not (IPC request address >> 8), but the interface number.

2 Shutdown Identical to VEN
3 GetDeviceInfo 0x20 bytes

1-2: Device index
2-4: Device number

(0-4 is considered as a whole as the device ID, but IOS only cares about these two values.)

0x60 bytes (memset to 0)

0-4: Device ID
4-8: Unknown byte from ioctl_2_out_buffer[5]
36-56: Device descriptor
56-68: Config descriptor
68-80: Interface descriptor
80-88: Interrupt IN endpoint descriptor
88-96: Interrupt OUT endpoint descriptor

Get USB descriptors for a device. Behind the scenes, calls /dev/usb/usb ioctl 2 (input: internal ID, output: descriptors) and copies information to the output buffer and the internal device struct (must be called before a device can be used).

The descriptor structures match the ones used by libusb (with padding).

This is very similar to VEN, but with different offsets and only interrupt endpoint descriptors, at fixed offsets.

4 ? Identical to VEN
5 ? Identical to VEN
6 AttachFinish Identical to VEN
7 SetAlternateSetting Not available in HID
8 ? Not available in HID
0x10 SuspendResume Identical to VEN
0x11 CancelEndpoint 0x20 bytes

1-2: Device index
2-4: Device number
8-9: Endpoint [check]

None Calls USB backend (EHC or OHCI0) ioctl 0x10 with a device ID and an endpoint address. Unlike VEN, there are 3 valid values for the endpoint, which determine the endpoint address that gets passed to the backend.

Valid values: 0 (control, endpoint 0), 1 (interrupt IN) and 2 (interrupt OUT)

Cancels all queued transfers with return code -7022 (USB_CANCELLED).

0x12 (ioctlv) CtrlTransfer (?) ? ? Submit a control transfer.

Appears to use the Starlet timer (HW_TIMER) and possibly rate limit requests [check]

0x13 (ioctlv) IntrTransfer (?) ? ? Submit an interrupt transfer.

Appears to use the Starlet timer (HW_TIMER) and possibly rate limit requests [check]

Unlike VEN, the endpoint is determined by the value at 8-12. If it's non-zero, HID submits the request to the interrupt OUT endpoint. Otherwise, the request is submitted to the IN endpoint.

0x14 (ioctlv) IsoTransfer Not available in HID
0x15 (ioctlv) BulkTransfer Not available in HID