Source code of Windows XP (NT5)
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.

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