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.

886 lines
40 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. mini.h
  5. Abstract:
  6. NDIS miniport wrapper definitions
  7. Author:
  8. Environment:
  9. Kernel mode, FSD
  10. Revision History:
  11. Jun-95 Jameel Hyder Split up from a monolithic file
  12. --*/
  13. #ifndef __MINI_H
  14. #define __MINI_H
  15. //
  16. // Macros for setting, clearing, and testing bits in the Miniport Flags.
  17. //
  18. #define MINIPORT_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
  19. #define MINIPORT_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
  20. #define MINIPORT_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
  21. #define MINIPORT_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
  22. /*
  23. #define MINIPORT_SET_FLAG(_M, _F) \
  24. { \
  25. volatile ULONG _OldFlags = (_M)->Flags; \
  26. ((_M)->Flags |= (_F)); \
  27. if (((_M)->Flags ^ _OldFlags) & (~(_F))) \
  28. { \
  29. DbgPrint("_OldFlags %lx, _M->flags %lx, _F %lx\n", _OldFlags, (_M)->Flags, (_F)); \
  30. DbgBreakPoint(); \
  31. } \
  32. }
  33. #define MINIPORT_CLEAR_FLAG(_M, _F) \
  34. { \
  35. volatile ULONG _OldFlags = (_M)->Flags; \
  36. ((_M)->Flags &= ~(_F)); \
  37. if (((_M)->Flags ^ _OldFlags) & (~(_F))) \
  38. { \
  39. DbgPrint("_OldFlags %lx, _M->flags %lx, _F %lx\n", _OldFlags, (_M)->Flags, (_F)); \
  40. DbgBreakPoint(); \
  41. } \
  42. }
  43. */
  44. #define MINIPORT_SET_SEND_FLAG(_M, _F) ((_M)->SendFlags |= (_F))
  45. #define MINIPORT_CLEAR_SEND_FLAG(_M, _F) ((_M)->SendFlags &= ~(_F))
  46. #define MINIPORT_TEST_SEND_FLAG(_M, _F) (((_M)->SendFlags & (_F)) != 0)
  47. #define MINIPORT_PNP_SET_FLAG(_M, _F) ((_M)->PnPFlags |= (_F))
  48. #define MINIPORT_PNP_CLEAR_FLAG(_M, _F) ((_M)->PnPFlags &= ~(_F))
  49. #define MINIPORT_PNP_TEST_FLAG(_M, _F) (((_M)->PnPFlags & (_F)) != 0)
  50. #define MINIPORT_PNP_TEST_FLAGS(_M, _F) (((_M)->PnPFlags & (_F)) == (_F))
  51. #define MINIPORT_VERIFY_SET_FLAG(_M, _F) ((_M)->DriverVerifyFlags |= (_F))
  52. #define MINIPORT_VERIFY_CLEAR_FLAG(_M, _F) ((_M)->DriverVerifyFlags &= ~(_F))
  53. #define MINIPORT_VERIFY_TEST_FLAG(_M, _F) (((_M)->DriverVerifyFlags & (_F)) != 0)
  54. #define MINIPORT_VERIFY_TEST_FLAGS(_M, _F) (((_M)->DriverVerifyFlags & (_F)) == (_F))
  55. #define OPEN_SET_FLAG(_O, _F) ((_O)->Flags |= (_F))
  56. #define OPEN_CLEAR_FLAG(_O, _F) ((_O)->Flags &= ~(_F))
  57. #define OPEN_TEST_FLAG(_O, _F) (((_O)->Flags & (_F)) != 0)
  58. #define OPEN_TEST_FLAGS(_O, _F) (((_O)->Flags & (_F)) == (_F))
  59. //
  60. // Flags for packet information.
  61. //
  62. #define MINIPORT_SET_PACKET_FLAG(_P, _F) ((_P)->Private.NdisPacketFlags |= (_F))
  63. #define MINIPORT_CLEAR_PACKET_FLAG(_P, _F) ((_P)->Private.NdisPacketFlags &= ~(_F))
  64. #define MINIPORT_TEST_PACKET_FLAG(_P, _F) (((_P)->Private.NdisPacketFlags & (_F)) != 0)
  65. //
  66. // Low-bits in the packet flags are reserved by NDIS Wrapper for internal use
  67. //
  68. #if (fPACKET_WRAPPER_RESERVED != 0x3F)
  69. #error (Packet flags overlap)
  70. #endif
  71. #define fPACKET_HAS_TIMED_OUT 0x01
  72. #define fPACKET_IS_LOOPBACK 0x02
  73. #define fPACKET_SELF_DIRECTED 0x04
  74. #define fPACKET_DONT_COMPLETE 0x08
  75. #define fPACKET_PENDING 0x10
  76. #define fPACKET_ALREADY_LOOPEDBACK 0x20
  77. #define fPACKET_CLEAR_ITEMS 0x3F
  78. #define NDIS_STATISTICS_HEADER_SIZE FIELD_OFFSET(NDIS_STATISTICS_VALUE, Data[0])
  79. //
  80. // Timeout values
  81. //
  82. #define NDIS_MINIPORT_WAKEUP_TIMEOUT 2000 // Wakeup DPC
  83. #define NDIS_MINIPORT_DEFERRED_TIMEOUT 15 // Deferred timer
  84. #define NDIS_MINIPORT_TR_RESET_TIMEOUT 15 // Number of WakeUps per reset attempt
  85. #define NDIS_CFHANG_TIME_SECONDS 2
  86. #define NDISWAN_OPTIONS (NDIS_MAC_OPTION_RESERVED | NDIS_MAC_OPTION_NDISWAN)
  87. #define NDIS_MINIPORT_DISCONNECT_TIMEOUT 20 // 20 seconds
  88. #define INTERNAL_INDICATION_SIZE (UINT)-2
  89. #define INTERNAL_INDICATION_BUFFER (PVOID)-1
  90. #define NDIS_M_MAX_MULTI_LIST 32
  91. typedef struct _NDIS_PENDING_IM_INSTANCE NDIS_PENDING_IM_INSTANCE, *PNDIS_PENDING_IM_INSTANCE;
  92. typedef struct _NDIS_PENDING_IM_INSTANCE
  93. {
  94. PNDIS_PENDING_IM_INSTANCE Next;
  95. NDIS_HANDLE Context;
  96. UNICODE_STRING Name;
  97. } NDIS_PENDING_IM_INSTANCE, *PNDIS_PENDING_IM_INSTANCE;
  98. typedef struct _NDIS_POST_OPEN_PROCESSING
  99. {
  100. PNDIS_OPEN_BLOCK Open;
  101. WORK_QUEUE_ITEM WorkItem;
  102. } NDIS_POST_OPEN_PROCESSING, *PNDIS_POST_OPEN_PROCESSING;
  103. //
  104. // one of these per Driver
  105. //
  106. struct _NDIS_M_DRIVER_BLOCK
  107. {
  108. PNDIS_M_DRIVER_BLOCK NextDriver;
  109. PNDIS_MINIPORT_BLOCK MiniportQueue; // queue of mini-ports for this driver
  110. PNDIS_WRAPPER_HANDLE NdisDriverInfo; // Driver information.
  111. PNDIS_PROTOCOL_BLOCK AssociatedProtocol; // For IM drivers
  112. LIST_ENTRY DeviceList;
  113. PNDIS_PENDING_IM_INSTANCE PendingDeviceList;
  114. PDRIVER_UNLOAD UnloadHandler;
  115. // of this NDIS_DRIVER_BLOCK structure
  116. NDIS51_MINIPORT_CHARACTERISTICS MiniportCharacteristics; // handler addresses
  117. KEVENT MiniportsRemovedEvent;// used to find when all mini-ports are gone.
  118. REFERENCE Ref; // contains spinlock for MiniportQueue
  119. USHORT Flags;
  120. KMUTEX IMStartRemoveMutex; // Synchronizes call to IMInitDevInstance and PnpRemove
  121. ULONG DriverVersion;
  122. };
  123. #define fMINIBLOCK_INTERMEDIATE_DRIVER 0x0001
  124. #define fMINIBLOCK_VERIFYING 0x0002
  125. #define fMINIBLOCK_RECEIVED_TERMINATE_WRAPPER 0x0004
  126. #define fMINIBLOCK_IO_UNLOAD 0x0008
  127. #define fMINIBLOCK_TERMINATE_WRAPPER_UNLOAD 0x0010
  128. #define fMINIBLOCK_UNLOADING 0x8000
  129. #define ndisMDereferenceOpen(_Open) \
  130. { \
  131. UINT _OpenRef; \
  132. DBGPRINT(DBG_COMP_OPENREF, DBG_LEVEL_INFO, \
  133. ("- Open 0x%x Reference 0x%x\n", \
  134. _Open, (_Open)->References)); \
  135. \
  136. M_OPEN_DECREMENT_REF_INTERLOCKED(_Open, _OpenRef); \
  137. \
  138. DBGPRINT(DBG_COMP_OPENREF, DBG_LEVEL_INFO, \
  139. ("==0 Open 0x%x Reference 0x%x\n", \
  140. _Open, _OpenRef)); \
  141. \
  142. if (_OpenRef == 0) \
  143. { \
  144. ndisMFinishClose(_Open); \
  145. } \
  146. }
  147. //
  148. // Flags definition for NDIS_OPEN_BLOCK.
  149. //
  150. #define fMINIPORT_OPEN_USING_ETH_ENCAPSULATION 0x00000001
  151. #define fMINIPORT_OPEN_NO_LOOPBACK 0x00000002
  152. #define fMINIPORT_OPEN_PMODE 0x00000004
  153. #define fMINIPORT_OPEN_NO_PROT_RSVD 0x00000008
  154. #define fMINIPORT_OPEN_PROCESSING 0x00000010
  155. #define fMINIPORT_PACKET_RECEIVED 0x00000080
  156. #define fMINIPORT_STATUS_RECEIVED 0x00000100
  157. #define fMINIPORT_OPEN_CLOSING 0x00008000
  158. #define fMINIPORT_OPEN_UNBINDING 0x00010000
  159. #define fMINIPORT_OPEN_CALL_MANAGER 0x00020000
  160. #define fMINIPORT_OPEN_CLIENT 0x00040000
  161. #define fMINIPORT_OPEN_NOTIFY_PROCESSING 0x00080000
  162. #define fMINIPORT_OPEN_CLOSE_COMPLETE 0x00100000
  163. #define fMINIPORT_OPEN_DONT_FREE 0x00200000
  164. #define fMINIPORT_OPEN_NO_BIND_REQUEST 0x00400000
  165. //
  166. // Definitions for NDIS_MINIPORT_BLOCK GeneralFlags.
  167. //
  168. #define fMINIPORT_NORMAL_INTERRUPTS 0x00000001
  169. #define fMINIPORT_IN_INITIALIZE 0x00000002
  170. #define fMINIPORT_ARCNET_BROADCAST_SET 0x00000004
  171. #define fMINIPORT_BUS_MASTER 0x00000008
  172. #define fMINIPORT_64BITS_DMA 0x00000010
  173. #define fMINIPORT_DEREGISTERED_INTERRUPT 0x00000020
  174. #define fMINIPORT_SG_LIST 0x00000040
  175. #define fMINIPORT_REQUEST_TIMEOUT 0x00000100
  176. #define fMINIPORT_PROCESSING_REQUEST 0x00000400
  177. #define fMINIPORT_IGNORE_PACKET_QUEUE 0x00000800
  178. #define fMINIPORT_IGNORE_REQUEST_QUEUE 0x00001000
  179. #define fMINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00002000
  180. #define fMINIPORT_CHECK_FOR_LOOPBACK 0x00004000
  181. #define fMINIPORT_INTERMEDIATE_DRIVER 0x00008000
  182. #define fMINIPORT_IS_NDIS_5 0x00010000
  183. #define fMINIPORT_IS_CO 0x00020000
  184. #define fMINIPORT_DESERIALIZE 0x00040000
  185. #define fMINIPORT_CALLING_RESET 0x00080000
  186. #define fMINIPORT_RESET_REQUESTED 0x00100000
  187. #define fMINIPORT_RESET_IN_PROGRESS 0x00200000
  188. #define fMINIPORT_RESOURCES_AVAILABLE 0x00400000
  189. #define fMINIPORT_SEND_LOOPBACK_DIRECTED 0x00800000
  190. #define fMINIPORT_RESTORING_FILTERS 0x01000000
  191. #define fMINIPORT_REQUIRES_MEDIA_POLLING 0x02000000
  192. #define fMINIPORT_SUPPORTS_MEDIA_SENSE 0x04000000
  193. #define fMINIPORT_DOES_NOT_DO_LOOPBACK 0x08000000
  194. #define fMINIPORT_SECONDARY 0x10000000
  195. #define fMINIPORT_MEDIA_CONNECTED 0x20000000
  196. #define fMINIPORT_NETBOOT_CARD 0x40000000
  197. #define fMINIPORT_PM_HALTING 0x80000000
  198. #define MINIPORT_LOCK_ACQUIRED(_Miniport) ((_Miniport)->LockAcquired & 0x01)
  199. #define MINIPORT_AT_DPC_LEVEL (CURRENT_IRQL == DISPATCH_LEVEL)
  200. #define ASSERT_MINIPORT_LOCKED(_Miniport) \
  201. if (!MINIPORT_TEST_FLAG(_Miniport, fMINIPORT_DESERIALIZE)) \
  202. { \
  203. ASSERT(MINIPORT_LOCK_ACQUIRED(_Miniport)); \
  204. ASSERT(MINIPORT_AT_DPC_LEVEL); \
  205. }
  206. //
  207. // Send flags
  208. //
  209. #define fMINIPORT_SEND_PACKET_ARRAY 0x01
  210. #define fMINIPORT_SEND_DO_NOT_MAP_MDLS 0x02
  211. //
  212. // Flags used in PnPFlags
  213. //
  214. #define fMINIPORT_PM_SUPPORTED 0x00000001
  215. #define fMINIPORT_NO_SHUTDOWN 0x00000004
  216. #define fMINIPORT_MEDIA_DISCONNECT_WAIT 0x00000008
  217. #define fMINIPORT_REMOVE_IN_PROGRESS 0x00000010
  218. #define fMINIPORT_DEVICE_POWER_ENABLE 0x00000020
  219. #define fMINIPORT_DEVICE_POWER_WAKE_ENABLE 0x00000040
  220. #define fMINIPORT_DEVICE_FAILED 0x00000100
  221. #define fMINIPORT_MEDIA_DISCONNECT_CANCELLED 0x00000200
  222. #define fMINIPORT_SEND_WAIT_WAKE 0x00000400
  223. #define fMINIPORT_SYSTEM_SLEEPING 0x00000800
  224. #define fMINIPORT_HIDDEN 0x00001000
  225. #define fMINIPORT_SWENUM 0x00002000
  226. #define fMINIPORT_PM_HALTED 0x00004000
  227. #define fMINIPORT_NO_HALT_ON_SUSPEND 0x00008000
  228. #define fMINIPORT_RECEIVED_START 0x00010000
  229. #define fMINIPORT_REJECT_REQUESTS 0x00020000
  230. #define fMINIPORT_PROCESSING 0x00040000
  231. #define fMINIPORT_HALTING 0x00080000
  232. #define fMINIPORT_VERIFYING 0x00100000
  233. #define fMINIPORT_HARDWARE_DEVICE 0x00200000
  234. #define fMINIPORT_NDIS_WDM_DRIVER 0x00400000
  235. #define fMINIPORT_SHUT_DOWN 0x00800000
  236. #define fMINIPORT_SHUTTING_DOWN 0x01000000
  237. #define fMINIPORT_ORPHANED 0x02000000
  238. #define fMINIPORT_QUEUED_BIND_WORKITEM 0x04000000
  239. #define fMINIPORT_FILTER_IM 0x08000000
  240. #define fMINIPORT_MEDIA_DISCONNECT_INDICATED 0x10000000
  241. #define fMINIPORT_CANCEL_WAKE_UP_TIMER 0x20000000
  242. #if NDIS_RECV_SCALE
  243. #define fMINIPORT_SUPPORTS_RECEIVE_SCALE 0x40000000
  244. #endif
  245. //
  246. // flags used in DriverVerifyFlags
  247. //
  248. #define fMINIPORT_VERIFY_FAIL_MAP_REG_ALLOC 0x00000001
  249. #define fMINIPORT_VERIFY_FAIL_INTERRUPT_REGISTER 0x00000002
  250. #define fMINIPORT_VERIFY_FAIL_SHARED_MEM_ALLOC 0x00000004
  251. #define fMINIPORT_VERIFY_FAIL_CANCEL_TIMER 0x00000008
  252. #define fMINIPORT_VERIFY_FAIL_MAP_IO_SPACE 0x00000010
  253. #define fMINIPORT_VERIFY_FAIL_REGISTER_IO 0x00000020
  254. #define fMINIPORT_VERIFY_FAIL_READ_CONFIG_SPACE 0x00000040
  255. #define fMINIPORT_VERIFY_FAIL_WRITE_CONFIG_SPACE 0x00000080
  256. #define fMINIPORT_VERIFY_FAIL_INIT_SG 0x00000100
  257. //
  258. // flags used in XState field to show why we have set handlers to fake ones
  259. //
  260. #define fMINIPORT_STATE_RESETTING 0x01
  261. #define fMINIPORT_STATE_MEDIA_DISCONNECTED 0x02
  262. #define fMINIPORT_STATE_PM_STOPPED 0x04
  263. //
  264. // The following defines the NDIS usage of the PacketStack->NdisReserved area. It has different semantics
  265. // for send and receive
  266. //
  267. #define NUM_PACKET_STACKS 2 // Default, registry configurable
  268. typedef struct _NDIS_STACK_RESERVED
  269. {
  270. union
  271. {
  272. struct _SEND_STACK_RESERVED
  273. {
  274. PNDIS_OPEN_BLOCK Open; // Tracks who the packet owner is - only for de-serialized drivers
  275. PNDIS_CO_VC_PTR_BLOCK VcPtr; // For CO miniports, identifies the VC
  276. };
  277. struct _RECV_STACK_RESERVED
  278. {
  279. union
  280. {
  281. PNDIS_MINIPORT_BLOCK Miniport; // Identifies the miniport (IM) that indicated the packet
  282. PNDIS_PACKET NextPacket; // In the return-packet queue
  283. };
  284. union // Keeps track of ref-counts
  285. {
  286. struct
  287. {
  288. LONG RefCount;
  289. LONG XRefCount;
  290. };
  291. ULONG RefUlong;
  292. };
  293. };
  294. struct _XFER_DATA_STACK_RESERVED
  295. {
  296. PNDIS_OPEN_BLOCK Opens[3];
  297. };
  298. };
  299. KSPIN_LOCK Lock;
  300. } NDIS_STACK_RESERVED, *PNDIS_STACK_RESERVED;
  301. #define NDIS_STACK_RESERVED_FROM_PACKET(_P, _NSR) \
  302. { \
  303. PNDIS_PACKET_STACK _Stack; \
  304. \
  305. GET_CURRENT_PACKET_STACK((_P), &_Stack); \
  306. ASSERT(_Stack != NULL); \
  307. *(_NSR) = (PNDIS_STACK_RESERVED)(_Stack->NdisReserved); \
  308. }
  309. #define NDIS_XFER_DATA_STACK_RESERVED_FROM_PACKET(_P, _NSR_OPENS) \
  310. { \
  311. \
  312. GET_CURRENT_XFER_DATA_PACKET_STACK((_P), &_NSR_OPENS); \
  313. ASSERT(_NSR_OPENS != NULL); \
  314. }
  315. typedef struct _NDIS_LOOPBACK_REF
  316. {
  317. PNDIS_OPEN_BLOCK Open;
  318. PNDIS_PACKET NextLoopbackPacket;
  319. } NDIS_LB_REF, *PNDIS_LB_REF;
  320. #define PNDIS_LB_REF_FROM_PNDIS_PACKET(_P) ((PNDIS_LB_REF)((_P)->MiniportReserved))
  321. #define LOOPBACK_OPEN_IN_PACKET(_P) PNDIS_LB_REF_FROM_PNDIS_PACKET(_P)->Open
  322. #define SET_LOOPBACK_OPEN_IN_PACKET(_P, _O) LOOPBACK_OPEN_IN_PACKET(_P) = (_O)
  323. #define LOOPBACK_LINKAGE(_P) PNDIS_LB_REF_FROM_PNDIS_PACKET(_P)->NextLoopbackPacket
  324. //
  325. // PnP Event reserved information for NDIS.
  326. //
  327. typedef struct _NDIS_PNP_EVENT_RESERVED
  328. {
  329. PKEVENT pEvent;
  330. NDIS_STATUS Status;
  331. NDIS_HANDLE Open;
  332. } NDIS_PNP_EVENT_RESERVED, *PNDIS_PNP_EVENT_RESERVED;
  333. #define PNDIS_PNP_EVENT_RESERVED_FROM_NET_PNP_EVENT(x) ((PNDIS_PNP_EVENT_RESERVED)(x)->NdisReserved)
  334. #define NDISM_QUEUE_WORK_ITEM(_M, _WT, _WC) ndisMQueueWorkItem(_M, _WT, _WC)
  335. #define NDISM_QUEUE_NEW_WORK_ITEM(_M, _WT, _WC, _WH) ndisMQueueNewWorkItem(_M, _WT, _WC, _WH)
  336. #define NDISM_DEQUEUE_WORK_ITEM(_M, _WT, _pWC) ndisMDeQueueWorkItem(_M, _WT, _pWC, NULL)
  337. #define NDISM_DEQUEUE_WORK_ITEM_WITH_HANDLER(_M, _WT, _pWC, _pWH) \
  338. ndisMDeQueueWorkItem(_M, _WT, _pWC, _pWH)
  339. #define NDISM_PROCESS_DEFERRED(_M) ndisMProcessDeferred(_M)
  340. #define MINIPORT_ENABLE_INTERRUPT(_M_) \
  341. { \
  342. if ((_M_)->EnableInterruptHandler != NULL) \
  343. { \
  344. ((_M_)->EnableInterruptHandler)((_M_)->MiniportAdapterContext); \
  345. } \
  346. }
  347. #define MINIPORT_SYNC_ENABLE_INTERRUPT(_M_) \
  348. { \
  349. if (((_M_)->Interrupt != NULL) && \
  350. ((_M_)->EnableInterruptHandler != NULL)) \
  351. { \
  352. SYNC_WITH_ISR(((_M_))->Interrupt->InterruptObject, \
  353. ((_M_)->EnableInterruptHandler), \
  354. (_M_)->MiniportAdapterContext); \
  355. } \
  356. }
  357. #define MINIPORT_DISABLE_INTERRUPT(_M_) \
  358. { \
  359. ASSERT((_M_)->DisableInterruptHandler != NULL); \
  360. ((_M_)->DriverHandle->MiniportCharacteristics.DisableInterruptHandler)( \
  361. (_M_)->MiniportAdapterContext); \
  362. }
  363. #define MINIPORT_SYNC_DISABLE_INTERRUPT(_M_) \
  364. { \
  365. if (((_M_)->Interrupt != NULL) && \
  366. ((_M_)->DisableInterruptHandler != NULL)) \
  367. { \
  368. SYNC_WITH_ISR(((_M_))->Interrupt->InterruptObject, \
  369. ((_M_)->DisableInterruptHandler), \
  370. (_M_)->MiniportAdapterContext); \
  371. } \
  372. }
  373. #define MINIPORT_ENABLE_INTERRUPT_EX(_M_, _I_) \
  374. { \
  375. if ((_M_)->EnableInterruptHandler != NULL) \
  376. { \
  377. ((_M_)->EnableInterruptHandler)((_I_)->Reserved); \
  378. } \
  379. }
  380. #define MINIPORT_SYNC_ENABLE_INTERRUPT_EX(_M_, _I_) \
  381. { \
  382. if (((_M_)->Interrupt != NULL) && \
  383. ((_M_)->EnableInterruptHandler != NULL)) \
  384. { \
  385. SYNC_WITH_ISR(((_I_))->InterruptObject, \
  386. ((_M_)->EnableInterruptHandler), \
  387. (_I_)->Reserved); \
  388. } \
  389. }
  390. #define MINIPORT_DISABLE_INTERRUPT_EX(_M_, _I_) \
  391. { \
  392. ASSERT((_M_)->DisableInterruptHandler != NULL); \
  393. ((_M_)->DriverHandle->MiniportCharacteristics.DisableInterruptHandler)( \
  394. (_I_)->Reserved); \
  395. }
  396. #define MINIPORT_SYNC_DISABLE_INTERRUPT_EX(_M_, _I_) \
  397. { \
  398. if (((_M_)->Interrupt != NULL) && \
  399. ((_M_)->DisableInterruptHandler != NULL)) \
  400. { \
  401. SYNC_WITH_ISR(((_I_))->InterruptObject, \
  402. ((_M_)->DisableInterruptHandler), \
  403. (_I_)->Reserved); \
  404. } \
  405. }
  406. #define CHECK_FOR_NORMAL_INTERRUPTS(_M_) \
  407. if (((_M_)->Interrupt != NULL) && \
  408. !(_M_)->Interrupt->IsrRequested && \
  409. !(_M_)->Interrupt->SharedInterrupt) \
  410. { \
  411. (_M_)->Flags |= fMINIPORT_NORMAL_INTERRUPTS; \
  412. } \
  413. else \
  414. { \
  415. (_M_)->Flags &= ~fMINIPORT_NORMAL_INTERRUPTS; \
  416. }
  417. #define WMI_BUFFER_TOO_SMALL(_BufferSize, _Wnode, _WnodeSize, _pStatus, _pRSize) \
  418. { \
  419. if ((_BufferSize) < sizeof(WNODE_TOO_SMALL)) \
  420. { \
  421. *(_pStatus) = STATUS_BUFFER_TOO_SMALL; \
  422. *(_pRSize) = sizeof(ULONG); \
  423. } \
  424. else \
  425. { \
  426. (_Wnode)->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL); \
  427. (_Wnode)->WnodeHeader.Flags |= WNODE_FLAG_TOO_SMALL; \
  428. ((PWNODE_TOO_SMALL)(_Wnode))->SizeNeeded = (_WnodeSize); \
  429. *(_pRSize) = sizeof(WNODE_TOO_SMALL); \
  430. *(_pStatus) = STATUS_SUCCESS; \
  431. } \
  432. }
  433. #define MAP_NDIS_STATUS_TO_NT_STATUS(_NdisStatus, _pNtStatus) \
  434. { \
  435. /* \
  436. * The following NDIS status codes map directly to NT status codes. \
  437. */ \
  438. if (((NDIS_STATUS_SUCCESS == (_NdisStatus)) || \
  439. (NDIS_STATUS_PENDING == (_NdisStatus)) || \
  440. (NDIS_STATUS_BUFFER_OVERFLOW == (_NdisStatus)) || \
  441. (NDIS_STATUS_FAILURE == (_NdisStatus)) || \
  442. (NDIS_STATUS_RESOURCES == (_NdisStatus)) || \
  443. (NDIS_STATUS_NOT_SUPPORTED == (_NdisStatus)))) \
  444. { \
  445. *(_pNtStatus) = (NTSTATUS)(_NdisStatus); \
  446. } \
  447. else if (NDIS_STATUS_BUFFER_TOO_SHORT == (_NdisStatus)) \
  448. { \
  449. /* \
  450. * The above NDIS status codes require a little special casing. \
  451. */ \
  452. *(_pNtStatus) = STATUS_BUFFER_TOO_SMALL; \
  453. } \
  454. else if (NDIS_STATUS_INVALID_LENGTH == (_NdisStatus)) \
  455. { \
  456. *(_pNtStatus) = STATUS_INVALID_BUFFER_SIZE; \
  457. } \
  458. else if (NDIS_STATUS_INVALID_DATA == (_NdisStatus)) \
  459. { \
  460. *(_pNtStatus) = STATUS_INVALID_PARAMETER; \
  461. } \
  462. else \
  463. { \
  464. *(_pNtStatus) = STATUS_UNSUCCESSFUL; \
  465. } \
  466. }
  467. #define EXPERIMENTAL_SIZE 4
  468. #define VC_IDENTIFIER L':'
  469. #define VC_IDENTIFIER_STRING L":"
  470. #define VC_ID_INDEX 5
  471. #define VC_INSTANCE_ID_SIZE (sizeof(WCHAR) * 24) // "XXXX:YYYYYYYYYYYYYYYY "
  472. #define NIBBLE_MASK 0x0F
  473. #define fNDIS_GUID_EVENT_ENABLED 0x80000000
  474. #define fNDIS_GUID_NOT_SETTABLE 0x40000000
  475. #define fNDIS_GUID_NDIS_ONLY 0x20000000
  476. #define fNDIS_GUID_CO_NDIS 0x10000000
  477. #define NDIS_GUID_SET_FLAG(m, f) ((m)->Flags |= (f))
  478. #define NDIS_GUID_CLEAR_FLAG(m, f) ((m)->Flags &= ~(f))
  479. #define NDIS_GUID_TEST_FLAG(m, f) (((m)->Flags & (f)) != 0)
  480. typedef struct _AsyncWorkItem
  481. {
  482. WORK_QUEUE_ITEM ExWorkItem;
  483. PNDIS_MINIPORT_BLOCK Miniport;
  484. ULONG Length;
  485. BOOLEAN Cached;
  486. PVOID VAddr;
  487. PVOID Context;
  488. NDIS_PHYSICAL_ADDRESS PhyAddr;
  489. } ASYNC_WORKITEM, *PASYNC_WORKITEM;
  490. //
  491. // Macro for the deferred send handler.
  492. //
  493. #define NDISM_START_SENDS(_M) (_M)->DeferredSendHandler((_M))
  494. #define NDISM_DEFER_PROCESS_DEFERRED(_M) QUEUE_DPC(&(_M)->DeferredDpc)
  495. //
  496. // A list of registered address families are maintained here.
  497. //
  498. typedef struct _NDIS_AF_LIST
  499. {
  500. struct _NDIS_AF_LIST * NextAf; // For this miniport Head at NDIS_MINIPORT_BLOCK
  501. PNDIS_OPEN_BLOCK Open; // Back pointer to the open-block
  502. CO_ADDRESS_FAMILY AddressFamily;
  503. NDIS_CALL_MANAGER_CHARACTERISTICS CmChars;
  504. } NDIS_AF_LIST, *PNDIS_AF_LIST;
  505. typedef struct _NDIS_AF_NOTIFY
  506. {
  507. struct _NDIS_AF_NOTIFY * Next;
  508. WORK_QUEUE_ITEM WorkItem;
  509. PNDIS_MINIPORT_BLOCK Miniport;
  510. PNDIS_OPEN_BLOCK Open;
  511. CO_ADDRESS_FAMILY AddressFamily;
  512. } NDIS_AF_NOTIFY, *PNDIS_AF_NOTIFY;
  513. typedef struct _POWER_WORK_ITEM
  514. {
  515. //
  516. // NDIS_WORK_ITEM needs to be the first element here !!!
  517. //
  518. NDIS_WORK_ITEM WorkItem;
  519. PIRP pIrp;
  520. } POWER_WORK_ITEM, *PPOWER_WORK_ITEM;
  521. typedef
  522. NDIS_STATUS
  523. (FASTCALL *SET_INFO_HANDLER)(
  524. IN PNDIS_MINIPORT_BLOCK Miniport,
  525. IN PNDIS_REQUEST Request
  526. );
  527. typedef struct _OID_SETINFO_HANDLER
  528. {
  529. NDIS_OID Oid;
  530. SET_INFO_HANDLER SetInfoHandler;
  531. } OID_SETINFO_HANDLER, *POID_SETINFO_HANDLER;
  532. #define READ_LOCK 0
  533. #define WRITE_LOCK_STATE_UNKNOWN 1
  534. #define LOCK_STATE_ALREADY_ACQUIRED 2
  535. #define READ_LOCK_STATE_FREE 3
  536. #define WRITE_LOCK_STATE_FREE 4
  537. #define LOCK_STATE_UNKNOWN (USHORT)-1
  538. typedef
  539. VOID
  540. (FASTCALL *LOCK_HANDLER)(
  541. IN PVOID Filter,
  542. IN OUT PLOCK_STATE pLockState
  543. );
  544. #define READ_LOCK_FILTER(_Miniport, _Filter, _pLockState) NDIS_READ_LOCK(&(_Filter)->BindListLock, _pLockState);
  545. #define READ_UNLOCK_FILTER(_Miniport, _Filter, _pLockState) NDIS_READ_LOCK_STATE_FREE(&(_Filter)->BindListLock, _pLockState)
  546. #define READ_LOCK_FILTER_DPC(_Miniport, _Filter, _pLockState) NDIS_READ_LOCK_DPC(&(_Filter)->BindListLock, _pLockState);
  547. #define READ_UNLOCK_FILTER_DPC(_Miniport, _Filter, _pLockState) NDIS_READ_LOCK_STATE_FREE_DPC(&(_Filter)->BindListLock, _pLockState)
  548. #define WRITE_LOCK_FILTER(_Miniport, _Filter, _pLockState) \
  549. { \
  550. LOCK_HANDLER LockHandler = \
  551. (LOCK_HANDLER)((_Miniport)->LockHandler); \
  552. \
  553. (_pLockState)->LockState = WRITE_LOCK_STATE_UNKNOWN;\
  554. (*LockHandler)(_Filter, _pLockState); \
  555. }
  556. #define WRITE_UNLOCK_FILTER(_Miniport, _Filter, _pLockState) UNLOCK_FILTER(_Miniport, _Filter, _pLockState)
  557. #define UNLOCK_FILTER(_Miniport, _Filter, _pLockState) \
  558. { \
  559. LOCK_HANDLER LockHandler = \
  560. (LOCK_HANDLER)((_Miniport)->LockHandler); \
  561. \
  562. (*LockHandler)(_Filter, _pLockState); \
  563. }
  564. #define M_OPEN_INCREMENT_REF_INTERLOCKED(_O) \
  565. { \
  566. UINT MOpen_RefCount; \
  567. MOpen_RefCount = (ULONG)InterlockedIncrement(&(_O)->References);\
  568. NDIS_APPEND_MOPEN_LOGFILE(NDIS_INCREMENT_M_OPEN_REFCOUNT,\
  569. __LINE__, \
  570. MODULE_NUMBER, \
  571. (_O), \
  572. MOpen_RefCount); \
  573. }
  574. #define M_OPEN_DECREMENT_REF_INTERLOCKED(_O, _OR) \
  575. { \
  576. _OR = (ULONG)InterlockedDecrement(&(_O)->References); \
  577. NDIS_APPEND_MOPEN_LOGFILE(NDIS_DECREMENT_M_OPEN_REFCOUNT, \
  578. __LINE__, \
  579. MODULE_NUMBER, \
  580. _O, \
  581. _OR); \
  582. }
  583. #define OPEN_INCREMENT_AF_NOTIFICATION(_O) \
  584. { \
  585. UINT MOpen_AfRefCount; \
  586. MOpen_AfRefCount = (ULONG)InterlockedIncrement(&(_O)->PendingAfNotifications); \
  587. NDIS_APPEND_MOPEN_LOGFILE(NDIS_INCREMENT_OPEN_AF_NOTIFICATION, \
  588. __LINE__, \
  589. MODULE_NUMBER, \
  590. (_O), \
  591. MOpen_AfRefCount); \
  592. }
  593. #define OPEN_DECREMENT_AF_NOTIFICATION(_O, _OR) \
  594. { \
  595. _OR = (ULONG)InterlockedDecrement(&(_O)->PendingAfNotifications); \
  596. NDIS_APPEND_MOPEN_LOGFILE(NDIS_DECREMENT_OPEN_AF_NOTIFICATION, \
  597. __LINE__, \
  598. MODULE_NUMBER, \
  599. _O, \
  600. _OR); \
  601. }
  602. #ifdef TRACK_MINIPORT_REFCOUNTS
  603. #define MINIPORT_INCREMENT_REF(_M) ndisReferenceMiniportAndLog(_M, __LINE__, MODULE_NUMBER)
  604. #define MINIPORT_INCREMENT_REF_NO_CHECK(_M) ndisReferenceMiniportAndLogNoCheck(_M, __LINE__, MODULE_NUMBER)
  605. #define MINIPORT_INCREMENT_REF_CREATE(_M, _IRP) ndisReferenceMiniportAndLogCreate(_M, __LINE__, MODULE_NUMBER, _IRP)
  606. #else
  607. #define MINIPORT_INCREMENT_REF(_M) ndisReferenceMiniport(_M)
  608. #define MINIPORT_INCREMENT_REF_NO_CHECK(_M) ndisReferenceMiniportNoCheck(_M)
  609. #define MINIPORT_INCREMENT_REF_CREATE(_M, _IRP) ndisReferenceMiniport(_M)
  610. #endif
  611. #define MINIPORT_DECREMENT_REF(_M) \
  612. { \
  613. M_LOG_MINIPORT_DECREMENT_REF(_M, (_M)->Ref.ReferenceCount - 1);\
  614. ndisDereferenceMiniport(_M); \
  615. }
  616. #define MINIPORT_DECREMENT_REF_CLOSE(_M, _IRP) \
  617. { \
  618. M_LOG_MINIPORT_DECREMENT_REF_CLOSE(_M, (_M)->Ref.ReferenceCount - 1);\
  619. ndisDereferenceMiniport(_M); \
  620. }
  621. #define MINIPORT_DECREMENT_REF_NO_CLEAN_UP(_M) \
  622. { \
  623. M_LOG_MINIPORT_DECREMENT_REF(_M, (_M)->Ref.ReferenceCount - 1);\
  624. ndisDereferenceULongRef(&(_M)->Ref); \
  625. }
  626. #ifdef TRACK_MINIPORT_MPMODE_OPENS
  627. #define NDIS_CHECK_PMODE_OPEN_REF(_M) \
  628. { \
  629. PNDIS_OPEN_BLOCK _pOpen = (_M)->OpenQueue; \
  630. UINT _NumPmodeOpens = 0; \
  631. while(_pOpen) \
  632. { \
  633. if (_pOpen->Flags & fMINIPORT_OPEN_PMODE) \
  634. _NumPmodeOpens++; \
  635. _pOpen = _pOpen->MiniportNextOpen; \
  636. } \
  637. ASSERT((_M)->PmodeOpens == _NumPmodeOpens); \
  638. (_M)->PmodeOpens = (UCHAR)_NumPmodeOpens; \
  639. }
  640. #else
  641. #define NDIS_CHECK_PMODE_OPEN_REF(_M)
  642. #endif
  643. //
  644. // if PmodeOpens > 0 and NumOpens > 1, then check to see if we should
  645. // loop back the packet.
  646. //
  647. // we should also should loopback the packet if the protocol did not
  648. // explicitly asked for the packet not to be looped back and we either have a miniport
  649. // that has indicated that it does not do loopback itself or it is in all_local
  650. // mode.
  651. //
  652. #define NDIS_CHECK_FOR_LOOPBACK(_M, _P) \
  653. ((MINIPORT_TEST_FLAG(_M, fMINIPORT_CHECK_FOR_LOOPBACK)) || \
  654. (((NdisGetPacketFlags(_P) & NDIS_FLAGS_DONT_LOOPBACK) == 0) && \
  655. (MINIPORT_TEST_FLAG(_M, fMINIPORT_DOES_NOT_DO_LOOPBACK | \
  656. fMINIPORT_SEND_LOOPBACK_DIRECTED) \
  657. ) \
  658. ) \
  659. )
  660. //
  661. // obselete API. shouldn't show up in ndis.h
  662. //
  663. EXPORT
  664. NDIS_STATUS
  665. NdisQueryMapRegisterCount(
  666. IN NDIS_INTERFACE_TYPE BusType,
  667. OUT PUINT MapRegisterCount
  668. );
  669. EXPORT
  670. VOID
  671. NdisImmediateReadPortUchar(
  672. IN NDIS_HANDLE WrapperConfigurationContext,
  673. IN ULONG Port,
  674. OUT PUCHAR Data
  675. );
  676. EXPORT
  677. VOID
  678. NdisImmediateReadPortUshort(
  679. IN NDIS_HANDLE WrapperConfigurationContext,
  680. IN ULONG Port,
  681. OUT PUSHORT Data
  682. );
  683. EXPORT
  684. VOID
  685. NdisImmediateReadPortUlong(
  686. IN NDIS_HANDLE WrapperConfigurationContext,
  687. IN ULONG Port,
  688. OUT PULONG Data
  689. );
  690. EXPORT
  691. VOID
  692. NdisImmediateWritePortUchar(
  693. IN NDIS_HANDLE WrapperConfigurationContext,
  694. IN ULONG Port,
  695. IN UCHAR Data
  696. );
  697. EXPORT
  698. VOID
  699. NdisImmediateWritePortUshort(
  700. IN NDIS_HANDLE WrapperConfigurationContext,
  701. IN ULONG Port,
  702. IN USHORT Data
  703. );
  704. EXPORT
  705. VOID
  706. NdisImmediateWritePortUlong(
  707. IN NDIS_HANDLE WrapperConfigurationContext,
  708. IN ULONG Port,
  709. IN ULONG Data
  710. );
  711. EXPORT
  712. VOID
  713. NdisImmediateReadSharedMemory(
  714. IN NDIS_HANDLE WrapperConfigurationContext,
  715. IN ULONG SharedMemoryAddress,
  716. IN PUCHAR Buffer,
  717. IN ULONG Length
  718. );
  719. EXPORT
  720. VOID
  721. NdisImmediateWriteSharedMemory(
  722. IN NDIS_HANDLE WrapperConfigurationContext,
  723. IN ULONG SharedMemoryAddress,
  724. IN PUCHAR Buffer,
  725. IN ULONG Length
  726. );
  727. EXPORT
  728. ULONG
  729. NdisImmediateReadPciSlotInformation(
  730. IN NDIS_HANDLE WrapperConfigurationContext,
  731. IN ULONG SlotNumber,
  732. IN ULONG Offset,
  733. IN PVOID Buffer,
  734. IN ULONG Length
  735. );
  736. EXPORT
  737. ULONG
  738. NdisImmediateWritePciSlotInformation(
  739. IN NDIS_HANDLE WrapperConfigurationContext,
  740. IN ULONG SlotNumber,
  741. IN ULONG Offset,
  742. IN PVOID Buffer,
  743. IN ULONG Length
  744. );
  745. #define ALIGN_8_LENGTH(_length) (((ULONG)(_length) + 7) & ~7)
  746. #define ALIGN_8_TYPE(_type) ((sizeof(_type) + 7) & ~7)
  747. #define ALIGN_UP_MAX_NATURAL_ALIGNMENT_LENGTH(_length) (((ULONG)(_length) + (MAX_NATURAL_ALIGNMENT - 1)) & ~(MAX_NATURAL_ALIGNMENT - 1))
  748. #endif // __MINI_H