You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2100 lines
67 KiB
2100 lines
67 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
usbport.h
|
|
|
|
Abstract:
|
|
|
|
private header for usb port driver
|
|
|
|
Environment:
|
|
|
|
Kernel & user mode
|
|
|
|
Revision History:
|
|
|
|
10-27-95 : created
|
|
|
|
--*/
|
|
|
|
#ifndef __USBPORT_H__
|
|
#define __USBPORT_H__
|
|
|
|
/* This is the goatcode */
|
|
#define USBPORT_TRACKING_ID 3
|
|
|
|
//#define USBPERF // perf changes for windows XP second edition, longhorn?
|
|
#define XPSE // bug fixes for XP second edition, longhorn or SP?
|
|
#define LOG_OCA_DATA // enable saving oca crash data on stack
|
|
|
|
/* OS version we recognize */
|
|
|
|
typedef enum _USBPORT_OS_VERSION {
|
|
Win98 = 0,
|
|
WinMe,
|
|
Win2K,
|
|
WinXP
|
|
} USBPORT_OS_VERSION;
|
|
|
|
|
|
#define USBD_STATUS_NOT_SET 0xFFFFFFFF
|
|
|
|
#define SIG_DEVICE_HANDLE 'HveD' //DevH
|
|
#define SIG_PIPE_HANDLE 'HpiP' //PipH
|
|
#define SIG_TRANSFER 'CxrT' //TrxC
|
|
#define SIG_CMNBUF 'BnmC' //CmnB
|
|
#define SIG_CONFIG_HANDLE 'HgfC' //CfgH
|
|
#define SIG_INTERFACE_HANDLE 'HxfI' //IfxH
|
|
#define SIG_ENDPOINT 'PEch' //hcEP
|
|
#define SIG_ISOCH 'cosI' //Isoc
|
|
#define SIG_MP_TIMR 'MITm' //mTIM
|
|
#define SIG_TT 'TTch' //hcTT
|
|
#define SIG_FREE 'xbsu' //usbx
|
|
#define SIG_DB 'BBsu' //usBB
|
|
#define SIG_IRPC 'Cpri' //irpC
|
|
#define SIG_REG_CACHE 'Cger' //regC
|
|
|
|
// The USBPORT_ADDRESS_AND_SIZE_TO_SPAN_PAGES_4K macro takes a virtual address
|
|
// and size and returns the number of host controller 4KB pages spanned by
|
|
// the size.
|
|
//
|
|
#define USBPORT_ADDRESS_AND_SIZE_TO_SPAN_PAGES_4K(Va,Size) \
|
|
(((((Size) - 1) >> USB_PAGE_SHIFT) + \
|
|
(((((ULONG)(Size-1)&(USB_PAGE_SIZE-1)) + (PtrToUlong(Va) & (USB_PAGE_SIZE -1)))) >> USB_PAGE_SHIFT)) + 1L)
|
|
|
|
|
|
#define STATUS_BOGUS 0xFFFFFFFF
|
|
|
|
// deadman timer interval in milliseconds
|
|
#define USBPORT_DM_TIMER_INTERVAL 500
|
|
|
|
/*
|
|
Dummy USBD extension
|
|
*/
|
|
extern PUCHAR USBPORT_DummyUsbdExtension;
|
|
#define USBPORT_DUMMY_USBD_EXT_SIZE 512
|
|
|
|
/*
|
|
Registry Keys
|
|
*/
|
|
|
|
// Software Branch PDO Keys
|
|
#define USBPORT_SW_BRANCH TRUE
|
|
|
|
#define FLAVOR_KEY L"HcFlavor"
|
|
#define BW_KEY L"TotalBusBandwidth"
|
|
#define DISABLE_SS_KEY L"HcDisableSelectiveSuspend"
|
|
#define USB2_CC_ID L"Usb2cc"
|
|
#define EN_IDLE_ENDPOINT_SUPPORT L"EnIdleEndpointSupport"
|
|
|
|
|
|
// Hardware Branch PDO Keys
|
|
// HKLM\CCS\ENUM\PCI\DeviceParameters
|
|
#define USBPORT_HW_BRANCH FALSE
|
|
|
|
#define SYM_LINK_KEY L"SymbolicName"
|
|
#define SYM_LEGSUP_KEY L"DetectedLegacyBIOS"
|
|
#define PORT_ATTRIBUTES_KEY L"PortAttrX"
|
|
#define HACTION_KEY L"Haction"
|
|
|
|
// Global Reg Keys HKLM\CCS\Services\USB
|
|
#define DEBUG_LEVEL_KEY L"debuglevel"
|
|
#define DEBUG_WIN9X_KEY L"debugWin9x"
|
|
#define DEBUG_BREAK_ON L"debugbreak"
|
|
#define DEBUG_LOG_MASK L"debuglogmask"
|
|
#define DEBUG_CLIENTS L"debugclients"
|
|
#define DEBUG_CATC_ENABLE L"debugcatc"
|
|
#define DEBUG_LOG_ENABLE L"debuglogenable"
|
|
|
|
#define BIOS_X_KEY L"UsbBIOSx"
|
|
#define G_DISABLE_SS_KEY L"DisableSelectiveSuspend"
|
|
#define G_DISABLE_CC_DETECT_KEY L"DisableCcDetect"
|
|
#define G_EN_IDLE_ENDPOINT_SUPPORT L"EnIdleEndpointSupport"
|
|
|
|
|
|
#define ENABLE_DCA L"EnableDCA"
|
|
|
|
/*
|
|
BIOS Hacks
|
|
*/
|
|
|
|
// Wake hacks, these are exclusive
|
|
// diable wake s1 and deeper
|
|
#define BIOS_X_NO_USB_WAKE_S1 0x000000001
|
|
// disable wake s2 and deeper
|
|
#define BIOS_X_NO_USB_WAKE_S2 0x000000002
|
|
// disable wake s3 and deeper
|
|
#define BIOS_X_NO_USB_WAKE_S3 0x000000004
|
|
// disable wake s4 and deeper
|
|
#define BIOS_X_NO_USB_WAKE_S4 0x000000008
|
|
|
|
|
|
/*
|
|
HC types
|
|
define known HC types
|
|
|
|
*/
|
|
|
|
// Opti Hydra derivative
|
|
#define HC_VID_OPTI 0x1045
|
|
#define HC_PID_OPTI_HYDRA 0xC861
|
|
|
|
// Intel USB 2.0 controller emulator
|
|
#define HC_VID_INTEL 0x8086
|
|
#define HC_PID_INTEL_960 0x6960
|
|
#define HC_PID_INTEL_ICH2_1 0x2442
|
|
#define HC_PID_INTEL_ICH2_2 0x2444
|
|
#define HC_PID_INTEL_ICH1 0x2412
|
|
|
|
// VIA USB controller
|
|
#define HC_VID_VIA 0x1106
|
|
#define HC_PID_VIA 0x3038
|
|
|
|
// NEC USB companion controller
|
|
#define HC_VID_NEC_CC 0x1033
|
|
#define HC_PID_NEC_CC 0x0035
|
|
#define HC_REV_NEC_CC 0x41
|
|
|
|
// VIA USB companion controller
|
|
#define HC_VID_VIA_CC 0x1106
|
|
#define HC_PID_VIA_CC 0x3038
|
|
#define HC_REV_VIA_CC 0x50
|
|
|
|
|
|
// Intel USB companion controller
|
|
#define HC_VID_INTEL_CC 0x8086
|
|
#define HC_PID_INTEL_CC1 0x24C2
|
|
#define HC_PID_INTEL_CC2 0x24C4
|
|
#define HC_PID_INTEL_CC3 0x24C7
|
|
|
|
|
|
#define PENDPOINT_DATA PVOID
|
|
#define PDEVICE_DATA PVOID
|
|
#define PTRANSFER_CONTEXT PVOID
|
|
|
|
// the maximum interval we support for an interrupt
|
|
// endpoint in the schedule, larger intervals are
|
|
// rounded down
|
|
#define USBPORT_MAX_INTEP_POLLING_INTERVAL 32
|
|
|
|
/*
|
|
Power sttructures
|
|
*/
|
|
|
|
#define USBPORT_MAPPED_SLEEP_STATES 4
|
|
|
|
typedef enum _HC_POWER_ATTRIBUTES {
|
|
HcPower_Y_Wakeup_Y = 0,
|
|
HcPower_N_Wakeup_N,
|
|
HcPower_Y_Wakeup_N,
|
|
HcPower_N_Wakeup_Y
|
|
} HC_POWER_ATTRIBUTES;
|
|
|
|
typedef struct _HC_POWER_STATE {
|
|
SYSTEM_POWER_STATE SystemState;
|
|
DEVICE_POWER_STATE DeviceState;
|
|
HC_POWER_ATTRIBUTES Attributes;
|
|
} HC_POWER_STATE, *PHC_POWER_STATE;
|
|
|
|
typedef struct _HC_POWER_STATE_TABLE {
|
|
HC_POWER_STATE PowerState[USBPORT_MAPPED_SLEEP_STATES];
|
|
} HC_POWER_STATE_TABLE, *PHC_POWER_STATE_TABLE;
|
|
|
|
|
|
/*
|
|
common structure used to represent transfer
|
|
requests
|
|
*/
|
|
|
|
typedef struct _TRANSFER_URB {
|
|
|
|
struct _URB_HEADER Hdr;
|
|
|
|
PVOID UsbdPipeHandle;
|
|
ULONG TransferFlags;
|
|
ULONG TransferBufferLength;
|
|
PVOID TransferBuffer;
|
|
PMDL TransferBufferMDL;
|
|
PVOID ReservedMBNull; // no Linked Urbs
|
|
|
|
struct _USBPORT_DATA pd; // fields for USBPORT use
|
|
|
|
union {
|
|
struct {
|
|
ULONG StartFrame;
|
|
ULONG NumberOfPackets;
|
|
ULONG ErrorCount;
|
|
USBD_ISO_PACKET_DESCRIPTOR IsoPacket[0];
|
|
} Isoch;
|
|
UCHAR SetupPacket[8];
|
|
} u;
|
|
|
|
} TRANSFER_URB, *PTRANSFER_URB;
|
|
|
|
/* Internal IRP tracking structure */
|
|
|
|
typedef struct _TRACK_IRP {
|
|
PIRP Irp;
|
|
LIST_ENTRY ListEntry;
|
|
} TRACK_IRP, *PTRACK_IRP;
|
|
|
|
|
|
/* Internal work item structure */
|
|
|
|
typedef struct _USB_POWER_WORK {
|
|
WORK_QUEUE_ITEM QueueItem;
|
|
PDEVICE_OBJECT FdoDeviceObject;
|
|
} USB_POWER_WORK, *PUSB_POWER_WORK;
|
|
|
|
/* tracking information for OCA online crash analysis */
|
|
|
|
#define SIG_USB_OCA1 '1aco' //oca1
|
|
#define SIG_USB_OCA2 '2aco' //oca2
|
|
|
|
// save 16 chars of driver name
|
|
#define USB_DRIVER_NAME_LEN 16
|
|
|
|
#ifdef LOG_OCA_DATA
|
|
typedef struct _OCA_DATA {
|
|
ULONG OcaSig1;
|
|
PIRP Irp;
|
|
USHORT DeviceVID;
|
|
USHORT DevicePID;
|
|
UCHAR AnsiDriverName[USB_DRIVER_NAME_LEN];
|
|
USB_CONTROLLER_FLAVOR HcFlavor;
|
|
ULONG OcaSig2;
|
|
} OCA_DATA, *POCA_DATA;
|
|
#endif
|
|
|
|
/*
|
|
this is the structure we use to track
|
|
common buffer blocks we allocate.
|
|
|
|
The virtual address of this structure is the
|
|
pointer returned from HalAllocateCommonBuffer
|
|
*/
|
|
|
|
typedef struct _USBPORT_COMMON_BUFFER {
|
|
|
|
ULONG Sig;
|
|
ULONG Flags;
|
|
|
|
// total length of block,
|
|
// including header and any padding
|
|
ULONG TotalLength;
|
|
// va address returned by the hal
|
|
PVOID VirtualAddress;
|
|
// phys address returned by the hal
|
|
PHYSICAL_ADDRESS LogicalAddress;
|
|
|
|
// page aligned VirtualAddress
|
|
PUCHAR BaseVa;
|
|
// page aligned 32 bit phyical address
|
|
HW_32BIT_PHYSICAL_ADDRESS BasePhys;
|
|
|
|
// va passed to the miniport
|
|
ULONG MiniportLength;
|
|
ULONG PadLength;
|
|
|
|
// va passed to the miniport
|
|
PVOID MiniportVa;
|
|
// phys address passed to miniport
|
|
HW_32BIT_PHYSICAL_ADDRESS MiniportPhys;
|
|
|
|
} USBPORT_COMMON_BUFFER, *PUSBPORT_COMMON_BUFFER;
|
|
|
|
//
|
|
// use to track transfer irps in the port driver
|
|
// this size is totally arbitrary -- I just picked 512
|
|
#define IRP_TABLE_LENGTH 512
|
|
|
|
typedef struct _USBPORT_IRP_TABLE {
|
|
struct _USBPORT_IRP_TABLE *NextTable;
|
|
PIRP Irps[IRP_TABLE_LENGTH];
|
|
} USBPORT_IRP_TABLE, *PUSBPORT_IRP_TABLE;
|
|
|
|
#define USBPORT_InsertActiveTransferIrp(fdo, irp) \
|
|
{\
|
|
PDEVICE_EXTENSION devExt;\
|
|
GET_DEVICE_EXT(devExt, (fdo));\
|
|
ASSERT_FDOEXT(devExt);\
|
|
USBPORT_InsertIrpInTable((fdo), devExt->ActiveTransferIrpTable, (irp));\
|
|
}
|
|
|
|
#define USBPORT_InsertPendingTransferIrp(fdo, irp) \
|
|
{\
|
|
PDEVICE_EXTENSION devExt;\
|
|
GET_DEVICE_EXT(devExt, (fdo));\
|
|
ASSERT_FDOEXT(devExt);\
|
|
USBPORT_InsertIrpInTable((fdo), devExt->PendingTransferIrpTable, (irp));\
|
|
}
|
|
|
|
#define USBPORT_CHECK_URB_ACTIVE(fdo, urb, inIrp) \
|
|
{\
|
|
PDEVICE_EXTENSION devExt;\
|
|
GET_DEVICE_EXT(devExt, (fdo));\
|
|
ASSERT_FDOEXT(devExt);\
|
|
USBPORT_FindUrbInIrpTable((fdo), devExt->ActiveTransferIrpTable, (urb), \
|
|
(inIrp));\
|
|
}
|
|
|
|
/*
|
|
The goal of these structures is to keep the
|
|
spinlocks a cache line away from each other
|
|
and a cache line away from the data structures
|
|
they protect.
|
|
|
|
Apparently there is an advantage to doing this
|
|
on MP systems
|
|
*/
|
|
|
|
typedef struct _USBPORT_SPIN_LOCK {
|
|
|
|
union {
|
|
KSPIN_LOCK sl;
|
|
// bugbug -- needs to be cache line size
|
|
UCHAR CacheLineSize[16];
|
|
};
|
|
|
|
LONG Check;
|
|
ULONG SigA;
|
|
ULONG SigR;
|
|
|
|
} USBPORT_SPIN_LOCK, *PUSBPORT_SPIN_LOCK;
|
|
|
|
|
|
/*
|
|
structure we use to track bound drivers
|
|
*/
|
|
|
|
typedef struct _USBPORT_MINIPORT_DRIVER {
|
|
|
|
// driver object assocaited with this particular
|
|
// miniport
|
|
PDRIVER_OBJECT DriverObject;
|
|
|
|
LIST_ENTRY ListEntry;
|
|
|
|
PDRIVER_UNLOAD MiniportUnload;
|
|
|
|
ULONG HciVersion;
|
|
// copy of the registration packet passed in
|
|
USBPORT_REGISTRATION_PACKET RegistrationPacket;
|
|
|
|
} USBPORT_MINIPORT_DRIVER, *PUSBPORT_MINIPORT_DRIVER;
|
|
|
|
|
|
/*
|
|
A separate context structure used for IRP tracking.
|
|
we do this because clients frequently free the IRP
|
|
while it is pending corrupting any lists linked with
|
|
the irp itself.
|
|
*/
|
|
typedef struct _USB_IRP_CONTEXT {
|
|
ULONG Sig;
|
|
LIST_ENTRY ListEntry;
|
|
struct _USBD_DEVICE_HANDLE *DeviceHandle;
|
|
PIRP Irp;
|
|
} USB_IRP_CONTEXT, *PUSB_IRP_CONTEXT;
|
|
|
|
|
|
#define USBPORT_TXFLAG_CANCELED 0x00000001
|
|
#define USBPORT_TXFLAG_MAPPED 0x00000002
|
|
#define USBPORT_TXFLAG_HIGHSPEED 0x00000004
|
|
#define USBPORT_TXFLAG_IN_MINIPORT 0x00000008
|
|
#define USBPORT_TXFLAG_ABORTED 0x00000010
|
|
#define USBPORT_TXFLAG_ISO 0x00000020
|
|
#define USBPORT_TXFLAG_TIMEOUT 0x00000040
|
|
#define USBPORT_TXFLAG_DEVICE_GONE 0x00000080
|
|
#define USBPORT_TXFLAG_SPLIT_CHILD 0x00000100
|
|
#define USBPORT_TXFLAG_MPCOMPLETED 0x00000200
|
|
#define USBPORT_TXFLAG_SPLIT 0x00000400
|
|
#define USBPORT_TXFLAG_KILL_SPLIT 0x00000800
|
|
|
|
|
|
typedef enum _USBPORT_TRANSFER_DIRECTION {
|
|
NotSet = 0,
|
|
ReadData, // ie in
|
|
WriteData, // ie out
|
|
} USBPORT_TRANSFER_DIRECTION;
|
|
|
|
|
|
typedef struct _HCD_TRANSFER_CONTEXT {
|
|
|
|
ULONG Sig;
|
|
|
|
ULONG Flags;
|
|
|
|
// Total length of this structure
|
|
ULONG TotalLength;
|
|
// length up to miniport context
|
|
ULONG PrivateLength;
|
|
|
|
USBPORT_TRANSFER_DIRECTION Direction;
|
|
// timeout, 0 = no timeout
|
|
ULONG MillisecTimeout;
|
|
LARGE_INTEGER TimeoutTime;
|
|
|
|
// for perf work
|
|
ULONG MiniportFrameCompleted;
|
|
// track bytes transferred this transfer
|
|
ULONG MiniportBytesTransferred;
|
|
USBD_STATUS UsbdStatus;
|
|
|
|
// irp to signal on completion
|
|
PIRP Irp;
|
|
// event to signal on completion
|
|
PKEVENT CompleteEvent;
|
|
|
|
// point back to the original URB
|
|
PTRANSFER_URB Urb;
|
|
|
|
// for linkage on endpoint lists
|
|
LIST_ENTRY TransferLink;
|
|
|
|
KSPIN_LOCK Spin;
|
|
|
|
PVOID MapRegisterBase;
|
|
ULONG NumberOfMapRegisters;
|
|
|
|
TRANSFER_PARAMETERS Tp;
|
|
PMDL TransferBufferMdl;
|
|
// used for perf
|
|
ULONG IoMapStartFrame;
|
|
|
|
// for Double buffering
|
|
LIST_ENTRY DoubleBufferList;
|
|
|
|
// parent transfer
|
|
struct _HCD_TRANSFER_CONTEXT *Transfer;
|
|
struct _HCD_ENDPOINT *Endpoint;
|
|
|
|
PUCHAR MiniportContext;
|
|
|
|
LIST_ENTRY SplitTransferList;
|
|
LIST_ENTRY SplitLink;
|
|
|
|
PMINIPORT_ISO_TRANSFER IsoTransfer;
|
|
|
|
// OCA info from device
|
|
USHORT DeviceVID;
|
|
USHORT DevicePID;
|
|
WCHAR DriverName[USB_DRIVER_NAME_LEN];
|
|
|
|
TRANSFER_SG_LIST SgList;
|
|
|
|
} HCD_TRANSFER_CONTEXT, *PHCD_TRANSFER_CONTEXT;
|
|
|
|
|
|
/*
|
|
The pipe handle structure us our primary means of
|
|
tracking USB endpoints. Contained within the handle
|
|
is our endpoint data structure as well as the
|
|
miniport endpoint data structure.
|
|
*/
|
|
|
|
typedef VOID
|
|
(__stdcall *PENDPOINT_WORKER_FUNCTION) (
|
|
struct _HCD_ENDPOINT *
|
|
);
|
|
|
|
#define EPFLAG_MAP_XFERS 0x00000001
|
|
// ep is part of root hub
|
|
#define EPFLAG_ROOTHUB 0x00000002
|
|
//replaced with dedicated flag
|
|
//#define EPFLAG_LOCKED 0x00000004
|
|
// power management hosed this endpoint
|
|
#define EPFLAG_NUKED 0x00000008
|
|
// cleared when we receive a transfer for
|
|
// the endpoint reset when the pipe gets
|
|
// reset
|
|
#define EPFLAG_VIRGIN 0x00000010
|
|
|
|
#define EPFLAG_DEVICE_GONE 0x00000020
|
|
// enpoint used by vbus (virtual bus)
|
|
#define EPFLAG_VBUS 0x00000040
|
|
// enpoint is large ISO allowed for this TT
|
|
#define EPFLAG_FATISO 0x00000080
|
|
|
|
typedef struct _HCD_ENDPOINT {
|
|
|
|
ULONG Sig;
|
|
ULONG Flags;
|
|
ULONG LockFlag;
|
|
LONG Busy;
|
|
PDEVICE_OBJECT FdoDeviceObject;
|
|
|
|
DEBUG_LOG Log;
|
|
|
|
// NOTE: must be careful with this pointer as the
|
|
// endpoint can exist after the device handle
|
|
// is removed
|
|
struct _USBD_DEVICE_HANDLE *DeviceHandle;
|
|
struct _TRANSACTION_TRANSLATOR *Tt;
|
|
|
|
MP_ENDPOINT_STATUS CurrentStatus;
|
|
MP_ENDPOINT_STATE CurrentState;
|
|
MP_ENDPOINT_STATE NewState;
|
|
ULONG StateChangeFrame;
|
|
|
|
PENDPOINT_WORKER_FUNCTION EpWorkerFunction;
|
|
LIST_ENTRY ActiveList;
|
|
LIST_ENTRY PendingList;
|
|
LIST_ENTRY CancelList;
|
|
LIST_ENTRY AbortIrpList;
|
|
|
|
// for linkage to global endpoint list
|
|
LIST_ENTRY GlobalLink;
|
|
LIST_ENTRY AttendLink;
|
|
LIST_ENTRY StateLink;
|
|
LIST_ENTRY ClosedLink;
|
|
LIST_ENTRY BusyLink;
|
|
LIST_ENTRY KillActiveLink;
|
|
LIST_ENTRY TimeoutLink;
|
|
LIST_ENTRY FlushLink;
|
|
LIST_ENTRY PriorityLink;
|
|
LIST_ENTRY RebalanceLink;
|
|
LIST_ENTRY TtLink;
|
|
|
|
USBPORT_SPIN_LOCK ListSpin;
|
|
USBPORT_SPIN_LOCK StateChangeSpin;
|
|
|
|
KIRQL LockIrql;
|
|
KIRQL ScLockIrql;
|
|
UCHAR Pad[2];
|
|
|
|
// iso stuff
|
|
ULONG NextTransferStartFrame;
|
|
|
|
PUSBPORT_COMMON_BUFFER CommonBuffer;
|
|
ENDPOINT_PARAMETERS Parameters;
|
|
|
|
PVOID Usb2LibEpContext;
|
|
// used to stall close endpoint when we may still need access
|
|
LONG EndpointRef;
|
|
|
|
struct _HCD_ENDPOINT *BudgetNextEndpoint;
|
|
|
|
// iso stat counters
|
|
// late frames - count of packets passed by calling driver that were
|
|
// too late to transmit
|
|
ULONG lateFrames;
|
|
// gap frames - these are empty frames resulting from gaps in the
|
|
// stream, these are casued by periods between iso submissions
|
|
ULONG gapFrames;
|
|
// error frames - these are frames for which we passed a packet to
|
|
// the miniport and were completed with an error
|
|
ULONG errorFrames;
|
|
|
|
// iso transaction log
|
|
DEBUG_LOG IsoLog;
|
|
|
|
PVOID MiniportEndpointData[0]; // PVOID for IA64 alignment
|
|
|
|
} HCD_ENDPOINT, *PHCD_ENDPOINT;
|
|
|
|
#define USBPORT_TTFLAG_REMOVED 0x00000001
|
|
|
|
typedef struct _TRANSACTION_TRANSLATOR {
|
|
|
|
ULONG Sig;
|
|
|
|
ULONG TtFlags;
|
|
USHORT DeviceAddress;
|
|
USHORT Port;
|
|
|
|
LIST_ENTRY EndpointList;
|
|
LIST_ENTRY TtLink;
|
|
PDEVICE_OBJECT PdoDeviceObject;
|
|
|
|
ULONG TotalBusBandwidth;
|
|
ULONG BandwidthTable[USBPORT_MAX_INTEP_POLLING_INTERVAL];
|
|
|
|
ULONG MaxAllocedBw;
|
|
ULONG MinAllocedBw;
|
|
|
|
PVOID Usb2LibTtContext[0]; // PVOID for IA64 alignment
|
|
|
|
} TRANSACTION_TRANSLATOR, *PTRANSACTION_TRANSLATOR;
|
|
|
|
|
|
#define EP_MAX_TRANSFER(ep) ((ep)->Parameters.MaxTransferSize)
|
|
#define EP_MAX_PACKET(ep) ((ep)->Parameters.MaxPacketSize)
|
|
|
|
|
|
#define USBPORT_PIPE_STATE_CLOSED 0x00000001
|
|
#define USBPORT_PIPE_ZERO_BW 0x00000002
|
|
|
|
typedef struct _USBD_PIPE_HANDLE_I {
|
|
|
|
ULONG Sig;
|
|
USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
|
|
|
ULONG PipeStateFlags;
|
|
|
|
ULONG UsbdPipeFlags;
|
|
|
|
PHCD_ENDPOINT Endpoint;
|
|
|
|
// for pipe handle list attached to device
|
|
LIST_ENTRY ListEntry;
|
|
|
|
} USBD_PIPE_HANDLE_I, *PUSBD_PIPE_HANDLE_I;
|
|
|
|
#define INITIALIZE_DEFAULT_PIPE(dp, mp) \
|
|
do {\
|
|
(dp).UsbdPipeFlags = 0;\
|
|
(dp).EndpointDescriptor.bLength =\
|
|
sizeof(USB_ENDPOINT_DESCRIPTOR);\
|
|
(dp).EndpointDescriptor.bDescriptorType =\
|
|
USB_ENDPOINT_DESCRIPTOR_TYPE;\
|
|
(dp).EndpointDescriptor.bEndpointAddress =\
|
|
USB_DEFAULT_ENDPOINT_ADDRESS;\
|
|
(dp).EndpointDescriptor.bmAttributes =\
|
|
USB_ENDPOINT_TYPE_CONTROL;\
|
|
(dp).EndpointDescriptor.wMaxPacketSize =\
|
|
mp;\
|
|
(dp).EndpointDescriptor.bInterval = 0;\
|
|
(dp).Sig = SIG_PIPE_HANDLE;\
|
|
(dp).PipeStateFlags = USBPORT_PIPE_STATE_CLOSED;\
|
|
} while(0)
|
|
|
|
|
|
typedef struct _USBD_INTERFACE_HANDLE_I {
|
|
ULONG Sig;
|
|
LIST_ENTRY InterfaceLink;
|
|
BOOLEAN HasAlternateSettings;
|
|
// number associated with this interface defined
|
|
// in the interface descriptor
|
|
UCHAR Pad[3];
|
|
// copy of interface descriptor (header) ie no endpoints
|
|
// the endpoint descriptors are in the PipeHandles
|
|
USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
|
// array of pipe handle structures
|
|
USBD_PIPE_HANDLE_I PipeHandle[0];
|
|
} USBD_INTERFACE_HANDLE_I, *PUSBD_INTERFACE_HANDLE_I;
|
|
|
|
|
|
typedef struct _USBD_CONFIG_HANDLE {
|
|
ULONG Sig;
|
|
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
|
|
LIST_ENTRY InterfaceHandleList;
|
|
} USBD_CONFIG_HANDLE, *PUSBD_CONFIG_HANDLE;
|
|
|
|
#define TEST_DEVICE_FLAG(dh, flag) ((dh)->DeviceFlags & (flag)) ? TRUE : FALSE
|
|
#define SET_DEVICE_FLAG(dh, flag) ((dh)->DeviceFlags |= (flag))
|
|
#define CLEAR_DEVICE_FLAG(dh, flag) ((dh)->DeviceFlags &= ~(flag))
|
|
|
|
// values for DveiceFlags
|
|
#define USBPORT_DEVICEFLAG_FREED_BY_HUB 0x00000001
|
|
#define USBPORT_DEVICEFLAG_ROOTHUB 0x00000002
|
|
#define USBPORT_DEVICEFLAG_RAWHANDLE 0x00000004
|
|
#define USBPORT_DEVICEFLAG_REMOVED 0x00000008
|
|
#define USBPORT_DEVICEFLAG_HSHUB 0x00000010
|
|
|
|
|
|
#define IS_ROOT_HUB(dh) (BOOLEAN)((dh)->DeviceFlags & USBPORT_DEVICEFLAG_ROOTHUB)
|
|
|
|
/*
|
|
TopologyAddress
|
|
The USB topology address is a string of bytes
|
|
representing a the devices location in the usb
|
|
tree. This address is unique bud depends entirely
|
|
on which port the device is attached.
|
|
|
|
The byte array is 5 bytes long looks like this:
|
|
|
|
[0] root hub
|
|
[1] 1st tier hub
|
|
[2] 2nd tier hub
|
|
[3] 3rd tier hub
|
|
|
|
[4] 4th tier hub
|
|
[5] 5th tier hub
|
|
[6] reserved MBZ
|
|
[7] reserved MBZ
|
|
|
|
* the spec defines a maximum of five hubs
|
|
* the spec defines a maximum of 127 ports/hub
|
|
|
|
the entry in the array indicates the port to which the
|
|
device is attached
|
|
|
|
0, 0, 0, 0, 0, 0, r0, r0 - defines the root hub
|
|
1, 0, 0, 0, 0, 0, r0, r0 - defines a device attached to port 1 of the root hub
|
|
|
|
--p1
|
|
/ p1 |-p2
|
|
p1-HUB1- p2 / p1 |-p3
|
|
/ \ p3-HUB2- p2 -HUB3--p4
|
|
root \ p3 \-p5-HUB4-p1-DEV
|
|
\ \p2
|
|
p2
|
|
|
|
1, 3, 2, 5, 1, 0, r0, r0 - defines the above device
|
|
*/
|
|
|
|
typedef struct _USBD_DEVICE_HANDLE {
|
|
ULONG Sig;
|
|
// USB address assigned to the device
|
|
USHORT DeviceAddress;
|
|
USHORT TtPortNumber;
|
|
|
|
LONG PendingUrbs;
|
|
|
|
struct _TRANSACTION_TRANSLATOR *Tt;
|
|
struct _USBD_DEVICE_HANDLE *HubDeviceHandle;
|
|
|
|
PUSBD_CONFIG_HANDLE ConfigurationHandle;
|
|
|
|
USBD_PIPE_HANDLE_I DefaultPipe;
|
|
USB_DEVICE_SPEED DeviceSpeed;
|
|
|
|
// a copy of the USB device descriptor
|
|
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
|
|
|
|
ULONG DeviceFlags;
|
|
|
|
// used to created a list of valid device
|
|
// handles
|
|
LIST_ENTRY ListEntry;
|
|
|
|
// keep a list of valid open
|
|
// pipes
|
|
LIST_ENTRY PipeHandleList;
|
|
|
|
ULONG TtCount;
|
|
// keep a list of tt structures for high speed
|
|
// hubs
|
|
LIST_ENTRY TtList;
|
|
|
|
PDEVICE_OBJECT DevicePdo;
|
|
WCHAR DriverName[USB_DRIVER_NAME_LEN];
|
|
|
|
} USBD_DEVICE_HANDLE, *PUSBD_DEVICE_HANDLE;
|
|
|
|
// we serialize access to the device handle thru a
|
|
// semaphore, the reason for this is that we need
|
|
// exclusive access when we set the configuration or
|
|
// interface
|
|
|
|
|
|
#define LOCK_DEVICE(dh, fdo) \
|
|
{ \
|
|
PDEVICE_EXTENSION devExt;\
|
|
GET_DEVICE_EXT(devExt, (fdo)); \
|
|
USBPORT_KdPrint((2, "'***LOCK_DEVICE %x\n", (dh))); \
|
|
LOGENTRY(NULL, (fdo), LOG_PNP, 'LKdv', (dh), 0, 0);\
|
|
KeWaitForSingleObject(&(devExt)->Fdo.DeviceLock, \
|
|
Executive,\
|
|
KernelMode, \
|
|
FALSE, \
|
|
NULL); \
|
|
}
|
|
|
|
#define UNLOCK_DEVICE(dh, fdo) \
|
|
{ \
|
|
PDEVICE_EXTENSION devExt;\
|
|
GET_DEVICE_EXT(devExt, (fdo)); \
|
|
USBPORT_KdPrint((2, "'***UNLOCK_DEVICE %x\n", (dh))); \
|
|
LOGENTRY(NULL, (fdo), LOG_PNP, 'UKdv', (dh), 0, 0);\
|
|
KeReleaseSemaphore(&(devExt)->Fdo.DeviceLock,\
|
|
LOW_REALTIME_PRIORITY,\
|
|
1,\
|
|
FALSE);\
|
|
}
|
|
|
|
|
|
#define USBPORT_BAD_HANDLE ((PVOID)(-1))
|
|
#define USBPORT_BAD_POINTER ((PVOID)(-1))
|
|
|
|
|
|
// PnPStateFlags
|
|
|
|
#define USBPORT_PNP_STOPPED 0x00000001
|
|
#define USBPORT_PNP_STARTED 0x00000002
|
|
#define USBPORT_PNP_REMOVED 0x00000004
|
|
#define USBPORT_PNP_START_FAILED 0x00000008
|
|
#define USBPORT_PNP_DELETED 0x00000010
|
|
|
|
// Flags:both FDO and PDO
|
|
#define USBPORT_FLAG_SYM_LINK 0x00000001
|
|
|
|
|
|
#define TEST_FDO_FLAG(de, flag) (((de)->Fdo.FdoFlags & (flag)) ? TRUE : FALSE)
|
|
#define SET_FDO_FLAG(de, flag) ((de)->Fdo.FdoFlags |= (flag))
|
|
#define CLEAR_FDO_FLAG(de, flag) ((de)->Fdo.FdoFlags &= ~(flag))
|
|
|
|
|
|
#define TEST_PDO_FLAG(de, flag) (((de)->Pdo.PdoFlags & (flag)) ? TRUE : FALSE)
|
|
#define SET_PDO_FLAG(de, flag) ((de)->Pdo.PdoFlags |= (flag))
|
|
#define CLEAR_PDO_FLAG(de, flag) ((de)->Pdo.PdoFlags &= ~(flag))
|
|
|
|
|
|
// FdoFlags: Fdo Only
|
|
#define USBPORT_FDOFLAG_IRQ_CONNECTED 0x00000001
|
|
#define USBPORT_FDOFLAG_ENABLE_SYSTEM_WAKE 0x00000002
|
|
#define USBPORT_FDOFLAG_POLL_CONTROLLER 0x00000004
|
|
// set to indicate the worker thread should
|
|
// terminate
|
|
#define USBPORT_FDOFLAG_KILL_THREAD 0x00000008
|
|
// set if the HC should be wake enabled on the
|
|
// next D power state transition
|
|
#define USBPORT_FDOFLAG_WAKE_ENABLED 0x00000010
|
|
// set to indicate the controller should
|
|
// be put in D0 by the worker thread
|
|
#define USBPORT_FDOFLAG_NEED_SET_POWER_D0 0x00000020
|
|
// set when the DM_timer is running
|
|
#define USBPORT_FDOFLAG_DM_TIMER_ENABLED 0x00000040
|
|
// set to disable the DM tiners work
|
|
// while controller is in low power
|
|
#define USBPORT_FDOFLAG_SKIP_TIMER_WORK 0x00000080
|
|
|
|
// **NOTE: the following two flags are
|
|
// Mutually Exclusive
|
|
//
|
|
// since the true power state of the HW must remain independent
|
|
// of OS power management we have our own flags for this.
|
|
// set to indicate the controller is 'suspended'
|
|
#define USBPORT_FDOFLAG_SUSPENDED 0x00000100
|
|
// set to indicate the controller is 'OFF'
|
|
#define USBPORT_FDOFLAG_OFF 0x00000200
|
|
|
|
#define USBPORT_FDOFLAG_IRQ_EN 0x00000400
|
|
// set if the controller can 'suspend' the root hub
|
|
// this is the dynamic flag use to turn SS on and off
|
|
#define USBPORT_FDOFLAG_RH_CAN_SUSPEND 0x00000800
|
|
// set if controller detects resume signalling
|
|
#define USBPORT_FDOFLAG_RESUME_SIGNALLING 0x00001000
|
|
|
|
#define USBPORT_FDOFLAG_HCPENDING_WAKE_IRP 0x00002000
|
|
// set if we initialize the dm timer, used to
|
|
// bypass timer stop on failure
|
|
#define USBPORT_FDOFLAG_DM_TIMER_INIT 0x00004000
|
|
// set if we init the worker thread
|
|
#define USBPORT_FDOFLAG_THREAD_INIT 0x00008000
|
|
// means we created the HCDn symbolic name
|
|
#define USBPORT_FDOFLAG_LEGACY_SYM_LINK 0x00010000
|
|
// some knucklehead pulled out the controller
|
|
#define USBPORT_FDOFLAG_CONTROLLER_GONE 0x00020000
|
|
// miniport has requested hw reset
|
|
#define USBPORT_FDOFLAG_HW_RESET_PENDING 0x00040000
|
|
// set if tlegacy BIOS detected
|
|
#define USBPORT_FDOFLAG_LEGACY_BIOS 0x00080000
|
|
|
|
#define USBPORT_FDOFLAG_CATC_TRAP 0x00100000
|
|
/* polls hw while suspended */
|
|
#define USBPORT_FDOFLAG_POLL_IN_SUSPEND 0x00200000
|
|
#define USBPORT_FDOFLAG_FAIL_URBS 0x00400000
|
|
/* turn on Intel USB diag mode */
|
|
#define USBPORT_FDOFLAG_DIAG_MODE 0x00800000
|
|
/* set if 1.1 controller is CC */
|
|
#define USBPORT_FDOFLAG_IS_CC 0x01000000
|
|
/* synchronize registration with our ouwn start
|
|
stop routine, not intened to sync between instances */
|
|
#define USBPORT_FDOFLAG_FDO_REGISTERED 0x02000000
|
|
/* OK to enumerate devices on CC (usb 2o disabled) */
|
|
#define USBPORT_FDOFLAG_CC_ENUM_OK 0x04000000
|
|
/* This is a static flag that causes selective
|
|
suspend to always be disabled */
|
|
#define USBPORT_FDOFLAG_DISABLE_SS 0x08000000
|
|
#define USBPORT_FDOFLAG_CC_LOCK 0x10000000
|
|
/* indicates we are on the PNP thread */
|
|
#define USBPORT_FDOFLAG_ON_PNP_THREAD 0x20000000
|
|
|
|
/* signals OK to enumerate on the root hub */
|
|
#define USBPORT_FDOFLAG_SIGNAL_RH 0x80000000
|
|
|
|
|
|
// PdoFlags: Pdo Only
|
|
#define USBPORT_PDOFLAG_HAVE_IDLE_IRP 0x00000001
|
|
|
|
// MiniportStateFlags
|
|
// miniport is either started (set) OR not started (clear)
|
|
#define MP_STATE_STARTED 0x00000001
|
|
#define MP_STATE_SUSPENDED 0x00000002
|
|
|
|
// USB HC wake states
|
|
|
|
typedef enum _USBHC_WAKE_STATE {
|
|
HCWAKESTATE_DISARMED =1,
|
|
HCWAKESTATE_WAITING =2,
|
|
HCWAKESTATE_WAITING_CANCELLED =3,
|
|
HCWAKESTATE_ARMED =4,
|
|
HCWAKESTATE_ARMING_CANCELLED =5,
|
|
HCWAKESTATE_COMPLETING =7
|
|
} USBHC_WAKE_STATE;
|
|
|
|
|
|
typedef struct _FDO_EXTENSION {
|
|
|
|
// Device object that the bus extender created for
|
|
// us
|
|
PDEVICE_OBJECT PhysicalDeviceObject;
|
|
|
|
// Device object of the first guy on the stack
|
|
// -- the guy we pass our Irps on to.
|
|
PDEVICE_OBJECT TopOfStackDeviceObject;
|
|
|
|
// PhysicalDeviceObject we create for the
|
|
// root hub
|
|
PDEVICE_OBJECT RootHubPdo;
|
|
// serialize access to the root hub data structures
|
|
USBPORT_SPIN_LOCK RootHubSpin;
|
|
|
|
// pointer to miniport Data
|
|
PDEVICE_DATA MiniportDeviceData;
|
|
PUSBPORT_MINIPORT_DRIVER MiniportDriver;
|
|
|
|
PUSBPORT_COMMON_BUFFER ScratchCommonBuffer;
|
|
|
|
ULONG DeviceNameIdx;
|
|
LONG WorkerDpc;
|
|
|
|
// total bandwidth of the wire in bits/sec
|
|
// USB 1.1 is 12000 (12 MBits/sec)
|
|
// USB 2.0 is 400000 (400 MBits/sec)
|
|
ULONG TotalBusBandwidth;
|
|
ULONG BandwidthTable[USBPORT_MAX_INTEP_POLLING_INTERVAL];
|
|
|
|
// track alloactions
|
|
// for periods 1, 2, 4, 8, 16, 32
|
|
// in bits/sec
|
|
ULONG AllocedInterruptBW[6];
|
|
ULONG AllocedIsoBW;
|
|
ULONG AllocedLowSpeedBW;
|
|
|
|
ULONG MaxAllocedBw;
|
|
ULONG MinAllocedBw;
|
|
|
|
ULONG FdoFlags;
|
|
ULONG MpStateFlags;
|
|
LONG DmaBusy;
|
|
|
|
USB_CONTROLLER_FLAVOR HcFlavor;
|
|
USHORT PciVendorId;
|
|
// PCI deviceId == USB productId
|
|
USHORT PciDeviceId;
|
|
// PCI revision == USB bcdDevice
|
|
UCHAR PciRevisionId;
|
|
UCHAR PciClass;
|
|
UCHAR PciSubClass;
|
|
UCHAR PciProgIf;
|
|
|
|
PIRP HcPendingWakeIrp;
|
|
|
|
ULONG AddressList[4];
|
|
|
|
PUSBD_DEVICE_HANDLE RawDeviceHandle;
|
|
|
|
HC_POWER_STATE_TABLE HcPowerStateTbl;
|
|
SYSTEM_POWER_STATE LastSystemSleepState;
|
|
|
|
KSEMAPHORE DeviceLock;
|
|
KSEMAPHORE CcLock;
|
|
|
|
|
|
UNICODE_STRING LegacyLinkUnicodeString;
|
|
|
|
HC_RESOURCES HcResources;
|
|
|
|
// protects core functions called thru
|
|
// registration packet in MiniportDriver
|
|
USBPORT_SPIN_LOCK CoreFunctionSpin;
|
|
USBPORT_SPIN_LOCK MapTransferSpin;
|
|
USBPORT_SPIN_LOCK DoneTransferSpin;
|
|
USBPORT_SPIN_LOCK EndpointListSpin;
|
|
USBPORT_SPIN_LOCK EpStateChangeListSpin;
|
|
USBPORT_SPIN_LOCK DevHandleListSpin;
|
|
USBPORT_SPIN_LOCK EpClosedListSpin;
|
|
USBPORT_SPIN_LOCK TtEndpointListSpin;
|
|
|
|
USBPORT_SPIN_LOCK PendingTransferIrpSpin;
|
|
USBPORT_SPIN_LOCK ActiveTransferIrpSpin;
|
|
USBPORT_SPIN_LOCK WorkerThreadSpin;
|
|
USBPORT_SPIN_LOCK PowerSpin;
|
|
USBPORT_SPIN_LOCK DM_TimerSpin;
|
|
USBPORT_SPIN_LOCK PendingIrpSpin;
|
|
USBPORT_SPIN_LOCK WakeIrpSpin;
|
|
USBPORT_SPIN_LOCK HcPendingWakeIrpSpin;
|
|
USBPORT_SPIN_LOCK IdleIrpSpin;
|
|
USBPORT_SPIN_LOCK BadRequestSpin;
|
|
USBPORT_SPIN_LOCK IsrDpcSpin;
|
|
USBPORT_SPIN_LOCK StatCounterSpin;
|
|
USBPORT_SPIN_LOCK HcSyncSpin;
|
|
|
|
LONG CoreSpinCheck;
|
|
|
|
KEVENT WorkerThreadEvent;
|
|
HANDLE WorkerThreadHandle;
|
|
PKTHREAD WorkerPkThread;
|
|
|
|
KEVENT HcPendingWakeIrpEvent;
|
|
KEVENT HcPendingWakeIrpPostedEvent;
|
|
|
|
PDMA_ADAPTER AdapterObject;
|
|
ULONG NumberOfMapRegisters;
|
|
LONG NextTransferSequenceNumber;
|
|
|
|
PKINTERRUPT InterruptObject;
|
|
KDPC IsrDpc;
|
|
KDPC TransferFlushDpc;
|
|
KDPC SurpriseRemoveDpc;
|
|
KDPC HcResetDpc;
|
|
KDPC HcWakeDpc;
|
|
|
|
KDPC DM_TimerDpc;
|
|
KTIMER DM_Timer;
|
|
LONG DM_TimerInterval;
|
|
|
|
// global common buffer allocated and
|
|
// passed to miniport on start.
|
|
PUSBPORT_COMMON_BUFFER ControllerCommonBuffer;
|
|
|
|
// no longer used
|
|
USBPORT_SPIN_LOCK LogSpinLock;
|
|
|
|
LIST_ENTRY DeviceHandleList;
|
|
LIST_ENTRY MapTransferList;
|
|
LIST_ENTRY DoneTransferList;
|
|
LIST_ENTRY EpStateChangeList;
|
|
LIST_ENTRY EpClosedList;
|
|
LIST_ENTRY BadRequestList;
|
|
LIST_ENTRY RegistryCache;
|
|
|
|
LIST_ENTRY GlobalEndpointList;
|
|
LIST_ENTRY AttendEndpointList;
|
|
|
|
// stat counters
|
|
ULONG StatBulkDataBytes;
|
|
ULONG StatIsoDataBytes;
|
|
ULONG StatInterruptDataBytes;
|
|
ULONG StatControlDataBytes;
|
|
ULONG StatPciInterruptCount;
|
|
ULONG StatHardResetCount;
|
|
ULONG StatWorkSignalCount;
|
|
ULONG StatWorkIdleTime;
|
|
ULONG StatCommonBufferBytes;
|
|
|
|
|
|
ULONG BadRequestFlush;
|
|
ULONG BadReqFlushThrottle;
|
|
|
|
// context for USB2 budgeter engine
|
|
PVOID Usb2LibHcContext;
|
|
ULONG BiosX;
|
|
|
|
USBHC_WAKE_STATE HcWakeState;
|
|
|
|
ULONG Usb2BusFunction;
|
|
ULONG BusNumber; // slot
|
|
ULONG BusDevice;
|
|
ULONG BusFunction;
|
|
|
|
// usbed to synchronize CCs and USB 2 controllers
|
|
LONG DependentControllers;
|
|
LONG PendingRhCallback;
|
|
|
|
LIST_ENTRY ControllerLink;
|
|
|
|
#ifdef XPSE
|
|
// additional stat tracking
|
|
LARGE_INTEGER D0ResumeTimeStart;
|
|
LARGE_INTEGER S0ResumeTimeStart;
|
|
LARGE_INTEGER ThreadResumeTimeStart;
|
|
ULONG ThreadResumeTime;
|
|
ULONG ControllerResumeTime;
|
|
ULONG D0ResumeTime;
|
|
ULONG S0ResumeTime;
|
|
#endif
|
|
|
|
ULONG InterruptOrdinalTable[65];
|
|
|
|
PVOID MiniportExtension[0]; // PVOID for IA64 alignment
|
|
|
|
} FDO_EXTENSION, *PFDO_EXTENSION;
|
|
|
|
// this is where we keep
|
|
// all the root hub data
|
|
|
|
typedef struct _PDO_EXTENSION {
|
|
|
|
USBD_DEVICE_HANDLE RootHubDeviceHandle;
|
|
PHCD_ENDPOINT RootHubInterruptEndpoint;
|
|
|
|
ULONG PdoFlags;
|
|
|
|
UCHAR ConfigurationValue;
|
|
UCHAR Pad3[3];
|
|
|
|
// pointers to our root hub descriptors
|
|
// NOTE: these ptrs point in to the 'Descriptors'
|
|
// buffer so son't try to free them
|
|
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
|
|
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
|
|
PUSB_HUB_DESCRIPTOR HubDescriptor;
|
|
|
|
// irp associated with remote wakeup,
|
|
// ie irp posted by the HUB driver
|
|
PIRP PendingWaitWakeIrp;
|
|
PIRP PendingIdleNotificationIrp;
|
|
|
|
// pointer to buffer contining descriptors
|
|
PUCHAR Descriptors;
|
|
|
|
PRH_INIT_CALLBACK HubInitCallback;
|
|
PVOID HubInitContext;
|
|
|
|
} PDO_EXTENSION, *PPDO_EXTENSION;
|
|
|
|
// signatures for our device extensions
|
|
#define USBPORT_DEVICE_EXT_SIG 'ODFH' //HFDO
|
|
#define ROOTHUB_DEVICE_EXT_SIG 'ODPR' //RPDO
|
|
|
|
/* USB spec defined port flags */
|
|
#define PORT_STATUS_CONNECT 0x001
|
|
#define PORT_STATUS_ENABLE 0x002
|
|
#define PORT_STATUS_SUSPEND 0x004
|
|
#define PORT_STATUS_OVER_CURRENT 0x008
|
|
#define PORT_STATUS_RESET 0x010
|
|
#define PORT_STATUS_POWER 0x100
|
|
#define PORT_STATUS_LOW_SPEED 0x200
|
|
#define PORT_STATUS_HIGH_SPEED 0x400
|
|
|
|
/*
|
|
root hub status codes
|
|
*/
|
|
typedef enum _RHSTATUS {
|
|
|
|
RH_SUCCESS = 0,
|
|
RH_NAK,
|
|
RH_STALL
|
|
|
|
} RHSTATUS;
|
|
|
|
/* port operations */
|
|
|
|
typedef enum _PORT_OPERATION {
|
|
|
|
SetFeaturePortReset = 0,
|
|
SetFeaturePortPower,
|
|
SetFeaturePortEnable,
|
|
SetFeaturePortSuspend,
|
|
ClearFeaturePortEnable,
|
|
ClearFeaturePortPower,
|
|
ClearFeaturePortSuspend,
|
|
ClearFeaturePortEnableChange,
|
|
ClearFeaturePortConnectChange,
|
|
ClearFeaturePortResetChange,
|
|
ClearFeaturePortSuspendChange,
|
|
ClearFeaturePortOvercurrentChange
|
|
|
|
} PORT_OPERATION;
|
|
|
|
#define NUMBER_OF_PORTS(de) ((de)->Pdo.HubDescriptor->bNumberOfPorts)
|
|
#define HUB_DESRIPTOR_LENGTH(de) ((de)->Pdo.HubDescriptor->bDescriptorLength)
|
|
|
|
|
|
typedef struct _DEVICE_EXTENSION {
|
|
// Necessary to support Legacy USB hub driver(s)
|
|
// AKA 'backport'
|
|
PUCHAR DummyUsbdExtension;
|
|
// The following fields are common to both the
|
|
// root hub PDO and the HC FDO
|
|
|
|
// signature
|
|
ULONG Sig;
|
|
|
|
// for the FDO this points to ourselves
|
|
// for PDO this points to FDO
|
|
PDEVICE_OBJECT HcFdoDeviceObject;
|
|
|
|
// put the log ptrs at the beginning
|
|
// to make them easy to find
|
|
DEBUG_LOG Log;
|
|
DEBUG_LOG TransferLog;
|
|
DEBUG_LOG EnumLog;
|
|
|
|
// these ptrs are in the global extension to
|
|
// make them easier to find on win9x
|
|
PUSBPORT_IRP_TABLE PendingTransferIrpTable;
|
|
PUSBPORT_IRP_TABLE ActiveTransferIrpTable;
|
|
|
|
ULONG Flags;
|
|
ULONG PnpStateFlags;
|
|
|
|
// current power state of this DO
|
|
// this is the state the OS has placed us in
|
|
DEVICE_POWER_STATE CurrentDevicePowerState;
|
|
PIRP SystemPowerIrp;
|
|
|
|
// device caps for this DO
|
|
DEVICE_CAPABILITIES DeviceCapabilities;
|
|
|
|
//
|
|
// count of requests currently 'in' our driver
|
|
// this is tracked per DevObj.
|
|
// We also keep a list of irps in the debug driver.
|
|
//
|
|
LONG PendingRequestCount;
|
|
LIST_ENTRY TrackIrpList;
|
|
|
|
USBPORT_SPIN_LOCK PendingRequestSpin;
|
|
KEVENT PendingRequestEvent;
|
|
|
|
UNICODE_STRING SymbolicLinkName;
|
|
|
|
union {
|
|
PDO_EXTENSION Pdo;
|
|
FDO_EXTENSION Fdo;
|
|
};
|
|
|
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
|
|
|
/*
|
|
used to track cached registry keys for miniports
|
|
*/
|
|
|
|
typedef struct _USBPORT_REG_CACHE_ENTRY {
|
|
ULONG Sig;
|
|
LIST_ENTRY RegLink;
|
|
BOOLEAN SoftwareBranch;
|
|
// length in bytes
|
|
ULONG DataLength;
|
|
PUCHAR Data;
|
|
ULONG KeyNameStringLength;
|
|
WCHAR KeyNameString[0];
|
|
} USBPORT_REG_CACHE_ENTRY, *PUSBPORT_REG_CACHE_ENTRY;
|
|
|
|
|
|
|
|
// define an interlocked version of RemoveEntryList
|
|
#define USBPORT_InterlockedRemoveEntryList(ListEntry, Spinlock) \
|
|
{\
|
|
KIRQL irql;\
|
|
KeAcquireSpinLock((Spinlock), &irql);\
|
|
RemoveEntryList((ListEntry));\
|
|
KeReleaseSpinLock((Spinlock), irql);\
|
|
}
|
|
|
|
#define GET_HEAD_LIST(head, le) \
|
|
if (IsListEmpty(&(head))) {\
|
|
le = NULL;\
|
|
} else {\
|
|
le = (head).Flink;\
|
|
}
|
|
|
|
|
|
#define FREE_POOL(fdo, p) ExFreePool((p))
|
|
|
|
//
|
|
// allocates a zeroed buffer that the OS is expedected to free
|
|
//
|
|
#define ALLOC_POOL_OSOWNED(p, PoolType, NumberOfBytes) \
|
|
do { \
|
|
(p) = ExAllocatePoolWithTag((PoolType), (NumberOfBytes), USBPORT_TAG); \
|
|
if ((p)) { \
|
|
RtlZeroMemory((p), (NumberOfBytes)); \
|
|
} \
|
|
} while (0) \
|
|
|
|
//
|
|
// allocates a zeroed buffer that we are expected to free
|
|
//
|
|
#define ALLOC_POOL_Z(p, PoolType, NumberOfBytes) \
|
|
do { \
|
|
(p) = ExAllocatePoolWithTag((PoolType), (NumberOfBytes), USBPORT_TAG); \
|
|
if ((p)) { \
|
|
RtlZeroMemory((p), (NumberOfBytes)); \
|
|
} \
|
|
} while (0) \
|
|
|
|
#define GET_DEVICE_EXT(e, d) (e) = (d)->DeviceExtension
|
|
#define GET_DEVICE_HANDLE(dh, urb) (dh) = ((PURB)(urb))->UrbHeader.UsbdDeviceHandle;
|
|
|
|
#define DEVEXT_FROM_DEVDATA(de, dd) \
|
|
(de) = (PDEVICE_EXTENSION) \
|
|
CONTAINING_RECORD((dd),\
|
|
struct _DEVICE_EXTENSION, \
|
|
Fdo.MiniportExtension)
|
|
|
|
#define ENDPOINT_FROM_EPDATA(ep, epd) \
|
|
(ep) = (PHCD_ENDPOINT) \
|
|
CONTAINING_RECORD((epd),\
|
|
struct _HCD_ENDPOINT, \
|
|
MiniportEndpointData)
|
|
|
|
#define TRANSFER_FROM_TPARAMETERS(t, tp) \
|
|
(t) = (PHCD_TRANSFER_CONTEXT) \
|
|
CONTAINING_RECORD((tp),\
|
|
struct _HCD_TRANSFER_CONTEXT, \
|
|
Tp)
|
|
|
|
#define SET_USBD_ERROR(u, s) USBPORT_SetUSBDError((PURB)(u),(s))
|
|
|
|
#define INCREMENT_PENDING_REQUEST_COUNT(devobj, irp) \
|
|
USBPORT_TrackPendingRequest((devobj), (irp), TRUE)
|
|
|
|
#define DECREMENT_PENDING_REQUEST_COUNT(devobj, irp) \
|
|
USBPORT_TrackPendingRequest((devobj), (irp), FALSE)
|
|
|
|
//328555
|
|
#define REF_DEVICE(urb) \
|
|
do {\
|
|
PUSBD_DEVICE_HANDLE dh;\
|
|
GET_DEVICE_HANDLE(dh, (urb));\
|
|
ASSERT_DEVICE_HANDLE(dh);\
|
|
InterlockedIncrement(&dh->PendingUrbs);\
|
|
} while (0)
|
|
|
|
#define DEREF_DEVICE(urb) \
|
|
do {\
|
|
PUSBD_DEVICE_HANDLE dh;\
|
|
GET_DEVICE_HANDLE(dh, (urb));\
|
|
ASSERT_DEVICE_HANDLE(dh);\
|
|
InterlockedDecrement(&dh->PendingUrbs);\
|
|
} while (0)
|
|
//328555
|
|
|
|
#define INITIALIZE_PENDING_REQUEST_COUNTER(de) \
|
|
KeInitializeSpinLock(&(de)->PendingRequestSpin.sl);\
|
|
(de)->PendingRequestCount = -1; \
|
|
InitializeListHead(&(de)->TrackIrpList);
|
|
|
|
//328555
|
|
#define REF_DEVICE(urb) \
|
|
do {\
|
|
PUSBD_DEVICE_HANDLE dh;\
|
|
GET_DEVICE_HANDLE(dh, (urb));\
|
|
ASSERT_DEVICE_HANDLE(dh);\
|
|
InterlockedIncrement(&dh->PendingUrbs);\
|
|
} while (0)
|
|
|
|
#define DEREF_DEVICE(urb) \
|
|
do {\
|
|
PUSBD_DEVICE_HANDLE dh;\
|
|
GET_DEVICE_HANDLE(dh, (urb));\
|
|
ASSERT_DEVICE_HANDLE(dh);\
|
|
InterlockedDecrement(&dh->PendingUrbs);\
|
|
} while (0)
|
|
//328555
|
|
|
|
#define ACQUIRE_TRANSFER_LOCK(fdo, t, i) \
|
|
do {\
|
|
PDEVICE_EXTENSION ext;\
|
|
GET_DEVICE_EXT(ext, (fdo));\
|
|
ASSERT_FDOEXT(ext);\
|
|
LOGENTRY(NULL, fdo, LOG_MISC, 'tfL+', 0, (fdo), 0);\
|
|
KeAcquireSpinLock(&(t)->Spin, &(i));\
|
|
} while (0)
|
|
|
|
#define RELEASE_TRANSFER_LOCK(fdo, t, i) \
|
|
do {\
|
|
PDEVICE_EXTENSION ext;\
|
|
GET_DEVICE_EXT(ext, (fdo));\
|
|
ASSERT_FDOEXT(ext);\
|
|
LOGENTRY(NULL, fdo, LOG_MISC, 'tfL-', 0, (fdo), (i));\
|
|
KeReleaseSpinLock(&t->Spin, (i));\
|
|
} while (0)
|
|
|
|
|
|
#define ACQUIRE_IDLEIRP_LOCK(fdo, i) \
|
|
do {\
|
|
PDEVICE_EXTENSION ext;\
|
|
GET_DEVICE_EXT(ext, (fdo));\
|
|
ASSERT_FDOEXT(ext);\
|
|
LOGENTRY(NULL, fdo, LOG_MISC, 'idL+', 0, (fdo), 0);\
|
|
KeAcquireSpinLock(&ext->Fdo.IdleIrpSpin.sl, &(i));\
|
|
} while (0)
|
|
|
|
#define RELEASE_IDLEIRP_LOCK(fdo, i) \
|
|
do {\
|
|
PDEVICE_EXTENSION ext;\
|
|
GET_DEVICE_EXT(ext, (fdo));\
|
|
ASSERT_FDOEXT(ext);\
|
|
LOGENTRY(NULL, fdo, LOG_MISC, 'idL-', 0, (fdo), (i));\
|
|
KeReleaseSpinLock(&ext->Fdo.IdleIrpSpin.sl, (i));\
|
|
} while (0)
|
|
|
|
|
|
#define ACQUIRE_BADREQUEST_LOCK(fdo, i) \
|
|
do {\
|
|
PDEVICE_EXTENSION ext;\
|
|
GET_DEVICE_EXT(ext, (fdo));\
|
|
ASSERT_FDOEXT(ext);\
|
|
LOGENTRY(NULL, fdo, LOG_MISC, 'brL+', 0, (fdo), 0);\
|
|
KeAcquireSpinLock(&ext->Fdo.BadRequestSpin.sl, &(i));\
|
|
} while (0)
|
|
|
|
#define RELEASE_BADREQUEST_LOCK(fdo, i) \
|
|
do {\
|
|
PDEVICE_EXTENSION ext;\
|
|
GET_DEVICE_EXT(ext, (fdo));\
|
|
ASSERT_FDOEXT(ext);\
|
|
LOGENTRY(NULL, fdo, LOG_MISC, 'brL-', 0, (fdo), (i));\
|
|
KeReleaseSpinLock(&ext->Fdo.BadRequestSpin.sl, (i));\
|
|
} while (0)
|
|
|
|
|
|
#define ACQUIRE_WAKEIRP_LOCK(fdo, i) \
|
|
do {\
|
|
PDEVICE_EXTENSION ext;\
|
|
GET_DEVICE_EXT(ext, (fdo));\
|
|
ASSERT_FDOEXT(ext);\
|
|
LOGENTRY(NULL, fdo, LOG_POWER, 'wwL+', 0, (fdo), 0);\
|
|
KeAcquireSpinLock(&ext->Fdo.WakeIrpSpin.sl, &(i));\
|
|
} while (0)
|
|
|
|
#define RELEASE_WAKEIRP_LOCK(fdo, i) \
|
|
do {\
|
|
PDEVICE_EXTENSION ext;\
|
|
GET_DEVICE_EXT(ext, (fdo));\
|
|
ASSERT_FDOEXT(ext);\
|
|
LOGENTRY(NULL, fdo, LOG_POWER, 'wwL-', 0, (fdo), (i));\
|
|
KeReleaseSpinLock(&ext->Fdo.WakeIrpSpin.sl, (i));\
|
|
} while (0)
|
|
|
|
#define ACQUIRE_ENDPOINT_LOCK(ep, fdo, s) \
|
|
do {\
|
|
LOGENTRY(NULL, fdo, LOG_SPIN, s, (ep), 0, 0);\
|
|
USBPORT_AcquireSpinLock((fdo), &(ep)->ListSpin, &(ep)->LockIrql);\
|
|
LOGENTRY(NULL, fdo, LOG_SPIN, s, (ep), (ep)->LockFlag, 1);\
|
|
USBPORT_ASSERT((ep)->LockFlag == 0); \
|
|
(ep)->LockFlag++;\
|
|
} while (0)
|
|
|
|
#define RELEASE_ENDPOINT_LOCK(ep, fdo, s) \
|
|
do {\
|
|
LOGENTRY(NULL, fdo, LOG_SPIN, s, (ep), (ep)->LockFlag, 0);\
|
|
USBPORT_ASSERT((ep)->LockFlag == 1); \
|
|
(ep)->LockFlag--;\
|
|
USBPORT_ReleaseSpinLock(fdo, &(ep)->ListSpin, (ep)->LockIrql);\
|
|
} while (0)
|
|
|
|
#define ACQUIRE_STATECHG_LOCK(fdo, ep) \
|
|
USBPORT_AcquireSpinLock((fdo), &(ep)->StateChangeSpin, &(ep)->ScLockIrql);
|
|
|
|
#define RELEASE_STATECHG_LOCK(fdo, ep) \
|
|
USBPORT_ReleaseSpinLock((fdo), &(ep)->StateChangeSpin, (ep)->ScLockIrql);
|
|
|
|
#define ACQUIRE_ROOTHUB_LOCK(fdo, i) \
|
|
{\
|
|
PDEVICE_EXTENSION de;\
|
|
de = (fdo)->DeviceExtension;\
|
|
LOGENTRY(NULL, (fdo), LOG_MISC, 'Lhub', 0, 0, 0);\
|
|
KeAcquireSpinLock(&de->Fdo.RootHubSpin.sl, &(i));\
|
|
}
|
|
|
|
#define RELEASE_ROOTHUB_LOCK(fdo, i) \
|
|
{\
|
|
PDEVICE_EXTENSION de;\
|
|
de = (fdo)->DeviceExtension;\
|
|
LOGENTRY(NULL, (fdo), LOG_MISC, 'Uhub', 0, 0, 0);\
|
|
KeReleaseSpinLock(&de->Fdo.RootHubSpin.sl, (i));\
|
|
}
|
|
|
|
#define ACQUIRE_ACTIVE_IRP_LOCK(fdo, de, i) \
|
|
{\
|
|
USBPORT_AcquireSpinLock((fdo), &(de)->Fdo.ActiveTransferIrpSpin, &(i));\
|
|
}
|
|
|
|
#define RELEASE_ACTIVE_IRP_LOCK(fdo, de, i) \
|
|
{\
|
|
USBPORT_ReleaseSpinLock((fdo), &(de)->Fdo.ActiveTransferIrpSpin, (i));\
|
|
}
|
|
|
|
#define USBPORT_IS_USB20(de)\
|
|
(REGISTRATION_PACKET((de)).OptionFlags & USB_MINIPORT_OPT_USB20)
|
|
|
|
|
|
#define ACQUIRE_PENDING_IRP_LOCK(de, i) \
|
|
KeAcquireSpinLock(&(de)->Fdo.PendingIrpSpin.sl, &(i))
|
|
|
|
#define RELEASE_PENDING_IRP_LOCK(de, i) \
|
|
KeReleaseSpinLock(&(de)->Fdo.PendingIrpSpin.sl, (i))
|
|
|
|
#define USBPORT_ACQUIRE_DM_LOCK(de, i) \
|
|
KeAcquireSpinLock(&(de)->Fdo.DM_TimerSpin.sl, &(i))
|
|
|
|
#define USBPORT_RELEASE_DM_LOCK(de, i) \
|
|
KeReleaseSpinLock(&(de)->Fdo.DM_TimerSpin.sl, (i))
|
|
|
|
//#define USBPORT_ACQUIRE_DM_LOCK(de, i) \
|
|
// KeAcquireSpinLock(&(de)->Fdo.DM_TimerSpin.sl, &(i));
|
|
//
|
|
//#define USBPORT_RELEASE_DM_LOCK(de, i) \
|
|
// KeReleaseSpinLock(&(de)->Fdo.DM_TimerSpin.sl, (i));
|
|
|
|
|
|
#define IS_ON_ATTEND_LIST(ep) \
|
|
(BOOLEAN) ((ep)->AttendLink.Flink != NULL \
|
|
&& (ep)->AttendLink.Blink != NULL)
|
|
|
|
|
|
//
|
|
// Macros to set transfer direction flag
|
|
//
|
|
|
|
#define USBPORT_SET_TRANSFER_DIRECTION_IN(tf) ((tf) |= USBD_TRANSFER_DIRECTION_IN)
|
|
|
|
#define USBPORT_SET_TRANSFER_DIRECTION_OUT(tf) ((tf) &= ~USBD_TRANSFER_DIRECTION_IN)
|
|
|
|
|
|
//
|
|
// Flags for the URB header flags field used by port
|
|
//
|
|
|
|
#define USBPORT_REQUEST_IS_TRANSFER 0x00000001
|
|
#define USBPORT_REQUEST_MDL_ALLOCATED 0x00000002
|
|
#define USBPORT_REQUEST_USES_DEFAULT_PIPE 0x00000004
|
|
#define USBPORT_REQUEST_NO_DATA_PHASE 0x00000008
|
|
#define USBPORT_RESET_DATA_TOGGLE 0x00000010
|
|
#define USBPORT_TRANSFER_ALLOCATED 0x00000020
|
|
|
|
// defined in USB100.h
|
|
#if 0
|
|
//
|
|
// Values for the bmRequest field
|
|
//
|
|
|
|
//bmRequest.Dir
|
|
#define BMREQUEST_HOST_TO_DEVICE 0
|
|
#define BMREQUEST_DEVICE_TO_HOST 1
|
|
|
|
//bmRequest.Type
|
|
#define BMREQUEST_STANDARD 0
|
|
#define BMREQUEST_CLASS 1
|
|
#define BMREQUEST_VENDOR 2
|
|
|
|
//bmRequest.Recipient
|
|
#define BMREQUEST_TO_DEVICE 0
|
|
#define BMREQUEST_TO_INTERFACE 1
|
|
#define BMREQUEST_TO_ENDPOINT 2
|
|
#define BMREQUEST_TO_OTHER 3
|
|
|
|
|
|
typedef union _BM_REQUEST_TYPE {
|
|
struct _BM {
|
|
UCHAR Recipient:2;
|
|
UCHAR Reserved:3;
|
|
UCHAR Type:2;
|
|
UCHAR Dir:1;
|
|
};
|
|
UCHAR B;
|
|
} BM_REQUEST_TYPE, *PBM_REQUEST_TYPE;
|
|
|
|
typedef struct _USB_DEFAULT_PIPE_SETUP_PACKET {
|
|
|
|
BM_REQUEST_TYPE bmRequestType;
|
|
UCHAR bRequest;
|
|
|
|
union _wValue {
|
|
struct {
|
|
UCHAR lowPart;
|
|
UCHAR hiPart;
|
|
};
|
|
USHORT W;
|
|
} wValue;
|
|
USHORT wIndex;
|
|
USHORT wLength;
|
|
} USB_DEFAULT_PIPE_SETUP_PACKET, *PUSB_DEFAULT_PIPE_SETUP_PACKET;
|
|
|
|
|
|
// setup packet is eight bytes -- defined by spec
|
|
C_ASSERT(sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) == 8);
|
|
#endif
|
|
|
|
#define USBPORT_INIT_SETUP_PACKET(s, brequest, \
|
|
direction, recipient, typ, wvalue, windex, wlength) \
|
|
{\
|
|
(s).bRequest = (brequest);\
|
|
(s).bmRequestType.Dir = (direction);\
|
|
(s).bmRequestType.Type = (typ);\
|
|
(s).bmRequestType.Recipient = (recipient);\
|
|
(s).bmRequestType.Reserved = 0;\
|
|
(s).wValue.W = (wvalue);\
|
|
(s).wIndex.W = (windex);\
|
|
(s).wLength = (wlength);\
|
|
}
|
|
|
|
|
|
// ************************************************
|
|
// miniport callout Macros to CORE FUNCTIONS
|
|
// ************************************************
|
|
|
|
#define REGISTRATION_PACKET(de) \
|
|
((de)->Fdo.MiniportDriver->RegistrationPacket)
|
|
|
|
//xxxjd
|
|
//#define MP_GetEndpointState(de, ep, state) \
|
|
// {\
|
|
// KIRQL irql;\
|
|
// USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
// RegistrationPacket.MINIPORT_GetEndpointState != NULL); \
|
|
// USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
// (state) = \
|
|
// (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_GetEndpointState(\
|
|
// (de)->Fdo.MiniportDeviceData,\
|
|
// &(ep)->MiniportEndpointData[0]);\
|
|
// USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
// }
|
|
|
|
#define MP_GetEndpointStatus(de, ep, status) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_GetEndpointStatus != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(status) = \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_GetEndpointStatus(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0]);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_SetEndpointState(de, ep, state) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_SetEndpointState != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SetEndpointState(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0],\
|
|
(state));\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_SetEndpointStatus(de, ep, status) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_SetEndpointState != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SetEndpointStatus(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0],\
|
|
(status));\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_SetEndpointDataToggle(de, ep, t) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_SetEndpointDataToggle != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SetEndpointDataToggle(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0],\
|
|
(t));\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
|
|
#define MP_PollEndpoint(de, ep) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_PollEndpoint != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PollEndpoint(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0]);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_OpenEndpoint(de, ep, mpStatus) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_OpenEndpoint != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(mpStatus) = \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_OpenEndpoint(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->Parameters,\
|
|
&(ep)->MiniportEndpointData[0]);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_RebalanceEndpoint(de, ep) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_RebalanceEndpoint != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RebalanceEndpoint(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->Parameters,\
|
|
&(ep)->MiniportEndpointData[0]);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_CloseEndpoint(de, ep) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_OpenEndpoint != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_CloseEndpoint(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0]);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_PokeEndpoint(de, ep, mpStatus) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_PokeEndpoint != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(mpStatus) = \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PokeEndpoint(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->Parameters,\
|
|
&(ep)->MiniportEndpointData[0]);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_InterruptNextSOF(de) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_InterruptNextSOF != NULL); \
|
|
LOGENTRY(NULL, (de)->HcFdoDeviceObject, LOG_MISC, 'rSOF', 0, 0, 0);\
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_InterruptNextSOF(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_Get32BitFrameNumber(de, f) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_Get32BitFrameNumber != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(f) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_Get32BitFrameNumber(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
MINIPORT_SubmitTransfer(
|
|
PDEVICE_DATA DeviceData,
|
|
PENDPOINT_DATA EndpointData,
|
|
PTRANSFER_PARAMETERS TransferParameters,
|
|
PTRANSFER_CONTEXT TransferContext,
|
|
PTRANSFER_SG_LIST TransferSGList
|
|
);
|
|
|
|
#define MP_SubmitTransfer(de, ep, t, mpStatus) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_SubmitTransfer != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(mpStatus) = \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SubmitTransfer(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0],\
|
|
&(t)->Tp,\
|
|
(t)->MiniportContext,\
|
|
&(t)->SgList);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_SubmitIsoTransfer(de, ep, t, mpStatus) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_SubmitIsoTransfer != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(mpStatus) = \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SubmitIsoTransfer(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0],\
|
|
&(t)->Tp,\
|
|
(t)->MiniportContext,\
|
|
(t)->IsoTransfer);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_AbortTransfer(de, ep, t, b) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_AbortTransfer != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_AbortTransfer(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->MiniportEndpointData[0],\
|
|
(t)->MiniportContext,\
|
|
&(b));\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
|
|
#define MP_QueryEndpointRequirements(de, ep, r) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_QueryEndpointRequirements != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_QueryEndpointRequirements(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
&(ep)->Parameters,\
|
|
(r));\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
|
|
#define MP_InterruptDpc(de, e) {\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_InterruptDpc != NULL); \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_InterruptDpc(\
|
|
(de)->Fdo.MiniportDeviceData, \
|
|
(e));\
|
|
}
|
|
|
|
#define MP_StartSendOnePacket(de, p, mpd, mpl, vaddr, phys, len, u, mpStatus) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_StartSendOnePacket != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
mpStatus = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_StartSendOnePacket(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(p),\
|
|
(mpd),\
|
|
(mpl),\
|
|
(vaddr),\
|
|
(phys),\
|
|
(len),\
|
|
(u));\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
|
|
#define MP_EndSendOnePacket(de,p, mpd, mpl, vaddr, phys, len, u, mpStatus) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_EndSendOnePacket != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
mpStatus = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_EndSendOnePacket(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(p),\
|
|
(mpd),\
|
|
(mpl),\
|
|
(vaddr),\
|
|
(phys),\
|
|
(len),\
|
|
(u));\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_PollController(de) \
|
|
{\
|
|
KIRQL irql;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_PollController != NULL); \
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PollController(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
}
|
|
|
|
#define MP_CheckController(de) \
|
|
do {\
|
|
KIRQL irql;\
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
if (!TEST_FDO_FLAG((de), USBPORT_FDOFLAG_CONTROLLER_GONE) && \
|
|
!TEST_FDO_FLAG((de), USBPORT_FDOFLAG_SUSPENDED) && \
|
|
!TEST_FDO_FLAG((de), USBPORT_FDOFLAG_OFF)) {\
|
|
LOGENTRY(NULL, (de)->HcFdoDeviceObject, LOG_MISC, 'chkC', \
|
|
(de)->HcFdoDeviceObject, (de)->Fdo.FdoFlags, 0);\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_CheckController != NULL); \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_CheckController(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
}\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
} while (0)
|
|
|
|
|
|
#define MP_ResetController(de) \
|
|
do {\
|
|
KIRQL irql;\
|
|
USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
|
|
LOGENTRY(NULL, (de)->HcFdoDeviceObject, LOG_MISC, 'rset', \
|
|
(de)->HcFdoDeviceObject, (de)->Fdo.FdoFlags, 0);\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_ResetController != NULL); \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_ResetController(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
|
|
} while (0)
|
|
|
|
|
|
|
|
// *************************************************
|
|
// miniport callout Macros to NON CORE FUNCTIONS
|
|
// *************************************************
|
|
|
|
#define MP_StopController(de, hw) \
|
|
{\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_StopController != NULL);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_StopController(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(hw));\
|
|
}
|
|
|
|
#define MP_StartController(de, r, mpStatus) \
|
|
{\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_StartController != NULL);\
|
|
(mpStatus) = \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_StartController(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(r));\
|
|
}
|
|
|
|
#define MP_SuspendController(de) \
|
|
{\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_SuspendController != NULL);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SuspendController(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
}
|
|
|
|
#define MP_ResumeController(de, s) \
|
|
{\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_ResumeController != NULL);\
|
|
(s) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_ResumeController(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
}
|
|
|
|
#define MP_DisableInterrupts(fdo, de) \
|
|
do {\
|
|
KIRQL iql;\
|
|
BOOLEAN sync = TRUE;\
|
|
if (REGISTRATION_PACKET(de).OptionFlags & USB_MINIPORT_OPT_NO_IRQ_SYNC) {\
|
|
sync = FALSE;}\
|
|
if (sync) {KeAcquireSpinLock(&(de)->Fdo.IsrDpcSpin.sl, &iql);}\
|
|
LOGENTRY(NULL, (fdo), LOG_MISC, 'irqD', (fdo), 0, 0);\
|
|
REGISTRATION_PACKET((de)).MINIPORT_DisableInterrupts(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
CLEAR_FDO_FLAG((de), USBPORT_FDOFLAG_IRQ_EN);\
|
|
if (sync) {KeReleaseSpinLock(&(de)->Fdo.IsrDpcSpin.sl, iql);}\
|
|
} while (0)
|
|
|
|
|
|
#define MP_EnableInterrupts(de) \
|
|
do {\
|
|
KIRQL iql;\
|
|
BOOLEAN sync = TRUE;\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_EnableInterrupts != NULL);\
|
|
if ((REGISTRATION_PACKET(de).OptionFlags & USB_MINIPORT_OPT_NO_IRQ_SYNC)) {\
|
|
sync = FALSE;}\
|
|
if (sync) {KeAcquireSpinLock(&(de)->Fdo.IsrDpcSpin.sl, &iql);}\
|
|
SET_FDO_FLAG((de), USBPORT_FDOFLAG_IRQ_EN);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_EnableInterrupts(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
if (sync) {KeReleaseSpinLock(&(de)->Fdo.IsrDpcSpin.sl, iql);}\
|
|
} while (0)
|
|
|
|
|
|
#define MP_FlushInterrupts(de) \
|
|
do {\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_FlushInterrupts != NULL);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_FlushInterrupts(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
} while (0)
|
|
|
|
// note that take port control and chirp_ports are version 2 specific
|
|
// and we need them for power managemnt to work properly
|
|
#define MP_TakePortControl(de) \
|
|
do {\
|
|
if ((de)->Fdo.MiniportDriver->HciVersion >= USB_MINIPORT_HCI_VERSION_2) {\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_TakePortControl != NULL);\
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_TakePortControl(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
};\
|
|
} while (0)
|
|
|
|
#define MP_InterruptService(de, usbint) {\
|
|
USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_InterruptService != NULL);\
|
|
(usbint) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_InterruptService(\
|
|
(de)->Fdo.MiniportDeviceData);\
|
|
}
|
|
|
|
#define MPRH_GetStatus(de, s, mpStatus) \
|
|
(mpStatus) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_GetStatus(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(s))
|
|
|
|
#define MPRH_GetPortStatus(de, port, status, mpStatus) \
|
|
(mpStatus) = \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_GetPortStatus(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(port),\
|
|
(status))
|
|
|
|
#define MPRH_GetHubStatus(de, status, mpStatus) \
|
|
(mpStatus) = \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_GetHubStatus(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(status))
|
|
|
|
#define MPRH_GetRootHubData(de, data) \
|
|
(de)->Fdo.MiniportDriver->\
|
|
RegistrationPacket.MINIPORT_RH_GetRootHubData(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(data))
|
|
|
|
#define MPRH_DisableIrq(de) \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_DisableIrq(\
|
|
(de)->Fdo.MiniportDeviceData)
|
|
|
|
#define MPRH_EnableIrq(de) \
|
|
(de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_EnableIrq(\
|
|
(de)->Fdo.MiniportDeviceData)
|
|
|
|
#define MP_PassThru(de, guid, l, data, mpStatus) \
|
|
\
|
|
if ((de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PassThru) { \
|
|
(mpStatus) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PassThru(\
|
|
(de)->Fdo.MiniportDeviceData,\
|
|
(guid),\
|
|
(l),\
|
|
(data)); \
|
|
} \
|
|
else { \
|
|
(mpStatus) = USBMP_STATUS_NOT_SUPPORTED; \
|
|
}
|
|
|
|
#define MILLISECONDS_TO_100_NS_UNITS(ms) (((LONG)(ms)) * 10000)
|
|
|
|
|
|
#define USBPORT_GET_BIT_SET(d, bit) \
|
|
do { \
|
|
UCHAR tmp = (d);\
|
|
(bit)=0; \
|
|
while (!(tmp & 0x01)) {\
|
|
(bit)++;\
|
|
tmp >>= 1;\
|
|
};\
|
|
} while (0)
|
|
|
|
|
|
#endif /* __USBPORT_H__ */
|