/*---------------------------------------------------------------------------* Project: USB Host Stack (UHS) File: uhs_types.h Description: Core public data types Copyright (C) 2011 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ #ifndef __UHS_TYPES_H__ #define __UHS_TYPES_H__ #ifdef __cplusplus extern "C" { #endif /*---------------------------------------------------------------------------* * * Constants defined for this file * -- #Defines -- * *---------------------------------------------------------------------------*/ /* Per device EP counts, reflecting standard USB architecture */ #define UHS_MAX_ENDPOINTS 32 #define UHS_MAX_ENDPOINT_PAIRS 16 #define UHS_MAX_USER_ENDPOINT_PAIRS (UHS_MAX_ENDPOINT_PAIRS-1) /* These are upper limits imposed by UHS; we must define some upper limit making it high enough to satisfy all. */ #define UHS_MAX_CONFIGURATIONS_PER_DEVICE 32 #define UHS_MAX_INTERFACES_PER_CONFIGURATION 32 #define UHS_MAX_ALT_INTERFACE_SETTINGS 64 #define UHS_MAX_DEVICE_MANUFACTURER_DESCRIPTION_SIZE 64 #define UHS_MAX_DEVICE_PRODUCT_DESCRIPTION_SIZE 64 #define UHS_MAX_DEVICE_SERIAL_NUMBER_DESCRIPTION_SIZE 64 #define UHS_MAX_INTERFACE_DESCRIPTION_SIZE 64 #define UHS_MAX_TRANSACTIONS_PER_CLIENT 64 /* Maximum number of class driver registrations that a specific client is allowed to submit. */ #define UHS_MAX_CLIENT_CLASS_DRV_REGISTRATIONS 16 /* Maximum number of USB interfaces that a specific client is allowed to own */ #define UHS_MAX_CLIENT_INTERFACES 32 /* Maximum number of stacked hubs guaranteed to be supported */ #define UHS_MAX_HUB_HIERARCHY 8 /* Maximum number of URBs that may be submitted to any one endpoint */ #define UHS_MAX_URBS_PER_ENDPOINT 256 /* Maximum contiguous transfer size allowed by a single URB */ #define UHS_MAX_URB_XFER_SIZE 0x10000000 /* Maximum number of devices that may be returned via UhsQueryInterfaces(), for sanity */ #define UHS_MAX_QUERIED_INTERFACES 1000 /* Special flag for UhsTime to indicate infinite */ #define UHS_TIME_FOREVER -1 /* Flag for indicating invalid port number */ #define UHS_HUB_PORT_NUMBER_INVALID 0 /* Macro for constructing UhsEndpointMask */ #define UHS_MAKE_EP_OUT_MASK(endpointNumber) (1 << ((endpointNumber))) #define UHS_MAKE_EP_IN_MASK(endpointNumber) (1 << ((endpointNumber)+16)) /*---------------------------------------------------------------------------* * * Data types defined for this file * -- Structs, Typedefs, Enums -- * *---------------------------------------------------------------------------*/ typedef s32 UhsStatus; typedef s32 UhsDevRegHandle; typedef s32 UhsInterfaceHandle; typedef s32 UhsClientHandle; typedef void* UhsClientContext; typedef u32 UhsEndpointMask; typedef s8 UhsEndpointNumber; typedef u32 UhsEndpointOptions; typedef u32 UhsDeviceOptions; typedef s32 UhsTime; typedef s16 UhsHubPortNum; typedef u32 UhsDeviceUid; typedef enum { UHS_DEVICE_SPEED_INVALID = 0, UHS_DEVICE_SPEED_LOW, /* USB 1.1 */ UHS_DEVICE_SPEED_FULL, /* USB 1.1 */ UHS_DEVICE_SPEED_HIGH /* USB 2.0 */ }UhsDeviceSpeed; typedef enum { UHS_EP_CMD_INVALID, UHS_EP_CMD_ENABLE, UHS_EP_CMD_DISABLE, UHS_EP_CMD_CANCEL, UHS_EP_CMD_CANCEL_AND_RESET, }UhsEpCommandType; /* for backward compatibility */ #define UHS_EP_CMD_RESET UHS_EP_CMD_CANCEL typedef enum { UHS_DEV_CMD_INVALID, UHS_DEV_CMD_RESET, UHS_DEV_CMD_DISABLE, UHS_DEV_CMD_SUSPEND, UHS_DEV_CMD_RESUME, UHS_DEV_CMD_DESTROY }UhsDeviceCommandType; typedef enum { UHS_EP_TYPE_INVALID, UHS_EP_TYPE_CONTROL, UHS_EP_TYPE_ISOC, UHS_EP_TYPE_BULK, UHS_EP_TYPE_INTERRUPT }UhsEpType; typedef enum { UHS_DEV_POWER_MANAGEMENT_STATE_INVALID, UHS_DEV_POWER_MANAGEMENT_STATE_SUSPENDED, UHS_DEV_POWER_MANAGEMENT_STATE_RESUMED }UhsDevicePowerManagementState; /* UhsEndpointOptions definitions */ #define UHS_EP_OPTION_NONE 0x00000000 #define UHS_EP_OPTION_PRESERVE_MAX_LIMITS 0x00000001 /* Public UhsDeviceOptions definitions */ #define UHS_DEV_OPTION_NONE 0x00000000 #define UHS_DEV_OPTION_UNCONDITIONAL 0x00000001 /* USB directions, used in endpoint descriptor bEndpointAddress field and in control requests bRequestType. */ typedef enum { UHS_DIRECTION_INVALID, UHS_DIRECTION_TO_DEVICE, /* "out" */ UHS_DIRECTION_TO_HOST /* "in" */ }UhsDirection; PACKED_STRUCT_BEGIN /* * Identification of USB devices for probing and hotplugging * matchFlags: Bit mask controlling which fields below are used to match * against new devices. * idVendor: USB vendor ID for a device; numbers are assigned * by the USB forum to its members. * idProduct: Vendor-assigned product ID. * bcdDeviceLo: Low end of range of vendor-assigned product version numbers. * This is also used to identify individual product versions, for * a range consisting of a single device. * bcdDeviceHi: High end of version number range. The range of product * versions is inclusive. * bDeviceClass: Class of device * bDeviceSubClass: Subclass of device, associated with bDeviceClass. * bDeviceProtocol: Protocol of device, associated with bDeviceClass. * bInterfaceClass: Class of interface * bInterfaceSubClass: Subclass of interface, associated with bInterfaceClass. * bInterfaceProtocol: Protocol of interface, associated with bInterfaceClass. * driverInfo: Holds information used by the driver. Usually it holds * a pointer to a descriptor understood by the driver, or perhaps * device flags. */ typedef struct { /* which fields to match against? */ u16 matchFlags; /* Used for product specific matches; range is inclusive */ u16 idVendor; u16 idProduct; u16 bcdDeviceLo; u16 bcdDeviceHi; /* Used for device class matches */ u8 bDeviceClass; u8 bDeviceSubClass; u8 bDeviceProtocol; /* Used for interface class matches */ u8 bInterfaceClass; u8 bInterfaceSubClass; u8 bInterfaceProtocol; }PACKED_STRUCT_ATTRIBUTE UhsDeviceId; #define UHS_INVALID_DEVICE_ID {0,0,0,0,0,0,0,0,0,0,0} /* matchFlags bitmask */ #define UHS_DEVICE_ID_MATCH_VENDOR 0x0001 #define UHS_DEVICE_ID_MATCH_PRODUCT 0x0002 #define UHS_DEVICE_ID_MATCH_DEV_LO 0x0004 #define UHS_DEVICE_ID_MATCH_DEV_HI 0x0008 #define UHS_DEVICE_ID_MATCH_DEV_CLASS 0x0010 #define UHS_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 #define UHS_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 #define UHS_DEVICE_ID_MATCH_INT_CLASS 0x0080 #define UHS_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 #define UHS_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 #define UHS_DEVICE_ID_WILDCARD 0 /* * Interfaces are presented to prospective drivers using this * structure, which provides device, interface and endpoint information */ typedef struct { /* handle associated with this specific device interface */ UhsInterfaceHandle ifHandle; /* speed of device interface */ UhsDeviceSpeed devSpeed; /* console port information */ s32 hcGroup; s32 hcIndex; UhsHubPortNum port[UHS_MAX_HUB_HIERARCHY]; /* unique device id, providing a way for a class driver to know if multiple interfaces belong to the same physical device */ UhsDeviceUid deviceUid; /* number of alternate settings offered by this interface */ s32 altSettings; /* standard descriptors */ UhsDeviceDescriptor devDescriptor; UhsConfigDescriptor cfgDescriptor; UhsInterfaceDescriptor ifDescriptor; /* Index corresponds with endpoint number in bEndpointAddress. Index '0' is not valid (as it is managed by the core host stack) but it is instantiated in these arrays that that the index corresponds directly with endpoint number. */ UhsEndpointDescriptor epInDescriptors[UHS_MAX_ENDPOINT_PAIRS]; UhsEndpointDescriptor epOutDescriptors[UHS_MAX_ENDPOINT_PAIRS]; }PACKED_STRUCT_ATTRIBUTE UhsInterfaceProfile; typedef enum { UHS_INTERFACE_INVALID_INDICATION, UHS_INTERFACE_SUSPEND_INDICATION, UHS_INTERFACE_RESUME_INDICATION, UHS_INTERFACE_PROBE_INDICATION, UHS_INTERFACE_DISCONNECT_INDICATION }UhsInterfaceIndication; #define UHS_INTERFACE_INDICATION_NAMES \ {"UHS_INTERFACE_INVALID_INDICATION","UHS_INTERFACE_SUSPEND_INDICATION","UHS_INTERFACE_RESUME_INDICATION",\ "UHS_INTERFACE_PROBE_INDICATION","UHS_INTERFACE_DISCONNECT_INDICATION"} #define MAX_NUM_ISOC_FRAMES 32 typedef enum { UHS_ISOC_START_TYPE_ABSOLUTE, UHS_ISOC_START_TYPE_RELATIVE, UHS_ISOC_START_TYPE_CONTINUE } UhsIsocStartType; typedef struct { /* to be filled in when API is invoked */ u32 bufSize; /* fields populated by UHS when transaction completes */ UhsStatus status; u32 xferSize; }PACKED_STRUCT_ATTRIBUTE UhsIsocFrameElement; typedef struct { u32 numberOfFrames; void* pBuffer; u32 totalBufSize; UhsIsocFrameElement frames[MAX_NUM_ISOC_FRAMES]; }PACKED_STRUCT_ATTRIBUTE UhsIsocPayload; PACKED_STRUCT_END /*---------------------------------------------------------------------------* * * -- Async API Callbacks Prototypes -- * *---------------------------------------------------------------------------*/ typedef void (*UhsControlUrbCompletionCallback)(UhsClientContext clientContext, UhsStatus status, UhsInterfaceHandle ifHandle, u8 bRequest, u8 bRequestType, u16 wValue, u16 wIndex, void* pData, u32 xferSize); typedef void (*UhsInterruptUrbCompletionCallback)(UhsClientContext clientContext, UhsStatus status, UhsInterfaceHandle ifHandle, UhsEndpointNumber epNumber, UhsDirection direction, void* pData, u32 xferSize); typedef void (*UhsBulkUrbCompletionCallback)(UhsClientContext clientContext, UhsStatus status, UhsInterfaceHandle ifHandle, UhsEndpointNumber epNumber, UhsDirection direction, void* pData, u32 xferSize); typedef void (*UhsIsocUrbCompletionCallback)(UhsClientContext clientContext, UhsStatus status, UhsInterfaceHandle ifHandle, UhsEndpointNumber epNumber, UhsDirection direction, void* pData, u32 numEntries, UhsIsocFrameElement* isocFrameData); typedef void (*UhsIfProbeFunction)(UhsClientContext clientContext, UhsInterfaceProfile* pIfProfile); typedef void (*UhsIfIndicationFunction)(UhsClientContext clientContext, UhsInterfaceHandle ifHandle, UhsInterfaceIndication ifIndication); /*---------------------------------------------------------------------------* * * -- in-line helper functions for use with UHS API -- * *---------------------------------------------------------------------------*/ /** * uhs_endpoint_num - get the endpoint's number * @epd: endpoint to be checked * * Returns @epd's number: 0 to 15. */ static inline int uhs_endpoint_num(const UhsEndpointDescriptor *epd) { return epd->bEndpointAddress & UHS_ENDPOINT_NUMBER_MASK; } /** * uhs_endpoint_dir_in - check if the endpoint has IN direction * @epd: endpoint to be checked * * Returns TRUE if the endpoint is of type IN, otherwise it * returns FALSE. */ static inline BOOL uhs_endpoint_dir_in(const UhsEndpointDescriptor *epd) { return((epd->bEndpointAddress & UHS_ENDPOINT_DIR_MASK) == UHS_DIR_IN) ? TRUE : FALSE; } /** * uhs_endpoint_dir_out - check if the endpoint has OUT direction * @epd: endpoint to be checked * * Returns TRUE if the endpoint is of type OUT, otherwise it * returns FALSE. */ static inline BOOL uhs_endpoint_dir_out(const UhsEndpointDescriptor *epd) { return((epd->bEndpointAddress & UHS_ENDPOINT_DIR_MASK) == UHS_DIR_OUT) ? TRUE : FALSE; } /** * uhs_endpoint_address - form an endpoint address * @epNumber: endpoint number * @direction: direction of endpoint * * Returns endpoint address. */ static inline u8 uhs_endpoint_address(UhsEndpointNumber epNumber, UhsDirection direction) { u8 bEndpointAddress = (u8)((epNumber<bmAttributes & UHS_ENDPOINT_XFERTYPE_MASK) == UHS_ENDPOINT_XFER_BULK) ? TRUE : FALSE; } /** * uhs_endpoint_xfer_control - check if the endpoint has control transfer type * @epd: endpoint to be checked * * Returns TRUE if the endpoint is of type control, otherwise it * returns FALSE. */ static inline BOOL uhs_endpoint_xfer_control(const UhsEndpointDescriptor *epd) { return((epd->bmAttributes & UHS_ENDPOINT_XFERTYPE_MASK) == UHS_ENDPOINT_XFER_CONTROL) ? TRUE : FALSE; } /** * uhs_endpoint_xfer_int - check if the endpoint has interrupt transfer type * @epd: endpoint to be checked * * Returns TRUE if the endpoint is of type interrupt, otherwise * it returns FALSE. */ static inline BOOL uhs_endpoint_xfer_int(const UhsEndpointDescriptor *epd) { return((epd->bmAttributes & UHS_ENDPOINT_XFERTYPE_MASK) == UHS_ENDPOINT_XFER_INT); } /** * uhs_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type * @epd: endpoint to be checked * * Returns TRUE if the endpoint is of type isochronous, * otherwise it returns FALSE. */ static inline BOOL uhs_endpoint_xfer_isoc(const UhsEndpointDescriptor *epd) { return((epd->bmAttributes & UHS_ENDPOINT_XFERTYPE_MASK) == UHS_ENDPOINT_XFER_ISOC) ? TRUE : FALSE; } /** * uhs_endpoint_is_bulk_in - check if the endpoint is bulk IN * @epd: endpoint to be checked * * Returns TRUE if the endpoint has bulk transfer type and IN * direction, otherwise it returns FALSE. */ static inline BOOL uhs_endpoint_is_bulk_in(const UhsEndpointDescriptor *epd) { return uhs_endpoint_xfer_bulk(epd) && uhs_endpoint_dir_in(epd); } /** * uhs_endpoint_is_bulk_out - check if the endpoint is bulk OUT * @epd: endpoint to be checked * * Returns TRUE if the endpoint has bulk transfer type and OUT * direction, otherwise it returns FALSE. */ static inline BOOL uhs_endpoint_is_bulk_out(const UhsEndpointDescriptor *epd) { return uhs_endpoint_xfer_bulk(epd) && uhs_endpoint_dir_out(epd); } /** * uhs_endpoint_is_int_in - check if the endpoint is interrupt IN * @epd: endpoint to be checked * * Returns TRUE if the endpoint has interrupt transfer type and * IN direction, otherwise it returns FALSE. */ static inline BOOL uhs_endpoint_is_int_in(const UhsEndpointDescriptor *epd) { return uhs_endpoint_xfer_int(epd) && uhs_endpoint_dir_in(epd); } /** * uhs_endpoint_is_int_out - check if the endpoint is interrupt OUT * @epd: endpoint to be checked * * Returns TRUE if the endpoint has interrupt transfer type and * OUT direction, otherwise it returns FALSE. */ static inline BOOL uhs_endpoint_is_int_out(const UhsEndpointDescriptor *epd) { return uhs_endpoint_xfer_int(epd) && uhs_endpoint_dir_out(epd); } /** * uhs_endpoint_is_isoc_in - check if the endpoint is isochronous IN * @epd: endpoint to be checked * * Returns TRUE if the endpoint has isochronous transfer type * and IN direction, otherwise it returns FALSE. */ static inline BOOL uhs_endpoint_is_isoc_in(const UhsEndpointDescriptor *epd) { return uhs_endpoint_xfer_isoc(epd) && uhs_endpoint_dir_in(epd); } /** * uhs_endpoint_is_isoc_out - check if the endpoint is isochronous OUT * @epd: endpoint to be checked * * Returns TRUE if the endpoint has isochronous transfer type * and OUT direction, otherwise it returns FALSE. */ static inline BOOL uhs_endpoint_is_isoc_out(const UhsEndpointDescriptor *epd) { return uhs_endpoint_xfer_isoc(epd) && uhs_endpoint_dir_out(epd); } /** * uhs_endpoint_mask - get the endpoint's mask, a logical representation * used by UHS API * @epd: endpoint to be checked * * Returns @epd's mask of type UhsEndpointMask. */ static inline UhsEndpointMask uhs_endpoint_mask(const UhsEndpointDescriptor *epd) { if (uhs_endpoint_dir_in(epd)) { return(1 << (uhs_endpoint_num(epd)+16)); } else { return(1 << uhs_endpoint_num(epd)); } } /** * uhs_endpoint_direction - get the endpoint's direction, a * logical representation used by UHS API * @epd: endpoint to be checked * * Returns @epd's direction of type UhsDirection. */ static inline UhsDirection uhs_endpoint_direction(const UhsEndpointDescriptor *epd) { if (uhs_endpoint_dir_in(epd)) { return UHS_DIRECTION_TO_HOST; } else { return UHS_DIRECTION_TO_DEVICE; } } /** * uhs_endpoint_type - get the endpoint's transfer type * @epd: endpoint to be checked * * Returns value of type UhsEpType. */ static inline UhsEpType uhs_endpoint_type(const UhsEndpointDescriptor *epd) { UhsEpType epType=UHS_EP_TYPE_INVALID; switch (epd->bmAttributes & UHS_ENDPOINT_XFERTYPE_MASK) { case UHS_ENDPOINT_XFER_CONTROL: epType=UHS_EP_TYPE_CONTROL; break; case UHS_ENDPOINT_XFER_ISOC: epType=UHS_EP_TYPE_ISOC; break; case UHS_ENDPOINT_XFER_BULK: epType=UHS_EP_TYPE_BULK; break; case UHS_ENDPOINT_XFER_INT: epType=UHS_EP_TYPE_INTERRUPT; break; default: break; } return epType; } /** * uhs_endpoint_is_valid - determine whether specified endpoint * descriptor is valid * @epd: endpoint to be checked * * Returns value of type BOOL. */ static inline BOOL uhs_endpoint_is_valid(const UhsEndpointDescriptor *epd) { BOOL valid=FALSE; if ((epd->bLength>=UHS_DT_ENDPOINT_SIZE) && (epd->bEndpointAddress!=0)) { valid=TRUE; } return valid; } /** * uhs_mark_endpoint_invalid - marks an endpoint as being * "invalid" * @epd: endpoint to be marked invalid * * Returns nothing. */ static inline void uhs_mark_endpoint_invalid(UhsEndpointDescriptor *epd) { epd->bLength=0; epd->bEndpointAddress=0; } #ifdef __cplusplus } #endif #endif // __UHS_TYPES_H__