/*++ Copyright (c) Microsoft Corporation. All rights reserved. Module Name: usbd.h Generated from usb.x Abstract: Private Header for USBD internal modules 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 // // 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; //--------------------------------------------------------------------------------------------------------------- // USB_HOST_CONTROLLER - Host Controller Configuration Selection //--------------------------------------------------------------------------------------------------------------- #define USB_SINGLE_HOST_CONTROLLER 1 #define USB_DUAL_HOST_CONTROLLER_XDK 2 // Select which configuragtion to use. #ifndef USB_HOST_CONTROLLER_CONFIGURATION #ifdef SILVER #define USB_HOST_CONTROLLER_CONFIGURATION USB_DUAL_HOST_CONTROLLER_XDK #else //!SILVER #define USB_HOST_CONTROLLER_CONFIGURATION USB_SINGLE_HOST_CONTROLLER #endif ////!SILVER #endif USB_HOST_CONTROLLER_CONFIGURATION # //------------------------------------------------------------------------------------ // Forward declaration of classes //------------------------------------------------------------------------------------ class IUsbDevice; class CDeviceTree; //--------------------------------------------------------------------------------------------------------------- // USBD_HOST_CONTROLLER - Context of USBD by host controller. Instead of a DEVICE_OBJECT //--------------------------------------------------------------------------------------------------------------- #pragma warning(disable : 4200) //Turn off zero length array warning typedef struct _USBD_HOST_CONTROLLER { ULONG ControllerNumber; //Number of this controller. IUsbDevice *RootHub; //Root Hub ULONG AddressList[4]; //128 bit bitfield of used USB addresses. ULONG HcdExtension[0]; //The Host controllers extension starts here. } USBD_HOST_CONTROLLER, *PUSBD_HOST_CONTROLLER; #pragma warning(default : 4200) //Turn zero length array warning back on // // Stuff related to the Host Controller Driver, its endpoint size and its extension // extern ULONG GLOBAL_HostControllerExtensionSize; #define USBD_GetHCDExtension(_UsbdHostController_) ((PVOID)(_UsbdHostController_->HcdExtension)) #define USBD_HostControllerFromHCDExtension(_HCDExtension_) CONTAINING_RECORD(_HCDExtension_, USBD_HOST_CONTROLLER, HcdExtension) //--------------------------------------------------------------------------------------------------------------- // Types of USB Device Nodes. // UDN_TYPE_HUB - represents a hub device. // UDN_TYPE_FUNCTION - a USB function for which bDeviceClass != 0. // UDN_TYPE_INTERFACE_FUNCTION - a USB function where bDeviceClass is 0, but there is only one interface. // UDN_TYPE_COMPOSITE_FUNCTION - a USB function where bDeviceClass is 0, and there are multiple interfaces. // a COMPOSITE_FUNCTION always has one INTERFACE child be interface. // UDN_TYPE_INTERFACE - represents an INTERFACE on a COMPOSITE_FUNCTION. //=============================================================================================================== // Special types not signifying a device // UDN_TYPE_UNUSED - Not currently representing a device. Node should be on the free list. // UDN_TYPE_PENDING_ENUM - Device has been detected, but is in the list of nodes awaiting enumeration. // UDN_TYPE_ENUMERATING - Device is currently being enumerated, but has not reached a stage of enumeration // yet where the node type is known. //--------------------------------------------------------------------------------------------------------------- #define UDN_TYPE_ROOT_HUB 0 #define UDN_TYPE_HUB 1 #define UDN_TYPE_FUNCTION 2 #define UDN_TYPE_INTERFACE_FUNCTION 3 #define UDN_TYPE_COMPOSITE_FUNCTION 4 #define UDN_TYPE_INTERFACE 5 #define UDN_TYPE_UNUSED 0xFF #define UDN_TYPE_PENDING_ENUM 0xFE #define UDN_TYPE_ENUMERATING 0xFD //--------------------------------------------------------------------------------------------------------------- // Device node constants //--------------------------------------------------------------------------------------------------------------- #define UDN_INVALID_NODE_INDEX 128 // Indicates that index does not point to a valid node. #define UDN_LOWSPEED_PORT 0x80 #define UDN_NO_CLASS_DRIVER_SUPPORT 0xFF #define UDN_HUB_TYPE_EXTERNAL 0x01 //-------------------------------------------------------------------------------- // Resource structure shared between USBD and OHCD //-------------------------------------------------------------------------------- extern "C" { #define HCD_INTERRUPT_TD_QUOTA 3 typedef struct _HCD_RESOURCE_REQUIREMENTS { ULONG EndpointCount; ULONG IsochEndpointCount; ULONG TDCount; UCHAR ControlTDQuota; UCHAR BulkTDQuota; UCHAR IsochMaxBuffers; } HCD_RESOURCE_REQUIREMENTS, *PHCD_RESOURCE_REQUIREMENTS; } //end 'extern "C"' //-------------------------------------------------------------------------------------------------------------- // 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(); //c'tor IUsbInit(ULONG NumDeviceTypes, PXDEVICE_PREALLOC_TYPE DeviceTypes) : m_NumDeviceTypes(NumDeviceTypes), m_pDeviceTypes(DeviceTypes), m_NodeCount(0), m_MaxCompositeInterfaces(0) { RtlZeroMemory(m_Direct, sizeof(m_Direct)); RtlZeroMemory(m_TopSlots, sizeof(m_TopSlots)); RtlZeroMemory(m_BottomSlots, sizeof(m_BottomSlots)); RtlZeroMemory(&m_HcdResources, sizeof(m_HcdResources)); } //services for usbd to retrieve information void Process(); inline UCHAR GetNodeCount() {return m_NodeCount;} inline UCHAR GetMaxCompositeInterfaces() {return m_MaxCompositeInterfaces;} inline PHCD_RESOURCE_REQUIREMENTS GetHcdResourcePtr() {return &m_HcdResources;} private: USB_RESOURCE_REQUIREMENTS m_Direct[5]; USB_RESOURCE_REQUIREMENTS m_TopSlots[5]; USB_RESOURCE_REQUIREMENTS m_BottomSlots[5]; ULONG m_NumDeviceTypes; PXDEVICE_PREALLOC_TYPE m_pDeviceTypes; // Fields valid after process UCHAR m_NodeCount; UCHAR m_MaxCompositeInterfaces; HCD_RESOURCE_REQUIREMENTS m_HcdResources; }; //-------------------------------------------------------------------------------------------------------------- // 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); /* c'tor */ IUsbDevice::IUsbDevice() : m_Type(UDN_TYPE_UNUSED), m_NextFree(UDN_INVALID_NODE_INDEX), m_FirstChild(UDN_INVALID_NODE_INDEX), m_Sibling(UDN_INVALID_NODE_INDEX){} /* IUsbDevice short and sweet methods used in USBD, these are inline, but defined below due to declaration order */ UCHAR GetIndex() const; BOOLEAN GetLowSpeed() const; UCHAR GetHubPort() const; IUsbDevice *GetParent() const; IUsbDevice *GetFirstChild() const; IUsbDevice *GetSibling() const; IUsbDevice *FindChild(UCHAR PortNumber) const; void InsertChild(IUsbDevice *child); BOOLEAN RemoveChild(IUsbDevice *child); BOOLEAN IsEnumTime() const; PNP_CLASS_ID GetClassId() const; /* public helper function*/ void SetExternalPort(); #ifndef SILVER void SetExternalPortWithHub(IUsbDevice **pParentArray, UINT DeviceIndex); void SetExternalPortWithoutHub(IUsbDevice **pParentArray, UINT DeviceIndex); #endif // // These are not declared private as most of the code is already coded in C // and manipulates this class directly. // UCHAR m_Type; union { UCHAR m_Parent; UCHAR m_NextFree; }; union { UCHAR m_FirstChild; UCHAR m_bInterfaceNumber; }; UCHAR m_Sibling; UCHAR m_PortNumber; union { UCHAR m_Address; UCHAR m_RetryCount; }; UCHAR m_MaxPacket0; UCHAR m_ClassSpecificType; PVOID m_DefaultEndpoint; PUSBD_HOST_CONTROLLER m_HostController; union { PUSB_CLASS_DRIVER_DESCRIPTION m_ClassDriver; IUsbDevice *m_NextPending; }; LONG m_ExternalPort; union { LARGE_INTEGER m_EarliestEnumTime; struct { ULONG m_DataToggleBits; PVOID m_ClassDriverExtension; }; }; /* IUsbDevice helpers, these are only called internally so can be private */ private: USBD_STATUS OpenDefaultEndpoint(PURB Urb); USBD_STATUS CloseDefaultEndpoint(PURB Urb); }; //-------------------------------------------------------------------------------- // Hub driver must implement this method //-------------------------------------------------------------------------------- extern VOID USBHUB_DisableResetPort( IN IUsbDevice *HubDevice, IN UCHAR PortNumber, IN PVOID Context, IN BOOLEAN Disable ); //-------------------------------------------------------------------------------- // Enum Stages, mostly for debugging really //-------------------------------------------------------------------------------- #define USBD_ENUM_DEVICE_CONNECTED 0x80 #define USBD_ENUM_STAGE_0 0 #define USBD_ENUM_STAGE_PRE1 0x81 #define USBD_ENUM_STAGE_1 1 #define USBD_ENUM_STAGE_2 2 #define USBD_ENUM_STAGE_3 3 #define USBD_ENUM_STAGE_PRE4 0x84 #define USBD_ENUM_STAGE_4 4 #define USBD_ENUM_STAGE_5 5 #define USBD_ENUM_STAGE_6 6 #define USBD_ENUM_STAGE_ADD_COMPLETE 7 #define USBD_ENUM_STAGE_ABORT1 8 #define USBD_ENUM_STAGE_DISABLE_COMPLETE 9 #define USBD_ENUM_STAGE_ABORT2 10 //-------------------------------------------------------------------------------- // CDeviceTree keeps track of all the devices //-------------------------------------------------------------------------------- #define USBD_MAX_CONFIG_DESC_SIZE 80 #define USBD_DEFAULT_MAXPACKET0 8 #define USBD_CONTROL_TD_QUOTA (USBD_MAX_CONFIG_DESC_SIZE/USBD_DEFAULT_MAXPACKET0) + 3 //the three is for SETUP, SETUP's data and STATUS #define USBD_BASE_NODES_PER_PORT 4 class CDeviceTree { public: // // There is no defined c'tor, because there is no way // to make sure that it gets called. // void Init(ULONG NodeCount, ULONG MaxCompositeInterfaces); IUsbDevice *AllocDevice() { UCHAR nodeIndex = m_FirstFree; ASSERT(UDN_INVALID_NODE_INDEX != nodeIndex); m_FirstFree = m_Devices[nodeIndex].m_NextFree; m_Devices[nodeIndex].m_Parent = UDN_INVALID_NODE_INDEX; m_Devices[nodeIndex].m_FirstChild = UDN_INVALID_NODE_INDEX; m_Devices[nodeIndex].m_Sibling = UDN_INVALID_NODE_INDEX; m_Devices[nodeIndex].m_ClassDriverExtension = NULL; m_Devices[nodeIndex].m_ClassSpecificType = 0xFF; return m_Devices + nodeIndex; } VOID FreeDevice(IUsbDevice *usbDevice) { ASSERT(usbDevice >= m_Devices); UCHAR nodeIndex = usbDevice - m_Devices; ASSERT(UDN_INVALID_NODE_INDEX > nodeIndex); m_Devices[nodeIndex].m_Type = UDN_TYPE_UNUSED; m_Devices[nodeIndex].m_NextFree = m_FirstFree; m_FirstFree = nodeIndex; } BOOLEAN m_InProgress; BOOLEAN m_DeviceRemoved; BOOLEAN m_RetryCount; UCHAR m_EnumStage; URB m_EnumUrb; KDPC m_EnumDpc; KTIMER m_EnumTimer; UCHAR m_TimerReason; UCHAR m_FirstFree; UCHAR m_NodeCount; UCHAR m_MaxCompositeInterfaces; IUsbDevice *m_FirstPendingEnum; IUsbDevice *m_CurrentEnum; USB_DEVICE_DESCRIPTOR8 m_DeviceDescriptor; UCHAR m_ConfigurationDescriptorBuffer[USBD_MAX_CONFIG_DESC_SIZE]; PUSB_INTERFACE_DESCRIPTOR m_InterfaceDescriptor; IUsbDevice *m_Devices; }; extern CDeviceTree g_DeviceTree; #define USBD_TIMER_REASON_STAGE0 0 #define USBD_TIMER_REASON_WATCHDOG 1 #define USBD_TIMER_REASON_CONTINUE_STAGE1 2 #define USBD_TIMER_REASON_CONTINUE_STAGE4 3 /************************************************** *** Implementation of IUsbDevice inline functions *********/ inline UCHAR IUsbDevice::GetIndex() const /*++ Gets the index of this device in the global static tree. --*/ {return (UCHAR)(this - g_DeviceTree.m_Devices);} inline BOOLEAN IUsbDevice::GetLowSpeed() const /*++ Returns true if the device is lowspeed. THIS WILL BE REMOVED WHEN SUPPORT FOR LOWSPEED IS DROPPED. --*/ {return m_PortNumber & UDN_LOWSPEED_PORT ? TRUE : FALSE;} inline UCHAR IUsbDevice::GetHubPort() const /*++ Get the portnumber regardless of lowspeed or not. --*/ {return m_PortNumber & ~UDN_LOWSPEED_PORT;} inline IUsbDevice * IUsbDevice::GetParent() const /*++ Returns a pointer to the parent. NULL if there is no parent. --*/ {return (UDN_INVALID_NODE_INDEX != m_Parent) ? (g_DeviceTree.m_Devices + m_Parent) : NULL;} inline IUsbDevice * IUsbDevice::GetFirstChild() const /*++ Returns a pointer to the first child. NULL if there are no children. --*/ {return (UDN_INVALID_NODE_INDEX != m_FirstChild) ? (g_DeviceTree.m_Devices + m_FirstChild) : NULL;} inline IUsbDevice * IUsbDevice::GetSibling() const /*++ Returns a pointer to the next sibling. NULL if this is the last sibling. --*/ {return (UDN_INVALID_NODE_INDEX != m_Sibling) ? (g_DeviceTree.m_Devices + m_Sibling) : NULL;} //------------------------------------------------------------------------ // Methods used across modules //------------------------------------------------------------------------ PUSB_CLASS_DRIVER_DESCRIPTION USBD_FindClassDriver( IN PNP_CLASS_ID ClassId ); //------------------------------------------------ // Needed in ISBD_Init were we initialize the // the DPC for timing when to start enumeration. //------------------------------------------------ void USBD_DeviceEnumTimerProc( IN PKDPC Dpc, IN PVOID Unused1, IN PVOID Unused2, IN PVOID Unused3 ); //------------------------------------------------ // Entry Point XAPI must call //------------------------------------------------ EXTERNUSB VOID USBD_Init(DWORD NumDeviceTypes, PXDEVICE_PREALLOC_TYPE DeviceTypes); //-------------------------------------------------------------------------------- // Interface between the host controller driver and usbd //-------------------------------------------------------------------------------- extern "C" { // // HCD specific URBs // #define USBD_EP_FLAG_LOWSPEED 0x0001 #define USBD_EP_FLAG_NEVERHALT 0x0002 // // Common transfer request definition, all transfer // requests passed to the HCD will be mapped to this // format. The HCD will can use this structure to // reference fields that are common to all transfers // as well as fields specific to isochronous and // control transfers. // // bandwidth related definitions // // overhead in bytes/ms #define USB_ISO_OVERHEAD_BYTES 9 #define USB_INTERRUPT_OVERHEAD_BYTES 13 //------------------------------------------------------------- // Utility procedures supported by USB System Driver //------------------------------------------------------------- VOID USBD_CompleteRequest( IN PURB Urb ); USHORT USBD_CalculateUsbBandwidth( IN USHORT MaxPacketSize, IN UCHAR EndpointType, IN BOOLEAN LowSpeed ); VOID USBD_DeviceConnected( IN PVOID HcdExtension, IN UCHAR PortNumber ); VOID USBD_DeviceDisconnected( IN PVOID HcdExtension, IN UCHAR PortNumber ); VOID USBD_NewHostController( IN PPCI_DEVICE_DESCRIPTOR PciDevice, IN ULONG HcdDeviceExtensionSize ); //------------------------------------------------------------- // Procedures which must be exported by Host Controller Driver //------------------------------------------------------------- VOID HCD_DriverEntry( PHCD_RESOURCE_REQUIREMENTS ResourceRequirements ); VOID HCD_EnumHardware(); NTSTATUS HCD_NewHostController( IN PVOID HcdExtension, IN UCHAR HostControllerNumber, IN PPCI_DEVICE_DESCRIPTOR PciDevice ); USBD_STATUS HCD_SubmitRequest( IN PVOID HcdExtension, IN PURB Urb ); USBD_STATUS HCD_CancelRequest( IN PVOID HcdExtension, IN PURB Urb ); typedef VOID (*PFNHCD_RESET_COMPLETE)( IN USBD_STATUS Status, IN PVOID Context ); VOID HCD_ResetRootHubPort( IN PVOID HcdExtension, IN ULONG PortNumber, IN PFNHCD_RESET_COMPLETE ResetCompleteProc, IN PVOID CompleteContext ); VOID HCD_DisableRootHubPort( IN PVOID HcdExtension, IN ULONG PortNumber ); } //end 'extern "C"' #endif //__USB_X__