/*! \file lusbk_shared.h * \brief Types and defines shared with the driver. */ #ifndef __LUSBK_SHARED_H_ #define __LUSBK_SHARED_H_ // fix C_ASSERT macro error notifications in VS2010+ code browser #if defined(_MSC_VER) && _MSC_VER >= 1600 #define USBK_C_ASSERT(name,x) typedef char C_ASSERT_ ## name ## _COUNTER_ [(x) ? 1 : -1]; #else #define USBK_C_ASSERT(name,x) C_ASSERT(x) #endif #ifndef __USB_H__ //! Values used in the \c bmAttributes field of a \ref USB_ENDPOINT_DESCRIPTOR typedef enum _USBD_PIPE_TYPE { //! Indicates a control endpoint UsbdPipeTypeControl, //! Indicates an isochronous endpoint UsbdPipeTypeIsochronous, //! Indicates a bulk endpoint UsbdPipeTypeBulk, //! Indicates an interrupt endpoint UsbdPipeTypeInterrupt, } USBD_PIPE_TYPE; #endif #if !defined(__WINUSB_COMPAT_IO_H__) && !defined(__WUSBIO_H__) // pipe policy types /////////////// #define SHORT_PACKET_TERMINATE 0x01 #define AUTO_CLEAR_STALL 0x02 #define PIPE_TRANSFER_TIMEOUT 0x03 #define IGNORE_SHORT_PACKETS 0x04 #define ALLOW_PARTIAL_READS 0x05 #define AUTO_FLUSH 0x06 #define RAW_IO 0x07 #define MAXIMUM_TRANSFER_SIZE 0x08 #define RESET_PIPE_ON_RESUME 0x09 // libusbK ISO pipe policy types /// #define ISO_START_LATENCY 0x20 #define ISO_ALWAYS_START_ASAP 0x21 #define ISO_NUM_FIXED_PACKETS 0x22 // http://msdn.microsoft.com/en-us/library/windows/hardware/ff552359%28v=vs.85%29.aspx // Settings.Parallel.NumberOfPresentedRequests // Maximum number of transfers that can be asynchronously delivered at a // time. Available in version 1.9 and later versions of KMDF. #define SIMUL_PARALLEL_REQUESTS 0x30 // Power policy types ////////////// #define AUTO_SUSPEND 0x81 #define SUSPEND_DELAY 0x83 // Device Information types //////// #define DEVICE_SPEED 0x01 // Device Speeds #define LowSpeed 0x01 #define FullSpeed 0x02 #define HighSpeed 0x03 //! The \c WINUSB_PIPE_INFORMATION structure contains pipe information that the \ref UsbK_QueryPipe routine retrieves. typedef struct _WINUSB_PIPE_INFORMATION { //! A \c USBD_PIPE_TYPE enumeration value that specifies the pipe type USBD_PIPE_TYPE PipeType; //! The pipe identifier (ID) UCHAR PipeId; //! The maximum size, in bytes, of the packets that are transmitted on the pipe USHORT MaximumPacketSize; //! The pipe interval UCHAR Interval; } WINUSB_PIPE_INFORMATION; //! Pointer to a \ref WINUSB_PIPE_INFORMATION structure typedef WINUSB_PIPE_INFORMATION* PWINUSB_PIPE_INFORMATION; USBK_C_ASSERT(WINUSB_PIPE_INFORMATION,sizeof(WINUSB_PIPE_INFORMATION) == 12); //! The \c WINUSB_PIPE_INFORMATION_EX structure contains pipe information that the \ref UsbK_QueryPipeEx routine retrieves. typedef struct _WINUSB_PIPE_INFORMATION_EX { //! A \c USBD_PIPE_TYPE enumeration value that specifies the pipe type USBD_PIPE_TYPE PipeType; //! The pipe identifier (ID) UCHAR PipeId; //! The maximum size, in bytes, of the packets that are transmitted on the pipe USHORT MaximumPacketSize; //! The pipe interval UCHAR Interval; //! The maximum number of bytes that can be transmitted in single interval. /*! * This value may be a larger than the MaximumPacketSize value on high-bandwidth, * high-speed periodic endpoints and SuperSpeed periodic endpoints, such as * isochronous endpoints. */ ULONG MaximumBytesPerInterval; } WINUSB_PIPE_INFORMATION_EX; //! Pointer to a \ref WINUSB_PIPE_INFORMATION_EX structure typedef WINUSB_PIPE_INFORMATION_EX* PWINUSB_PIPE_INFORMATION_EX; USBK_C_ASSERT(WINUSB_PIPE_INFORMATION_EX, sizeof(WINUSB_PIPE_INFORMATION_EX) == 16); #include //! The \c WINUSB_SETUP_PACKET structure describes a USB setup packet. /*! * It is often more convient to use this structure in combination with a \ref KUSB_SETUP_PACKET. * For example: * \code * \endcode */ typedef struct _WINUSB_SETUP_PACKET { //! The request type. The values that are assigned to this member are defined in Table 9.2 of section 9.3 of the Universal Serial Bus (USB) specification (www.usb.org). UCHAR RequestType; //! The device request. The values that are assigned to this member are defined in Table 9.3 of section 9.4 of the Universal Serial Bus (USB) specification. UCHAR Request; //! The meaning of this member varies according to the request. For an explanation of this member, see the Universal Serial Bus (USB) specification. USHORT Value; //! The meaning of this member varies according to the request. For an explanation of this member, see the Universal Serial Bus (USB) specification. USHORT Index; //! The number of bytes to transfer. (not including the \c WINUSB_SETUP_PACKET itself) USHORT Length; } WINUSB_SETUP_PACKET; //! pointer to a \c WINUSB_SETUP_PACKET structure typedef WINUSB_SETUP_PACKET* PWINUSB_SETUP_PACKET; USBK_C_ASSERT(WINUSB_SETUP_PACKET,sizeof(WINUSB_SETUP_PACKET) == 8); #include #endif // __WUSBIO_H__ __WINUSB_COMPAT_IO_H__ #include /*! \addtogroup isok * @{ */ //! Structure describing an isochronous transfer packet for libusbK. typedef struct _KISO_PACKET { //! Specifies the offset, in bytes, of the buffer for this packet from the beginning of the entire isochronous transfer data buffer. /*! * \c Offset represents an absolute data offset from the start of the \c Buffer parameter \ref UsbK_IsoReadPipe or \ref UsbK_IsoWritePipe. * * \note This field is assigned by the user application only and used by the driver upon transfer submission and completion. */ UINT Offset; //! Set by the host controller to indicate the actual number of bytes received by the device for isochronous IN transfers. Length not used for isochronous OUT transfers. /*! * \note This field is is not user assignable and is updated by the driver upon transfer completion. */ USHORT Length; //! Contains the 16 least significant USBD status bits, on return from the host controller driver, of this transfer packet. /*! * See MSDN for USBD status codes: USBD status code reference * * \note This field is is not user assignable and is updated by the driver upon transfer completion. */ USHORT Status; } KISO_PACKET; //! pointer to a \c KISO_PACKET structure typedef KISO_PACKET* PKISO_PACKET; //! Structure describing an isochronous transfer packet for winusb. typedef struct _KISO_WUSB_PACKET { //! Specifies the offset, in bytes, of the buffer for this packet from the beginning of the entire isochronous transfer data buffer. /*! * \c Offset represents an absolute data offset from the start of the \c Buffer parameter \ref UsbK_IsoReadPipe or \ref UsbK_IsoWritePipe. * * \note This field is assigned by the user application only and used by the driver upon transfer submission and completion. */ UINT Offset; //! Set by the host controller to indicate the actual number of bytes received by the device for isochronous IN transfers. Length not used for isochronous OUT transfers. /*! * \note This field is is not user assignable and is updated by the driver upon transfer completion. */ UINT Length; //! Contains the 16 least significant USBD status bits, on return from the host controller driver, of this transfer packet. /*! * See MSDN for USBD status codes: USBD status code reference * * \note This field is is not user assignable and is updated by the driver upon transfer completion. */ UINT Status; } KISO_WUSB_PACKET; //! pointer to a \c KISO_PACKET structure typedef KISO_WUSB_PACKET* PKISO_WUSB_PACKET; #pragma warning(disable:4200) //! Additional ISO transfer flags. typedef enum _KISO_FLAG { KISO_FLAG_NONE = 0, //! Do not start the transfer immediately, instead use \ref KISO_CONTEXT::StartFrame. /*! * By default, isochronous transfers start on the next frame and \ref KISO_CONTEXT::StartFrame is * ignored. If this flag is specified, the transfer is postponed until the current usb frame number * equals that specified by \ref KISO_CONTEXT::StartFrame. * * Under certain circumstances, the driver can specify 0 for \ref KISO_CONTEXT::StartFrame, and the bus * driver will begin the transaction in the next available frame. * * Specifing \b 0 for \ref KISO_CONTEXT::StartFrame (start transfer ASAP) is restricted to the first * transaction on a newly opened or reset pipe. Furthermore, the USB stack contains a bug in Microsoft * Windows Server 2003 and Windows XP that limits the use of this to an isochronous context with 255 or fewer * packets. * * For more information about resetting pipes, see \ref UsbK_ResetPipe. */ KISO_FLAG_SET_START_FRAME = 0x00000001, } KISO_FLAG; //! Structure describing a user defined isochronous transfer. /*! * * \fixedstruct{16} * * The \ref KISO_CONTEXT::StartFrame member of the \ref KISO_CONTEXT specifies the starting USB frame number * for the transaction. The driver can use \ref UsbK_GetCurrentFrameNumber to request the current frame * number. * * In full-speed transmissions, the frame number for any particular packet will be the sum of the start frame * number and the packet index. For instance, the fourth packet in the \ref KISO_CONTEXT has an index of 3, so * its frame number will be StartFrame + 3. In a write transfer, the port driver loads this frame with the * buffer data at the data buffer offset specified by IsoPacket[3].Offset. * * When the driver processes the \ref KISO_CONTEXT, it discards all packets in the \ref KISO_CONTEXT whose * frame numbers are lower than the current frame number. The port driver sets the Status member of the packet * descriptor for each discarded packet to USBD_STATUS_ISO_NA_LATE_USBPORT, USBD_STATUS_ISO_NOT_ACCESSED_BY_HW * or USBD_STATUS_ISO_NOT_ACCESSED_LATE. Even if it discards some packets, the port driver attempts to * transmit those packets in the \ref KISO_CONTEXT whose frame numbers are higher than the current frame * number. * * The check for a valid StartFrame member is slightly more complicated in high-speed transmissions because * the port driver loads each packet into a high-speed microframe; however, the value in StartFrame refers to * the 1 millisecond (full-speed) frame number, not the microframe. For example, if the StartFrame value * recorded in the \ref KISO_CONTEXT is one less than the current frame, the port driver will discard as many * as eight packets. The exact number of packets that the port driver discards depends on the period * associated with the isochronous pipe. * * High-speed isochronous pipes can have periods of 1, 2, 4, or 8. The period number specifies the frequency * with which the port driver inserts packets into the data stream. If the period is 2, for example, the port * driver will insert a packet into the data stream every two microframes. This means that it will only use * four of the eight microframes available within each 1-millisecond frame for isochronous data transmission. * * In general, the higher the period, the fewer packets the port driver will discard when a \ref KISO_CONTEXT * arrives late. Assume the period on an isochronous pipe is 2. With a period of 2, each 1-millisecond speed * frame will carry four packets of isochronous data for that pipe. So, for example, if CurrentFrame - * StartFrame = 3, the port driver will discard 3 * 4 = 12 packets. On the other hand, if the period is 4, * each 1-millisecond frame carries only two packets of isochronous data for the pipe. Therefore, if the * \ref KISO_CONTEXT arrives three 1-millisecond frames late, as in the previous example, the port driver will * discard 3 * 2 = 6 packets, instead of 12 packets. * * For all types of isochronous pipe, the distance between the current frame and the StartFrame value * specified in the \ref KISO_CONTEXT must be less than USBD_ISO_START_FRAME_RANGE. If StartFrame is not * within the proper range, the driver sets the Status member of the \ref KISO_PACKET * \c USBD_STATUS_BAD_START_FRAME and discards the entire \ref KISO_CONTEXT. The following code example shows * the precise check that the port driver does on the \ref KISO_CONTEXT start frame: * \code * if (abs((CurrentFrame - StartFrame)) > USBD_ISO_START_FRAME_RANGE) * { * // discard the KISO_CONTEXT * } * \endcode * */ typedef struct _KISO_CONTEXT { //! Additional ISO transfer flags. See \ref KISO_FLAG. KISO_FLAG Flags; //! Specifies the frame number that the transfer should begin on (0 for ASAP). /*! * This variable must be within a system-defined range of the current frame. The range is specified by the * constant \ref USBD_ISO_START_FRAME_RANGE. * * If /ref KISO_FLAG_SET_START_FRAME was specified, this member contains the frame number that the transfer should begin on. * When the request is returned by the host controller driver, this member is updated to reflect the frame number this transfer * did begin on. * * \note This field may be assigned by the user application and is updated by the driver upon transfer * completion. */ UINT StartFrame; //! Contains the number of packets that completed with an error condition on return from the host controller driver. /*! * \note This field is is not user assignable and is updated by the driver upon transfer completion. */ SHORT ErrorCount; //! Specifies the number of packets that are described by the variable-length array member \c IsoPacket. /* * \note This field is assigned by the user application only and used by the driver upon transfer submission * and completion. */ SHORT NumberOfPackets; //! Contains the URB Hdr.Status value on return from the host controller driver. /*! * \note This field is is not user assignable and is updated by the driver upon transfer completion. * * The USB bus driver always returns a value of USBD_STATUS_SUCCESS in * Hdr.Status, unless every packet in the transfer generated an error or * the request was not well-formed and could not be executed at all. The * following table includes possible error codes returned in Hdr.Status: * - USBD_STATUS_ISOCH_REQUEST_FAILED * Indicates that every packet of an isochronous request was completed with * errors. * - USBD_STATUS_BAD_START_FRAME * Indicates that the requested start frame is not within * USBD_ISO_START_FRAME_RANGE of the current USB frame. * - USBD_ISO_NOT_ACCESSED_LATE * Indicates that every packet was submitted too late for the packet to be * sent, based on the requested start frame. * - USBD_STATUS_INVALID_PARAMETER * Indicates that one of the URB parameters was incorrect. */ UINT UrbHdrStatus; //! Contains a variable-length array of \c KISO_PACKET structures that describe the isochronous transfer packets to be transferred on the USB bus. /* * \note This field is assigned by the user application, used by the driver upon transfer submission, and * updated by the driver upon transfer completion. */ KISO_PACKET IsoPackets[0]; } KISO_CONTEXT; USBK_C_ASSERT(KISO_CONTEXT,sizeof(KISO_CONTEXT) == 16); //! pointer to a \c KISO_CONTEXT structure typedef KISO_CONTEXT* PKISO_CONTEXT; //! Structure describing additional information about how an isochronous pipe transfers data. /*! */ typedef struct _KISOCH_PACKET_INFORMATION { //! Number of ISO packets transferred per whole USB frame (1 millisecond). /*! * Example: * - For a full speed device this value will always be 1. On Windows, 1 is the only supported pipe interval for Full speed isochronous endpoints * - For a high speed or super speed device with an interval of 1, this value will be 8 * - For a high speed or super speed device with an interval of 2, this value will be 4 */ UINT PacketsPerFrame; //! How often a pipe transfers data. /*! * Example: * - For a full speed device with an interval value of 1, this value will be 1000 * - For a high speed or super speed device with an interval of 1, this value will be 125 */ UINT PollingPeriodMicroseconds; //! Number of bytes transferred per millisecond (or whole frame). /*! * Example: * - For a full speed device with an interval value of 1 and a maximum packet size of 64, this value will be 64 * - For a high speed or super speed device with an interval of 1 and a maximum packet size of 64, this value will be 512 */ UINT BytesPerMillisecond; }KISOCH_PACKET_INFORMATION; //! pointer to a \c KISOCH_PACKET_INFORMATION structure typedef KISOCH_PACKET_INFORMATION* PKISOCH_PACKET_INFORMATION; /*! @} */ #pragma warning(default:4200) #include #endif // __LUSBK_SHARED_H_