In memory of Ben “bushing” Byer, who passed away on Monday, February 8th, 2016.

/dev/uhs

From WiiUBrew
< /dev
Revision as of 19:03, 12 April 2015 by Marionumber1 (talk | contribs) (→‎0x11 - UhsQueryInterfaces(): Better descriptions of inputs and outputs for UhsQueryInterfaces())
Jump to navigation Jump to search

/dev/uhs is the IOSU device node for the USB Host Stack (UHS). It provides an interface for low-level USB device access, which nsysuhs.rpl exposes to the Cafe OS userspace. The interface is opened through /dev/uhs/%d, where %d is an integer representing something (controller number?). Only 0 can be opened, as 1 returns access denied and further values do not exist as device nodes. Once opened, ioctl() requests can be issued to the interface, which are documented below.

ioctl() interface

0x11 - UhsQueryInterfaces()

This function is used to determine which USB device interfaces are plugged in and available. Its input is an interface filter buffer containing a series of parameters to filter the interfaces by, such as class, subclass, vendor ID, and product ID. The output is an array of interface profiles, one for each interface being read. IOS_Ioctl() with this function returns the number of attached USB interfaces permitted by the filter.

Structures

Interface Filter

This structure is passed to several functions to determine which interface profiles to return or handle.

/* Determines which parameters to check */
#define MATCH_ANY             0x000
#define MATCH_DEV_VID         0x001
#define MATCH_DEV_PID         0x002
#define MATCH_DEV_CLASS       0x010
#define MATCH_DEV_SUBCLASS    0x020
#define MATCH_DEV_PROTOCOL    0x040
#define MATCH_IF_CLASS        0x080
#define MATCH_IF_SUBCLASS     0x100
#define MATCH_IF_PROTOCOL     0x200

/* Interface filter */
typedef struct
{
    uint16_t match_params;    /* Bitmask of above flags */
    uint16_t vid, pid;        /* Vendor ID and product ID */
    char unknown6[0xa - 0x6];
    uint8_t dev_class;        /* Device class */
    uint8_t dev_subclass;     /* Device subclass */
    uint8_t dev_protocol;     /* Device protocol */
    uint8_t if_class;         /* Interface class */
    uint8_t if_subclass;      /* Interface subclass */
    uint8_t if_protocol;      /* Interface protocol */ 
} UhsInterfaceFilter;

USB Descriptors

These are device, configuration, and interface descriptors defined by the USB specification.

/* USB device descriptor */
typedef struct
{
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t bcdUsb;
    uint8_t bDeviceClass;
    uint8_t bDeviceSubclass;
    uint8_t bDeviceProtocol;
    uint8_t bMaxPacketSize;
    uint16_t idVendor;
    uint16_t idProduct;
    uint16_t bcdDevice;
    uint8_t iManufacturer;
    uint8_t iProduct;
    uint8_t iSerialNumber;
    uint8_t bNumConfigurations;
} UhsDeviceDescriptor;

/* USB configuration descriptor */
typedef struct
{
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t wTotalLength;
    uint8_t bNumInterfaces;
    uint8_t bConfigurationValue;
    uint8_t iConfiguration;
    uint8_t bmAttributes;
    uint8_t bMaxPower;
} UhsConfigDescriptor;

/* USB interface descriptor */
typedef struct
{
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t bInterfaceNumber;
    uint8_t bAlternateSetting;
    uint8_t bNumEndpoints;
    uint8_t bInterfaceClass;
    uint8_t bInterfaceSubClass;
    uint8_t bInterfaceProtocol;
    uint8_t iInterface;
} UhsInterfaceDescriptor;

Interface Profile

This structure is used to represent an available device interface attached to the Wii U.

/* Interface profile */
typedef struct
{
    uint32_t if_handle;
    char unknown4[0x28 - 0x4];
    UhsDeviceDescriptor dev_desc;
    UhsConfigDescriptor cfg_desc;
    UhsInterfaceDescriptor if_desc;
    char unknown4c[0x16c - 0x4c];
} UhsInterfaceProfile;