xbox-kernel/public/ddk/inc/usb.h
2020-09-30 17:17:25 +02:00

1236 lines
55 KiB
C++

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
usb.h
Generated from usb.x
Abstract:
Header File for all class drivers
Environment:
Xbox
C++ Only
--*/
#ifndef __USB_X__
#define __USB_X__
#ifndef __cplusplus
#error "usb.h may only be included by C++ modules"
#endif
#define EXTERNUSB extern "C"
//
// USB drivers, and XAPI code modules that rely on USB all go into
// the XPP section.
//
#pragma code_seg(".XPPCODE")
#pragma data_seg(".XPP$Data")
#pragma const_seg(".XPPRDATA")
#include <usb100.h>
//
// XBOX platform USB device classes
//
#define XBOX_DEVICE_CLASS_INPUT_DEVICE 0x58
#define XBOX_DEVICE_CLASS_XDCS 0x59
#define XBOX_DEVICE_CLASS_AUDIO_DEVICE 0x78
//
// USBD status codes
//
// Status values are 32 bit values layed out as follows:
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---+---------------------------+-------------------------------+
// | S | Status Code |
// +---+---------------------------+-------------------------------+
//
// where
//
// S - is the state code
//
// 00 - completed with success
// 01 - request is pending
// 10 - completed with error, endpoint not stalled
// 11 - completed with error, endpoint stalled
//
//
// Code - is the status code
//
typedef LONG USBD_STATUS;
//
// Generic test for success on any status value (non-negative numbers
// indicate success).
//
#define USBD_SUCCESS(Status) ((USBD_STATUS)(Status) >= 0)
//
// Generic test for pending status value.
//
#define USBD_PENDING(Status) ((ULONG)(Status) >> 30 == 1)
//
// Generic test for error on any status value.
//
#define USBD_ERROR(Status) ((USBD_STATUS)(Status) < 0)
//
// Macro to ensure that error bit is set.
//
#define SET_USBD_ERROR(err) ((err) | USBD_STATUS_ERROR)
//
// Generic test for stall on any status value.
//
#define USBD_HALTED(Status) ((ULONG)(Status) >> 30 == 3)
#define USBD_STATUS_SUCCESS ((USBD_STATUS)0x00000000L)
#define USBD_STATUS_PENDING ((USBD_STATUS)0x40000000L)
#define USBD_STATUS_HALTED ((USBD_STATUS)0xC0000000L)
#define USBD_STATUS_ERROR ((USBD_STATUS)0x80000000L)
//
// HC status codes
// Note: these status codes have both the error and the stall bit set.
//
#define USBD_STATUS_CRC ((USBD_STATUS)0xC0000001L)
#define USBD_STATUS_BTSTUFF ((USBD_STATUS)0xC0000002L)
#define USBD_STATUS_DATA_TOGGLE_MISMATCH ((USBD_STATUS)0xC0000003L)
#define USBD_STATUS_STALL_PID ((USBD_STATUS)0xC0000004L)
#define USBD_STATUS_DEV_NOT_RESPONDING ((USBD_STATUS)0xC0000005L)
#define USBD_STATUS_PID_CHECK_FAILURE ((USBD_STATUS)0xC0000006L)
#define USBD_STATUS_UNEXPECTED_PID ((USBD_STATUS)0xC0000007L)
#define USBD_STATUS_DATA_OVERRUN ((USBD_STATUS)0xC0000008L)
#define USBD_STATUS_DATA_UNDERRUN ((USBD_STATUS)0xC0000009L)
#define USBD_STATUS_RESERVED1 ((USBD_STATUS)0xC000000AL)
#define USBD_STATUS_RESERVED2 ((USBD_STATUS)0xC000000BL)
#define USBD_STATUS_BUFFER_OVERRUN ((USBD_STATUS)0xC000000CL)
#define USBD_STATUS_BUFFER_UNDERRUN ((USBD_STATUS)0xC000000DL)
#define USBD_STATUS_NOT_ACCESSED ((USBD_STATUS)0xC000000EL)
#define USBD_STATUS_FIFO ((USBD_STATUS)0xC0000010L)
//
// HC status codes
// Note: these status codes have the error bit and not the stall bit set.
//
#define USBD_ISOCH_STATUS_CRC (1)
#define USBD_ISOCH_STATUS_BTSTUFF (2)
#define USBD_ISOCH_STATUS_DATA_TOGGLE_MISMATCH (3)
#define USBD_ISOCH_STATUS_STALL_PID (4)
#define USBD_ISOCH_STATUS_DEV_NOT_RESPONDING (5)
#define USBD_ISOCH_STATUS_PID_CHECK_FAILURE (6)
#define USBD_ISOCH_STATUS_UNEXPECTED_PID (7)
#define USBD_ISOCH_STATUS_DATA_OVERRUN (8)
#define USBD_ISOCH_STATUS_DATA_UNDERRUN (9)
#define USBD_ISOCH_STATUS_RESERVED1 (A)
#define USBD_ISOCH_STATUS_RESERVED2 (B)
#define USBD_ISOCH_STATUS_BUFFER_OVERRUN (C)
#define USBD_ISOCH_STATUS_BUFFER_UNDERRUN (D)
#define USBD_ISOCH_STATUS_NOT_ACCESSED (E)
//
// returned by HCD if a transfer is submitted to an endpoint that is
// stalled
//
#define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS)0xC0000030L)
//
// Software status codes
// Note: the following status codes have only the error bit set
//
#define USBD_STATUS_NO_MEMORY ((USBD_STATUS)0x80000100L)
#define USBD_STATUS_INVALID_URB_FUNCTION ((USBD_STATUS)0x80000200L)
#define USBD_STATUS_INVALID_PARAMETER ((USBD_STATUS)0x80000300L)
#define USBD_STATUS_UNSUPPORTED_DEVICE ((USBD_STATUS)0x80000400L)
#define USBD_STATUS_TRANSFER_TOO_LONG ((USBD_STATUS)0x80000500L)
//
// returned by USBD if it cannot complete a URB request, typically this
// will be returned in the URB status field when the Irp is completed
// with a more specific NT error code in the irp.status field.
//
#define USBD_STATUS_REQUEST_FAILED ((USBD_STATUS)0x80000600L)
#define USBD_STATUS_NO_DEVICE ((USBD_STATUS)0x80000700L)
// returned when there is not enough bandwidth avialable
// to open a requested endpoint
#define USBD_STATUS_NO_BANDWIDTH ((USBD_STATUS)0x80000800L)
//
// generic HC error
//
#define USBD_STATUS_INTERNAL_HC_ERROR ((USBD_STATUS)0x80000900L)
//
// returned when a short packet terminates the transfer
// ie USBD_SHORT_TRANSFER_OK bit not set
//
#define USBD_STATUS_ERROR_SHORT_TRANSFER ((USBD_STATUS)0x80000A00L)
//
// returned if the requested start frame is not within
// USBD_ISOCH_START_FRAME_RANGE of the current USB frame,
// note that the stall bit is set
//
#define USBD_STATUS_BAD_START_FRAME ((USBD_STATUS)0xC0000B00L)
//
// returned by HCD if all packets in an iso transfer complete with an error
//
#define USBD_STATUS_ISOCH_REQUEST_FAILED ((USBD_STATUS)0xC0000C00L)
//
// returned by HCD if an attempt is made to attach more isoch
// buffers to an endpoint than specified as the maximum when opening
// the endpoint.
//
#define USBD_STATUS_ISOCH_TOO_MANY_BUFFERS ((USBD_STATUS)0xC0000D00L)
//
// returned by HCD if an attempt is made to start an endpoint which is
// already started.
//
#define USBD_STATUS_ISOCH_ALREADY_STARTED ((USBD_STATUS)0xC0000E00L)
//
// returned by HCD if an attempt is made to stop an endpoint which is
// not already started.
//
#define USBD_STATUS_ISOCH_NOT_STARTED ((USBD_STATUS)0xC0000F00L)
//
// returned by HCD if an attempt is made to start an endpoint setup for
// circular DMA with fewer than MaxAttachedBuffers,
//
#define USBD_STATUS_ISOCH_ATTACH_MORE_BUFFERS ((USBD_STATUS)0xC0001000L)
//
// This build of the usb driver does not support isochronous requests.
//
#define USBD_STATUS_ISOCH_NOT_SUPPORTED ((USBD_STATUS)0xC0002000L)
//
// set when a transfers is completed due to an AbortPipe request from
// the client driver
//
#define USBD_STATUS_CANCELED ((USBD_STATUS)0xC000000FL)
#define USBD_STATUS_CANCELING ((USBD_STATUS)0x40020000L)
//
// Status returned by hub, when a reset completes successfully and the
// device is low-speed.
//
#define USBD_STATUS_LOWSPEED ((USBD_STATUS)0x01000000L)
extern "C" {
//------------------------------------------------------------------------------------
// URB Function Codes - High bit indicates that USBD (pre-)processes URB
//------------------------------------------------------------------------------------
//-- special bit in URB_FUNCTION codes -----------------
#define URB_FUNCTION_USBD_PROCESSED 0x80
#define URB_FUNCTION_ASYNCHRONOUS 0x40
//------------------------------------------------------
#define URB_FUNCTION_CONTROL_TRANSFER (0x00 | URB_FUNCTION_ASYNCHRONOUS)
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x01 | URB_FUNCTION_ASYNCHRONOUS)
#define URB_FUNCTION_OPEN_ENDPOINT 0x02
#define URB_FUNCTION_CLOSE_ENDPOINT (0x03 | URB_FUNCTION_ASYNCHRONOUS)
#define URB_FUNCTION_GET_ENDPOINT_STATE 0x04
#define URB_FUNCTION_SET_ENDPOINT_STATE 0x05
#define URB_FUNCTION_ABORT_ENDPOINT (0x06 | URB_FUNCTION_ASYNCHRONOUS)
#define URB_FUNCTION_GET_FRAME_NUMBER 0x07
#define URB_FUNCTION_OPEN_DEFAULT_ENDPOINT (URB_FUNCTION_USBD_PROCESSED | URB_FUNCTION_OPEN_ENDPOINT)
#define URB_FUNCTION_CLOSE_DEFAULT_ENDPOINT (URB_FUNCTION_USBD_PROCESSED | URB_FUNCTION_CLOSE_ENDPOINT)
#define URB_FUNCTION_RESET_PORT (URB_FUNCTION_USBD_PROCESSED | 0x08)
#define URB_FUNCTION_ISOCH_OPEN_ENDPOINT 0x09
#define URB_FUNCTION_ISOCH_CLOSE_ENDPOINT (0x0A | URB_FUNCTION_ASYNCHRONOUS)
#define URB_FUNCTION_ISOCH_ATTACH_BUFFER 0x0B
#define URB_FUNCTION_ISOCH_START_TRANSFER 0x0C
#define URB_FUNCTION_ISOCH_STOP_TRANSFER 0x0D
//------------------------------------------------------------------------------------
// Values for the transfer directions
//------------------------------------------------------------------------------------
#define USB_TRANSFER_DIRECTION_OUT 0x01
#define USB_TRANSFER_DIRECTION_IN 0x02
//----------------------------------------------------------------------------------------------------------------------
// Flags for URB_FUNCTION_GET_ENDPOINT_STATE
//----------------------------------------------------------------------------------------------------------------------
#define USB_ENDPOINT_STATE_HALTED 0x01 //Set on return if endpoint is halted.
#define USB_ENDPOINT_STATE_TRANSFERS_QUEUED 0x02 //Set on return if one or more transfers are queued to endpoint.
//----------------------------------------------------------------------------------------------------------------------
// Flags for URB_FUNCTION_SET_ENDPOINT_STATE
//----------------------------------------------------------------------------------------------------------------------
#define USB_ENDPOINT_STATE_CLEAR_HALT 0x00 //Clear endpoint halt.
#define USB_ENDPOINT_STATE_KEEP_HALT 0x01 //Do not clear enddpoint halt
#define USB_ENDPOINT_STATE_DATA_TOGGLE_RESET 0x04 //Reset data toggle. (i.e. DATA0)
#define USB_ENDPOINT_STATE_DATA_TOGGLE_SET 0x08 //Set data toggle. (i.e. DATA1), provided for testing.
//There is no USB_ENDPOINT_STATE_SET_HALT, since only the hardware may set it.
//----------------------------------------------------------------------------------------------------------------------
// Macros for the InterruptDelay variable in transfer and attach buffer URBs - this is really an OpenHCI thing,
// but gives more control to class drivers. These are the same as OHCI_TD_DELAY_INTERRUPT_XXX
// DUE TO BUG 9512 IT IS ONLY SAFE TO USE USBD_DELAY_INTERRUPT_0_MS. OTHERWISE, YOU MAY EXPERIENCE PROBLEMS
// WHEN CLOSING THE ENDPOINT. SEE BUG 9512 FOR MORE DETAILS.
//----------------------------------------------------------------------------------------------------------------------
#define USBD_DELAY_INTERRUPT_0_MS 0 // Interrupt at end of frame TD is completed
#define USBD_DELAY_INTERRUPT_1_MS 1 // Interrupt within 1 frame of TD compeletion
#define USBD_DELAY_INTERRUPT_2_MS 2 // Interrupt within 2 frames of TD compeletion
#define USBD_DELAY_INTERRUPT_3_MS 3 // Interrupt within 3 frame of TD compeletion
#define USBD_DELAY_INTERRUPT_4_MS 4 // Interrupt within 4 frame of TD compeletion
#define USBD_DELAY_INTERRUPT_5_MS 5 // Interrupt within 5 frame of TD compeletion
#define USBD_DELAY_INTERRUPT_6_MS 6 // Interrupt within frame of TD compeletion
#define USBD_DELAY_INTERRUPT_NONE 7 // Do not Interrupt upon completion of TD
//------------------------------------------------------------------------------------
// USBD Structures for class drivers
//------------------------------------------------------------------------------------
typedef union _URB *PURB;
typedef VOID (*PURB_COMPLETE_PROC)(PURB Urb, PVOID Context);
//
// See approptate HCD header file for
// for flags.
//
struct _URB_HCD_AREA
{
union
{
USHORT HcdTDCount;
USHORT HcdOriginalLength; //While programed contains the original length
};
USHORT HcdUrbFlags;
PURB HcdUrbLink; //Used while the URB is pending
};
struct _URB_HEADER
{
UCHAR Length;
UCHAR Function;
USBD_STATUS Status;
PURB_COMPLETE_PROC CompleteProc; // A completetion routine if the URB is not associated with an Irp
PVOID CompleteContext; // Context to pass into the completion routine.
};
typedef struct _USB_CONTROL_SETUP_PACKET
{
UCHAR bmRequestType;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} USB_CONTROL_SETUP_PACKET;
typedef struct _URB_CONTROL_TRANSFER
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
ULONG TransferBufferLength;
PVOID TransferBuffer;
UCHAR TransferDirection;
BOOLEAN ShortTransferOK;
UCHAR InterruptDelay;
UCHAR Padding;
struct _URB_HCD_AREA Hca;
USB_CONTROL_SETUP_PACKET SetupPacket;
} URB_CONTROL_TRANSFER, *PURB_CONTROL_TRANSFER;
typedef struct _URB_BULK_OR_INTERRUPT_TRANSFER
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
ULONG TransferBufferLength;
PVOID TransferBuffer;
UCHAR TransferDirection;
BOOLEAN ShortTransferOK;
UCHAR InterruptDelay;
UCHAR Padding;
struct _URB_HCD_AREA Hca; // fields for HCD use
} URB_BULK_OR_INTERRUPT_TRANSFER, *PURB_BULK_OR_INTERRUPT_TRANSFER;
typedef struct _URB_OPEN_ENDPOINT
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
UCHAR FunctionAddress;
UCHAR EndpointAddress;
UCHAR EndpointType;
UCHAR Interval;
PULONG DataToggleBits; // Filled out by USBD
USHORT MaxPacketSize;
BOOLEAN LowSpeed; //Temporary - filled out by USBD
} URB_OPEN_ENDPOINT, *PURB_OPEN_ENDPOINT;
typedef struct _URB_CLOSE_ENDPOINT
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
PURB HcdNextClose; // An extra pointer which Hcd can use to link pending closes.
PULONG DataToggleBits; // Filled out by USBD
} URB_CLOSE_ENDPOINT, *PURB_CLOSE_ENDPOINT;
typedef struct _URB_GET_SET_ENDPOINT_STATE
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
ULONG EndpointState;
} URB_GET_SET_ENDPOINT_STATE, *PURB_GET_SET_ENDPOINT_STATE;
typedef struct _URB_ABORT_ENDPOINT
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
PURB HcdNextAbort; // An extra pointer which Hcd can use to link pending aborts.
} URB_ABORT_ENDPOINT, *PURB_ABORT_ENDPOINT;
typedef struct _URB_RESET_PORT
{
struct _URB_HEADER Hdr;
UCHAR DeviceNode;
UCHAR PortNumber;
} URB_RESET_PORT, *PURB_RESET_PORT;
typedef struct _URB_GET_FRAME_NUMBER
{
struct _URB_HEADER Hdr;
UCHAR DeviceNode;
ULONG FrameNumber;
} URB_GET_FRAME_NUMBER, *PURB_GET_FRAME_NUMBER;
//------------------------------------------------
// Isoch related URBs and related structures
//------------------------------------------------
typedef struct _USBD_ISOCH_PACKET_STATUS_WORD
{
USHORT BytesRead:12;
USHORT ConditionCode:4;
} USBD_ISOCH_PACKET_STATUS_WORD, *PUSBD_ISOCH_PACKET_STATUS_WORD;
typedef struct _USBD_ISOCH_TRANSFER_STATUS
{
USBD_STATUS Status;
ULONG FrameCount;
USBD_ISOCH_PACKET_STATUS_WORD PacketStatus[8];
} USBD_ISOCH_TRANSFER_STATUS, *PUSBD_ISOCH_TRANSFER_STATUS;
typedef VOID (*PFNUSBD_ISOCH_TRANSFER_COMPLETE)(PUSBD_ISOCH_TRANSFER_STATUS Status, PVOID Context);
typedef struct _USBD_ISOCH_BUFFER_DESCRIPTOR
{
ULONG FrameCount;
PVOID TransferBuffer;
USHORT Pattern[8];
PFNUSBD_ISOCH_TRANSFER_COMPLETE TransferComplete;
PVOID Context;
} USBD_ISOCH_BUFFER_DESCRIPTOR, *PUSBD_ISOCH_BUFFER_DESCRIPTOR;
typedef struct _URB_ISOCH_ATTACH_BUFFER
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
UCHAR InterruptDelay;
PUSBD_ISOCH_BUFFER_DESCRIPTOR BufferDescriptor;
} URB_ISOCH_ATTACH_BUFFER, *PURB_ISOCH_ATTACH_BUFFER;
typedef struct _URB_ISOCH_START_TRANSFER
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
ULONG FrameNumber;
ULONG Flags;
} URB_ISOCH_START_TRANSFER, *PURB_ISOCH_START_TRANSFER;
#define URB_FLAG_ISOCH_START_ASAP 0x0001
#define USBD_ISOCH_START_FRAME_RANGE 1024
typedef struct _URB_ISOCH_STOP_TRANSFER
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
} URB_ISOCH_STOP_TRANSFER, *PURB_ISOCH_STOP_TRANSFER;
typedef struct _URB_ISOCH_OPEN_ENDPOINT
{
struct _URB_HEADER Hdr;
PVOID EndpointHandle;
UCHAR FunctionAddress;
UCHAR EndpointAddress;
USHORT MaxPacketSize;
USHORT Flags;
USHORT Pad;
} URB_ISOCH_OPEN_ENDPOINT, *PURB_ISOCH_OPEN_ENDPOINT;
#define URB_FLAG_ISOCH_CIRCULAR_DMA 0x0001
typedef struct _URB_CLOSE_ENDPOINT URB_ISOCH_CLOSE_ENDPOINT, *PURB_ISOCH_CLOSE_ENDPOINT;
//------------------------------------------------
// Union of all URBs
//------------------------------------------------
typedef union _URB
{
struct _URB_HEADER Header;
URB_CONTROL_TRANSFER ControlTransfer;
URB_BULK_OR_INTERRUPT_TRANSFER BulkOrInterruptTransfer;
URB_BULK_OR_INTERRUPT_TRANSFER CommonTransfer;
URB_OPEN_ENDPOINT OpenEndpoint;
URB_CLOSE_ENDPOINT CloseEndpoint;
URB_GET_SET_ENDPOINT_STATE GetSetEndpointState;
URB_ABORT_ENDPOINT AbortEndpoint;
URB_RESET_PORT ResetPort;
URB_GET_FRAME_NUMBER GetFrame;
URB_ISOCH_ATTACH_BUFFER IsochAttachBuffer;
URB_ISOCH_START_TRANSFER IsochStartTransfer;
URB_ISOCH_STOP_TRANSFER IsochStopTransfer;
URB_ISOCH_OPEN_ENDPOINT IsochOpenEndpoint;
URB_ISOCH_CLOSE_ENDPOINT IsochCloseEndpoint;
} URB;
//------------------------------------------------------------------------------------
// Macros to build USB Request Blocks
//------------------------------------------------------------------------------------
#define USB_BUILD_CONTROL_TRANSFER(\
_UrbControlTransfer_,\
_EndpointHandle_,\
_TransferBuffer_,\
_TransferBufferLength_,\
_TransferDirection_,\
_CompleteProc_,\
_CompleteContext_,\
_ShortTransferOK_,\
_bmRequestType_,\
_bRequest_,\
_wValue_,\
_wIndex_,\
_wLength_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = (_EndpointHandle_);\
(_UrbControlTransfer_)->TransferBuffer = (_TransferBuffer_);\
(_UrbControlTransfer_)->TransferBufferLength = (_TransferBufferLength_);\
(_UrbControlTransfer_)->TransferDirection = (_TransferDirection_);\
(_UrbControlTransfer_)->ShortTransferOK = (_ShortTransferOK_);\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = (_bmRequestType_);\
(_UrbControlTransfer_)->SetupPacket.bRequest = (_bRequest_);\
(_UrbControlTransfer_)->SetupPacket.wValue = (_wValue_);\
(_UrbControlTransfer_)->SetupPacket.wIndex = (_wIndex_);\
(_UrbControlTransfer_)->SetupPacket.wLength = (_wLength_);\
}
#define USB_BUILD_BULK_OR_INTERRUPT_TRANSFER(\
_UrbBulkOrInterruptTransfer_,\
_EndpointHandle_,\
_TransferBuffer_,\
_TransferBufferLength_,\
_TransferDirection_,\
_CompleteProc_,\
_CompleteContext_,\
_ShortTransferOK_\
)\
{\
(_UrbBulkOrInterruptTransfer_)->Hdr.Length = sizeof(URB_BULK_OR_INTERRUPT_TRANSFER);\
(_UrbBulkOrInterruptTransfer_)->Hdr.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;\
(_UrbBulkOrInterruptTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbBulkOrInterruptTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbBulkOrInterruptTransfer_)->EndpointHandle = (_EndpointHandle_);\
(_UrbBulkOrInterruptTransfer_)->TransferBuffer = (_TransferBuffer_);\
(_UrbBulkOrInterruptTransfer_)->TransferBufferLength= (_TransferBufferLength_);\
(_UrbBulkOrInterruptTransfer_)->TransferDirection = (_TransferDirection_);\
(_UrbBulkOrInterruptTransfer_)->ShortTransferOK = (_ShortTransferOK_);\
(_UrbBulkOrInterruptTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
}
//
// Isoch requests
//
#define USB_BUILD_ISOCH_OPEN_ENDPOINT(\
_UrbIsochOpenEndpoint_,\
_EndpointAddress_,\
_MaxPacketSize_,\
_Flags_\
)\
{\
(_UrbIsochOpenEndpoint_)->Hdr.Length = sizeof(URB_ISOCH_OPEN_ENDPOINT);\
(_UrbIsochOpenEndpoint_)->Hdr.Function = URB_FUNCTION_ISOCH_OPEN_ENDPOINT;\
(_UrbIsochOpenEndpoint_)->Hdr.CompleteProc = NULL;\
(_UrbIsochOpenEndpoint_)->Hdr.CompleteContext= NULL;\
(_UrbIsochOpenEndpoint_)->EndpointAddress = (_EndpointAddress_);\
(_UrbIsochOpenEndpoint_)->MaxPacketSize = (_MaxPacketSize_);\
(_UrbIsochOpenEndpoint_)->Flags = (_Flags_);\
}
#define USB_BUILD_ISOCH_CLOSE_ENDPOINT(\
_UrbIsochCloseEndpoint_,\
_EndpointHandle_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbIsochCloseEndpoint_)->Hdr.Length = sizeof(URB_ISOCH_CLOSE_ENDPOINT);\
(_UrbIsochCloseEndpoint_)->Hdr.Function = URB_FUNCTION_ISOCH_CLOSE_ENDPOINT;\
(_UrbIsochCloseEndpoint_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbIsochCloseEndpoint_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbIsochCloseEndpoint_)->EndpointHandle = (_EndpointHandle_);\
}
#define USB_BUILD_ISOCH_START_TRANSFER(\
_UrbIsochStartTransfer_,\
_EndpointHandle_,\
_FrameNumber_,\
_Flags_\
)\
{\
(_UrbIsochStartTransfer_)->Hdr.Length = sizeof(URB_ISOCH_START_TRANSFER);\
(_UrbIsochStartTransfer_)->Hdr.Function = URB_FUNCTION_ISOCH_START_TRANSFER;\
(_UrbIsochStartTransfer_)->Hdr.CompleteProc = NULL;\
(_UrbIsochStartTransfer_)->Hdr.CompleteContext = NULL;\
(_UrbIsochStartTransfer_)->EndpointHandle = (_EndpointHandle_);\
(_UrbIsochStartTransfer_)->FrameNumber = (_FrameNumber_);\
(_UrbIsochStartTransfer_)->Flags = (_Flags_);\
}
#define USB_BUILD_ISOCH_STOP_TRANSFER(\
_UrbIsochStopTransfer_,\
_EndpointHandle_\
)\
{\
(_UrbIsochStopTransfer_)->Hdr.Length = sizeof(URB_ISOCH_STOP_TRANSFER);\
(_UrbIsochStopTransfer_)->Hdr.Function = URB_FUNCTION_ISOCH_STOP_TRANSFER;\
(_UrbIsochStopTransfer_)->Hdr.CompleteProc = NULL;\
(_UrbIsochStopTransfer_)->Hdr.CompleteContext = NULL;\
(_UrbIsochStopTransfer_)->EndpointHandle = (_EndpointHandle_);\
}
#define USB_BUILD_ISOCH_ATTACH_BUFFER(\
_UrbIsochAttachBuffer_,\
_EndpointHandle_,\
_InterruptDelay_,\
_BufferDescriptor_\
)\
{\
(_UrbIsochAttachBuffer_)->Hdr.Length = sizeof(URB_ISOCH_ATTACH_BUFFER);\
(_UrbIsochAttachBuffer_)->Hdr.Function = URB_FUNCTION_ISOCH_ATTACH_BUFFER;\
(_UrbIsochAttachBuffer_)->Hdr.CompleteProc = NULL;\
(_UrbIsochAttachBuffer_)->Hdr.CompleteContext = NULL;\
(_UrbIsochAttachBuffer_)->EndpointHandle = (_EndpointHandle_);\
(_UrbIsochAttachBuffer_)->InterruptDelay = (_InterruptDelay_);\
(_UrbIsochAttachBuffer_)->BufferDescriptor = (_BufferDescriptor_);\
}
//
// Bulk or Interrupt requests
//
#define USB_BUILD_OPEN_ENDPOINT(\
_UrbOpenEndpoint_,\
_EndpointAddress_,\
_EndpointType_,\
_MaxPacketSize_,\
_Interval_\
)\
{\
(_UrbOpenEndpoint_)->Hdr.Length = sizeof(URB_OPEN_ENDPOINT);\
(_UrbOpenEndpoint_)->Hdr.Function = URB_FUNCTION_OPEN_ENDPOINT;\
(_UrbOpenEndpoint_)->Hdr.CompleteProc = NULL;\
(_UrbOpenEndpoint_)->EndpointAddress = (_EndpointAddress_);\
(_UrbOpenEndpoint_)->EndpointType = (_EndpointType_);\
(_UrbOpenEndpoint_)->Interval = (_Interval_);\
(_UrbOpenEndpoint_)->MaxPacketSize = (_MaxPacketSize_);\
}
#define USB_BUILD_CLOSE_ENDPOINT(\
_UrbCloseEndpoint_,\
_EndpointHandle_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbCloseEndpoint_)->Hdr.Length = sizeof(URB_CLOSE_ENDPOINT);\
(_UrbCloseEndpoint_)->Hdr.Function = URB_FUNCTION_CLOSE_ENDPOINT;\
(_UrbCloseEndpoint_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbCloseEndpoint_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbCloseEndpoint_)->EndpointHandle = (_EndpointHandle_);\
}
#define USB_BUILD_OPEN_DEFAULT_ENDPOINT(\
_UrbOpenEndpoint_\
)\
{\
(_UrbOpenEndpoint_)->Hdr.Length = sizeof(URB_OPEN_ENDPOINT);\
(_UrbOpenEndpoint_)->Hdr.Function = URB_FUNCTION_OPEN_DEFAULT_ENDPOINT;\
(_UrbOpenEndpoint_)->Hdr.CompleteProc = NULL;\
}
#define USB_BUILD_CLOSE_DEFAULT_ENDPOINT(_UrbCloseEndpoint_, _CompleteProc_, _CompleteContext_)\
{\
(_UrbCloseEndpoint_)->Hdr.Length = sizeof(URB_CLOSE_ENDPOINT);\
(_UrbCloseEndpoint_)->Hdr.Function = URB_FUNCTION_CLOSE_DEFAULT_ENDPOINT;\
(_UrbCloseEndpoint_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbCloseEndpoint_)->Hdr.CompleteContext = (_CompleteContext_);\
}
#define USB_BUILD_GET_ENDPOINT_STATE(_UrbGetSetEndpointState_, _EndpointHandle_)\
{\
(_UrbGetSetEndpointState_)->Hdr.Length = sizeof(URB_GET_SET_ENDPOINT_STATE);\
(_UrbGetSetEndpointState_)->Hdr.Function = URB_FUNCTION_GET_ENDPOINT_STATE;\
(_UrbGetSetEndpointState_)->Hdr.CompleteProc = NULL;\
(_UrbGetSetEndpointState_)->EndpointHandle = (_EndpointHandle_);\
}
#define USB_BUILD_SET_ENDPOINT_STATE(_UrbGetSetEndpointState_, _EndpointHandle_, _StateFlags_)\
{\
(_UrbGetSetEndpointState_)->Hdr.Length = sizeof(URB_GET_SET_ENDPOINT_STATE);\
(_UrbGetSetEndpointState_)->Hdr.Function = URB_FUNCTION_SET_ENDPOINT_STATE;\
(_UrbGetSetEndpointState_)->Hdr.CompleteProc = NULL;\
(_UrbGetSetEndpointState_)->EndpointHandle = (_EndpointHandle_);\
(_UrbGetSetEndpointState_)->EndpointState = (_StateFlags_);\
}
#define USB_BUILD_ABORT_ENDPOINT(_UrbAbortEndpoint_, _EndpointHandle_, _CompleteProc_, _CompleteContext_)\
{\
(_UrbAbortEndpoint_)->Hdr.Length = sizeof(URB_ABORT_ENDPOINT);\
(_UrbAbortEndpoint_)->Hdr.Function = URB_FUNCTION_ABORT_ENDPOINT;\
(_UrbAbortEndpoint_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbAbortEndpoint_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbAbortEndpoint_)->EndpointHandle = (_EndpointHandle_);\
}
#define USB_BUILD_RESET_PORT(_UrbResetPort_)\
{\
(_UrbResetPort_)->Hdr.Length = sizeof(URB_RESET_PORT);\
(_UrbResetPort_)->Hdr.Function = URB_FUNCTION_RESET_PORT;\
(_UrbResetPort_)->Hdr.CompleteProc = NULL;\
}
#define USB_BUILD_GET_FRAME(_UrbGetFrame_)\
{\
(_UrbResetPort_)->Hdr.Length = sizeof(URB_GET_FRAME);\
(_UrbResetPort_)->Hdr.Function = URB_FUNCTION_GET_FRAME;\
(_UrbResetPort_)->Hdr.CompleteProc = NULL;\
}
//------------------------------------------------------------------------------------
// Macros to build standard USB Command Request Blocks
//------------------------------------------------------------------------------------
#define USB_BUILD_CLEAR_FEATURE(\
_UrbControlTransfer_,\
_Recipient_,\
_FeatureSelect_,\
_Index_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = NULL;\
(_UrbControlTransfer_)->TransferBufferLength = 0;\
(_UrbControlTransfer_)->TransferDirection = 0;\
(_UrbControlTransfer_)->ShortTransferOK = 0;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = (_Recipient_);\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_CLEAR_FEATURE;\
(_UrbControlTransfer_)->SetupPacket.wValue = (_FeatureSelect_);\
(_UrbControlTransfer_)->SetupPacket.wIndex = (_Index_);\
(_UrbControlTransfer_)->SetupPacket.wLength = 0;\
}
#define USB_BUILD_SET_FEATURE(\
_UrbControlTransfer_,\
_Recipient_,\
_FeatureSelect_,\
_Index_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = NULL;\
(_UrbControlTransfer_)->TransferBufferLength = 0;\
(_UrbControlTransfer_)->TransferDirection = 0;\
(_UrbControlTransfer_)->ShortTransferOK = 0;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = (_Recipient_);\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_SET_FEATURE;\
(_UrbControlTransfer_)->SetupPacket.wValue = (_FeatureSelect_);\
(_UrbControlTransfer_)->SetupPacket.wIndex = (_Index_);\
(_UrbControlTransfer_)->SetupPacket.wLength = 0;\
}
#define USB_BUILD_GET_CONFIGURATION(\
_UrbControlTransfer_,\
_Configuration_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = (_Configuration_);\
(_UrbControlTransfer_)->TransferBufferLength = sizeof(UCHAR);\
(_UrbControlTransfer_)->TransferDirection = USB_TRANSFER_DIRECTION_IN;\
(_UrbControlTransfer_)->ShortTransferOK = 0;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = USB_DEVICE_TO_HOST;\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_GET_CONFIGURATION;\
(_UrbControlTransfer_)->SetupPacket.wValue = 0;\
(_UrbControlTransfer_)->SetupPacket.wIndex = 0;\
(_UrbControlTransfer_)->SetupPacket.wLength = 1;\
}
#define USB_BUILD_SET_CONFIGURATION(\
_UrbControlTransfer_,\
_Configuration_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = 0;\
(_UrbControlTransfer_)->TransferBufferLength = 0;\
(_UrbControlTransfer_)->TransferDirection = 0;\
(_UrbControlTransfer_)->ShortTransferOK = 0;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = USB_HOST_TO_DEVICE;\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_SET_CONFIGURATION;\
(_UrbControlTransfer_)->SetupPacket.wValue = (_Configuration_);\
(_UrbControlTransfer_)->SetupPacket.wIndex = 0;\
(_UrbControlTransfer_)->SetupPacket.wLength = 0;\
}
#define USB_BUILD_GET_DESCRIPTOR(\
_UrbControlTransfer_,\
_DescriptorType_,\
_DescriptorIndex_,\
_LanguageID_,\
_DescriptorBuffer_,\
_DescriptorBufferLength_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = (_DescriptorBuffer_);\
(_UrbControlTransfer_)->TransferBufferLength = (_DescriptorBufferLength_);\
(_UrbControlTransfer_)->TransferDirection = USB_TRANSFER_DIRECTION_IN;\
(_UrbControlTransfer_)->ShortTransferOK = TRUE;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = USB_DEVICE_TO_HOST;\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;\
(_UrbControlTransfer_)->SetupPacket.wValue = ((_DescriptorType_)<<8)|(_DescriptorIndex_);\
(_UrbControlTransfer_)->SetupPacket.wIndex = (_LanguageID_);\
(_UrbControlTransfer_)->SetupPacket.wLength = (_DescriptorBufferLength_);\
}
#define USB_BUILD_SET_DESCRIPTOR(\
_UrbControlTransfer_,\
_DescriptorType_,\
_DescriptorIndex_,\
_LanguageID_,\
_DescriptorBuffer_,\
_DescriptorBufferLength_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = (_DescriptorBuffer_);\
(_UrbControlTransfer_)->TransferBufferLength = (_DescriptorBufferLength_);\
(_UrbControlTransfer_)->TransferDirection = USB_TRANSFER_DIRECTION_OUT;\
(_UrbControlTransfer_)->ShortTransferOK = FALSE;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = USB_HOST_TO_DEVICE;\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_SET_DESCRIPTOR;\
(_UrbControlTransfer_)->SetupPacket.wValue = ((_DescriptorType_)<<8)|(_DescriptorIndex_);\
(_UrbControlTransfer_)->SetupPacket.wIndex = (_LanguageID_);\
(_UrbControlTransfer_)->SetupPacket.wLength = (_DescriptorBufferLength_);\
}
#define USB_BUILD_GET_INTERFACE(\
_UrbControlTransfer_,\
_Interface_,\
_AlternateSetting_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = (_AlternateSetting_);\
(_UrbControlTransfer_)->TransferBufferLength = sizeof(UCHAR);\
(_UrbControlTransfer_)->TransferDirection = USB_TRANSFER_DIRECTION_IN;\
(_UrbControlTransfer_)->ShortTransferOK = 0;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = USB_DEVICE_TO_HOST;\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_GET_INTERFACE;\
(_UrbControlTransfer_)->SetupPacket.wValue = 0\
(_UrbControlTransfer_)->SetupPacket.wIndex = (_Interface_);\
(_UrbControlTransfer_)->SetupPacket.wLength = 1;\
}
#define USB_BUILD_SET_INTERFACE(\
_UrbControlTransfer_,\
_Interface_,\
_AlternateSetting_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = 0;\
(_UrbControlTransfer_)->TransferBufferLength = 0;\
(_UrbControlTransfer_)->TransferDirection = 0;\
(_UrbControlTransfer_)->ShortTransferOK = 0;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = USB_HOST_TO_DEVICE;\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_SET_INTERFACE;\
(_UrbControlTransfer_)->SetupPacket.wValue = (_AlternateSetting_);\
(_UrbControlTransfer_)->SetupPacket.wIndex = (_Interface_);\
(_UrbControlTransfer_)->SetupPacket.wLength = 0;\
}
#define USB_BUILD_GET_STATUS(\
_UrbControlTransfer_,\
_Recipient_,\
_Index_,\
_Status_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = (_Status_);\
(_UrbControlTransfer_)->TransferBufferLength = size(WORD);\
(_UrbControlTransfer_)->TransferDirection = USB_TRANSFER_DIRECTION_IN;\
(_UrbControlTransfer_)->ShortTransferOK = 0;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = (USB_DEVICE_TO_HOST|(_Recipient_));\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_GET_STATUS;\
(_UrbControlTransfer_)->SetupPacket.wValue = 0;\
(_UrbControlTransfer_)->SetupPacket.wIndex =(_Index_);\
(_UrbControlTransfer_)->SetupPacket.wLength = 2;\
}
#define USB_BUILD_SYNC_FRAME(\
_UrbControlTransfer_,\
_Endpoint_,\
_Frame_,\
_CompleteProc_,\
_CompleteContext_\
)\
{\
(_UrbControlTransfer_)->Hdr.Length = sizeof(URB_CONTROL_TRANSFER);\
(_UrbControlTransfer_)->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;\
(_UrbControlTransfer_)->Hdr.CompleteProc = (_CompleteProc_);\
(_UrbControlTransfer_)->Hdr.CompleteContext = (_CompleteContext_);\
(_UrbControlTransfer_)->EndpointHandle = NULL;\
(_UrbControlTransfer_)->TransferBuffer = (_Frame_);\
(_UrbControlTransfer_)->TransferBufferLength = size(WORD);\
(_UrbControlTransfer_)->TransferDirection = USB_TRANSFER_DIRECTION_IN;\
(_UrbControlTransfer_)->ShortTransferOK = 0;\
(_UrbControlTransfer_)->InterruptDelay = USBD_DELAY_INTERRUPT_0_MS;\
(_UrbControlTransfer_)->SetupPacket.bmRequestType = (USB_DEVICE_TO_HOST|USB_COMMAND_TO_ENDPOINT);\
(_UrbControlTransfer_)->SetupPacket.bRequest = USB_REQUEST_SYNC_FRAME;\
(_UrbControlTransfer_)->SetupPacket.wValue = 0;\
(_UrbControlTransfer_)->SetupPacket.wIndex =(_Endpoint_);\
(_UrbControlTransfer_)->SetupPacket.wLength = 2;\
}
//-------------------------------------------------------------------------------------------------------------
// Get the USB status code
//-------------------------------------------------------------------------------------------------------------
#define URB_STATUS(urb) ((urb)->Header.Status)
} //end of 'extern "C"'
//------------------------------------------------------------------------------------
// bmRequestType values for commands over control pipes, belongs in usb100.h
//------------------------------------------------------------------------------------
// Data Direction
#define USB_HOST_TO_DEVICE 0x00
#define USB_DEVICE_TO_HOST 0x80
// Type
#define USB_STANDARD_COMMAND 0x00
#define USB_CLASS_COMMAND 0x20
#define USB_VENDOR_COMMAND 0x40
// Recipient
#define USB_COMMAND_TO_DEVICE 0x00
#define USB_COMMAND_TO_INTERFACE 0x01
#define USB_COMMAND_TO_ENDPOINT 0x02
#define USB_COMMAND_TO_OTHER 0x03
//------------------------------------------------------------------------------------
// The enumerator only provides the first eight bytes of the device descriptor
//------------------------------------------------------------------------------------
typedef struct _USB_DEVICE_DESCRIPTOR8 {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT bcdUSB;
UCHAR bDeviceClass;
UCHAR bDeviceSubClass;
UCHAR bDeviceProtocol;
UCHAR bMaxPacketSize0;
} USB_DEVICE_DESCRIPTOR8, *PUSB_DEVICE_DESCRIPTOR8;
//------------------------------------------------------------------------------------
// Forward declaration of classes
//------------------------------------------------------------------------------------
class IUsbDevice;
//--------------------------------------------------------------------------------------------------------------
// Resource Requirements Structure
//--------------------------------------------------------------------------------------------------------------
typedef struct _USB_RESOURCE_REQUIREMENTS
{
UCHAR ConnectorType;
UCHAR MaxDevices;
UCHAR MaxCompositeInterfaces;
UCHAR MaxControlEndpoints;
UCHAR MaxBulkEndpoints;
UCHAR MaxInterruptEndpoints;
UCHAR MaxControlTDperTransfer;
UCHAR MaxBulkTDperTransfer;
//Isoch
UCHAR MaxIsochEndpoints;
UCHAR MaxIsochMaxBuffers;
} USB_RESOURCE_REQUIREMENTS, *PUSB_RESOURCE_REQUIREMENTS;
//-------------------------------------------------------------------------------------------------
// This class is used to assist initialization.
//-------------------------------------------------------------------------------------------------
class IUsbInit
{
public:
ULONG GetMaxDeviceTypeCount(PXPP_DEVICE_TYPE XppDeviceType);
VOID RegisterResources(PUSB_RESOURCE_REQUIREMENTS pResourceRequirements);
BOOL UseDefaultCount();
};
//--------------------------------------------------------------------------------------------------------------
// Class Driver Static Registration
//--------------------------------------------------------------------------------------------------------------
typedef union _PNP_CLASS_ID
{
LONG AsLong;
struct
{
UCHAR bClassSpecificType;
UCHAR bClass;
UCHAR bSubClass;
UCHAR bProtocol;
} USB;
} PNP_CLASS_ID, *PPNP_CLASS_ID;
// The high-bit of bClassSpecificType is set
// if the class driver has not indicated a class
// specific type. Prior to calling AddDevice
// this is used to track whether this is a
// device level or interface level class.
//
// USB_CLASS_DRIVER_DECLARATION assumes PNP_INTERFACE_LEVEL_CLASS
//
#define PNP_CLASS_SPECIFIC_TYPE_NOT_SET(bClassSpecificType) (bClassSpecificType&0x80)
#define PNP_DEVICE_LEVEL_CLASS 0x81
#define PNP_INTERFACE_LEVEL_CLASS 0x82
typedef
VOID
(*PFNINIT_USB_DRIVER)(IUsbInit *UsbInit);
typedef
VOID
(*PFNADD_USB_DEVICE)(
IN IUsbDevice *Device
);
typedef
VOID
(*PFNREMOVE_USB_DEVICE)(
IN IUsbDevice *Device
);
typedef struct _USB_DEVICE_TYPE_DESCRIPTION
{
PXPP_DEVICE_TYPE XppDeviceType;
} USB_DEVICE_TYPE_DESCRIPTION, *PUSB_DEVICE_TYPE_DESCRIPTION;
#define USB_CONNECTOR_TYPE_DIRECT 0 //Plugs directly into the front of xbox (or a hub port)
#define USB_CONNECTOR_TYPE_HIGH_POWER 1 //Plugs into a high power slot in gamepad
#define USB_CONNECTOR_TYPE_LOW_POWER 2 //Plugs into a high power or low power slot in gamepad
typedef struct _USB_CLASS_DRIVER_DESCRIPTION
{
PNP_CLASS_ID ClassId;
PFNINIT_USB_DRIVER Init;
PFNADD_USB_DEVICE AddDevice;
PFNREMOVE_USB_DEVICE RemoveDevice;
ULONG DeviceTypeCount;
PXPP_DEVICE_TYPE *DeviceTypes;
} USB_CLASS_DRIVER_DESCRIPTION, *PUSB_CLASS_DRIVER_DESCRIPTION;
#define DECLARE_XPP_TYPE(XppTypeName)\
EXTERNUSB XPP_DEVICE_TYPE XppTypeName##_TABLE = {0,0,0};
#define USB_DEVICE_TYPE_TABLE_BEGIN(ClassName)\
EXTERNUSB PXPP_DEVICE_TYPE ClassName##Types[]={
#define USB_DEVICE_TYPE_TABLE_ENTRY(XppDeviceType)\
(XppDeviceType)
#define USB_DEVICE_TYPE_TABLE_END() };
#define USB_CLASS_DRIVER_DECLARATION(ClassName, bClass, bSubClass, bProtocol)\
EXTERNUSB VOID ClassName##Init(IUsbInit *UsbInit);\
EXTERNUSB VOID ClassName##AddDevice(IUsbDevice *Device);\
EXTERNUSB VOID ClassName##RemoveDevice(IUsbDevice *Device);\
EXTERNUSB USB_CLASS_DRIVER_DESCRIPTION ClassName##Description = {\
PNP_INTERFACE_LEVEL_CLASS + ((bClass << 8) + (bSubClass << 16) + (bProtocol << 24)),\
ClassName##Init,\
ClassName##AddDevice,\
ClassName##RemoveDevice,\
sizeof(ClassName##Types)/sizeof(USB_DEVICE_TYPE_DESCRIPTION),\
ClassName##Types\
};
#define USB_CLASS_DRIVER_DECLARATION_DUPLICATE(ClassName, DuplicateNumber, bClass, bSubClass, bProtocol)\
EXTERNUSB USB_CLASS_DRIVER_DESCRIPTION ClassName##DuplicateNumber##Description = {\
PNP_INTERFACE_LEVEL_CLASS + ((bClass << 8) + (bSubClass << 16) + (bProtocol << 24)),\
ClassName##Init,\
ClassName##AddDevice,\
ClassName##RemoveDevice,\
sizeof(ClassName##Types)/sizeof(USB_DEVICE_TYPE_DESCRIPTION),\
ClassName##Types\
};
#define USB_CLASS_DRIVER_DECLARATION_DEVICE_LEVEL(ClassName, bClass, bSubClass, bProtocol)\
EXTERNUSB VOID ClassName##Init(IUsbInit *UsbInit);\
EXTERNUSB VOID ClassName##AddDevice(IUsbDevice *Device);\
EXTERNUSB VOID ClassName##RemoveDevice(IUsbDevice *Device);\
EXTERNUSB USB_CLASS_DRIVER_DESCRIPTION ClassName##Description = {\
PNP_DEVICE_LEVEL_CLASS + ((bClass << 8) + (bSubClass << 16) + (bProtocol << 24)),\
ClassName##Init,\
ClassName##AddDevice,\
ClassName##RemoveDevice,\
sizeof(ClassName##Types)/sizeof(USB_DEVICE_TYPE_DESCRIPTION),\
ClassName##Types\
};
#define USB_CLASS_DECLARATION_POINTER(ClassName)\
EXTERNUSB USB_CLASS_DRIVER_DESCRIPTION *ClassName##DescriptionPointer=&ClassName##Description;
#define USB_CLASS_DECLARATION_POINTER_DUPLICATE(ClassName, DuplicateNumber)\
EXTERNUSB USB_CLASS_DRIVER_DESCRIPTION *ClassName##DuplicateNumber##DescriptionPointer=\
&ClassName##DuplicateNumber##Description;
#define REFERENCE_CLASS(ClassName)\
EXTERNUSB USB_CLASS_DRIVER_DESCRIPTION ClassName##Description;\
static USB_CLASS_DRIVER_DESCRIPTION *classMU = &(ClassName##Description);
//---------------------------------------------------------------------------------------------------------------
// IUsbDevice is the main interface to the core driver
//---------------------------------------------------------------------------------------------------------------
class IUsbDevice
{
public:
/* IUsbDevice methods calleable at any time by class driver*/
USBD_STATUS SubmitRequest(PURB Urb);
USBD_STATUS CancelRequest(PURB Urb);
BOOLEAN IsHardwareConnected() const;
PVOID GetExtension() const;
PVOID SetExtension(PVOID Extension);
UCHAR GetInterfaceNumber() const;
void SetClassSpecificType(UCHAR ClassSpecificType);
ULONG GetPort() const;
/* IUsbDevice methods related to device enumeration*/
void AddComplete(USBD_STATUS UsbdStatus);
void RemoveComplete();
void DeviceNotResponding();
/* IUsbDevice methods calleable only at enum time*/
const USB_DEVICE_DESCRIPTOR8 *GetDeviceDescriptor() const;
const USB_CONFIGURATION_DESCRIPTOR *GetConfigurationDescriptor() const;
const USB_INTERFACE_DESCRIPTOR *GetInterfaceDescriptor() const;
const USB_ENDPOINT_DESCRIPTOR *GetEndpointDescriptor(UCHAR EndpointType, BOOLEAN Direction, UCHAR Index) const;
/* IUsbDevice methods used only by hubs */
void DeviceConnected(UCHAR PortNumber, UCHAR RetryCount);
void DeviceDisconnected(UCHAR PortNumber);
void ResetComplete(USBD_STATUS UsbdStatus, PVOID Context);
void DisableComplete(USBD_STATUS UsbdStatus, PVOID Context);
/* static IUsbDevice methods */
static ULONG Win32FromUsbdStatus(USBD_STATUS UsbdStatus);
static NTSTATUS NtStatusFromUsbdStatus(USBD_STATUS UsbdStatus);
};
//--------------------------------------------------------------------------------
// Hub driver must implement this method
//--------------------------------------------------------------------------------
extern VOID USBHUB_DisableResetPort(
IN IUsbDevice *HubDevice,
IN UCHAR PortNumber,
IN PVOID Context,
IN BOOLEAN Disable
);
#endif //__USB_X__