Difference between revisions of "/dev/usb/oh0"
Line 163: | Line 163: | ||
|- | |- | ||
− | | 8 (ioctlv) || ? || | + | | 8 (ioctlv) || ? || 1 || 1 || OH0 |
| | | | ||
− | ??? | + | Unknown. |
+ | * in 0: u8 - ??? | ||
+ | * io 0: u32 - ??? | ||
|- | |- |
Revision as of 21:11, 21 December 2016
/dev/usb/oh0 is used to interact with the Wii's external USB bus. This interface is very similar to /dev/usb/oh1 and has two parts: the "root" or host device, and individual devices on which USB requests can be submitted.
/dev/usb/oh0 (IOS57 and newer)
In recent versions of IOS (after IOS 57), the OHCI0 module appears to implement a different interface and seems to only register this new interface of /dev/usb/oh0.
Only IOS_OPEN, IOS_CLOSE and IOS_IOCTL are valid commands. The other commands immediately return IPC_EINVAL (-4).
Additionally, /dev/usb/oh0 can only be opened from UID 0x11. Attempts to open OH0 with other UIDs will result in IPC_EACCES (-1).
Ioctl | Name | Input | Output | Notes |
---|---|---|---|---|
0 | USBV2_IOCTL_GET_VERSION | - | 0x20 bytes | Writes the version 0x20001 to the output buffer. This is very similar to the IOS58 version of /dev/usb/hid, which writes 0x50001 to the output buffer instead. It is also reminiscent of /dev/usb/ehc which does the same thing (but with an ioctlv). |
1 | ? | ? | ? | ? |
2 | ? | ? | ? | ? |
3 | ? | 0x20 bytes | ? | ? |
4 | ? | 0x20 bytes | ? | ? |
5 | ? | 0x20 bytes | ? | ? |
16 | ? | 0x20 bytes | ? | ? |
17 | ? | 0x20 bytes | ? | ? |
18 | ? | 0x20 bytes | ? | Handled by the same function as for ioctl 20. |
19 | ? | 0x20 bytes | ? | ? |
20 | ? | 0x20 bytes | ? | Handled by the same function as for ioctl 18. |
/dev/usb/oh0
The OH1 module appears to be able to register itself as /dev/usb/oh0 and implements a similar set of requests.
Request | Name | Input | Output | OH0/OH1 | Notes |
---|---|---|---|---|---|
12 (ioctlv) | USBV0_IOCTL_GETDEVLIST | 2 | 2 | Both |
|
15 (ioctl) | ? | - | 4 bytes | Both | Unknown. Appears to return 02 00 03 02 regardless of the number of plugged in devices. |
20 (ioctlv) | ? | 1 | 1 | Both | Unknown.
|
25 (ioctlv) | ? | 2 | ? | Both | Unknown. Returns IPC_EINVAL if in_vectors[0] is greater than the least significant byte of (heap + 0x40). Possibly has to do with suspend/resume. [check]
|
27 (ioctlv) | USBV0_IOCTL_DEVINSERTHOOK | 2 | 0 | OH0 |
Returns when a device with the requested VID/PID is plugged in, or immediately if the device is already inserted.
|
30 (ioctlv) | USBV0_IOCTL_DEVINSERTHOOKID (RegisterInsertionNotifyWithId) | 3 | 1 | OH0 |
Returns when a device with the requested VID/PID is plugged in, or immediately if the device is already inserted. It is similar to USBV0_IOCTL_DEVINSERTHOOK, but it has an additional in vector + io vector, possibly used for passing an "ID" (according the official name). Its purpose is unknown.
|
31 (ioctl) | USBV0_IOCTL_CANCEL_DEVINSERTHOOK | 4 bytes | - | OH0 | Internal names: IUSB_CancelInsertionNotify / __ohciCancelNotifyInsertion
Cancels a device insertion hook (the hook request will be replied to with return value -7022). The input buffer is probably used to specify the VID/PID. Returns IPC_EINVAL if input buffer was nullptr. Otherwise, IPC_SUCCESS is returned if there was no hook;
if there was a pending hook, the return value of |
/dev/usb/oh0/%x/%x
These devices represent an individual USB device, based on its vendor ID and product ID (in hexadecimal format without leading zeroes). It is unclear how devices with the same VID/PID can be used at the same time.
Only one device handle can be opened at the same time. Attempting to open more than one results in IPC_EEXIST (-2).
Request | Name | Input | Output | OH0/OH1 | Notes |
---|---|---|---|---|---|
0 (ioctlv) | USBV0_IOCTL_CTRLMSG | 6 | 1 | Both |
Submits a control transfer.
|
1 (ioctlv) | USBV0_IOCTL_BLKMSG | 2 | 1 | Both |
Submits a bulk transfer.
If io_vectors[0].size and the length don't match, returns IPC_EINVAL. |
2 (ioctlv) | USBV0_IOCTL_INTRMSG | 2 | 1 | Both |
Submits an interrupt transfer.
If io_vectors[0].size and the length don't match, returns IPC_EINVAL. |
5 (ioctl) | USBV0_IOCTL_SUSPENDDEV | - | - | Both |
Used to suspend a device. |
6 (ioctl) | USBV0_IOCTL_RESUMEDEV | - | - | Both |
Used to resume a device. |
8 (ioctlv) | ? | 1 | 1 | OH0 |
Unknown.
|
9 (ioctlv) | USBV0_IOCTL_ISOMSG | 3 | 2 | OH0 |
Submits an isochronous transfer.
|
10 (ioctlv) | ? | 2 | 1 | OH0 |
Submits a transfer. (Which type?) [check] Handled by the same function as for bulk and interrupt transfers.
If io_vectors[0].size and the length don't match, returns IPC_EINVAL. |
18 (ioctlv) | ? (IntrBlkIRP) | 3 | 1 | OH0 |
Unknown.
|
26 (ioctl) | USBV0_IOCTL_DEVREMOVALHOOK | - | - | Both |
Returns when the device is unplugged or reset, or on device close. Only one hook is allowed at the same time. Further ioctls to set up another hook before it is triggered result in IPC_EEXIST. |
29 (ioctl) | USBV0_IOCTL_RESET_DEVICE | - | - | OH0 |
Triggers the associated removal hook before resetting the USB device. |
Known Devices
- /dev/usb/oh0/0b95/7720: ASIX AX88772 USB2.0 to Fast Ethernet Adapter (referenced in IOS eth driver)
- /dev/usb/oh0/57e/308: Nintendo Wii Speak (microphone)
- /dev/usb/oh0/46d/a03: Logitech microphone
Errors
-4 (IPC_EINVAL): might be caused by an invalid device fd
-7003: STALL (according to gc-linux)
-7004: STALL (according to gc-linux)
-7005: NAK (according to gc-linux)
-7008
-7022