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.

621 lines
16 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Copyright (c) 1991 Nokia Data Systems AB
  4. Module Name:
  5. dlctyp.h
  6. Abstract:
  7. This module defines all data structures of the DLC module.
  8. Author:
  9. Antti Saarenheimo 22-Jul-1991
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. //
  15. // forward declarations
  16. //
  17. struct _DLC_OBJECT;
  18. typedef struct _DLC_OBJECT DLC_OBJECT, *PDLC_OBJECT;
  19. struct _DLC_EVENT;
  20. typedef struct _DLC_EVENT DLC_EVENT, *PDLC_EVENT;
  21. struct _DLC_COMMAND;
  22. typedef struct _DLC_COMMAND DLC_COMMAND, *PDLC_COMMAND;
  23. struct _DLC_CLOSE_WAIT_INFO;
  24. typedef struct _DLC_CLOSE_WAIT_INFO DLC_CLOSE_WAIT_INFO, *PDLC_CLOSE_WAIT_INFO;
  25. union _DLC_PACKET;
  26. typedef union _DLC_PACKET DLC_PACKET, *PDLC_PACKET;
  27. union _DLC_BUFFER_HEADER;
  28. typedef union _DLC_BUFFER_HEADER DLC_BUFFER_HEADER;
  29. typedef DLC_BUFFER_HEADER *PDLC_BUFFER_HEADER;
  30. struct _DLC_FILE_CONTEXT;
  31. typedef struct _DLC_FILE_CONTEXT DLC_FILE_CONTEXT;
  32. typedef DLC_FILE_CONTEXT *PDLC_FILE_CONTEXT;
  33. enum _DLC_FILE_CONTEXT_STATUS {
  34. DLC_FILE_CONTEXT_OPEN,
  35. DLC_FILE_CONTEXT_CLOSE_PENDING,
  36. DLC_FILE_CONTEXT_CLOSED
  37. };
  38. enum DlcObjectTypes {
  39. DLC_ADAPTER_OBJECT,
  40. DLC_SAP_OBJECT,
  41. DLC_LINK_OBJECT,
  42. DLC_DIRECT_OBJECT
  43. };
  44. //
  45. // DLC structures/objects
  46. //
  47. struct _DLC_OBJECT {
  48. //
  49. // DEBUG version - we have a 16-byte identifier header for consistency
  50. // checking and to help when looking at DLC using the kernel debugger
  51. //
  52. // DBG_OBJECT_ID;
  53. //
  54. // single-linked list of link stations if this is a SAP object
  55. //
  56. PDLC_OBJECT pLinkStationList;
  57. //
  58. // pointer to owning FILE_CONTEXT
  59. //
  60. PDLC_FILE_CONTEXT pFileContext;
  61. //
  62. // pointer to RECEIVE command parameters active for this SAP/link station
  63. //
  64. PNT_DLC_PARMS pRcvParms;
  65. //
  66. // 'handle' (aka pointer to) of corresponding object in LLC
  67. //
  68. PVOID hLlcObject;
  69. PDLC_EVENT pReceiveEvent;
  70. PVOID pPrevXmitCcbAddress;
  71. PVOID pFirstChainedCcbAddress;
  72. PDLC_CLOSE_WAIT_INFO pClosingInfo;
  73. ULONG CommittedBufferSpace;
  74. USHORT ChainedTransmitCount;
  75. SHORT PendingLlcRequests;
  76. USHORT StationId; // nn00 or nnss
  77. UCHAR Type;
  78. UCHAR LinkAllCcbs;
  79. UCHAR State;
  80. BOOLEAN LlcObjectExists;
  81. USHORT LlcReferenceCount; // protects LLC objects when used
  82. // Need to have a close packet just in case we are out of resources and
  83. // can't allocate a packet to close.
  84. LLC_PACKET ClosePacket;
  85. UCHAR ClosePacketInUse;
  86. //
  87. // u - variant fields depending on object type: SAP, LINK or DIRECT station
  88. //
  89. union {
  90. struct {
  91. ULONG DlcStatusFlag;
  92. PVOID GlobalGroupSapHandle;
  93. PVOID* GroupSapHandleList;
  94. USHORT GroupSapCount;
  95. USHORT UserStatusValue;
  96. UCHAR LinkStationCount;
  97. UCHAR OptionsPriority;
  98. UCHAR MaxStationCount;
  99. } Sap;
  100. struct {
  101. struct _DLC_OBJECT* pSap;
  102. PDLC_EVENT pStatusEvent; // permanent status event
  103. USHORT MaxInfoFieldLength;
  104. } Link;
  105. struct {
  106. USHORT OpenOptions;
  107. USHORT ProtocolTypeOffset;
  108. ULONG ProtocolTypeMask;
  109. ULONG ProtocolTypeMatch;
  110. } Direct;
  111. } u;
  112. };
  113. typedef
  114. VOID
  115. (*PFCLOSE_COMPLETE)(
  116. IN PDLC_FILE_CONTEXT pFileContext,
  117. IN PDLC_CLOSE_WAIT_INFO pClosingInfo,
  118. IN PVOID pCcbLink
  119. );
  120. typedef
  121. BOOLEAN
  122. (*PFCOMPLETION_HANDLER)(
  123. IN PDLC_FILE_CONTEXT pFileContext,
  124. IN PDLC_OBJECT pDlcObject,
  125. IN PIRP pIrp,
  126. IN ULONG Event,
  127. IN PVOID pEventInformation,
  128. IN ULONG SecondaryInfo
  129. );
  130. //
  131. // DLC_COMMAND and DLC_EVENT structures may be
  132. // overloaded by the code. Do not change the field
  133. // order and add the new fields only to the end.
  134. //
  135. struct _DLC_COMMAND {
  136. //
  137. // !!!!! Keep this fixed - same fields with DLC_EVENT !!!!!
  138. //
  139. LLC_PACKET LlcPacket;
  140. ULONG Event;
  141. USHORT StationId;
  142. USHORT StationIdMask;
  143. //
  144. // !!!!! Keep this fixed - same fields with DLC_EVENT !!!!!
  145. //
  146. PVOID AbortHandle;
  147. PIRP pIrp;
  148. union {
  149. PFCOMPLETION_HANDLER pfCompletionHandler;
  150. ULONG TimerTicks;
  151. } Overlay;
  152. };
  153. struct _DLC_EVENT {
  154. LLC_PACKET LlcPacket;
  155. ULONG Event;
  156. USHORT StationId; // -1 => global event
  157. union {
  158. USHORT StationIdMask;
  159. UCHAR RcvReadOption;
  160. } Overlay;
  161. PDLC_OBJECT pOwnerObject; // if null => no owner
  162. PVOID pEventInformation;
  163. ULONG SecondaryInfo;
  164. BOOLEAN bFreeEventInfo;
  165. };
  166. typedef struct {
  167. LLC_PACKET LlcPacket;
  168. PVOID pCcbAddress;
  169. PDLC_BUFFER_HEADER pReceiveBuffers;
  170. ULONG CommandCompletionFlag;
  171. USHORT CcbCount;
  172. USHORT StationId;
  173. } DLC_COMPLETION_EVENT_INFO, *PDLC_COMPLETION_EVENT_INFO;
  174. //
  175. // CLOSE_WAIT_INFO
  176. //
  177. // The pointer of this structure is provided to CompleteReadRequest in
  178. // the command completion of close/reset commands. The info pointer
  179. // is null for the other command completions.
  180. //
  181. struct _DLC_CLOSE_WAIT_INFO {
  182. PDLC_CLOSE_WAIT_INFO pNext;
  183. PIRP pIrp;
  184. ULONG Event;
  185. PFCLOSE_COMPLETE pfCloseComplete;
  186. PDLC_BUFFER_HEADER pRcvFrames;
  187. PVOID pCcbLink;
  188. PDLC_COMMAND pReadCommand;
  189. PDLC_COMMAND pRcvCommand;
  190. PDLC_COMPLETION_EVENT_INFO pCompletionInfo;
  191. ULONG CancelStatus;
  192. USHORT CcbCount;
  193. USHORT CloseCounter; // event sent when 0
  194. BOOLEAN ChainCommands;
  195. BOOLEAN CancelReceive;
  196. BOOLEAN ClosingAdapter;
  197. BOOLEAN FreeCompletionInfo;
  198. };
  199. //
  200. // This is a queued FlowControl command (the flow control commands
  201. // are completed immediately synchronously, but the local 'out of buffers'
  202. // busy state of the link is cleared when there is enough buffers
  203. // in the buffer pool to receive all expected data.
  204. //
  205. typedef struct {
  206. LIST_ENTRY List;
  207. LONG RequiredBufferSpace;
  208. USHORT StationId;
  209. } DLC_RESET_LOCAL_BUSY_CMD, *PDLC_RESET_LOCAL_BUSY_CMD;
  210. //
  211. // The transmit commands are not queued as a standard commands
  212. // but using the linked buffer headers (each frame has own xmit
  213. // header having links to buffer header list and MDL list).
  214. // The xmit nodes of the same send are queued together.
  215. //
  216. typedef struct {
  217. LLC_PACKET LlcPacket;
  218. PDLC_BUFFER_HEADER pNextSegment;
  219. PDLC_PACKET pTransmitNode;
  220. PIRP pIrp;
  221. ULONG FrameCount;
  222. PMDL pMdl;
  223. } DLC_XMIT_NODE, *PDLC_XMIT_NODE;
  224. //
  225. // DLC driver use the same packet pool for many small packets
  226. // that have approximately the same size.
  227. //
  228. union _DLC_PACKET {
  229. union _DLC_PACKET* pNext;
  230. LLC_PACKET LlcPacket;
  231. DLC_XMIT_NODE Node;
  232. DLC_EVENT Event;
  233. DLC_COMMAND DlcCommand;
  234. DLC_CLOSE_WAIT_INFO ClosingInfo;
  235. DLC_RESET_LOCAL_BUSY_CMD ClearCmd;
  236. struct {
  237. LLC_PACKET LlcPacket;
  238. PDLC_CLOSE_WAIT_INFO pClosingInfo;
  239. } ResetPacket;
  240. };
  241. //
  242. // The buffer pool states protects the app to corrupt the buffer pool!!
  243. // All states are needed because of internal consistency checking code
  244. // and implementation of the receive.
  245. //
  246. enum _DLC_BUFFER_STATES {
  247. //
  248. // major states:
  249. //
  250. BUF_READY = 0x01, // buffer/page locked and ready for I/O
  251. BUF_USER = 0x02, // buffer owned by user
  252. BUF_LOCKED = 0x04, // buffer have been locked for I/O
  253. BUF_RCV_PENDING = 0x08, // buffer not yet chained to other frames!
  254. //
  255. // free xmit buffer when used
  256. //
  257. DEALLOCATE_AFTER_USE = 0x80
  258. };
  259. union _DLC_BUFFER_HEADER {
  260. //
  261. // This struct is the header of the buffers split from a page.
  262. // We save the local and global virtual addresses here.
  263. // The individual offset is always GlobalVa + Index * 256.
  264. // An entry in main page table points to this header,
  265. // if the page has been locked in the memory.
  266. //
  267. struct {
  268. PDLC_BUFFER_HEADER pNextHeader;
  269. PDLC_BUFFER_HEADER pPrevHeader;
  270. PDLC_BUFFER_HEADER pNextChild;
  271. PUCHAR pLocalVa;
  272. PUCHAR pGlobalVa;
  273. UCHAR FreeSegments; // free segments ready for alloc
  274. UCHAR SegmentsOut; // number of segments given to user
  275. UCHAR BufferState; // BUF_READY, BUF_USER, BUF_LOCKED ...
  276. UCHAR Reserved; //
  277. PMDL pMdl;
  278. } Header;
  279. //
  280. // Structure is used in the double linked free lists.
  281. // All segments having the same buffer size have been linked
  282. // to the same link list.
  283. // On another level each segment is linked to the parent (Header)
  284. // and all childs of a parent are also linked together.
  285. //
  286. struct {
  287. PDLC_BUFFER_HEADER pNext;
  288. PDLC_BUFFER_HEADER pPrev;
  289. PDLC_BUFFER_HEADER pParent;
  290. PDLC_BUFFER_HEADER pNextChild;
  291. ULONG ReferenceCount; // number of references to this buffer
  292. UCHAR Size; // size in 256 blocks
  293. UCHAR Index; // offset = Index * 256
  294. UCHAR BufferState; // BUF_READY, BUF_USER, BUF_LOCKED ...
  295. UCHAR FreeListIndex; //
  296. PMDL pMdl;
  297. } FreeBuffer;
  298. //
  299. // The allocated frames are linked in different ways:
  300. // - the segments of the same frame are together
  301. // - the frames are linked together
  302. // These links are discarded, when the frame is given to
  303. // client (the client may free them in any order back to the buffer pool)
  304. // (The last extra pointer doesn't actually take any extra space,
  305. // because packets are round up to next 8 byte boundary)
  306. //
  307. struct {
  308. PDLC_BUFFER_HEADER pReserved;
  309. PDLC_BUFFER_HEADER pNextFrame;
  310. PDLC_BUFFER_HEADER pParent;
  311. PDLC_BUFFER_HEADER pNextChild;
  312. ULONG ReferenceCount; // number of references to this buffer
  313. UCHAR Size; // size in 256 blocks
  314. UCHAR Index; // offset = Index * 256
  315. UCHAR BufferState; // BUF_READY, BUF_USER, BUF_LOCKED ...
  316. UCHAR FreeListIndex;
  317. PMDL pMdl;
  318. PDLC_BUFFER_HEADER pNextSegment;
  319. } FrameBuffer;
  320. PDLC_BUFFER_HEADER pNext;
  321. };
  322. typedef struct _DLC_BUFFER_POOL {
  323. //
  324. // DEBUG version - we have a 16-byte identifier header for consistency
  325. // checking and to help when looking at DLC using the kernel debugger
  326. //
  327. // DBG_OBJECT_ID;
  328. //
  329. // control fields
  330. //
  331. struct _DLC_BUFFER_POOL* pNext;
  332. KSPIN_LOCK SpinLock;
  333. LONG ReferenceCount; // when -1 => deallocate
  334. //
  335. // buffer pool description fields (addresses, various lengths)
  336. //
  337. PVOID BaseOffset; // page-aligned base address of the pool
  338. PVOID MaxOffset; // maximum byte address in the pool + 1
  339. ULONG MaxBufferSize; // the maximum (free) size
  340. ULONG BufferPoolSize; // size of all memory in the pool
  341. ULONG FreeSpace; // size of free memory in the pool
  342. LONG UncommittedSpace; // size of free and reserved memory
  343. LONG MissingSize; // the size missing the last request
  344. ULONG MaximumIndex; // maximum index of buffer table
  345. PVOID hHeaderPool; // packet pool for buffer headers
  346. LIST_ENTRY PageHeaders; // the allocated blocks
  347. //
  348. // pUnlockedEntryList is a singly-linked list of DLC_BUFFER_HEADERS which
  349. // describe the free pages in the pool
  350. //
  351. PDLC_BUFFER_HEADER pUnlockedEntryList;
  352. //
  353. // FreeLists is an array of doubly-linked lists - one for each size of
  354. // block that can exists in the pool. The blocks start out at a page
  355. // length (4K on x86) and are successively halved until they reach
  356. // 256 bytes which is the smallest buffer that the DLC buffer manager
  357. // can deal with
  358. //
  359. LIST_ENTRY FreeLists[DLC_BUFFER_SEGMENTS];
  360. //
  361. // appended to the DLC_BUFFER_POOL structure is an array of pointers to
  362. // DLC_BUFFER_HEADER structures that describe the pages that comprise
  363. // the pool. There are MaximumIndex of these
  364. //
  365. PDLC_BUFFER_HEADER BufferHeaders[];
  366. } DLC_BUFFER_POOL, *PDLC_BUFFER_POOL;
  367. //
  368. // The buffer header and frame headers have been define in the
  369. // IBM LAN Architecture reference in the end of chapter 2.
  370. // They have also been defined in dlcapi.h, but for cosmetic reason
  371. // I want to use version without those funny prefixes.
  372. //
  373. typedef struct _NEXT_DLC_SEGMENT {
  374. struct _NEXT_DLC_SEGMENT* pNext;
  375. USHORT FrameLength;
  376. USHORT DataLength;
  377. USHORT UserOffset;
  378. USHORT UserLength;
  379. } NEXT_DLC_SEGMENT, *PNEXT_DLC_SEGMENT;
  380. union _FIRST_DLC_SEGMENT;
  381. typedef union _FIRST_DLC_SEGMENT FIRST_DLC_SEGMENT, *PFIRST_DLC_SEGMENT;
  382. typedef struct {
  383. PNEXT_DLC_SEGMENT pNext;
  384. USHORT FrameLength;
  385. USHORT DataLength;
  386. USHORT UserOffset;
  387. USHORT UserLength;
  388. USHORT StationId;
  389. UCHAR Options;
  390. UCHAR MessageType;
  391. USHORT BuffersLeft;
  392. UCHAR RcvFs;
  393. UCHAR AdapterNumber;
  394. PFIRST_DLC_SEGMENT pNextFrame;
  395. } DLC_CONTIGUOUS_RECEIVE, *PDLC_CONTIGUOUS_RECEIVE;
  396. typedef struct {
  397. PNEXT_DLC_SEGMENT pNext;
  398. USHORT FrameLength;
  399. USHORT DataLength;
  400. USHORT UserOffset;
  401. USHORT UserLength;
  402. USHORT StationId;
  403. UCHAR Options;
  404. UCHAR MessageType;
  405. USHORT BuffersLeft;
  406. UCHAR RcvFs;
  407. UCHAR AdapterNumber;
  408. PFIRST_DLC_SEGMENT pNextFrame;
  409. UCHAR LanHeaderLength;
  410. UCHAR DlcHeaderLength;
  411. UCHAR LanHeader[32];
  412. UCHAR DlcHeader[4];
  413. } DLC_NOT_CONTIGUOUS_RECEIVE, *PDLC_NOT_CONTIGUOUS_RECEIVE;
  414. union _FIRST_DLC_SEGMENT {
  415. DLC_CONTIGUOUS_RECEIVE Cont;
  416. DLC_NOT_CONTIGUOUS_RECEIVE NotCont;
  417. };
  418. //
  419. // Each application using DLC create its own file
  420. // context with the DlcOpenAdapter command.
  421. //
  422. struct _DLC_FILE_CONTEXT {
  423. //
  424. // all file contexts are put on single-entry list
  425. //
  426. SINGLE_LIST_ENTRY List; // linked list of file contexts
  427. #if DBG
  428. //
  429. // DEBUG version - we have a 16-byte identifier header for consistency
  430. // checking and to help when looking at DLC using the kernel debugger
  431. //
  432. // DBG_OBJECT_ID;
  433. #endif
  434. #if !defined(DLC_UNILOCK)
  435. NDIS_SPIN_LOCK SpinLock; // global lock for this file context
  436. #endif
  437. //
  438. // hBufferPool - handle of buffer pool created by BufferPoolCreate
  439. //
  440. PVOID hBufferPool;
  441. PVOID hExternalBufferPool;
  442. PVOID hPacketPool;
  443. PVOID hLinkStationPool;
  444. PVOID pBindingContext;
  445. //
  446. // Notification flags for error situations
  447. //
  448. ULONG AdapterCheckFlag;
  449. ULONG NetworkStatusFlag;
  450. ULONG PcErrorFlag;
  451. ULONG SystemActionFlag;
  452. LIST_ENTRY EventQueue;
  453. LIST_ENTRY CommandQueue;
  454. LIST_ENTRY ReceiveQueue;
  455. LIST_ENTRY FlowControlQueue;
  456. PDLC_COMMAND pTimerQueue;
  457. PVOID pSecurityDescriptor;
  458. PFILE_OBJECT FileObject; // back link to file obejct!
  459. ULONG WaitingTransmitCount;
  460. NDIS_MEDIUM ActualNdisMedium;
  461. LONG ReferenceCount;
  462. ULONG BufferPoolReferenceCount;
  463. ULONG TimerTickCounter;
  464. USHORT DlcObjectCount; // count of all DLC objects
  465. USHORT State;
  466. USHORT MaxFrameLength;
  467. UCHAR AdapterNumber;
  468. UCHAR LinkStationCount;
  469. PDLC_OBJECT SapStationTable[MAX_SAP_STATIONS];
  470. PDLC_OBJECT LinkStationTable[MAX_LINK_STATIONS];
  471. ULONG NdisErrorCounters[ADAPTER_ERROR_COUNTERS];
  472. DLC_CLOSE_WAIT_INFO ClosingPacket; // to close the adapter context
  473. // Event used to make cleanup synchronous and wait for all references on
  474. // DLC_FILE_CONTEXT to be removed before completing.
  475. KEVENT CleanupEvent;
  476. #if DBG
  477. //
  478. // Debug allocation counters
  479. //
  480. MEMORY_USAGE MemoryUsage;
  481. #endif
  482. };
  483. typedef
  484. NTSTATUS
  485. (*PFDLC_COMMAND_HANDLER)(
  486. IN PIRP pIrp,
  487. IN PDLC_FILE_CONTEXT pFileContext,
  488. IN PNT_DLC_PARMS pDlcParms,
  489. IN ULONG InputBufferLength,
  490. IN ULONG OutputBufferLength
  491. );