Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. usbport.h
  5. Abstract:
  6. private header for usb port driver
  7. Environment:
  8. Kernel & user mode
  9. Revision History:
  10. 10-27-95 : created
  11. --*/
  12. #ifndef __USBPORT_H__
  13. #define __USBPORT_H__
  14. /* This is the goatcode */
  15. #define USBPORT_TRACKING_ID 3
  16. //#define USBPERF // perf changes for windows XP second edition, longhorn?
  17. #define XPSE // bug fixes for XP second edition, longhorn or SP?
  18. #define LOG_OCA_DATA // enable saving oca crash data on stack
  19. /* OS version we recognize */
  20. typedef enum _USBPORT_OS_VERSION {
  21. Win98 = 0,
  22. WinMe,
  23. Win2K,
  24. WinXP
  25. } USBPORT_OS_VERSION;
  26. #define USBD_STATUS_NOT_SET 0xFFFFFFFF
  27. #define SIG_DEVICE_HANDLE 'HveD' //DevH
  28. #define SIG_PIPE_HANDLE 'HpiP' //PipH
  29. #define SIG_TRANSFER 'CxrT' //TrxC
  30. #define SIG_CMNBUF 'BnmC' //CmnB
  31. #define SIG_CONFIG_HANDLE 'HgfC' //CfgH
  32. #define SIG_INTERFACE_HANDLE 'HxfI' //IfxH
  33. #define SIG_ENDPOINT 'PEch' //hcEP
  34. #define SIG_ISOCH 'cosI' //Isoc
  35. #define SIG_MP_TIMR 'MITm' //mTIM
  36. #define SIG_TT 'TTch' //hcTT
  37. #define SIG_FREE 'xbsu' //usbx
  38. #define SIG_DB 'BBsu' //usBB
  39. #define SIG_IRPC 'Cpri' //irpC
  40. #define SIG_REG_CACHE 'Cger' //regC
  41. // The USBPORT_ADDRESS_AND_SIZE_TO_SPAN_PAGES_4K macro takes a virtual address
  42. // and size and returns the number of host controller 4KB pages spanned by
  43. // the size.
  44. //
  45. #define USBPORT_ADDRESS_AND_SIZE_TO_SPAN_PAGES_4K(Va,Size) \
  46. (((((Size) - 1) >> USB_PAGE_SHIFT) + \
  47. (((((ULONG)(Size-1)&(USB_PAGE_SIZE-1)) + (PtrToUlong(Va) & (USB_PAGE_SIZE -1)))) >> USB_PAGE_SHIFT)) + 1L)
  48. #define STATUS_BOGUS 0xFFFFFFFF
  49. // deadman timer interval in milliseconds
  50. #define USBPORT_DM_TIMER_INTERVAL 500
  51. /*
  52. Dummy USBD extension
  53. */
  54. extern PUCHAR USBPORT_DummyUsbdExtension;
  55. #define USBPORT_DUMMY_USBD_EXT_SIZE 512
  56. /*
  57. Registry Keys
  58. */
  59. // Software Branch PDO Keys
  60. #define USBPORT_SW_BRANCH TRUE
  61. #define FLAVOR_KEY L"HcFlavor"
  62. #define BW_KEY L"TotalBusBandwidth"
  63. #define DISABLE_SS_KEY L"HcDisableSelectiveSuspend"
  64. #define USB2_CC_ID L"Usb2cc"
  65. #define EN_IDLE_ENDPOINT_SUPPORT L"EnIdleEndpointSupport"
  66. // Hardware Branch PDO Keys
  67. // HKLM\CCS\ENUM\PCI\DeviceParameters
  68. #define USBPORT_HW_BRANCH FALSE
  69. #define SYM_LINK_KEY L"SymbolicName"
  70. #define SYM_LEGSUP_KEY L"DetectedLegacyBIOS"
  71. #define PORT_ATTRIBUTES_KEY L"PortAttrX"
  72. #define HACTION_KEY L"Haction"
  73. // Global Reg Keys HKLM\CCS\Services\USB
  74. #define DEBUG_LEVEL_KEY L"debuglevel"
  75. #define DEBUG_WIN9X_KEY L"debugWin9x"
  76. #define DEBUG_BREAK_ON L"debugbreak"
  77. #define DEBUG_LOG_MASK L"debuglogmask"
  78. #define DEBUG_CLIENTS L"debugclients"
  79. #define DEBUG_CATC_ENABLE L"debugcatc"
  80. #define DEBUG_LOG_ENABLE L"debuglogenable"
  81. #define BIOS_X_KEY L"UsbBIOSx"
  82. #define G_DISABLE_SS_KEY L"DisableSelectiveSuspend"
  83. #define G_DISABLE_CC_DETECT_KEY L"DisableCcDetect"
  84. #define G_EN_IDLE_ENDPOINT_SUPPORT L"EnIdleEndpointSupport"
  85. #define ENABLE_DCA L"EnableDCA"
  86. /*
  87. BIOS Hacks
  88. */
  89. // Wake hacks, these are exclusive
  90. // diable wake s1 and deeper
  91. #define BIOS_X_NO_USB_WAKE_S1 0x000000001
  92. // disable wake s2 and deeper
  93. #define BIOS_X_NO_USB_WAKE_S2 0x000000002
  94. // disable wake s3 and deeper
  95. #define BIOS_X_NO_USB_WAKE_S3 0x000000004
  96. // disable wake s4 and deeper
  97. #define BIOS_X_NO_USB_WAKE_S4 0x000000008
  98. /*
  99. HC types
  100. define known HC types
  101. */
  102. // Opti Hydra derivative
  103. #define HC_VID_OPTI 0x1045
  104. #define HC_PID_OPTI_HYDRA 0xC861
  105. // Intel USB 2.0 controller emulator
  106. #define HC_VID_INTEL 0x8086
  107. #define HC_PID_INTEL_960 0x6960
  108. #define HC_PID_INTEL_ICH2_1 0x2442
  109. #define HC_PID_INTEL_ICH2_2 0x2444
  110. #define HC_PID_INTEL_ICH1 0x2412
  111. // VIA USB controller
  112. #define HC_VID_VIA 0x1106
  113. #define HC_PID_VIA 0x3038
  114. // NEC USB companion controller
  115. #define HC_VID_NEC_CC 0x1033
  116. #define HC_PID_NEC_CC 0x0035
  117. #define HC_REV_NEC_CC 0x41
  118. // VIA USB companion controller
  119. #define HC_VID_VIA_CC 0x1106
  120. #define HC_PID_VIA_CC 0x3038
  121. #define HC_REV_VIA_CC 0x50
  122. // Intel USB companion controller
  123. #define HC_VID_INTEL_CC 0x8086
  124. #define HC_PID_INTEL_CC1 0x24C2
  125. #define HC_PID_INTEL_CC2 0x24C4
  126. #define HC_PID_INTEL_CC3 0x24C7
  127. #define PENDPOINT_DATA PVOID
  128. #define PDEVICE_DATA PVOID
  129. #define PTRANSFER_CONTEXT PVOID
  130. // the maximum interval we support for an interrupt
  131. // endpoint in the schedule, larger intervals are
  132. // rounded down
  133. #define USBPORT_MAX_INTEP_POLLING_INTERVAL 32
  134. /*
  135. Power sttructures
  136. */
  137. #define USBPORT_MAPPED_SLEEP_STATES 4
  138. typedef enum _HC_POWER_ATTRIBUTES {
  139. HcPower_Y_Wakeup_Y = 0,
  140. HcPower_N_Wakeup_N,
  141. HcPower_Y_Wakeup_N,
  142. HcPower_N_Wakeup_Y
  143. } HC_POWER_ATTRIBUTES;
  144. typedef struct _HC_POWER_STATE {
  145. SYSTEM_POWER_STATE SystemState;
  146. DEVICE_POWER_STATE DeviceState;
  147. HC_POWER_ATTRIBUTES Attributes;
  148. } HC_POWER_STATE, *PHC_POWER_STATE;
  149. typedef struct _HC_POWER_STATE_TABLE {
  150. HC_POWER_STATE PowerState[USBPORT_MAPPED_SLEEP_STATES];
  151. } HC_POWER_STATE_TABLE, *PHC_POWER_STATE_TABLE;
  152. /*
  153. common structure used to represent transfer
  154. requests
  155. */
  156. typedef struct _TRANSFER_URB {
  157. struct _URB_HEADER Hdr;
  158. PVOID UsbdPipeHandle;
  159. ULONG TransferFlags;
  160. ULONG TransferBufferLength;
  161. PVOID TransferBuffer;
  162. PMDL TransferBufferMDL;
  163. PVOID ReservedMBNull; // no Linked Urbs
  164. struct _USBPORT_DATA pd; // fields for USBPORT use
  165. union {
  166. struct {
  167. ULONG StartFrame;
  168. ULONG NumberOfPackets;
  169. ULONG ErrorCount;
  170. USBD_ISO_PACKET_DESCRIPTOR IsoPacket[0];
  171. } Isoch;
  172. UCHAR SetupPacket[8];
  173. } u;
  174. } TRANSFER_URB, *PTRANSFER_URB;
  175. /* Internal IRP tracking structure */
  176. typedef struct _TRACK_IRP {
  177. PIRP Irp;
  178. LIST_ENTRY ListEntry;
  179. } TRACK_IRP, *PTRACK_IRP;
  180. /* Internal work item structure */
  181. typedef struct _USB_POWER_WORK {
  182. WORK_QUEUE_ITEM QueueItem;
  183. PDEVICE_OBJECT FdoDeviceObject;
  184. } USB_POWER_WORK, *PUSB_POWER_WORK;
  185. /* tracking information for OCA online crash analysis */
  186. #define SIG_USB_OCA1 '1aco' //oca1
  187. #define SIG_USB_OCA2 '2aco' //oca2
  188. // save 16 chars of driver name
  189. #define USB_DRIVER_NAME_LEN 16
  190. #ifdef LOG_OCA_DATA
  191. typedef struct _OCA_DATA {
  192. ULONG OcaSig1;
  193. PIRP Irp;
  194. USHORT DeviceVID;
  195. USHORT DevicePID;
  196. UCHAR AnsiDriverName[USB_DRIVER_NAME_LEN];
  197. USB_CONTROLLER_FLAVOR HcFlavor;
  198. ULONG OcaSig2;
  199. } OCA_DATA, *POCA_DATA;
  200. #endif
  201. /*
  202. this is the structure we use to track
  203. common buffer blocks we allocate.
  204. The virtual address of this structure is the
  205. pointer returned from HalAllocateCommonBuffer
  206. */
  207. typedef struct _USBPORT_COMMON_BUFFER {
  208. ULONG Sig;
  209. ULONG Flags;
  210. // total length of block,
  211. // including header and any padding
  212. ULONG TotalLength;
  213. // va address returned by the hal
  214. PVOID VirtualAddress;
  215. // phys address returned by the hal
  216. PHYSICAL_ADDRESS LogicalAddress;
  217. // page aligned VirtualAddress
  218. PUCHAR BaseVa;
  219. // page aligned 32 bit phyical address
  220. HW_32BIT_PHYSICAL_ADDRESS BasePhys;
  221. // va passed to the miniport
  222. ULONG MiniportLength;
  223. ULONG PadLength;
  224. // va passed to the miniport
  225. PVOID MiniportVa;
  226. // phys address passed to miniport
  227. HW_32BIT_PHYSICAL_ADDRESS MiniportPhys;
  228. } USBPORT_COMMON_BUFFER, *PUSBPORT_COMMON_BUFFER;
  229. //
  230. // use to track transfer irps in the port driver
  231. // this size is totally arbitrary -- I just picked 512
  232. #define IRP_TABLE_LENGTH 512
  233. typedef struct _USBPORT_IRP_TABLE {
  234. struct _USBPORT_IRP_TABLE *NextTable;
  235. PIRP Irps[IRP_TABLE_LENGTH];
  236. } USBPORT_IRP_TABLE, *PUSBPORT_IRP_TABLE;
  237. #define USBPORT_InsertActiveTransferIrp(fdo, irp) \
  238. {\
  239. PDEVICE_EXTENSION devExt;\
  240. GET_DEVICE_EXT(devExt, (fdo));\
  241. ASSERT_FDOEXT(devExt);\
  242. USBPORT_InsertIrpInTable((fdo), devExt->ActiveTransferIrpTable, (irp));\
  243. }
  244. #define USBPORT_InsertPendingTransferIrp(fdo, irp) \
  245. {\
  246. PDEVICE_EXTENSION devExt;\
  247. GET_DEVICE_EXT(devExt, (fdo));\
  248. ASSERT_FDOEXT(devExt);\
  249. USBPORT_InsertIrpInTable((fdo), devExt->PendingTransferIrpTable, (irp));\
  250. }
  251. #define USBPORT_CHECK_URB_ACTIVE(fdo, urb, inIrp) \
  252. {\
  253. PDEVICE_EXTENSION devExt;\
  254. GET_DEVICE_EXT(devExt, (fdo));\
  255. ASSERT_FDOEXT(devExt);\
  256. USBPORT_FindUrbInIrpTable((fdo), devExt->ActiveTransferIrpTable, (urb), \
  257. (inIrp));\
  258. }
  259. /*
  260. The goal of these structures is to keep the
  261. spinlocks a cache line away from each other
  262. and a cache line away from the data structures
  263. they protect.
  264. Apparently there is an advantage to doing this
  265. on MP systems
  266. */
  267. typedef struct _USBPORT_SPIN_LOCK {
  268. union {
  269. KSPIN_LOCK sl;
  270. // bugbug -- needs to be cache line size
  271. UCHAR CacheLineSize[16];
  272. };
  273. LONG Check;
  274. ULONG SigA;
  275. ULONG SigR;
  276. } USBPORT_SPIN_LOCK, *PUSBPORT_SPIN_LOCK;
  277. /*
  278. structure we use to track bound drivers
  279. */
  280. typedef struct _USBPORT_MINIPORT_DRIVER {
  281. // driver object assocaited with this particular
  282. // miniport
  283. PDRIVER_OBJECT DriverObject;
  284. LIST_ENTRY ListEntry;
  285. PDRIVER_UNLOAD MiniportUnload;
  286. ULONG HciVersion;
  287. // copy of the registration packet passed in
  288. USBPORT_REGISTRATION_PACKET RegistrationPacket;
  289. } USBPORT_MINIPORT_DRIVER, *PUSBPORT_MINIPORT_DRIVER;
  290. /*
  291. A separate context structure used for IRP tracking.
  292. we do this because clients frequently free the IRP
  293. while it is pending corrupting any lists linked with
  294. the irp itself.
  295. */
  296. typedef struct _USB_IRP_CONTEXT {
  297. ULONG Sig;
  298. LIST_ENTRY ListEntry;
  299. struct _USBD_DEVICE_HANDLE *DeviceHandle;
  300. PIRP Irp;
  301. } USB_IRP_CONTEXT, *PUSB_IRP_CONTEXT;
  302. #define USBPORT_TXFLAG_CANCELED 0x00000001
  303. #define USBPORT_TXFLAG_MAPPED 0x00000002
  304. #define USBPORT_TXFLAG_HIGHSPEED 0x00000004
  305. #define USBPORT_TXFLAG_IN_MINIPORT 0x00000008
  306. #define USBPORT_TXFLAG_ABORTED 0x00000010
  307. #define USBPORT_TXFLAG_ISO 0x00000020
  308. #define USBPORT_TXFLAG_TIMEOUT 0x00000040
  309. #define USBPORT_TXFLAG_DEVICE_GONE 0x00000080
  310. #define USBPORT_TXFLAG_SPLIT_CHILD 0x00000100
  311. #define USBPORT_TXFLAG_MPCOMPLETED 0x00000200
  312. #define USBPORT_TXFLAG_SPLIT 0x00000400
  313. #define USBPORT_TXFLAG_KILL_SPLIT 0x00000800
  314. typedef enum _USBPORT_TRANSFER_DIRECTION {
  315. NotSet = 0,
  316. ReadData, // ie in
  317. WriteData, // ie out
  318. } USBPORT_TRANSFER_DIRECTION;
  319. typedef struct _HCD_TRANSFER_CONTEXT {
  320. ULONG Sig;
  321. ULONG Flags;
  322. // Total length of this structure
  323. ULONG TotalLength;
  324. // length up to miniport context
  325. ULONG PrivateLength;
  326. USBPORT_TRANSFER_DIRECTION Direction;
  327. // timeout, 0 = no timeout
  328. ULONG MillisecTimeout;
  329. LARGE_INTEGER TimeoutTime;
  330. // for perf work
  331. ULONG MiniportFrameCompleted;
  332. // track bytes transferred this transfer
  333. ULONG MiniportBytesTransferred;
  334. USBD_STATUS UsbdStatus;
  335. // irp to signal on completion
  336. PIRP Irp;
  337. // event to signal on completion
  338. PKEVENT CompleteEvent;
  339. // point back to the original URB
  340. PTRANSFER_URB Urb;
  341. // for linkage on endpoint lists
  342. LIST_ENTRY TransferLink;
  343. KSPIN_LOCK Spin;
  344. PVOID MapRegisterBase;
  345. ULONG NumberOfMapRegisters;
  346. TRANSFER_PARAMETERS Tp;
  347. PMDL TransferBufferMdl;
  348. // used for perf
  349. ULONG IoMapStartFrame;
  350. // for Double buffering
  351. LIST_ENTRY DoubleBufferList;
  352. // parent transfer
  353. struct _HCD_TRANSFER_CONTEXT *Transfer;
  354. struct _HCD_ENDPOINT *Endpoint;
  355. PUCHAR MiniportContext;
  356. LIST_ENTRY SplitTransferList;
  357. LIST_ENTRY SplitLink;
  358. PMINIPORT_ISO_TRANSFER IsoTransfer;
  359. // OCA info from device
  360. USHORT DeviceVID;
  361. USHORT DevicePID;
  362. WCHAR DriverName[USB_DRIVER_NAME_LEN];
  363. TRANSFER_SG_LIST SgList;
  364. } HCD_TRANSFER_CONTEXT, *PHCD_TRANSFER_CONTEXT;
  365. /*
  366. The pipe handle structure us our primary means of
  367. tracking USB endpoints. Contained within the handle
  368. is our endpoint data structure as well as the
  369. miniport endpoint data structure.
  370. */
  371. typedef VOID
  372. (__stdcall *PENDPOINT_WORKER_FUNCTION) (
  373. struct _HCD_ENDPOINT *
  374. );
  375. #define EPFLAG_MAP_XFERS 0x00000001
  376. // ep is part of root hub
  377. #define EPFLAG_ROOTHUB 0x00000002
  378. //replaced with dedicated flag
  379. //#define EPFLAG_LOCKED 0x00000004
  380. // power management hosed this endpoint
  381. #define EPFLAG_NUKED 0x00000008
  382. // cleared when we receive a transfer for
  383. // the endpoint reset when the pipe gets
  384. // reset
  385. #define EPFLAG_VIRGIN 0x00000010
  386. #define EPFLAG_DEVICE_GONE 0x00000020
  387. // enpoint used by vbus (virtual bus)
  388. #define EPFLAG_VBUS 0x00000040
  389. // enpoint is large ISO allowed for this TT
  390. #define EPFLAG_FATISO 0x00000080
  391. typedef struct _HCD_ENDPOINT {
  392. ULONG Sig;
  393. ULONG Flags;
  394. ULONG LockFlag;
  395. LONG Busy;
  396. PDEVICE_OBJECT FdoDeviceObject;
  397. DEBUG_LOG Log;
  398. // NOTE: must be careful with this pointer as the
  399. // endpoint can exist after the device handle
  400. // is removed
  401. struct _USBD_DEVICE_HANDLE *DeviceHandle;
  402. struct _TRANSACTION_TRANSLATOR *Tt;
  403. MP_ENDPOINT_STATUS CurrentStatus;
  404. MP_ENDPOINT_STATE CurrentState;
  405. MP_ENDPOINT_STATE NewState;
  406. ULONG StateChangeFrame;
  407. PENDPOINT_WORKER_FUNCTION EpWorkerFunction;
  408. LIST_ENTRY ActiveList;
  409. LIST_ENTRY PendingList;
  410. LIST_ENTRY CancelList;
  411. LIST_ENTRY AbortIrpList;
  412. // for linkage to global endpoint list
  413. LIST_ENTRY GlobalLink;
  414. LIST_ENTRY AttendLink;
  415. LIST_ENTRY StateLink;
  416. LIST_ENTRY ClosedLink;
  417. LIST_ENTRY BusyLink;
  418. LIST_ENTRY KillActiveLink;
  419. LIST_ENTRY TimeoutLink;
  420. LIST_ENTRY FlushLink;
  421. LIST_ENTRY PriorityLink;
  422. LIST_ENTRY RebalanceLink;
  423. LIST_ENTRY TtLink;
  424. USBPORT_SPIN_LOCK ListSpin;
  425. USBPORT_SPIN_LOCK StateChangeSpin;
  426. KIRQL LockIrql;
  427. KIRQL ScLockIrql;
  428. UCHAR Pad[2];
  429. // iso stuff
  430. ULONG NextTransferStartFrame;
  431. PUSBPORT_COMMON_BUFFER CommonBuffer;
  432. ENDPOINT_PARAMETERS Parameters;
  433. PVOID Usb2LibEpContext;
  434. // used to stall close endpoint when we may still need access
  435. LONG EndpointRef;
  436. struct _HCD_ENDPOINT *BudgetNextEndpoint;
  437. // iso stat counters
  438. // late frames - count of packets passed by calling driver that were
  439. // too late to transmit
  440. ULONG lateFrames;
  441. // gap frames - these are empty frames resulting from gaps in the
  442. // stream, these are casued by periods between iso submissions
  443. ULONG gapFrames;
  444. // error frames - these are frames for which we passed a packet to
  445. // the miniport and were completed with an error
  446. ULONG errorFrames;
  447. // iso transaction log
  448. DEBUG_LOG IsoLog;
  449. PVOID MiniportEndpointData[0]; // PVOID for IA64 alignment
  450. } HCD_ENDPOINT, *PHCD_ENDPOINT;
  451. #define USBPORT_TTFLAG_REMOVED 0x00000001
  452. typedef struct _TRANSACTION_TRANSLATOR {
  453. ULONG Sig;
  454. ULONG TtFlags;
  455. USHORT DeviceAddress;
  456. USHORT Port;
  457. LIST_ENTRY EndpointList;
  458. LIST_ENTRY TtLink;
  459. PDEVICE_OBJECT PdoDeviceObject;
  460. ULONG TotalBusBandwidth;
  461. ULONG BandwidthTable[USBPORT_MAX_INTEP_POLLING_INTERVAL];
  462. ULONG MaxAllocedBw;
  463. ULONG MinAllocedBw;
  464. PVOID Usb2LibTtContext[0]; // PVOID for IA64 alignment
  465. } TRANSACTION_TRANSLATOR, *PTRANSACTION_TRANSLATOR;
  466. #define EP_MAX_TRANSFER(ep) ((ep)->Parameters.MaxTransferSize)
  467. #define EP_MAX_PACKET(ep) ((ep)->Parameters.MaxPacketSize)
  468. #define USBPORT_PIPE_STATE_CLOSED 0x00000001
  469. #define USBPORT_PIPE_ZERO_BW 0x00000002
  470. typedef struct _USBD_PIPE_HANDLE_I {
  471. ULONG Sig;
  472. USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
  473. ULONG PipeStateFlags;
  474. ULONG UsbdPipeFlags;
  475. PHCD_ENDPOINT Endpoint;
  476. // for pipe handle list attached to device
  477. LIST_ENTRY ListEntry;
  478. } USBD_PIPE_HANDLE_I, *PUSBD_PIPE_HANDLE_I;
  479. #define INITIALIZE_DEFAULT_PIPE(dp, mp) \
  480. do {\
  481. (dp).UsbdPipeFlags = 0;\
  482. (dp).EndpointDescriptor.bLength =\
  483. sizeof(USB_ENDPOINT_DESCRIPTOR);\
  484. (dp).EndpointDescriptor.bDescriptorType =\
  485. USB_ENDPOINT_DESCRIPTOR_TYPE;\
  486. (dp).EndpointDescriptor.bEndpointAddress =\
  487. USB_DEFAULT_ENDPOINT_ADDRESS;\
  488. (dp).EndpointDescriptor.bmAttributes =\
  489. USB_ENDPOINT_TYPE_CONTROL;\
  490. (dp).EndpointDescriptor.wMaxPacketSize =\
  491. mp;\
  492. (dp).EndpointDescriptor.bInterval = 0;\
  493. (dp).Sig = SIG_PIPE_HANDLE;\
  494. (dp).PipeStateFlags = USBPORT_PIPE_STATE_CLOSED;\
  495. } while(0)
  496. typedef struct _USBD_INTERFACE_HANDLE_I {
  497. ULONG Sig;
  498. LIST_ENTRY InterfaceLink;
  499. BOOLEAN HasAlternateSettings;
  500. // number associated with this interface defined
  501. // in the interface descriptor
  502. UCHAR Pad[3];
  503. // copy of interface descriptor (header) ie no endpoints
  504. // the endpoint descriptors are in the PipeHandles
  505. USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
  506. // array of pipe handle structures
  507. USBD_PIPE_HANDLE_I PipeHandle[0];
  508. } USBD_INTERFACE_HANDLE_I, *PUSBD_INTERFACE_HANDLE_I;
  509. typedef struct _USBD_CONFIG_HANDLE {
  510. ULONG Sig;
  511. PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
  512. LIST_ENTRY InterfaceHandleList;
  513. } USBD_CONFIG_HANDLE, *PUSBD_CONFIG_HANDLE;
  514. #define TEST_DEVICE_FLAG(dh, flag) ((dh)->DeviceFlags & (flag)) ? TRUE : FALSE
  515. #define SET_DEVICE_FLAG(dh, flag) ((dh)->DeviceFlags |= (flag))
  516. #define CLEAR_DEVICE_FLAG(dh, flag) ((dh)->DeviceFlags &= ~(flag))
  517. // values for DveiceFlags
  518. #define USBPORT_DEVICEFLAG_FREED_BY_HUB 0x00000001
  519. #define USBPORT_DEVICEFLAG_ROOTHUB 0x00000002
  520. #define USBPORT_DEVICEFLAG_RAWHANDLE 0x00000004
  521. #define USBPORT_DEVICEFLAG_REMOVED 0x00000008
  522. #define USBPORT_DEVICEFLAG_HSHUB 0x00000010
  523. #define IS_ROOT_HUB(dh) (BOOLEAN)((dh)->DeviceFlags & USBPORT_DEVICEFLAG_ROOTHUB)
  524. /*
  525. TopologyAddress
  526. The USB topology address is a string of bytes
  527. representing a the devices location in the usb
  528. tree. This address is unique bud depends entirely
  529. on which port the device is attached.
  530. The byte array is 5 bytes long looks like this:
  531. [0] root hub
  532. [1] 1st tier hub
  533. [2] 2nd tier hub
  534. [3] 3rd tier hub
  535. [4] 4th tier hub
  536. [5] 5th tier hub
  537. [6] reserved MBZ
  538. [7] reserved MBZ
  539. * the spec defines a maximum of five hubs
  540. * the spec defines a maximum of 127 ports/hub
  541. the entry in the array indicates the port to which the
  542. device is attached
  543. 0, 0, 0, 0, 0, 0, r0, r0 - defines the root hub
  544. 1, 0, 0, 0, 0, 0, r0, r0 - defines a device attached to port 1 of the root hub
  545. --p1
  546. / p1 |-p2
  547. p1-HUB1- p2 / p1 |-p3
  548. / \ p3-HUB2- p2 -HUB3--p4
  549. root \ p3 \-p5-HUB4-p1-DEV
  550. \ \p2
  551. p2
  552. 1, 3, 2, 5, 1, 0, r0, r0 - defines the above device
  553. */
  554. typedef struct _USBD_DEVICE_HANDLE {
  555. ULONG Sig;
  556. // USB address assigned to the device
  557. USHORT DeviceAddress;
  558. USHORT TtPortNumber;
  559. LONG PendingUrbs;
  560. struct _TRANSACTION_TRANSLATOR *Tt;
  561. struct _USBD_DEVICE_HANDLE *HubDeviceHandle;
  562. PUSBD_CONFIG_HANDLE ConfigurationHandle;
  563. USBD_PIPE_HANDLE_I DefaultPipe;
  564. USB_DEVICE_SPEED DeviceSpeed;
  565. // a copy of the USB device descriptor
  566. USB_DEVICE_DESCRIPTOR DeviceDescriptor;
  567. ULONG DeviceFlags;
  568. // used to created a list of valid device
  569. // handles
  570. LIST_ENTRY ListEntry;
  571. // keep a list of valid open
  572. // pipes
  573. LIST_ENTRY PipeHandleList;
  574. ULONG TtCount;
  575. // keep a list of tt structures for high speed
  576. // hubs
  577. LIST_ENTRY TtList;
  578. PDEVICE_OBJECT DevicePdo;
  579. WCHAR DriverName[USB_DRIVER_NAME_LEN];
  580. } USBD_DEVICE_HANDLE, *PUSBD_DEVICE_HANDLE;
  581. // we serialize access to the device handle thru a
  582. // semaphore, the reason for this is that we need
  583. // exclusive access when we set the configuration or
  584. // interface
  585. #define LOCK_DEVICE(dh, fdo) \
  586. { \
  587. PDEVICE_EXTENSION devExt;\
  588. GET_DEVICE_EXT(devExt, (fdo)); \
  589. USBPORT_KdPrint((2, "'***LOCK_DEVICE %x\n", (dh))); \
  590. LOGENTRY(NULL, (fdo), LOG_PNP, 'LKdv', (dh), 0, 0);\
  591. KeWaitForSingleObject(&(devExt)->Fdo.DeviceLock, \
  592. Executive,\
  593. KernelMode, \
  594. FALSE, \
  595. NULL); \
  596. }
  597. #define UNLOCK_DEVICE(dh, fdo) \
  598. { \
  599. PDEVICE_EXTENSION devExt;\
  600. GET_DEVICE_EXT(devExt, (fdo)); \
  601. USBPORT_KdPrint((2, "'***UNLOCK_DEVICE %x\n", (dh))); \
  602. LOGENTRY(NULL, (fdo), LOG_PNP, 'UKdv', (dh), 0, 0);\
  603. KeReleaseSemaphore(&(devExt)->Fdo.DeviceLock,\
  604. LOW_REALTIME_PRIORITY,\
  605. 1,\
  606. FALSE);\
  607. }
  608. #define USBPORT_BAD_HANDLE ((PVOID)(-1))
  609. #define USBPORT_BAD_POINTER ((PVOID)(-1))
  610. // PnPStateFlags
  611. #define USBPORT_PNP_STOPPED 0x00000001
  612. #define USBPORT_PNP_STARTED 0x00000002
  613. #define USBPORT_PNP_REMOVED 0x00000004
  614. #define USBPORT_PNP_START_FAILED 0x00000008
  615. #define USBPORT_PNP_DELETED 0x00000010
  616. // Flags:both FDO and PDO
  617. #define USBPORT_FLAG_SYM_LINK 0x00000001
  618. #define TEST_FDO_FLAG(de, flag) (((de)->Fdo.FdoFlags & (flag)) ? TRUE : FALSE)
  619. #define SET_FDO_FLAG(de, flag) ((de)->Fdo.FdoFlags |= (flag))
  620. #define CLEAR_FDO_FLAG(de, flag) ((de)->Fdo.FdoFlags &= ~(flag))
  621. #define TEST_PDO_FLAG(de, flag) (((de)->Pdo.PdoFlags & (flag)) ? TRUE : FALSE)
  622. #define SET_PDO_FLAG(de, flag) ((de)->Pdo.PdoFlags |= (flag))
  623. #define CLEAR_PDO_FLAG(de, flag) ((de)->Pdo.PdoFlags &= ~(flag))
  624. // FdoFlags: Fdo Only
  625. #define USBPORT_FDOFLAG_IRQ_CONNECTED 0x00000001
  626. #define USBPORT_FDOFLAG_ENABLE_SYSTEM_WAKE 0x00000002
  627. #define USBPORT_FDOFLAG_POLL_CONTROLLER 0x00000004
  628. // set to indicate the worker thread should
  629. // terminate
  630. #define USBPORT_FDOFLAG_KILL_THREAD 0x00000008
  631. // set if the HC should be wake enabled on the
  632. // next D power state transition
  633. #define USBPORT_FDOFLAG_WAKE_ENABLED 0x00000010
  634. // set to indicate the controller should
  635. // be put in D0 by the worker thread
  636. #define USBPORT_FDOFLAG_NEED_SET_POWER_D0 0x00000020
  637. // set when the DM_timer is running
  638. #define USBPORT_FDOFLAG_DM_TIMER_ENABLED 0x00000040
  639. // set to disable the DM tiners work
  640. // while controller is in low power
  641. #define USBPORT_FDOFLAG_SKIP_TIMER_WORK 0x00000080
  642. // **NOTE: the following two flags are
  643. // Mutually Exclusive
  644. //
  645. // since the true power state of the HW must remain independent
  646. // of OS power management we have our own flags for this.
  647. // set to indicate the controller is 'suspended'
  648. #define USBPORT_FDOFLAG_SUSPENDED 0x00000100
  649. // set to indicate the controller is 'OFF'
  650. #define USBPORT_FDOFLAG_OFF 0x00000200
  651. #define USBPORT_FDOFLAG_IRQ_EN 0x00000400
  652. // set if the controller can 'suspend' the root hub
  653. // this is the dynamic flag use to turn SS on and off
  654. #define USBPORT_FDOFLAG_RH_CAN_SUSPEND 0x00000800
  655. // set if controller detects resume signalling
  656. #define USBPORT_FDOFLAG_RESUME_SIGNALLING 0x00001000
  657. #define USBPORT_FDOFLAG_HCPENDING_WAKE_IRP 0x00002000
  658. // set if we initialize the dm timer, used to
  659. // bypass timer stop on failure
  660. #define USBPORT_FDOFLAG_DM_TIMER_INIT 0x00004000
  661. // set if we init the worker thread
  662. #define USBPORT_FDOFLAG_THREAD_INIT 0x00008000
  663. // means we created the HCDn symbolic name
  664. #define USBPORT_FDOFLAG_LEGACY_SYM_LINK 0x00010000
  665. // some knucklehead pulled out the controller
  666. #define USBPORT_FDOFLAG_CONTROLLER_GONE 0x00020000
  667. // miniport has requested hw reset
  668. #define USBPORT_FDOFLAG_HW_RESET_PENDING 0x00040000
  669. // set if tlegacy BIOS detected
  670. #define USBPORT_FDOFLAG_LEGACY_BIOS 0x00080000
  671. #define USBPORT_FDOFLAG_CATC_TRAP 0x00100000
  672. /* polls hw while suspended */
  673. #define USBPORT_FDOFLAG_POLL_IN_SUSPEND 0x00200000
  674. #define USBPORT_FDOFLAG_FAIL_URBS 0x00400000
  675. /* turn on Intel USB diag mode */
  676. #define USBPORT_FDOFLAG_DIAG_MODE 0x00800000
  677. /* set if 1.1 controller is CC */
  678. #define USBPORT_FDOFLAG_IS_CC 0x01000000
  679. /* synchronize registration with our ouwn start
  680. stop routine, not intened to sync between instances */
  681. #define USBPORT_FDOFLAG_FDO_REGISTERED 0x02000000
  682. /* OK to enumerate devices on CC (usb 2o disabled) */
  683. #define USBPORT_FDOFLAG_CC_ENUM_OK 0x04000000
  684. /* This is a static flag that causes selective
  685. suspend to always be disabled */
  686. #define USBPORT_FDOFLAG_DISABLE_SS 0x08000000
  687. #define USBPORT_FDOFLAG_CC_LOCK 0x10000000
  688. /* indicates we are on the PNP thread */
  689. #define USBPORT_FDOFLAG_ON_PNP_THREAD 0x20000000
  690. /* signals OK to enumerate on the root hub */
  691. #define USBPORT_FDOFLAG_SIGNAL_RH 0x80000000
  692. // PdoFlags: Pdo Only
  693. #define USBPORT_PDOFLAG_HAVE_IDLE_IRP 0x00000001
  694. // MiniportStateFlags
  695. // miniport is either started (set) OR not started (clear)
  696. #define MP_STATE_STARTED 0x00000001
  697. #define MP_STATE_SUSPENDED 0x00000002
  698. // USB HC wake states
  699. typedef enum _USBHC_WAKE_STATE {
  700. HCWAKESTATE_DISARMED =1,
  701. HCWAKESTATE_WAITING =2,
  702. HCWAKESTATE_WAITING_CANCELLED =3,
  703. HCWAKESTATE_ARMED =4,
  704. HCWAKESTATE_ARMING_CANCELLED =5,
  705. HCWAKESTATE_COMPLETING =7
  706. } USBHC_WAKE_STATE;
  707. typedef struct _FDO_EXTENSION {
  708. // Device object that the bus extender created for
  709. // us
  710. PDEVICE_OBJECT PhysicalDeviceObject;
  711. // Device object of the first guy on the stack
  712. // -- the guy we pass our Irps on to.
  713. PDEVICE_OBJECT TopOfStackDeviceObject;
  714. // PhysicalDeviceObject we create for the
  715. // root hub
  716. PDEVICE_OBJECT RootHubPdo;
  717. // serialize access to the root hub data structures
  718. USBPORT_SPIN_LOCK RootHubSpin;
  719. // pointer to miniport Data
  720. PDEVICE_DATA MiniportDeviceData;
  721. PUSBPORT_MINIPORT_DRIVER MiniportDriver;
  722. PUSBPORT_COMMON_BUFFER ScratchCommonBuffer;
  723. ULONG DeviceNameIdx;
  724. LONG WorkerDpc;
  725. // total bandwidth of the wire in bits/sec
  726. // USB 1.1 is 12000 (12 MBits/sec)
  727. // USB 2.0 is 400000 (400 MBits/sec)
  728. ULONG TotalBusBandwidth;
  729. ULONG BandwidthTable[USBPORT_MAX_INTEP_POLLING_INTERVAL];
  730. // track alloactions
  731. // for periods 1, 2, 4, 8, 16, 32
  732. // in bits/sec
  733. ULONG AllocedInterruptBW[6];
  734. ULONG AllocedIsoBW;
  735. ULONG AllocedLowSpeedBW;
  736. ULONG MaxAllocedBw;
  737. ULONG MinAllocedBw;
  738. ULONG FdoFlags;
  739. ULONG MpStateFlags;
  740. LONG DmaBusy;
  741. USB_CONTROLLER_FLAVOR HcFlavor;
  742. USHORT PciVendorId;
  743. // PCI deviceId == USB productId
  744. USHORT PciDeviceId;
  745. // PCI revision == USB bcdDevice
  746. UCHAR PciRevisionId;
  747. UCHAR PciClass;
  748. UCHAR PciSubClass;
  749. UCHAR PciProgIf;
  750. PIRP HcPendingWakeIrp;
  751. ULONG AddressList[4];
  752. PUSBD_DEVICE_HANDLE RawDeviceHandle;
  753. HC_POWER_STATE_TABLE HcPowerStateTbl;
  754. SYSTEM_POWER_STATE LastSystemSleepState;
  755. KSEMAPHORE DeviceLock;
  756. KSEMAPHORE CcLock;
  757. UNICODE_STRING LegacyLinkUnicodeString;
  758. HC_RESOURCES HcResources;
  759. // protects core functions called thru
  760. // registration packet in MiniportDriver
  761. USBPORT_SPIN_LOCK CoreFunctionSpin;
  762. USBPORT_SPIN_LOCK MapTransferSpin;
  763. USBPORT_SPIN_LOCK DoneTransferSpin;
  764. USBPORT_SPIN_LOCK EndpointListSpin;
  765. USBPORT_SPIN_LOCK EpStateChangeListSpin;
  766. USBPORT_SPIN_LOCK DevHandleListSpin;
  767. USBPORT_SPIN_LOCK EpClosedListSpin;
  768. USBPORT_SPIN_LOCK TtEndpointListSpin;
  769. USBPORT_SPIN_LOCK PendingTransferIrpSpin;
  770. USBPORT_SPIN_LOCK ActiveTransferIrpSpin;
  771. USBPORT_SPIN_LOCK WorkerThreadSpin;
  772. USBPORT_SPIN_LOCK PowerSpin;
  773. USBPORT_SPIN_LOCK DM_TimerSpin;
  774. USBPORT_SPIN_LOCK PendingIrpSpin;
  775. USBPORT_SPIN_LOCK WakeIrpSpin;
  776. USBPORT_SPIN_LOCK HcPendingWakeIrpSpin;
  777. USBPORT_SPIN_LOCK IdleIrpSpin;
  778. USBPORT_SPIN_LOCK BadRequestSpin;
  779. USBPORT_SPIN_LOCK IsrDpcSpin;
  780. USBPORT_SPIN_LOCK StatCounterSpin;
  781. USBPORT_SPIN_LOCK HcSyncSpin;
  782. LONG CoreSpinCheck;
  783. KEVENT WorkerThreadEvent;
  784. HANDLE WorkerThreadHandle;
  785. PKTHREAD WorkerPkThread;
  786. KEVENT HcPendingWakeIrpEvent;
  787. KEVENT HcPendingWakeIrpPostedEvent;
  788. PDMA_ADAPTER AdapterObject;
  789. ULONG NumberOfMapRegisters;
  790. LONG NextTransferSequenceNumber;
  791. PKINTERRUPT InterruptObject;
  792. KDPC IsrDpc;
  793. KDPC TransferFlushDpc;
  794. KDPC SurpriseRemoveDpc;
  795. KDPC HcResetDpc;
  796. KDPC HcWakeDpc;
  797. KDPC DM_TimerDpc;
  798. KTIMER DM_Timer;
  799. LONG DM_TimerInterval;
  800. // global common buffer allocated and
  801. // passed to miniport on start.
  802. PUSBPORT_COMMON_BUFFER ControllerCommonBuffer;
  803. // no longer used
  804. USBPORT_SPIN_LOCK LogSpinLock;
  805. LIST_ENTRY DeviceHandleList;
  806. LIST_ENTRY MapTransferList;
  807. LIST_ENTRY DoneTransferList;
  808. LIST_ENTRY EpStateChangeList;
  809. LIST_ENTRY EpClosedList;
  810. LIST_ENTRY BadRequestList;
  811. LIST_ENTRY RegistryCache;
  812. LIST_ENTRY GlobalEndpointList;
  813. LIST_ENTRY AttendEndpointList;
  814. // stat counters
  815. ULONG StatBulkDataBytes;
  816. ULONG StatIsoDataBytes;
  817. ULONG StatInterruptDataBytes;
  818. ULONG StatControlDataBytes;
  819. ULONG StatPciInterruptCount;
  820. ULONG StatHardResetCount;
  821. ULONG StatWorkSignalCount;
  822. ULONG StatWorkIdleTime;
  823. ULONG StatCommonBufferBytes;
  824. ULONG BadRequestFlush;
  825. ULONG BadReqFlushThrottle;
  826. // context for USB2 budgeter engine
  827. PVOID Usb2LibHcContext;
  828. ULONG BiosX;
  829. USBHC_WAKE_STATE HcWakeState;
  830. ULONG Usb2BusFunction;
  831. ULONG BusNumber; // slot
  832. ULONG BusDevice;
  833. ULONG BusFunction;
  834. // usbed to synchronize CCs and USB 2 controllers
  835. LONG DependentControllers;
  836. LONG PendingRhCallback;
  837. LIST_ENTRY ControllerLink;
  838. #ifdef XPSE
  839. // additional stat tracking
  840. LARGE_INTEGER D0ResumeTimeStart;
  841. LARGE_INTEGER S0ResumeTimeStart;
  842. LARGE_INTEGER ThreadResumeTimeStart;
  843. ULONG ThreadResumeTime;
  844. ULONG ControllerResumeTime;
  845. ULONG D0ResumeTime;
  846. ULONG S0ResumeTime;
  847. #endif
  848. ULONG InterruptOrdinalTable[65];
  849. PVOID MiniportExtension[0]; // PVOID for IA64 alignment
  850. } FDO_EXTENSION, *PFDO_EXTENSION;
  851. // this is where we keep
  852. // all the root hub data
  853. typedef struct _PDO_EXTENSION {
  854. USBD_DEVICE_HANDLE RootHubDeviceHandle;
  855. PHCD_ENDPOINT RootHubInterruptEndpoint;
  856. ULONG PdoFlags;
  857. UCHAR ConfigurationValue;
  858. UCHAR Pad3[3];
  859. // pointers to our root hub descriptors
  860. // NOTE: these ptrs point in to the 'Descriptors'
  861. // buffer so son't try to free them
  862. PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
  863. PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
  864. PUSB_HUB_DESCRIPTOR HubDescriptor;
  865. // irp associated with remote wakeup,
  866. // ie irp posted by the HUB driver
  867. PIRP PendingWaitWakeIrp;
  868. PIRP PendingIdleNotificationIrp;
  869. // pointer to buffer contining descriptors
  870. PUCHAR Descriptors;
  871. PRH_INIT_CALLBACK HubInitCallback;
  872. PVOID HubInitContext;
  873. } PDO_EXTENSION, *PPDO_EXTENSION;
  874. // signatures for our device extensions
  875. #define USBPORT_DEVICE_EXT_SIG 'ODFH' //HFDO
  876. #define ROOTHUB_DEVICE_EXT_SIG 'ODPR' //RPDO
  877. /* USB spec defined port flags */
  878. #define PORT_STATUS_CONNECT 0x001
  879. #define PORT_STATUS_ENABLE 0x002
  880. #define PORT_STATUS_SUSPEND 0x004
  881. #define PORT_STATUS_OVER_CURRENT 0x008
  882. #define PORT_STATUS_RESET 0x010
  883. #define PORT_STATUS_POWER 0x100
  884. #define PORT_STATUS_LOW_SPEED 0x200
  885. #define PORT_STATUS_HIGH_SPEED 0x400
  886. /*
  887. root hub status codes
  888. */
  889. typedef enum _RHSTATUS {
  890. RH_SUCCESS = 0,
  891. RH_NAK,
  892. RH_STALL
  893. } RHSTATUS;
  894. /* port operations */
  895. typedef enum _PORT_OPERATION {
  896. SetFeaturePortReset = 0,
  897. SetFeaturePortPower,
  898. SetFeaturePortEnable,
  899. SetFeaturePortSuspend,
  900. ClearFeaturePortEnable,
  901. ClearFeaturePortPower,
  902. ClearFeaturePortSuspend,
  903. ClearFeaturePortEnableChange,
  904. ClearFeaturePortConnectChange,
  905. ClearFeaturePortResetChange,
  906. ClearFeaturePortSuspendChange,
  907. ClearFeaturePortOvercurrentChange
  908. } PORT_OPERATION;
  909. #define NUMBER_OF_PORTS(de) ((de)->Pdo.HubDescriptor->bNumberOfPorts)
  910. #define HUB_DESRIPTOR_LENGTH(de) ((de)->Pdo.HubDescriptor->bDescriptorLength)
  911. typedef struct _DEVICE_EXTENSION {
  912. // Necessary to support Legacy USB hub driver(s)
  913. // AKA 'backport'
  914. PUCHAR DummyUsbdExtension;
  915. // The following fields are common to both the
  916. // root hub PDO and the HC FDO
  917. // signature
  918. ULONG Sig;
  919. // for the FDO this points to ourselves
  920. // for PDO this points to FDO
  921. PDEVICE_OBJECT HcFdoDeviceObject;
  922. // put the log ptrs at the beginning
  923. // to make them easy to find
  924. DEBUG_LOG Log;
  925. DEBUG_LOG TransferLog;
  926. DEBUG_LOG EnumLog;
  927. // these ptrs are in the global extension to
  928. // make them easier to find on win9x
  929. PUSBPORT_IRP_TABLE PendingTransferIrpTable;
  930. PUSBPORT_IRP_TABLE ActiveTransferIrpTable;
  931. ULONG Flags;
  932. ULONG PnpStateFlags;
  933. // current power state of this DO
  934. // this is the state the OS has placed us in
  935. DEVICE_POWER_STATE CurrentDevicePowerState;
  936. PIRP SystemPowerIrp;
  937. // device caps for this DO
  938. DEVICE_CAPABILITIES DeviceCapabilities;
  939. //
  940. // count of requests currently 'in' our driver
  941. // this is tracked per DevObj.
  942. // We also keep a list of irps in the debug driver.
  943. //
  944. LONG PendingRequestCount;
  945. LIST_ENTRY TrackIrpList;
  946. USBPORT_SPIN_LOCK PendingRequestSpin;
  947. KEVENT PendingRequestEvent;
  948. UNICODE_STRING SymbolicLinkName;
  949. union {
  950. PDO_EXTENSION Pdo;
  951. FDO_EXTENSION Fdo;
  952. };
  953. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  954. /*
  955. used to track cached registry keys for miniports
  956. */
  957. typedef struct _USBPORT_REG_CACHE_ENTRY {
  958. ULONG Sig;
  959. LIST_ENTRY RegLink;
  960. BOOLEAN SoftwareBranch;
  961. // length in bytes
  962. ULONG DataLength;
  963. PUCHAR Data;
  964. ULONG KeyNameStringLength;
  965. WCHAR KeyNameString[0];
  966. } USBPORT_REG_CACHE_ENTRY, *PUSBPORT_REG_CACHE_ENTRY;
  967. // define an interlocked version of RemoveEntryList
  968. #define USBPORT_InterlockedRemoveEntryList(ListEntry, Spinlock) \
  969. {\
  970. KIRQL irql;\
  971. KeAcquireSpinLock((Spinlock), &irql);\
  972. RemoveEntryList((ListEntry));\
  973. KeReleaseSpinLock((Spinlock), irql);\
  974. }
  975. #define GET_HEAD_LIST(head, le) \
  976. if (IsListEmpty(&(head))) {\
  977. le = NULL;\
  978. } else {\
  979. le = (head).Flink;\
  980. }
  981. #define FREE_POOL(fdo, p) ExFreePool((p))
  982. //
  983. // allocates a zeroed buffer that the OS is expedected to free
  984. //
  985. #define ALLOC_POOL_OSOWNED(p, PoolType, NumberOfBytes) \
  986. do { \
  987. (p) = ExAllocatePoolWithTag((PoolType), (NumberOfBytes), USBPORT_TAG); \
  988. if ((p)) { \
  989. RtlZeroMemory((p), (NumberOfBytes)); \
  990. } \
  991. } while (0) \
  992. //
  993. // allocates a zeroed buffer that we are expected to free
  994. //
  995. #define ALLOC_POOL_Z(p, PoolType, NumberOfBytes) \
  996. do { \
  997. (p) = ExAllocatePoolWithTag((PoolType), (NumberOfBytes), USBPORT_TAG); \
  998. if ((p)) { \
  999. RtlZeroMemory((p), (NumberOfBytes)); \
  1000. } \
  1001. } while (0) \
  1002. #define GET_DEVICE_EXT(e, d) (e) = (d)->DeviceExtension
  1003. #define GET_DEVICE_HANDLE(dh, urb) (dh) = ((PURB)(urb))->UrbHeader.UsbdDeviceHandle;
  1004. #define DEVEXT_FROM_DEVDATA(de, dd) \
  1005. (de) = (PDEVICE_EXTENSION) \
  1006. CONTAINING_RECORD((dd),\
  1007. struct _DEVICE_EXTENSION, \
  1008. Fdo.MiniportExtension)
  1009. #define ENDPOINT_FROM_EPDATA(ep, epd) \
  1010. (ep) = (PHCD_ENDPOINT) \
  1011. CONTAINING_RECORD((epd),\
  1012. struct _HCD_ENDPOINT, \
  1013. MiniportEndpointData)
  1014. #define TRANSFER_FROM_TPARAMETERS(t, tp) \
  1015. (t) = (PHCD_TRANSFER_CONTEXT) \
  1016. CONTAINING_RECORD((tp),\
  1017. struct _HCD_TRANSFER_CONTEXT, \
  1018. Tp)
  1019. #define SET_USBD_ERROR(u, s) USBPORT_SetUSBDError((PURB)(u),(s))
  1020. #define INCREMENT_PENDING_REQUEST_COUNT(devobj, irp) \
  1021. USBPORT_TrackPendingRequest((devobj), (irp), TRUE)
  1022. #define DECREMENT_PENDING_REQUEST_COUNT(devobj, irp) \
  1023. USBPORT_TrackPendingRequest((devobj), (irp), FALSE)
  1024. //328555
  1025. #define REF_DEVICE(urb) \
  1026. do {\
  1027. PUSBD_DEVICE_HANDLE dh;\
  1028. GET_DEVICE_HANDLE(dh, (urb));\
  1029. ASSERT_DEVICE_HANDLE(dh);\
  1030. InterlockedIncrement(&dh->PendingUrbs);\
  1031. } while (0)
  1032. #define DEREF_DEVICE(urb) \
  1033. do {\
  1034. PUSBD_DEVICE_HANDLE dh;\
  1035. GET_DEVICE_HANDLE(dh, (urb));\
  1036. ASSERT_DEVICE_HANDLE(dh);\
  1037. InterlockedDecrement(&dh->PendingUrbs);\
  1038. } while (0)
  1039. //328555
  1040. #define INITIALIZE_PENDING_REQUEST_COUNTER(de) \
  1041. KeInitializeSpinLock(&(de)->PendingRequestSpin.sl);\
  1042. (de)->PendingRequestCount = -1; \
  1043. InitializeListHead(&(de)->TrackIrpList);
  1044. //328555
  1045. #define REF_DEVICE(urb) \
  1046. do {\
  1047. PUSBD_DEVICE_HANDLE dh;\
  1048. GET_DEVICE_HANDLE(dh, (urb));\
  1049. ASSERT_DEVICE_HANDLE(dh);\
  1050. InterlockedIncrement(&dh->PendingUrbs);\
  1051. } while (0)
  1052. #define DEREF_DEVICE(urb) \
  1053. do {\
  1054. PUSBD_DEVICE_HANDLE dh;\
  1055. GET_DEVICE_HANDLE(dh, (urb));\
  1056. ASSERT_DEVICE_HANDLE(dh);\
  1057. InterlockedDecrement(&dh->PendingUrbs);\
  1058. } while (0)
  1059. //328555
  1060. #define ACQUIRE_TRANSFER_LOCK(fdo, t, i) \
  1061. do {\
  1062. PDEVICE_EXTENSION ext;\
  1063. GET_DEVICE_EXT(ext, (fdo));\
  1064. ASSERT_FDOEXT(ext);\
  1065. LOGENTRY(NULL, fdo, LOG_MISC, 'tfL+', 0, (fdo), 0);\
  1066. KeAcquireSpinLock(&(t)->Spin, &(i));\
  1067. } while (0)
  1068. #define RELEASE_TRANSFER_LOCK(fdo, t, i) \
  1069. do {\
  1070. PDEVICE_EXTENSION ext;\
  1071. GET_DEVICE_EXT(ext, (fdo));\
  1072. ASSERT_FDOEXT(ext);\
  1073. LOGENTRY(NULL, fdo, LOG_MISC, 'tfL-', 0, (fdo), (i));\
  1074. KeReleaseSpinLock(&t->Spin, (i));\
  1075. } while (0)
  1076. #define ACQUIRE_IDLEIRP_LOCK(fdo, i) \
  1077. do {\
  1078. PDEVICE_EXTENSION ext;\
  1079. GET_DEVICE_EXT(ext, (fdo));\
  1080. ASSERT_FDOEXT(ext);\
  1081. LOGENTRY(NULL, fdo, LOG_MISC, 'idL+', 0, (fdo), 0);\
  1082. KeAcquireSpinLock(&ext->Fdo.IdleIrpSpin.sl, &(i));\
  1083. } while (0)
  1084. #define RELEASE_IDLEIRP_LOCK(fdo, i) \
  1085. do {\
  1086. PDEVICE_EXTENSION ext;\
  1087. GET_DEVICE_EXT(ext, (fdo));\
  1088. ASSERT_FDOEXT(ext);\
  1089. LOGENTRY(NULL, fdo, LOG_MISC, 'idL-', 0, (fdo), (i));\
  1090. KeReleaseSpinLock(&ext->Fdo.IdleIrpSpin.sl, (i));\
  1091. } while (0)
  1092. #define ACQUIRE_BADREQUEST_LOCK(fdo, i) \
  1093. do {\
  1094. PDEVICE_EXTENSION ext;\
  1095. GET_DEVICE_EXT(ext, (fdo));\
  1096. ASSERT_FDOEXT(ext);\
  1097. LOGENTRY(NULL, fdo, LOG_MISC, 'brL+', 0, (fdo), 0);\
  1098. KeAcquireSpinLock(&ext->Fdo.BadRequestSpin.sl, &(i));\
  1099. } while (0)
  1100. #define RELEASE_BADREQUEST_LOCK(fdo, i) \
  1101. do {\
  1102. PDEVICE_EXTENSION ext;\
  1103. GET_DEVICE_EXT(ext, (fdo));\
  1104. ASSERT_FDOEXT(ext);\
  1105. LOGENTRY(NULL, fdo, LOG_MISC, 'brL-', 0, (fdo), (i));\
  1106. KeReleaseSpinLock(&ext->Fdo.BadRequestSpin.sl, (i));\
  1107. } while (0)
  1108. #define ACQUIRE_WAKEIRP_LOCK(fdo, i) \
  1109. do {\
  1110. PDEVICE_EXTENSION ext;\
  1111. GET_DEVICE_EXT(ext, (fdo));\
  1112. ASSERT_FDOEXT(ext);\
  1113. LOGENTRY(NULL, fdo, LOG_POWER, 'wwL+', 0, (fdo), 0);\
  1114. KeAcquireSpinLock(&ext->Fdo.WakeIrpSpin.sl, &(i));\
  1115. } while (0)
  1116. #define RELEASE_WAKEIRP_LOCK(fdo, i) \
  1117. do {\
  1118. PDEVICE_EXTENSION ext;\
  1119. GET_DEVICE_EXT(ext, (fdo));\
  1120. ASSERT_FDOEXT(ext);\
  1121. LOGENTRY(NULL, fdo, LOG_POWER, 'wwL-', 0, (fdo), (i));\
  1122. KeReleaseSpinLock(&ext->Fdo.WakeIrpSpin.sl, (i));\
  1123. } while (0)
  1124. #define ACQUIRE_ENDPOINT_LOCK(ep, fdo, s) \
  1125. do {\
  1126. LOGENTRY(NULL, fdo, LOG_SPIN, s, (ep), 0, 0);\
  1127. USBPORT_AcquireSpinLock((fdo), &(ep)->ListSpin, &(ep)->LockIrql);\
  1128. LOGENTRY(NULL, fdo, LOG_SPIN, s, (ep), (ep)->LockFlag, 1);\
  1129. USBPORT_ASSERT((ep)->LockFlag == 0); \
  1130. (ep)->LockFlag++;\
  1131. } while (0)
  1132. #define RELEASE_ENDPOINT_LOCK(ep, fdo, s) \
  1133. do {\
  1134. LOGENTRY(NULL, fdo, LOG_SPIN, s, (ep), (ep)->LockFlag, 0);\
  1135. USBPORT_ASSERT((ep)->LockFlag == 1); \
  1136. (ep)->LockFlag--;\
  1137. USBPORT_ReleaseSpinLock(fdo, &(ep)->ListSpin, (ep)->LockIrql);\
  1138. } while (0)
  1139. #define ACQUIRE_STATECHG_LOCK(fdo, ep) \
  1140. USBPORT_AcquireSpinLock((fdo), &(ep)->StateChangeSpin, &(ep)->ScLockIrql);
  1141. #define RELEASE_STATECHG_LOCK(fdo, ep) \
  1142. USBPORT_ReleaseSpinLock((fdo), &(ep)->StateChangeSpin, (ep)->ScLockIrql);
  1143. #define ACQUIRE_ROOTHUB_LOCK(fdo, i) \
  1144. {\
  1145. PDEVICE_EXTENSION de;\
  1146. de = (fdo)->DeviceExtension;\
  1147. LOGENTRY(NULL, (fdo), LOG_MISC, 'Lhub', 0, 0, 0);\
  1148. KeAcquireSpinLock(&de->Fdo.RootHubSpin.sl, &(i));\
  1149. }
  1150. #define RELEASE_ROOTHUB_LOCK(fdo, i) \
  1151. {\
  1152. PDEVICE_EXTENSION de;\
  1153. de = (fdo)->DeviceExtension;\
  1154. LOGENTRY(NULL, (fdo), LOG_MISC, 'Uhub', 0, 0, 0);\
  1155. KeReleaseSpinLock(&de->Fdo.RootHubSpin.sl, (i));\
  1156. }
  1157. #define ACQUIRE_ACTIVE_IRP_LOCK(fdo, de, i) \
  1158. {\
  1159. USBPORT_AcquireSpinLock((fdo), &(de)->Fdo.ActiveTransferIrpSpin, &(i));\
  1160. }
  1161. #define RELEASE_ACTIVE_IRP_LOCK(fdo, de, i) \
  1162. {\
  1163. USBPORT_ReleaseSpinLock((fdo), &(de)->Fdo.ActiveTransferIrpSpin, (i));\
  1164. }
  1165. #define USBPORT_IS_USB20(de)\
  1166. (REGISTRATION_PACKET((de)).OptionFlags & USB_MINIPORT_OPT_USB20)
  1167. #define ACQUIRE_PENDING_IRP_LOCK(de, i) \
  1168. KeAcquireSpinLock(&(de)->Fdo.PendingIrpSpin.sl, &(i))
  1169. #define RELEASE_PENDING_IRP_LOCK(de, i) \
  1170. KeReleaseSpinLock(&(de)->Fdo.PendingIrpSpin.sl, (i))
  1171. #define USBPORT_ACQUIRE_DM_LOCK(de, i) \
  1172. KeAcquireSpinLock(&(de)->Fdo.DM_TimerSpin.sl, &(i))
  1173. #define USBPORT_RELEASE_DM_LOCK(de, i) \
  1174. KeReleaseSpinLock(&(de)->Fdo.DM_TimerSpin.sl, (i))
  1175. //#define USBPORT_ACQUIRE_DM_LOCK(de, i) \
  1176. // KeAcquireSpinLock(&(de)->Fdo.DM_TimerSpin.sl, &(i));
  1177. //
  1178. //#define USBPORT_RELEASE_DM_LOCK(de, i) \
  1179. // KeReleaseSpinLock(&(de)->Fdo.DM_TimerSpin.sl, (i));
  1180. #define IS_ON_ATTEND_LIST(ep) \
  1181. (BOOLEAN) ((ep)->AttendLink.Flink != NULL \
  1182. && (ep)->AttendLink.Blink != NULL)
  1183. //
  1184. // Macros to set transfer direction flag
  1185. //
  1186. #define USBPORT_SET_TRANSFER_DIRECTION_IN(tf) ((tf) |= USBD_TRANSFER_DIRECTION_IN)
  1187. #define USBPORT_SET_TRANSFER_DIRECTION_OUT(tf) ((tf) &= ~USBD_TRANSFER_DIRECTION_IN)
  1188. //
  1189. // Flags for the URB header flags field used by port
  1190. //
  1191. #define USBPORT_REQUEST_IS_TRANSFER 0x00000001
  1192. #define USBPORT_REQUEST_MDL_ALLOCATED 0x00000002
  1193. #define USBPORT_REQUEST_USES_DEFAULT_PIPE 0x00000004
  1194. #define USBPORT_REQUEST_NO_DATA_PHASE 0x00000008
  1195. #define USBPORT_RESET_DATA_TOGGLE 0x00000010
  1196. #define USBPORT_TRANSFER_ALLOCATED 0x00000020
  1197. // defined in USB100.h
  1198. #if 0
  1199. //
  1200. // Values for the bmRequest field
  1201. //
  1202. //bmRequest.Dir
  1203. #define BMREQUEST_HOST_TO_DEVICE 0
  1204. #define BMREQUEST_DEVICE_TO_HOST 1
  1205. //bmRequest.Type
  1206. #define BMREQUEST_STANDARD 0
  1207. #define BMREQUEST_CLASS 1
  1208. #define BMREQUEST_VENDOR 2
  1209. //bmRequest.Recipient
  1210. #define BMREQUEST_TO_DEVICE 0
  1211. #define BMREQUEST_TO_INTERFACE 1
  1212. #define BMREQUEST_TO_ENDPOINT 2
  1213. #define BMREQUEST_TO_OTHER 3
  1214. typedef union _BM_REQUEST_TYPE {
  1215. struct _BM {
  1216. UCHAR Recipient:2;
  1217. UCHAR Reserved:3;
  1218. UCHAR Type:2;
  1219. UCHAR Dir:1;
  1220. };
  1221. UCHAR B;
  1222. } BM_REQUEST_TYPE, *PBM_REQUEST_TYPE;
  1223. typedef struct _USB_DEFAULT_PIPE_SETUP_PACKET {
  1224. BM_REQUEST_TYPE bmRequestType;
  1225. UCHAR bRequest;
  1226. union _wValue {
  1227. struct {
  1228. UCHAR lowPart;
  1229. UCHAR hiPart;
  1230. };
  1231. USHORT W;
  1232. } wValue;
  1233. USHORT wIndex;
  1234. USHORT wLength;
  1235. } USB_DEFAULT_PIPE_SETUP_PACKET, *PUSB_DEFAULT_PIPE_SETUP_PACKET;
  1236. // setup packet is eight bytes -- defined by spec
  1237. C_ASSERT(sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) == 8);
  1238. #endif
  1239. #define USBPORT_INIT_SETUP_PACKET(s, brequest, \
  1240. direction, recipient, typ, wvalue, windex, wlength) \
  1241. {\
  1242. (s).bRequest = (brequest);\
  1243. (s).bmRequestType.Dir = (direction);\
  1244. (s).bmRequestType.Type = (typ);\
  1245. (s).bmRequestType.Recipient = (recipient);\
  1246. (s).bmRequestType.Reserved = 0;\
  1247. (s).wValue.W = (wvalue);\
  1248. (s).wIndex.W = (windex);\
  1249. (s).wLength = (wlength);\
  1250. }
  1251. // ************************************************
  1252. // miniport callout Macros to CORE FUNCTIONS
  1253. // ************************************************
  1254. #define REGISTRATION_PACKET(de) \
  1255. ((de)->Fdo.MiniportDriver->RegistrationPacket)
  1256. //xxxjd
  1257. //#define MP_GetEndpointState(de, ep, state) \
  1258. // {\
  1259. // KIRQL irql;\
  1260. // USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1261. // RegistrationPacket.MINIPORT_GetEndpointState != NULL); \
  1262. // USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1263. // (state) = \
  1264. // (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_GetEndpointState(\
  1265. // (de)->Fdo.MiniportDeviceData,\
  1266. // &(ep)->MiniportEndpointData[0]);\
  1267. // USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1268. // }
  1269. #define MP_GetEndpointStatus(de, ep, status) \
  1270. {\
  1271. KIRQL irql;\
  1272. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1273. RegistrationPacket.MINIPORT_GetEndpointStatus != NULL); \
  1274. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1275. (status) = \
  1276. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_GetEndpointStatus(\
  1277. (de)->Fdo.MiniportDeviceData,\
  1278. &(ep)->MiniportEndpointData[0]);\
  1279. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1280. }
  1281. #define MP_SetEndpointState(de, ep, state) \
  1282. {\
  1283. KIRQL irql;\
  1284. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1285. RegistrationPacket.MINIPORT_SetEndpointState != NULL); \
  1286. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1287. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SetEndpointState(\
  1288. (de)->Fdo.MiniportDeviceData,\
  1289. &(ep)->MiniportEndpointData[0],\
  1290. (state));\
  1291. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1292. }
  1293. #define MP_SetEndpointStatus(de, ep, status) \
  1294. {\
  1295. KIRQL irql;\
  1296. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1297. RegistrationPacket.MINIPORT_SetEndpointState != NULL); \
  1298. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1299. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SetEndpointStatus(\
  1300. (de)->Fdo.MiniportDeviceData,\
  1301. &(ep)->MiniportEndpointData[0],\
  1302. (status));\
  1303. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1304. }
  1305. #define MP_SetEndpointDataToggle(de, ep, t) \
  1306. {\
  1307. KIRQL irql;\
  1308. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1309. RegistrationPacket.MINIPORT_SetEndpointDataToggle != NULL); \
  1310. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1311. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SetEndpointDataToggle(\
  1312. (de)->Fdo.MiniportDeviceData,\
  1313. &(ep)->MiniportEndpointData[0],\
  1314. (t));\
  1315. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1316. }
  1317. #define MP_PollEndpoint(de, ep) \
  1318. {\
  1319. KIRQL irql;\
  1320. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1321. RegistrationPacket.MINIPORT_PollEndpoint != NULL); \
  1322. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1323. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PollEndpoint(\
  1324. (de)->Fdo.MiniportDeviceData,\
  1325. &(ep)->MiniportEndpointData[0]);\
  1326. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1327. }
  1328. #define MP_OpenEndpoint(de, ep, mpStatus) \
  1329. {\
  1330. KIRQL irql;\
  1331. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1332. RegistrationPacket.MINIPORT_OpenEndpoint != NULL); \
  1333. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1334. (mpStatus) = \
  1335. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_OpenEndpoint(\
  1336. (de)->Fdo.MiniportDeviceData,\
  1337. &(ep)->Parameters,\
  1338. &(ep)->MiniportEndpointData[0]);\
  1339. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1340. }
  1341. #define MP_RebalanceEndpoint(de, ep) \
  1342. {\
  1343. KIRQL irql;\
  1344. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1345. RegistrationPacket.MINIPORT_RebalanceEndpoint != NULL); \
  1346. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1347. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RebalanceEndpoint(\
  1348. (de)->Fdo.MiniportDeviceData,\
  1349. &(ep)->Parameters,\
  1350. &(ep)->MiniportEndpointData[0]);\
  1351. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1352. }
  1353. #define MP_CloseEndpoint(de, ep) \
  1354. {\
  1355. KIRQL irql;\
  1356. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1357. RegistrationPacket.MINIPORT_OpenEndpoint != NULL); \
  1358. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1359. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_CloseEndpoint(\
  1360. (de)->Fdo.MiniportDeviceData,\
  1361. &(ep)->MiniportEndpointData[0]);\
  1362. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1363. }
  1364. #define MP_PokeEndpoint(de, ep, mpStatus) \
  1365. {\
  1366. KIRQL irql;\
  1367. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1368. RegistrationPacket.MINIPORT_PokeEndpoint != NULL); \
  1369. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1370. (mpStatus) = \
  1371. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PokeEndpoint(\
  1372. (de)->Fdo.MiniportDeviceData,\
  1373. &(ep)->Parameters,\
  1374. &(ep)->MiniportEndpointData[0]);\
  1375. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1376. }
  1377. #define MP_InterruptNextSOF(de) \
  1378. {\
  1379. KIRQL irql;\
  1380. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1381. RegistrationPacket.MINIPORT_InterruptNextSOF != NULL); \
  1382. LOGENTRY(NULL, (de)->HcFdoDeviceObject, LOG_MISC, 'rSOF', 0, 0, 0);\
  1383. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1384. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_InterruptNextSOF(\
  1385. (de)->Fdo.MiniportDeviceData);\
  1386. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1387. }
  1388. #define MP_Get32BitFrameNumber(de, f) \
  1389. {\
  1390. KIRQL irql;\
  1391. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1392. RegistrationPacket.MINIPORT_Get32BitFrameNumber != NULL); \
  1393. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1394. (f) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_Get32BitFrameNumber(\
  1395. (de)->Fdo.MiniportDeviceData);\
  1396. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1397. }
  1398. MINIPORT_SubmitTransfer(
  1399. PDEVICE_DATA DeviceData,
  1400. PENDPOINT_DATA EndpointData,
  1401. PTRANSFER_PARAMETERS TransferParameters,
  1402. PTRANSFER_CONTEXT TransferContext,
  1403. PTRANSFER_SG_LIST TransferSGList
  1404. );
  1405. #define MP_SubmitTransfer(de, ep, t, mpStatus) \
  1406. {\
  1407. KIRQL irql;\
  1408. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1409. RegistrationPacket.MINIPORT_SubmitTransfer != NULL); \
  1410. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1411. (mpStatus) = \
  1412. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SubmitTransfer(\
  1413. (de)->Fdo.MiniportDeviceData,\
  1414. &(ep)->MiniportEndpointData[0],\
  1415. &(t)->Tp,\
  1416. (t)->MiniportContext,\
  1417. &(t)->SgList);\
  1418. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1419. }
  1420. #define MP_SubmitIsoTransfer(de, ep, t, mpStatus) \
  1421. {\
  1422. KIRQL irql;\
  1423. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1424. RegistrationPacket.MINIPORT_SubmitIsoTransfer != NULL); \
  1425. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1426. (mpStatus) = \
  1427. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SubmitIsoTransfer(\
  1428. (de)->Fdo.MiniportDeviceData,\
  1429. &(ep)->MiniportEndpointData[0],\
  1430. &(t)->Tp,\
  1431. (t)->MiniportContext,\
  1432. (t)->IsoTransfer);\
  1433. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1434. }
  1435. #define MP_AbortTransfer(de, ep, t, b) \
  1436. {\
  1437. KIRQL irql;\
  1438. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1439. RegistrationPacket.MINIPORT_AbortTransfer != NULL); \
  1440. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1441. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_AbortTransfer(\
  1442. (de)->Fdo.MiniportDeviceData,\
  1443. &(ep)->MiniportEndpointData[0],\
  1444. (t)->MiniportContext,\
  1445. &(b));\
  1446. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1447. }
  1448. #define MP_QueryEndpointRequirements(de, ep, r) \
  1449. {\
  1450. KIRQL irql;\
  1451. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1452. RegistrationPacket.MINIPORT_QueryEndpointRequirements != NULL); \
  1453. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1454. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_QueryEndpointRequirements(\
  1455. (de)->Fdo.MiniportDeviceData,\
  1456. &(ep)->Parameters,\
  1457. (r));\
  1458. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1459. }
  1460. #define MP_InterruptDpc(de, e) {\
  1461. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1462. RegistrationPacket.MINIPORT_InterruptDpc != NULL); \
  1463. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_InterruptDpc(\
  1464. (de)->Fdo.MiniportDeviceData, \
  1465. (e));\
  1466. }
  1467. #define MP_StartSendOnePacket(de, p, mpd, mpl, vaddr, phys, len, u, mpStatus) \
  1468. {\
  1469. KIRQL irql;\
  1470. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1471. RegistrationPacket.MINIPORT_StartSendOnePacket != NULL); \
  1472. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1473. mpStatus = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_StartSendOnePacket(\
  1474. (de)->Fdo.MiniportDeviceData,\
  1475. (p),\
  1476. (mpd),\
  1477. (mpl),\
  1478. (vaddr),\
  1479. (phys),\
  1480. (len),\
  1481. (u));\
  1482. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1483. }
  1484. #define MP_EndSendOnePacket(de,p, mpd, mpl, vaddr, phys, len, u, mpStatus) \
  1485. {\
  1486. KIRQL irql;\
  1487. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1488. RegistrationPacket.MINIPORT_EndSendOnePacket != NULL); \
  1489. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1490. mpStatus = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_EndSendOnePacket(\
  1491. (de)->Fdo.MiniportDeviceData,\
  1492. (p),\
  1493. (mpd),\
  1494. (mpl),\
  1495. (vaddr),\
  1496. (phys),\
  1497. (len),\
  1498. (u));\
  1499. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1500. }
  1501. #define MP_PollController(de) \
  1502. {\
  1503. KIRQL irql;\
  1504. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1505. RegistrationPacket.MINIPORT_PollController != NULL); \
  1506. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1507. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PollController(\
  1508. (de)->Fdo.MiniportDeviceData);\
  1509. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1510. }
  1511. #define MP_CheckController(de) \
  1512. do {\
  1513. KIRQL irql;\
  1514. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1515. if (!TEST_FDO_FLAG((de), USBPORT_FDOFLAG_CONTROLLER_GONE) && \
  1516. !TEST_FDO_FLAG((de), USBPORT_FDOFLAG_SUSPENDED) && \
  1517. !TEST_FDO_FLAG((de), USBPORT_FDOFLAG_OFF)) {\
  1518. LOGENTRY(NULL, (de)->HcFdoDeviceObject, LOG_MISC, 'chkC', \
  1519. (de)->HcFdoDeviceObject, (de)->Fdo.FdoFlags, 0);\
  1520. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1521. RegistrationPacket.MINIPORT_CheckController != NULL); \
  1522. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_CheckController(\
  1523. (de)->Fdo.MiniportDeviceData);\
  1524. }\
  1525. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1526. } while (0)
  1527. #define MP_ResetController(de) \
  1528. do {\
  1529. KIRQL irql;\
  1530. USBPORT_AcquireSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, &irql);\
  1531. LOGENTRY(NULL, (de)->HcFdoDeviceObject, LOG_MISC, 'rset', \
  1532. (de)->HcFdoDeviceObject, (de)->Fdo.FdoFlags, 0);\
  1533. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1534. RegistrationPacket.MINIPORT_ResetController != NULL); \
  1535. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_ResetController(\
  1536. (de)->Fdo.MiniportDeviceData);\
  1537. USBPORT_ReleaseSpinLock((de)->HcFdoDeviceObject, &(de)->Fdo.CoreFunctionSpin, irql);\
  1538. } while (0)
  1539. // *************************************************
  1540. // miniport callout Macros to NON CORE FUNCTIONS
  1541. // *************************************************
  1542. #define MP_StopController(de, hw) \
  1543. {\
  1544. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1545. RegistrationPacket.MINIPORT_StopController != NULL);\
  1546. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_StopController(\
  1547. (de)->Fdo.MiniportDeviceData,\
  1548. (hw));\
  1549. }
  1550. #define MP_StartController(de, r, mpStatus) \
  1551. {\
  1552. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1553. RegistrationPacket.MINIPORT_StartController != NULL);\
  1554. (mpStatus) = \
  1555. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_StartController(\
  1556. (de)->Fdo.MiniportDeviceData,\
  1557. (r));\
  1558. }
  1559. #define MP_SuspendController(de) \
  1560. {\
  1561. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1562. RegistrationPacket.MINIPORT_SuspendController != NULL);\
  1563. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_SuspendController(\
  1564. (de)->Fdo.MiniportDeviceData);\
  1565. }
  1566. #define MP_ResumeController(de, s) \
  1567. {\
  1568. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1569. RegistrationPacket.MINIPORT_ResumeController != NULL);\
  1570. (s) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_ResumeController(\
  1571. (de)->Fdo.MiniportDeviceData);\
  1572. }
  1573. #define MP_DisableInterrupts(fdo, de) \
  1574. do {\
  1575. KIRQL iql;\
  1576. BOOLEAN sync = TRUE;\
  1577. if (REGISTRATION_PACKET(de).OptionFlags & USB_MINIPORT_OPT_NO_IRQ_SYNC) {\
  1578. sync = FALSE;}\
  1579. if (sync) {KeAcquireSpinLock(&(de)->Fdo.IsrDpcSpin.sl, &iql);}\
  1580. LOGENTRY(NULL, (fdo), LOG_MISC, 'irqD', (fdo), 0, 0);\
  1581. REGISTRATION_PACKET((de)).MINIPORT_DisableInterrupts(\
  1582. (de)->Fdo.MiniportDeviceData);\
  1583. CLEAR_FDO_FLAG((de), USBPORT_FDOFLAG_IRQ_EN);\
  1584. if (sync) {KeReleaseSpinLock(&(de)->Fdo.IsrDpcSpin.sl, iql);}\
  1585. } while (0)
  1586. #define MP_EnableInterrupts(de) \
  1587. do {\
  1588. KIRQL iql;\
  1589. BOOLEAN sync = TRUE;\
  1590. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1591. RegistrationPacket.MINIPORT_EnableInterrupts != NULL);\
  1592. if ((REGISTRATION_PACKET(de).OptionFlags & USB_MINIPORT_OPT_NO_IRQ_SYNC)) {\
  1593. sync = FALSE;}\
  1594. if (sync) {KeAcquireSpinLock(&(de)->Fdo.IsrDpcSpin.sl, &iql);}\
  1595. SET_FDO_FLAG((de), USBPORT_FDOFLAG_IRQ_EN);\
  1596. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_EnableInterrupts(\
  1597. (de)->Fdo.MiniportDeviceData);\
  1598. if (sync) {KeReleaseSpinLock(&(de)->Fdo.IsrDpcSpin.sl, iql);}\
  1599. } while (0)
  1600. #define MP_FlushInterrupts(de) \
  1601. do {\
  1602. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1603. RegistrationPacket.MINIPORT_FlushInterrupts != NULL);\
  1604. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_FlushInterrupts(\
  1605. (de)->Fdo.MiniportDeviceData);\
  1606. } while (0)
  1607. // note that take port control and chirp_ports are version 2 specific
  1608. // and we need them for power managemnt to work properly
  1609. #define MP_TakePortControl(de) \
  1610. do {\
  1611. if ((de)->Fdo.MiniportDriver->HciVersion >= USB_MINIPORT_HCI_VERSION_2) {\
  1612. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1613. RegistrationPacket.MINIPORT_TakePortControl != NULL);\
  1614. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_TakePortControl(\
  1615. (de)->Fdo.MiniportDeviceData);\
  1616. };\
  1617. } while (0)
  1618. #define MP_InterruptService(de, usbint) {\
  1619. USBPORT_ASSERT((de)->Fdo.MiniportDriver->\
  1620. RegistrationPacket.MINIPORT_InterruptService != NULL);\
  1621. (usbint) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_InterruptService(\
  1622. (de)->Fdo.MiniportDeviceData);\
  1623. }
  1624. #define MPRH_GetStatus(de, s, mpStatus) \
  1625. (mpStatus) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_GetStatus(\
  1626. (de)->Fdo.MiniportDeviceData,\
  1627. (s))
  1628. #define MPRH_GetPortStatus(de, port, status, mpStatus) \
  1629. (mpStatus) = \
  1630. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_GetPortStatus(\
  1631. (de)->Fdo.MiniportDeviceData,\
  1632. (port),\
  1633. (status))
  1634. #define MPRH_GetHubStatus(de, status, mpStatus) \
  1635. (mpStatus) = \
  1636. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_GetHubStatus(\
  1637. (de)->Fdo.MiniportDeviceData,\
  1638. (status))
  1639. #define MPRH_GetRootHubData(de, data) \
  1640. (de)->Fdo.MiniportDriver->\
  1641. RegistrationPacket.MINIPORT_RH_GetRootHubData(\
  1642. (de)->Fdo.MiniportDeviceData,\
  1643. (data))
  1644. #define MPRH_DisableIrq(de) \
  1645. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_DisableIrq(\
  1646. (de)->Fdo.MiniportDeviceData)
  1647. #define MPRH_EnableIrq(de) \
  1648. (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_RH_EnableIrq(\
  1649. (de)->Fdo.MiniportDeviceData)
  1650. #define MP_PassThru(de, guid, l, data, mpStatus) \
  1651. \
  1652. if ((de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PassThru) { \
  1653. (mpStatus) = (de)->Fdo.MiniportDriver->RegistrationPacket.MINIPORT_PassThru(\
  1654. (de)->Fdo.MiniportDeviceData,\
  1655. (guid),\
  1656. (l),\
  1657. (data)); \
  1658. } \
  1659. else { \
  1660. (mpStatus) = USBMP_STATUS_NOT_SUPPORTED; \
  1661. }
  1662. #define MILLISECONDS_TO_100_NS_UNITS(ms) (((LONG)(ms)) * 10000)
  1663. #define USBPORT_GET_BIT_SET(d, bit) \
  1664. do { \
  1665. UCHAR tmp = (d);\
  1666. (bit)=0; \
  1667. while (!(tmp & 0x01)) {\
  1668. (bit)++;\
  1669. tmp >>= 1;\
  1670. };\
  1671. } while (0)
  1672. #endif /* __USBPORT_H__ */