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.

1358 lines
46 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Copyright (c) 1991 Nokia Data Systems
  4. Module Name:
  5. vrdlc.h
  6. Abstract:
  7. This module is the only header file of Windows/Nt VDM DLC
  8. interface module.
  9. ALL STRUCTURES IN THIS FILE WHICH REFERENCE STRUCTURES IN DOS MEMORY
  10. ARE BYTE PACKED
  11. Author:
  12. Antti Saarenheimo (o-anttis) 26-01-1992
  13. Revision History:
  14. --*/
  15. //
  16. // constants
  17. //
  18. #define DOS_DLC_MAX_SAPS 128
  19. #define DOS_DLC_MAX_LINKS 255
  20. #define DOS_DLC_MAX_EVENTS 64
  21. #define LLC_DIR_MODIFY_OPEN_PARMS 0x01
  22. #define LLC_DIR_RESTORE_OPEN_PARMS 0x02
  23. #define LLC_DIR_SET_USER_APPENDAGE 0x2d
  24. #define LLC_DOS_SPECIAL_COMMAND ((ULONG)(-1))
  25. #define LLC_BREAK 0x20
  26. #define DOS_DLC_STATUS_NO_INDICATION 0x81
  27. #define LLC_SET_LOCAL_BUSY_BUFFER 0x20
  28. //
  29. // VRDLC_COMMAND_COMPLETION - this value is placed in the CCB_CMD_CMPL field
  30. // of every CCB2 that we issue that is NOT for the VDM. This value is used to
  31. // filter out command completions for commands that are generated by the DOS
  32. // DLC Emulator. This stops us passing command completions through to the
  33. // VDM that are not intended for it!
  34. //
  35. #define VRDLC_COMMAND_COMPLETION ((ULONG)(-2))
  36. //
  37. // buffer pool sizes
  38. //
  39. #define DOS_DLC_BUFFER_POOL_SIZE 0x00010000 // 64K
  40. #define DOS_DLC_MIN_FREE_THRESHOLD 0x00002000 // 8K
  41. //
  42. // flags for CopyFrame
  43. //
  44. #define CF_CONTIGUOUS 0x00000001 // frame is contiguous
  45. #define CF_BREAK 0x00000002 // options specified Break
  46. #define CF_PARTIAL 0x00000004 // receiving partial frame
  47. //
  48. // default values for DOS parameter tables (DD_ = DOS DEFAULT). These replace
  49. // the various parameters which can be specified as 0. They may be different
  50. // to the corresponding defaults applicable to NT DLC, so we fill them in
  51. // specifically
  52. //
  53. //
  54. // defaults for BUFFER.GET:
  55. //
  56. #define DD_BUFFER_GET 1
  57. //
  58. // defaults for DIR.INITIALIZE:
  59. //
  60. #define DD_SRAM_ADDRESS_0 0xd800
  61. #define DD_SRAM_ADDRESS_1 0xd400
  62. //
  63. // defaults for DIR.OPEN.ADAPTER, ADAPTER_PARMS:
  64. //
  65. #define DD_NUMBER_RCV_BUFFERS 8
  66. #define DD_RCV_BUFFER_LENGTH 112
  67. #define DD_DHB_BUFFER_LENGTH 600
  68. #define DD_DATA_HOLD_BUFFERS 1
  69. //
  70. // defaults for DIR.OPEN.ADAPTER, DIRECT_PARMS:
  71. //
  72. #define DD_DIR_BUF_SIZE 160
  73. #define DD_DIR_POOL_BLOCKS 256
  74. //
  75. // defaults for DIR.OPEN.ADAPTER, DLC_PARMS:
  76. //
  77. #define DD_DLC_MAX_SAP 2
  78. #define DD_DLC_MAX_STATIONS 6
  79. #define DD_DLC_MAX_GSAP 0
  80. #define DD_DLC_T1_TICK_ONE 5
  81. #define DD_DLC_T2_TICK_ONE 1
  82. #define DD_DLC_Ti_TICK_ONE 25
  83. #define DD_DLC_T1_TICK_TWO 25
  84. #define DD_DLC_T2_TICK_TWO 10
  85. #define DD_DLC_Ti_TICK_TWO 125
  86. //
  87. // defaults for DLC.OPEN.SAP:
  88. //
  89. #define DD_MAXOUT 2
  90. #define DD_MAXIN 1
  91. #define DD_MAX_RETRY_COUNT 8
  92. #define DD_MAX_I_FIELD 600
  93. #define DD_DLC_BUF_SIZE 160
  94. #define DD_DLC_POOL_LEN 256
  95. //
  96. // macros
  97. //
  98. //
  99. // DOS_PTR_TO_FLAT - given a DOS 16:16 pointer stored implicitly as a DWORD
  100. //
  101. #define DOS_PTR_TO_FLAT(a) (PVOID)GetVDMAddr(HIWORD(a), LOWORD(a))
  102. //
  103. // NEW_DOS_ADDRESS - generate a new DOS_ADDRESS, given a base DOS_ADDRESS and
  104. // a new pointer which is some number of bytes plus the base DOS_ADDRESS
  105. // converted to a flat pointer. For example, a DOS_ADDRESS of 1234:0000 becomes
  106. // (on x86) a flat pointer of 0x12340. We generate a new pointer 0x12380 and
  107. // want to convert this address back to a DOS_ADDRESS. So we use this macro.
  108. // Offset-wrap and segment update is automatically handled
  109. //
  110. #define NEW_DOS_ADDRESS(b, p) ((b) + ((DWORD)(p) - (DWORD)DOS_PTR_TO_FLAT(b)))
  111. //
  112. // POOL_INDEX_FROM_SAP - get the index in aBufferPools for a given SAP/adapter
  113. // combination. There are a maximum 127 SAPs per adapter, and 2 adapters which
  114. // are available to DOS
  115. //
  116. #define POOL_INDEX_FROM_SAP(Sap, Adapter) ((Sap & 0xfe) | Adapter)
  117. //
  118. // POOL_INDEX_FROM_ID - given a station ID (high byte = SAP, low byte = link
  119. // station), get the index to the SAP's buffer pool in aBufferPools
  120. //
  121. #define POOL_INDEX_FROM_ID(Id, Adapter) POOL_INDEX_FROM_SAP(HIBYTE(Id), Adapter)
  122. //
  123. // GET_POOL_INDEX - the original pool index macro
  124. //
  125. #define GET_POOL_INDEX(Adapter, usStationId) POOL_INDEX_FROM_ID(usStationId, Adapter)
  126. //
  127. // macros which initialize CCBs and call AcsLan
  128. //
  129. #define DlcFlowControl(Adapter, StationId, Options)\
  130. LlcCommand(Adapter, LLC_DLC_FLOW_CONTROL, ((DWORD)Options << 16) + StationId)
  131. #define DosDlcFlowControl(Adapter, StationId, Options)\
  132. LlcCommand(Adapter, LLC_DOS_DLC_FLOW_CONTROL, ((DWORD)Options << 16) + StationId)
  133. #define InitializeCcb(pCcb, AdapterNumber, Command, pParameter) \
  134. RtlZeroMemory((pCcb), sizeof(*(pCcb)));\
  135. RtlZeroMemory((pParameter), sizeof(*(pParameter)));\
  136. (pCcb)->uchAdapterNumber = (UCHAR)AdapterNumber;\
  137. (pCcb)->uchDlcCommand = (UCHAR)Command;\
  138. (pCcb)->u.pParameterTable = (PLLC_PARMS)(pParameter)
  139. #define InitializeCcb2(pCcb, AdapterNumber, Command) \
  140. RtlZeroMemory((pCcb), sizeof(*(pCcb)));\
  141. (pCcb)->uchAdapterNumber = (UCHAR)AdapterNumber;\
  142. (pCcb)->uchDlcCommand = (UCHAR)Command;
  143. #define ReceiveCancel(AdapterNumber, pCcb) \
  144. LlcCommand(AdapterNumber, LLC_RECEIVE_CANCEL, (DWORD)pCcb)
  145. //
  146. // DLC_ERROR_STATUS - after calling AcsLan, if an error was returned by AcsLan
  147. // then return that, else get the return code out of the CCB and return that
  148. //
  149. #define DLC_ERROR_STATUS(AcslanStatus, uchDlcStatus) \
  150. (DWORD)((AcslanStatus == 0) ? (DWORD)uchDlcStatus : (DWORD)AcslanStatus)
  151. //
  152. // VRDLC_ALLOC - standard allocation strategy in VDM REDIR DLC functions
  153. //
  154. #define VRDLC_ALLOC(Bytes) LocalAlloc(LMEM_FIXED, Bytes)
  155. //
  156. // VRDLC_FREE - companion to VRDLC_ALLOC - standard allocation free strategy
  157. //
  158. #define VRDLC_FREE(Pointer) LocalFree((HLOCAL)Pointer)
  159. //
  160. // SAP_ID - get the SAP from a station ID word. Used as array index 0..127
  161. // (corresponding to SAP 0..254 step 2)
  162. //
  163. #define SAP_ID(stationId) (HIBYTE(stationId) >> 1)
  164. //
  165. // LINK_ID - get the link station ID from a station ID word. Used as array index
  166. // 0..254 (corresponding to link station 1..255)
  167. //
  168. #define LINK_ID(stationId) (LOBYTE(stationId) - 1)
  169. //
  170. // types
  171. //
  172. union _LLC_DOS_PARMS;
  173. typedef union _LLC_DOS_PARMS LLC_DOS_PARMS, *PLLC_DOS_PARMS;
  174. typedef DWORD DOS_ADDRESS;
  175. typedef DOS_ADDRESS DPLLC_DOS_BUFFER;
  176. //
  177. // LLC_DOS_BUFFER - this is a union of all the DOS DLC data buffers. There are
  178. // basically 3 kinds: Buffer 1, the first buffer in a chain which contains net
  179. // address info, this can be in contigous or non-contiguous form, and Buffer 2
  180. // format which is the 2nd and subsequent buffers in a chain. DLC uses the
  181. // buffers for received data. Transmit data (passed from the app to DLC) can
  182. // use a buffer (or chain of buffers) from the pool or can source its own
  183. // buffer. The latter is preferred since taking buffers which DLC would use
  184. // for receiving data can leave DLC in the local busy state (ie no receive
  185. // buffers)
  186. //
  187. #include <packon.h>
  188. typedef union _LLC_DOS_BUFFER {
  189. //
  190. // pNext is just a pointer so we can follow the chain
  191. //
  192. union _LLC_DOS_BUFFER * pNext;
  193. //
  194. // NextDosBuffer is the Buffer 2 structure defined in the IBM Lan Tech.
  195. // Ref. pg 2-45
  196. //
  197. struct _NextDosBuffer {
  198. union _LLC_DOS_BUFFER * pNextBuffer;// next frame segment
  199. WORD cbFrame; // length of the whole rcvd frame
  200. WORD cbBuffer; // length of this segment
  201. WORD offUserData; // offset of data from descr header
  202. WORD cbUserData; // length of the data
  203. } Next;
  204. //
  205. // NotContiguous is the Not contiguous MAC/Data Buffer 1 structure defined
  206. // in IBM Lan Tech. Ref. pg 2-42
  207. //
  208. struct _DosDlcNotContiguousFirstBuffer {
  209. union _LLC_DOS_BUFFER * pNextBuffer; // next frame segment
  210. WORD cbFrame; // length of entire frame
  211. WORD cbBuffer; // length of this buffer
  212. WORD offUserData; // user data in this struct
  213. WORD cbUserData; // length of user data
  214. WORD usStationId; // ssnn station id
  215. UCHAR uchOptions; // option byte from RECEIVE param tbl
  216. UCHAR uchMsgType; // the message type
  217. WORD cBuffersLeft; // number of basic buffer units left
  218. UCHAR uchRcvFS; // the received frame status
  219. UCHAR uchAdapterNumber; // current adapter number
  220. UCHAR cbLanHeader; // length of the LAN header
  221. UCHAR cbDlcHeader; // length of the DLC header
  222. UCHAR auchLanHeader[32];// LAN header of the received frame
  223. UCHAR auchDlcHeader[4]; // DLC header of the received frame
  224. } NotContiguous;
  225. //
  226. // Contiguous is the Contiguous MAC/Data Buffer 1 structure defined
  227. // in IBM Lan Tech. Ref. pg 2-43
  228. //
  229. struct _DosDlcContiguousFirstBuffer {
  230. union _LLC_DOS_BUFFER * pNextBuffer; // next frame segment
  231. WORD cbFrame; // length of entire frame
  232. WORD cbBuffer; // length of this buffer
  233. WORD offUserData; // user data in this struct
  234. WORD cbUserData; // length of user data
  235. WORD usStationId; // ssnn station id
  236. UCHAR uchOptions; // option byte from RECEIVE param tbl
  237. UCHAR uchMsgType; // the message type
  238. WORD cBuffersLeft; // number of basic buffer units left
  239. UCHAR uchRcvFS; // the received frame status
  240. UCHAR uchAdapterNumber;
  241. } Contiguous;
  242. } LLC_DOS_BUFFER, *PLLC_DOS_BUFFER;
  243. #include <packoff.h>
  244. //
  245. // DOS_DLC_BUFFER_POOL - there is one of these per each SAP per adapter (max.
  246. // 127 SAPs per adapter * max. 2 adapters = 256), kept in an array. This
  247. // structure maintains basic information about the DOS buffer pool - its
  248. // starting address (dpBuffer) in DOS 16:16 format, the size of an individual
  249. // buffer in the pool (BufferSize) and the number of buffers in the pool
  250. // (BufferCount). A buffer must be an integral multiple of 16 bytes, a minimum
  251. // length of 80 bytes and not exceeding 64K-16 (0xfff0 = 65520)
  252. //
  253. typedef struct _DOS_DLC_BUFFER_POOL {
  254. DOS_ADDRESS dpBuffer;
  255. WORD BufferSize;
  256. WORD BufferCount;
  257. WORD MaximumBufferCount;
  258. } DOS_DLC_BUFFER_POOL, *PDOS_DLC_BUFFER_POOL;
  259. //
  260. // DOS DLC CCB aka CCB1 - see definition in IBM Lan Tech. Ref. pg 2-6
  261. //
  262. #include <packon.h>
  263. typedef struct _LLC_DOS_CCB {
  264. UCHAR uchAdapterNumber; // Adapter 0 or 1
  265. UCHAR uchDlcCommand; // DLC command
  266. UCHAR uchDlcStatus; // DLC command completion code
  267. UCHAR uchReserved1; // reserved for DLC DLL
  268. struct _LLC_DOS_CCB *pNext; // queued another CCB
  269. DWORD ulCompletionFlag; // used in command completion
  270. union {
  271. PLLC_DOS_PARMS pParms; // pointer to the parameter table
  272. struct {
  273. WORD usStationId; // Station id
  274. WORD usParameter; // optional parameter
  275. } dlc;
  276. struct {
  277. WORD usParameter0; // first optional parameter
  278. WORD usParameter1; // second optional parameter
  279. } dir;
  280. UCHAR auchBuffer[4]; // group/functional address
  281. DWORD ulParameter;
  282. } u;
  283. } LLC_DOS_CCB, *PLLC_DOS_CCB;
  284. //
  285. // additional parameter tables not defined in (sdk\inc\) DLCAPI.H (or where
  286. // CCB1 parameter tables different from those defined in DLCAPI.H)
  287. //
  288. //
  289. // LLC_DOS_DIR_INITIALIZE_PARMS - CCB1 DIR.INITIALIZE parameter table
  290. //
  291. typedef struct {
  292. WORD BringUps;
  293. WORD SharedRamAddress;
  294. WORD Reserved;
  295. DWORD AdapterCheckExit;
  296. DWORD NetworkStatusExit;
  297. DWORD PcErrorExit;
  298. } LLC_DOS_DIR_INITIALIZE_PARMS, *PLLC_DOS_DIR_INITIALIZE_PARMS;
  299. //
  300. // ADAPTER_PARMS, DIRECT_PARMS, DLC_PARMS and NCB_PARMS - these are the
  301. // parameter tables which are passed in to DIR.OPEN.ADAPTER
  302. //
  303. //
  304. // ADAPTER_PARMS - parameters returned from the adapter support s/w
  305. //
  306. typedef struct _ADAPTER_PARMS {
  307. WORD OpenErrorCode; // error detected opening adapter
  308. WORD OpenOptions; // options for Token Ring only:
  309. //
  310. // OpenOptions Bit Meanings
  311. //
  312. // This has been paraphrased from the IBM Lan Tech. Ref. p3-22. I don't
  313. // understand most of it, but I think I made it easier to read than the
  314. // IBM technicalese. Note: ONLY MEANINGFUL TO TOKEN RING ADAPTER
  315. //
  316. // Bit 15: Wrap Interface
  317. // The adapter doesn't attach to the network; instead, all
  318. // transmitted data is reflected back as received data
  319. //
  320. // Bit 14: Disable Hard Error
  321. // Stops network status change involving "Hard Error" and
  322. // "Transmit Beacon" bits from generating interrupt
  323. //
  324. // Bit 13: Disable Soft Errors
  325. // Stops network status change involving "Soft Error" bit
  326. // generating interrupt
  327. //
  328. // Bit 12: Pass Adapter MAC Frames
  329. // Unsupported MAC frames are passed to the direct station.
  330. // If OFF, these frames are ignored
  331. //
  332. // Bit 11: Pass Attention MAC Frames
  333. // Passes attention MAC frames which are not the same as the last
  334. // received Attention MAC Frame to the direct station. If OFF,
  335. // these frames are not passed to the direct station (ie App)
  336. //
  337. // Bit 10: Reserved
  338. // Should be zero, but not checked by adapter
  339. //
  340. // Bit 9: Pass Parameter Table
  341. // If the adapter is already open, returns options specified
  342. //
  343. // Bit 8: Contender
  344. // If ON, this adapter will participate in monitor contention
  345. // (claim token), should the need arise. If OFF, and it is
  346. // another adapter decides it is necessary to claim the token,
  347. // this adapter will not participate
  348. //
  349. // If this adapter decides it is necessary to determine a new
  350. // active monitor, this adapter will initiate monitor contention
  351. // processing IRRESPECTIVE OF THE VALUE OF THIS BIT
  352. //
  353. // Bit 7: Pass Beacon MAC Frames
  354. // Pass to direct station first Beacon MAC frame and all subsequent
  355. // Beacon MAC frames having a change in source address or beacon type
  356. //
  357. // Bit 6: Reserved
  358. // Should be zero, but not checked by adapter
  359. //
  360. // Bit 5: Remote Program Load
  361. // Only implemented on 16/4 adapters. Prevents adapter becoming
  362. // a monitor during open process. If ON, will cause this adapter
  363. // to fail the open if there are no other active adapters on the
  364. // ring when it tries to insert itself
  365. //
  366. // Bit 4: Token Release
  367. // Only implemented on 16/4 adapters and only available when
  368. // operating at 16 Mbps. OFF: use early token release (default).
  369. // ON: selects no early token release for adapter a 16 Mbps
  370. //
  371. // Bit 3: Reserved \
  372. // Bit 2: Reserved > Should be 0, but are not checked by adapter
  373. // Bit 1: Reserved /
  374. // Bit 0: Reserved /
  375. //
  376. BYTE NodeAddress[6]; // this adapter's address
  377. DWORD GroupAddress; // group address to set
  378. DWORD FunctionalAddress; // functional address to set
  379. WORD NumberReceiveBuffers; // number of receive buffers
  380. WORD ReceiveBufferLength; // size of receive buffer
  381. WORD DataHoldBufferLength; // size of transmit data hold buffer
  382. BYTE NumberDataHoldBuffers; // returned: only by Token Ring
  383. BYTE Reserved;
  384. WORD OpenLock; // Protection code to control closing adapter
  385. // This is NOT RETURNED when OpenOptions.9
  386. // is set (Pass parameter table)
  387. DWORD ProductId; // 18-byte product ID
  388. // This is NOT RETURNED when OpenOptions.9
  389. // is set (Pass parameter table)
  390. //
  391. // according to table 3-9 in IBM LAN Tech. Ref. (p3-25) the ProductId field
  392. // should point at an 18-byte buffer formatted like so:
  393. //
  394. // Byte 0 0x01 indicates workstation
  395. // Byte 1 0x10
  396. // Byte 2-5 last 4 digits from workstation serial number in EBCDIC
  397. // Byte 6-17 0x00
  398. //
  399. } ADAPTER_PARMS, *PADAPTER_PARMS;
  400. //
  401. // DIRECT_PARMS - input parameters defining Direct Station for adapter
  402. //
  403. typedef struct _DIRECT_PARMS {
  404. //
  405. // the direct buffer size is min. 80 bytes, and must be integral multiple
  406. // of 16-bytes. If 0, default of 160 is used
  407. //
  408. WORD DirectBufferSize; // size of buffers in direct buffer pool
  409. //
  410. // direct pool blocks - number of 16-byte blocks in direct station buffer
  411. // pool. If 0, default of 256 is used (= 4096 byte buffer pool)
  412. //
  413. WORD DirectPoolBlocks; // size of buffer in 16-byte blocks
  414. //
  415. // direct buffer pool - segment address in workstation memory where direct
  416. // station buffer pool is created. Spec. doesn't say what happens if there
  417. // is a non-zero (or any, for that matter) offset. If 0, the application
  418. // must build the direct station buffer pool, in which case DirectBufferSize
  419. // must indicate the size of each buffer
  420. //
  421. DWORD DirectBufferPool; // start address of direct buffer pool
  422. //
  423. // adapter check exit - vectors to this address when the adapter detects
  424. // an internal error. If 0, the value specified in DIR.INITIALIZE is used
  425. //
  426. DWORD AdapterCheckExit; // I/O appendage exit: adapter check
  427. //
  428. // network status exit - vectors to this address when the network status
  429. // changes (whatever that means). If 0, the value specified by
  430. // DIR.INITIALIZE is used
  431. //
  432. DWORD NetworkStatusExit; // I/O appendage exit: network status change
  433. //
  434. // PC error exit - vectors to this address when the adapter s/w detects an
  435. // error in the workstation (!). If 0, the value specified by DIR.INITIALIZE
  436. // is used
  437. //
  438. DWORD PcErrorExit; // I/O appendage exit: error in workstation
  439. //
  440. // adapter work area - segment of area of w/s memory which is to be used
  441. // by the adapter. Ignored if AdapterWorkAreaRequested is 0
  442. //
  443. DWORD AdapterWorkArea; // TR: adapter work are
  444. //
  445. // adapter work area length (requested) - the size of the workspace area,
  446. // the segment of which is specified in AdapterWorkArea. Size is calculated
  447. // thus: Number of SAPs x 36 + Number of stations (links) x 6 + 48
  448. //
  449. WORD AdapterWorkAreaRequested; // TR: work area length requested
  450. //
  451. // adapter work area length (actual) - this value is returned by the
  452. // adapter. It is the amount of the work area used by the adapter (in bytes).
  453. // If this is greater than AdapterWorkAreaRequested then an error is returned
  454. // (0x12)
  455. WORD AdapterWorkAreaActual; // TR: actual work area length taken
  456. } DIRECT_PARMS, *PDIRECT_PARMS;
  457. //
  458. // DLC_PARMS - returned values defining DLC limits
  459. //
  460. typedef struct _DLC_PARMS {
  461. //
  462. // maximum number of concurrently opened SAPs: limited by available
  463. // adapter memory and/or workspace memory. Maximum is 127 (126 if NetBIOS
  464. // is specified). If 0, the default 2 is used
  465. //
  466. BYTE MaxSaps; // maximum number of SAPs
  467. //
  468. // maximum number of concurrently opened link stations: limited by
  469. // available adapter and/or work area memory in workstation. Maximum is 255
  470. // for Token Ring, Ethernet or PC Network. If 0, the default of 6 is used
  471. //
  472. BYTE MaxStations; // maximum number of link stations
  473. //
  474. // maximum number of group SAPs concurrently opened. If 0, no group SAPs
  475. // can be opened. Maximum value is 126 for Token Ring, 125 for PC Network
  476. // and Ethernet
  477. //
  478. BYTE MaxGroupSaps; // maximum number of group SAPs
  479. //
  480. // maximum number of SAPs assigned to a group. Maximum is 127 for Token
  481. // Ring, 126 for PC Network and Ethernet
  482. //
  483. BYTE MaxGroupMembers; // maximum members per group SAP
  484. //
  485. // Timers. There are 3 timers: T1 is the Response Timer; T2 is the Inactivity
  486. // Timer; and Ti is the Receiver Acknowledgement Timer.
  487. //
  488. // Timers are set to a multiple of 40ms. They count down and interrupt the
  489. // adapter when they reach 0. Timer values can be between 1 and 10. If it
  490. // is between 1 and 5, the short timer tick (TICK_ONE) is used and is
  491. // referred to as group 1. If the number is between 6 and 10, the long timer
  492. // tick (TICK_TWO) is used and is referred to as group 2. The timer value is
  493. // the number (6 to 10) minus 5 multiplied by the long tick value.
  494. //
  495. //
  496. // Tick1 - number of 40 ms ticks for short DLC timer. Defaults (if 0):
  497. // T1 5 (200ms-400ms)
  498. // T2 1 (40ms-80ms)
  499. // Ti 25 (1s-2s)
  500. //
  501. BYTE T1Tick1; // Timer 1 short timer
  502. BYTE T2Tick1; // Timer 2 short timer
  503. BYTE TiTick1; // Timer i short timer
  504. //
  505. // Tick2 - number of 40 ms ticks for long DLC timer. Default (if 0):
  506. // T1 25 (1s-2s)
  507. // T2 10 (400ms-800ms)
  508. // Ti 125 (5s-10s)
  509. //
  510. BYTE T1Tick2; // Timer 1 long timer
  511. BYTE T2Tick2; // Timer 2 long timer
  512. BYTE TiTick2; // Timer i long timer
  513. } DLC_PARMS, *PDLC_PARMS;
  514. //
  515. // NCB_PARMS - we are not interested in running DOS NETBIOS over DOS DLC (are we?)
  516. //
  517. typedef struct _NCB_PARMS {
  518. BYTE Reserved1[4]; // adapter work area
  519. BYTE TimerT1;
  520. BYTE TimerT2;
  521. BYTE TimerTi;
  522. BYTE MaxOut;
  523. BYTE MaxIn;
  524. BYTE MaxOutIncr;
  525. BYTE MaxRetry;
  526. BYTE Reserved2[4];
  527. BYTE NcbAccessPri;
  528. BYTE MaxStations;
  529. BYTE Reserved3[19];
  530. BYTE MaxNames;
  531. BYTE MaxNcbs;
  532. BYTE MaxSessions;
  533. BYTE Reserved4[2];
  534. BYTE Options;
  535. WORD PoolLength;
  536. DWORD PoolAddress;
  537. BYTE TxTimeout;
  538. BYTE TxCount;
  539. } NCB_PARMS, *PNCB_PARMS;
  540. //
  541. // LLC_DOS_DIR_OPEN_ADAPTER_PARMS is the CCB1 DIR.OPEN.ADAPTER parameter table
  542. //
  543. typedef struct _LLC_DOS_DIR_OPEN_ADAPTER_PARMS {
  544. PADAPTER_PARMS pAdapterParms;
  545. PDIRECT_PARMS pDirectParms;
  546. PDLC_PARMS pDlcParms;
  547. PNCB_PARMS pNcbParms;
  548. } LLC_DOS_DIR_OPEN_ADAPTER_PARMS, *PLLC_DOS_DIR_OPEN_ADAPTER_PARMS;
  549. //
  550. // LLC_DOS_RECEIVE_PARMS is the CCB1 RECEIVE parameter table
  551. //
  552. typedef struct _LLC_DOS_RECEIVE_PARMS {
  553. WORD usStationId; // SAP, link station or direct id
  554. WORD usUserLength; // length of user data in buffer header
  555. DWORD ulReceiveExit; // the received data handler
  556. PLLC_BUFFER pFirstBuffer; // first buffer in the pool
  557. UCHAR uchOptions; // defines how the frame is received
  558. } LLC_DOS_RECEIVE_PARMS, *PLLC_DOS_RECEIVE_PARMS;
  559. //
  560. // LLC_DOS_RECEIVE_PARMS_EX is an extended version of the LLC_DOS_RECEIVE_PARMS
  561. // parameter table. We keep extra information - the DOS address of the original
  562. // CCB and the original RECEIVE_DATA completion exit routine
  563. //
  564. typedef struct _LLC_DOS_RECEIVE_PARMS_EX {
  565. WORD usStationId; // SAP, link station or direct id
  566. WORD usUserLength; // length of user data in buffer header
  567. DWORD ulReceiveExit; // the received data handler
  568. PLLC_BUFFER pFirstBuffer; // first buffer in the pool
  569. UCHAR uchOptions; // defines how the frame is received
  570. UCHAR auchReserved1[3]; //
  571. UCHAR uchRcvReadOption; // defines if rcv frames are chained
  572. UCHAR auchReserved2[3]; // align dpOriginalCcbAddress on DWORD
  573. DOS_ADDRESS dpOriginalCcbAddress; // dos address of orginal ccb
  574. DOS_ADDRESS dpCompletionFlag; // orginal completion flag
  575. } LLC_DOS_RECEIVE_PARMS_EX, *PLLC_DOS_RECEIVE_PARMS_EX;
  576. //
  577. // LLC_DOS_RECEIVE_MODIFY_PARMS is the parameter table for RECEIVE.MODIFY which
  578. // we don't seem to support in NT native DLC
  579. //
  580. typedef struct {
  581. WORD StationId; // SAP & link station Id
  582. WORD UserLength; // length of user area in buffer
  583. DWORD ReceivedDataExit; // address of routine to call with data
  584. DWORD FirstBuffer; // pointer to first buffer from pool
  585. DWORD Subroutine; // address of routine to call to get app buffer
  586. } LLC_DOS_RECEIVE_MODIFY_PARMS, *PLLC_DOS_RECEIVE_MODIFY_PARMS;
  587. //
  588. // LLC_DOS_TRANSMIT_PARMS this structure is identical to LLC_TRANSMIT_PARMS
  589. // except that there is no XMIT_READ_OPTION byte on the end, and the types of
  590. // the fields are different, although the sizes are the same: eg. DOS_ADDRESS
  591. // instead of PVOID or PLLC_XMIT_BUFFER
  592. //
  593. typedef struct _LLC_DOS_TRANSMIT_PARMS {
  594. WORD usStationId; // SAP and link station ID
  595. BYTE uchTransmitFs; // returned: Frame Status
  596. BYTE uchRemoteSap; // remote SAP we're talking to
  597. DOS_ADDRESS pXmitQueue1; // address of 1st buffer queue. Not pooled
  598. DOS_ADDRESS pXmitQueue2; // address of 2nd buffer queue. Pooled
  599. WORD cbBuffer1; // length of data in pBuffer1
  600. WORD cbBuffer2; // length of data in pBuffer2
  601. DOS_ADDRESS pBuffer1; // address of 1st data buffer
  602. DOS_ADDRESS pBuffer2; // address of 2nd data buffer
  603. } LLC_DOS_TRANSMIT_PARMS, *PLLC_DOS_TRANSMIT_PARMS;
  604. typedef struct _LLC_MODIFY_OPEN_PARMS {
  605. WORD usBufferSize; // block size of dlc buffers (>=80)
  606. WORD cPoolBlocks; // number of 16 bytes blocks in buffer
  607. DOS_ADDRESS dpPoolAddress;
  608. DOS_ADDRESS dpAdapterCheckExit;
  609. DOS_ADDRESS dpNetworkStatusExit;
  610. DOS_ADDRESS dpPcErrorExit;
  611. WORD usOpenOption;
  612. } LLC_MODIFY_OPEN_PARMS, *PLLC_MODIFY_OPEN_PARMS;
  613. typedef struct _DOS_DLC_DIRECT_PARMS {
  614. WORD usBufferSize; // block size of dlc buffers (>=80)
  615. WORD cPoolBlocks; // number of 16 bytes blocks in buffer
  616. DOS_ADDRESS dpPoolAddress; //
  617. DOS_ADDRESS dpAdapterCheckExit;
  618. DOS_ADDRESS dpNetworkStatusExit;
  619. DOS_ADDRESS dpPcErrorExit;
  620. DWORD ulReserved1;
  621. WORD usReserved2;
  622. WORD usReserved3;
  623. } DOS_DLC_DIRECT_PARMS, *PDOS_DLC_DIRECT_PARMS;
  624. typedef struct _DOS_DLC_OPEN_SAP_PARMS {
  625. WORD usStationId; // SAP or link station id
  626. WORD usUserStatValue; // reserved for user
  627. UCHAR uchT1; // response timer
  628. UCHAR uchT2; // aknowledgment timer
  629. UCHAR uchTi; // inactivity timer
  630. UCHAR uchMaxOut; // max tramists without ack
  631. UCHAR uchMaxIn; // max receives without ack
  632. UCHAR uchMaxOutIncr; // dynamic window increment value
  633. UCHAR uchMaxRetryCnt; // N2 value (retries)
  634. UCHAR uchMaxMembers; // maximum members for group SAP
  635. WORD usMaxI_Field; // maximum length of the Info field
  636. UCHAR uchSapValue; // SAP value to be assigned
  637. UCHAR uchOptionsPriority; // SAP options and access priority
  638. UCHAR uchcStationCount; // maximum number of link stations in sap
  639. UCHAR uchReserved2[2]; //
  640. UCHAR cGroupCount; // number of group SAPs of this SAP
  641. PUCHAR pGroupList; // offset to the group list
  642. DWORD DlcStatusFlags; // User notify flag for DLC status changes
  643. WORD usBufferSize; // size of individual buffer in bytes
  644. WORD cPoolBlocks; // number of 16-byte blocks in pool
  645. DOS_ADDRESS dpPoolAddress; // address of Buffer Pool (may be 0)
  646. } DOS_DLC_OPEN_SAP_PARMS, *PDOS_DLC_OPEN_SAP_PARMS;
  647. typedef struct _DOS_DIR_STATUS_PARMS {
  648. UCHAR auchPermanentAddress[6];// permanent encoded address
  649. UCHAR auchNodeAddress[6]; // adapter's network address
  650. UCHAR auchGroupAddress[4]; // adapter's group address
  651. UCHAR auchFunctAddr[4]; // adapter's functional address
  652. UCHAR uchMaxSap; // maximum allowable SAP
  653. UCHAR uchOpenSaps; // number of currently open saps
  654. UCHAR uchMaxStations; // max number of stations (always 253)
  655. UCHAR uchOpenStation; // number of open stations (only up to 253)
  656. UCHAR uchAvailStations; // number of available stations (always 253)
  657. UCHAR uchAdapterConfig; // adapter configuration flags
  658. UCHAR auchMicroCodeLevel[10]; // microcode level
  659. DOS_ADDRESS dpAdapterParmsAddr; // shared RAM address of adapter parms
  660. DOS_ADDRESS dpAdapterMacAddr; // shared RAM address of adapter MAC buffer
  661. DOS_ADDRESS dpTimerTick; // address of DLC timer tick counter
  662. USHORT usLastNetworkStatus; // most recent network status issued
  663. DOS_ADDRESS dpExtendedParms; // address of extended status table
  664. } DOS_DIR_STATUS_PARMS, *PDOS_DIR_STATUS_PARMS;
  665. typedef struct {
  666. DOS_ADDRESS dpAdapterCheckExit; // adapter check appendage
  667. DOS_ADDRESS dpNetworkStatusExit; // network status change appendage
  668. DOS_ADDRESS dpPcErrorExit; // workstation error appendage
  669. } LLC_DIR_SET_USER_APPENDAGE_PARMS, *PLLC_DIR_SET_USER_APPENDAGE_PARMS;
  670. #include <packoff.h>
  671. union _LLC_DOS_PARMS {
  672. LLC_BUFFER_FREE_PARMS BufferFree;
  673. LLC_BUFFER_GET_PARMS BufferGet;
  674. LLC_DLC_CONNECT_PARMS DlcConnectStation;
  675. LLC_DLC_MODIFY_PARMS DlcModify;
  676. LLC_DLC_OPEN_SAP_PARMS DlcOpenSap;
  677. LLC_DLC_OPEN_STATION_PARMS DlcOpenStation;
  678. LLC_DLC_REALLOCATE_PARMS DlcReallocate;
  679. LLC_DLC_SET_THRESHOLD_PARMS DlcSetThreshold;
  680. LLC_DLC_STATISTICS_PARMS DlcStatistics;
  681. LLC_DIR_INITIALIZE_PARMS DirInitialize;
  682. LLC_MODIFY_OPEN_PARMS DirModifyOpenParms;
  683. LLC_DIR_OPEN_ADAPTER_PARMS DirOpenAdapter;
  684. LLC_DIR_OPEN_DIRECT_PARMS DirOpenDirect;
  685. LLC_DIR_READ_LOG_PARMS DirReadLog;
  686. LLC_DIR_SET_EFLAG_PARMS DirSetExceptionFlags;
  687. LLC_DIR_SET_USER_APPENDAGE_PARMS DirSetUserAppendage;
  688. LLC_DIR_STATUS_PARMS DirStatus;
  689. DOS_DIR_STATUS_PARMS DosDirStatus;
  690. LLC_READ_PARMS Read;
  691. LLC_DOS_RECEIVE_PARMS_EX Receive;
  692. LLC_DOS_RECEIVE_PARMS DosReceive;
  693. LLC_TRANSMIT_PARMS Transmit;
  694. LLC_TRANSMIT2_COMMAND Transmit2;
  695. LLC_TRACE_INITIALIZE_PARMS TraceInitialize;
  696. DOS_DLC_OPEN_SAP_PARMS DosDlcOpenSap;
  697. };
  698. //
  699. // ADAPTER_TYPE - what type of network adapter we have - Token Ring, Ethernet
  700. // or (less likely) PC network
  701. //
  702. typedef enum {
  703. TokenRing,
  704. Ethernet,
  705. PcNetwork,
  706. UnknownAdapter
  707. } ADAPTER_TYPE;
  708. //
  709. // LOCAL_BUSY_STATE - a link station can be in 1 of 3 emulated local-busy
  710. // (buffer) states:
  711. //
  712. // NOT_BUSY
  713. // the station doesn't have any backed-up I-frames pending
  714. //
  715. // BUSY
  716. // the station is in emulated local-busy(buffer) state and a
  717. // DLC.FLOW.CONTROL(local-busy(buffer), set) has been sent to
  718. // the DLC device driver
  719. //
  720. // BUSY_BUFFER
  721. // to get out of BUSY state into CLEARING, we need at least one buffer and
  722. // a DLC.FLOW.CONTROL from the app. Because apps can issue DLC.FLOW.CONTROL
  723. // and BUFFER.FREE in the wrong order, we need an AND of these 2 commands
  724. // to get going again. So we have this intermediate state where we are
  725. // awaiting either command to restart I-Frame reception
  726. //
  727. // BUSY_FLOW
  728. // Together with BUSY_BUFFER, used to create a hysteresis whereby we can't
  729. // reach CLEARING from BUSY without getting both a DLC.FLOW.CONTROL and
  730. // BUFFER.FREE
  731. //
  732. // CLEARING
  733. // the VDM app has cleared the emulated local-busy state, but
  734. // the DLC device driver is still in local-busy (buffer) state.
  735. // When the last deferred I-Frame is indicated to the VDM app,
  736. // the NT device driver local-busy(buffer) state will be reset
  737. // and normal service will resume
  738. //
  739. //
  740. // State transitions:
  741. //
  742. // NOT_BUSY -> BUSY
  743. // occurs when we discover there aren't enough DOS buffers to
  744. // receive an I-Frame. This transition is distinguished by the
  745. // following actions:
  746. //
  747. // 1. DLC.FLOW.CONTROL(local-busy(buffer), set) is indicated to
  748. // the DLC device driver
  749. // 2. the received I-Frame is dequeued from the event queue for
  750. // this adapter and queued on the LocalBusyInfo.Queue
  751. // 3. a local-busy(buffer) DLC status change event is indicated to
  752. // the DOS DLC app
  753. //
  754. // BUSY -> BUSY_FLOW/BUSY_BUFFER
  755. // occurs when either a DLC.FLOW.CONTROL or BUFFER.FREE (resp) is issued
  756. //
  757. // BUSY_FLOW/BUSY_BUFFER -> CLEARING
  758. // occurs when the DOS DLC app indicates we can continue receiving.
  759. // This is done when the other (DLC.FLOW.CONTROL or BUFFER.FREE) required
  760. // command is issued
  761. // This transition is distinguished by the following actions:
  762. //
  763. // 1. DOS DLC app issues DLC.FLOW.CONTROL(local-busy(buffer), reset)
  764. // 2. DOS DLC app *may* issue BUFFER.FREE to return receive
  765. // buffers to the SAP pool
  766. //
  767. // CLEARING -> NOT_BUSY
  768. // occurs when we indicate the last deferred receive to the DOS DLC
  769. // app. At this point we can do the following:
  770. //
  771. // 1. issue DLC.FLOW.CONTROL(local-busy(buffer), reset) to the
  772. // device driver
  773. //
  774. // CLEARING -> BUSY
  775. // occurs when, during indicating deferred received I-Frames to the DOS
  776. // DLC app, we once again run out of buffers. Again, we indicate a DLC
  777. // status change of local-busy(buffer) to the DOS DLC app, but WE DO NOT
  778. // indicate local-busy(buffer) to the DLC device driver (it is still in
  779. // local-busy(buffer) state)
  780. //
  781. typedef enum {
  782. NOT_BUSY = 0,
  783. CLEARING,
  784. BUSY,
  785. BUSY_BUFFER,
  786. BUSY_FLOW
  787. } LOCAL_BUSY_STATE;
  788. //
  789. // LOCAL_BUSY_INFO - this structure maintains a local-busy(buffer) state
  790. // indicator and a pointer to a queue of deferred received I-Frames per link
  791. // station per adapter
  792. //
  793. typedef struct {
  794. //
  795. // State maintains the tri-state of the link station w.r.t. received I-Frames
  796. //
  797. // NOT_BUSY
  798. // nothing queued on Queue, get next completed event from event Q
  799. //
  800. // BUSY
  801. // local-busy(buffer) state has been set in DLC driver,
  802. // awaiting buffers & flow control command from DOS DLC app
  803. //
  804. // CLEARING
  805. // DOS DLC app has submitted DLC.FLOW.CONTROL(local_busy(buffer), reset)
  806. // command, we are now trying to indicate deferred received I-Frames to
  807. // DOS DLC app, pending enough DOS receive buffers
  808. //
  809. LOCAL_BUSY_STATE State;
  810. //
  811. // Queue - when in BUSY and CLEARING states, maintains a linked list of
  812. // completed NT READ CCBs containing received I-Frames
  813. //
  814. PLLC_CCB Queue;
  815. #if DBG
  816. //
  817. // track queue depth for each link station in debug version
  818. //
  819. DWORD Depth;
  820. #endif
  821. } LOCAL_BUSY_INFO;
  822. //
  823. // MAX_I_FRAME_DEPTH - we don't expect the queue of deferred I-Frames to grow
  824. // beyond this small number. The deferred I-Frame queue is a buffer between
  825. // running out of receive buffers & restarting I-Frame reception
  826. //
  827. #define MAX_I_FRAME_DEPTH 64 // !
  828. //
  829. // DOS_ADAPTER - there is one of these for each DOS adapter (i.e. 2 max.). The
  830. // structure contains information about the virtual state of each DOS adapter.
  831. // We record such information as the parameters used to open the adapter, the
  832. // exit addresses and the direct station information
  833. //
  834. typedef struct {
  835. //
  836. // AdapterType - tells us what type (class?) of adapter we are using. We
  837. // mainly use this to differentiate the types of values we return based
  838. // on whether this is a Token Ring adapter. We get the information from
  839. // the NT DIR.STATUS command
  840. //
  841. ADAPTER_TYPE AdapterType;
  842. //
  843. // IsOpen will be TRUE when this adapter has been successfully opened
  844. //
  845. BOOLEAN IsOpen;
  846. //
  847. // DirectStationOpen is TRUE when the direct station has been initialized
  848. // for this adapter. This is required because the direct station is opened
  849. // separately from the adapter in NT, but DOS expects both to be opened
  850. // simultaneously. Hence, we only issue a DIR.OPEN.DIRECT when the DOS app
  851. // issues a request for the direct station
  852. //
  853. BOOLEAN DirectStationOpen;
  854. //
  855. // if DirectReceive is TRUE then there is a receive outstanding on the
  856. // direct station for this adapter
  857. //
  858. BOOLEAN DirectReceive;
  859. //
  860. // if WaitingRestore is TRUE then we must get a DIR.RESTORE.OPEN.PARMS
  861. // before we can accept the next DIR.MODIFY.OPEN.PARMS
  862. //
  863. BOOLEAN WaitingRestore;
  864. //
  865. // BufferFree is TRUE when a BUFFER_FREE has been successfully issued for
  866. // any station ID belonging to this adapter
  867. //
  868. BOOLEAN BufferFree;
  869. //
  870. // BufferPool is the buffer pool for this adapter's direct station
  871. //
  872. PVOID BufferPool;
  873. //
  874. // CurrentExceptionHandlers and PreviousExceptionHandlers are the addresses
  875. // of exception 'exit' routines in DOS memory which are called asynchronously
  876. // if one of the special exceptions occurs. These are mapped to exception
  877. // flags in NT DLC and are presented as such in the READ CCB (ulCompletionFlag)
  878. //
  879. // exception handlers are always presented in the following order:
  880. //
  881. // Adapter Check Exit
  882. // Network Status Exit
  883. // PC Error Exit
  884. //
  885. DWORD CurrentExceptionHandlers[3];
  886. DWORD PreviousExceptionHandlers[3];
  887. //
  888. // DlcStatusChangeAppendage - this appendage pointer is supplied in DLC.OPEN.SAP
  889. // - one for each SAP. We need to keep them here because the emulator can
  890. // generate its own DLC status change call-backs (local-busy(buffer))
  891. //
  892. DWORD DlcStatusChangeAppendage[DOS_DLC_MAX_SAPS];
  893. //
  894. // LastNetworkStatusChange is the last network status change we recorded.
  895. // This is reported in DIR.STATUS
  896. //
  897. WORD LastNetworkStatusChange;
  898. //
  899. // UserStatusValue - we have to record the USER_STAT_VALUE from each
  900. // successful DLC.OPEN.SAP. This is returned to the DLC status change
  901. // appendage. We need this info for when we generate our own status change
  902. // event (ie when we detect emulated local busy (buffer) state)
  903. //
  904. WORD UserStatusValue[DOS_DLC_MAX_SAPS];
  905. //
  906. // AdapterParms are the actual adapter parameters that this adapter was
  907. // opened with - either specified in the DIR.OPEN.ADAPTER from the DOS
  908. // app, or those which we use internally when we automatically open the
  909. // adapter
  910. //
  911. ADAPTER_PARMS AdapterParms;
  912. //
  913. // DlcSpecified will be TRUE if the DLC_PARMS table was given when the
  914. // adapter was opened (either by DIR.OPEN.ADAPTER from DOS app, or by
  915. // DIR.OPEN.ADAPTER from automatic open)
  916. //
  917. BOOLEAN DlcSpecified;
  918. //
  919. // DlcParms - the DLC parameters specified in the open
  920. //
  921. DLC_PARMS DlcParms;
  922. //
  923. // AdapterCloseCcb - used in asynchronous adapter close when close is
  924. // initiated by emulator
  925. //
  926. LLC_CCB AdapterCloseCcb;
  927. //
  928. // DirectCloseCcb - used in asynchronous direct station close when close is
  929. // initiated by emulator
  930. //
  931. LLC_CCB DirectCloseCcb;
  932. //
  933. // ReadCcb - pointer to current READ CCB for this adapter
  934. //
  935. PLLC_CCB ReadCcb;
  936. //
  937. // EventQueueCritSec - must hold this while accessing EventQueue
  938. //
  939. CRITICAL_SECTION EventQueueCritSec;
  940. //
  941. // EventQueue - linked list of pending completed READ CCBs. These are linked
  942. // by pNext field which is not normally used by READ CCB. The event queue is
  943. // a serialized list of asynchronous events which have occurred for this
  944. // adapter. Events are command completions, transmit completions, received
  945. // data frames and status changes
  946. //
  947. PLLC_CCB EventQueueHead; // pointer to READ CCB at head of queue
  948. PLLC_CCB EventQueueTail; // " " " " " end " "
  949. DWORD QueueElements; // count of elements currently on EventQueue
  950. //
  951. // LocalBusyCritSec - must hold this while accessing DeferredReceives or
  952. // LocalBusyInfo array
  953. //
  954. CRITICAL_SECTION LocalBusyCritSec;
  955. //
  956. // DeferredReceives - reference count of number of link stations for this
  957. // adapter which are in local busy (buffer) state. Accessed while holding
  958. // LocalBusyCritSec. Serves as a boolean: check for !0 to discover if there
  959. // are deferred receives before checking all of LocalBusyInfo
  960. //
  961. DWORD DeferredReceives;
  962. //
  963. // FirstIndex and LastIndex - the start & stop points for searches through
  964. // LocalBusyInfo. These are used in an attempt to improve searching, since
  965. // for the vast majority of time, very few of the 255 possible slots in
  966. // LocalBusyInfo will be used
  967. //
  968. // NOTE: these are array indicies, NOT link station ids (index = id - 1)
  969. //
  970. DWORD FirstIndex;
  971. DWORD LastIndex;
  972. //
  973. // LocalBusyInfo - when a link station is in emulated local busy (buffer)
  974. // state, we dequeue any completed received I-Frames from the event queue
  975. // and link them onto the LocalBusyInfo list. For each adapter, there are
  976. // 255 lists - one per link station (there are 255 possible link stations
  977. // per adapter). The deferred receives are a list of completed NT READ CCBs
  978. // linked by CCB.pNext field. The lists serve as a buffer between realizing
  979. // we are out of buffers and the DLC device driver receiving the
  980. // DLC.FLOW.CONTROL(set, buffer) command. The lists are not expected to
  981. // grow very long
  982. //
  983. // This array combines the state of each link station for this adapter w.r.t.
  984. // local-busy(buffer) and maintains the list of deferred I-Frames.
  985. //
  986. // The array is accessed both by the main VDM thread and the EventHandlerThread
  987. // and so must only be accessed when holding LocalBusyCritSec
  988. //
  989. // Since there are 255 possible link stations per adapter and since the
  990. // Direct Station doesn't support link stations, link station 01 uses slot
  991. // 0, etc.
  992. //
  993. LOCAL_BUSY_INFO LocalBusyInfo[DOS_DLC_MAX_LINKS];
  994. } DOS_ADAPTER, *PDOS_ADAPTER;
  995. #define NO_LINKS_BUSY ((DWORD)0x7fffffff)
  996. //
  997. // DOS DLC prototypes and externals
  998. //
  999. extern PLLC_BUFFER aOverflowedData[];
  1000. extern DWORD OpenedAdapters;
  1001. extern DOS_ADDRESS dpVdmWindow;
  1002. //
  1003. // vrdlc5c.c
  1004. //
  1005. VOID
  1006. VrDlc5cHandler(
  1007. VOID
  1008. );
  1009. VOID
  1010. CompleteCcbProcessing(
  1011. IN LLC_STATUS Status,
  1012. IN LLC_DOS_CCB UNALIGNED * pCcb,
  1013. IN PLLC_PARMS pNtParms
  1014. );
  1015. LLC_STATUS
  1016. LlcCommand(
  1017. IN UCHAR AdapterNumber,
  1018. IN UCHAR Command,
  1019. IN DWORD Parameter
  1020. );
  1021. LLC_STATUS
  1022. BufferFree(
  1023. IN UCHAR AdapterNumber,
  1024. IN PVOID pFirstBuffer,
  1025. OUT LPWORD pusBuffersLeft
  1026. );
  1027. VOID
  1028. VrVdmWindowInit(
  1029. VOID
  1030. );
  1031. VOID
  1032. TerminateDlcEmulation(
  1033. VOID
  1034. );
  1035. //
  1036. // vrdlcbuf.c
  1037. //
  1038. VOID
  1039. InitializeBufferPools(
  1040. VOID
  1041. );
  1042. LLC_STATUS
  1043. CreateBufferPool(
  1044. IN DWORD PoolIndex,
  1045. IN DOS_ADDRESS dpBuffer,
  1046. IN WORD BufferCount,
  1047. IN WORD BufferSize
  1048. );
  1049. VOID
  1050. DeleteBufferPool(
  1051. IN DWORD PoolIndex
  1052. );
  1053. LLC_STATUS
  1054. GetBuffers(
  1055. IN DWORD PoolIndex,
  1056. IN WORD BuffersToGet,
  1057. IN DPLLC_DOS_BUFFER *pdpBuffer,
  1058. OUT LPWORD pusBuffersLeft,
  1059. IN BOOLEAN PartialList,
  1060. OUT PWORD BuffersGot OPTIONAL
  1061. );
  1062. LLC_STATUS
  1063. FreeBuffers(
  1064. IN DWORD PoolIndex,
  1065. IN DPLLC_DOS_BUFFER dpBuffer,
  1066. OUT LPWORD pusBuffersLeft
  1067. );
  1068. WORD
  1069. CalculateBufferRequirement(
  1070. IN UCHAR Adapter,
  1071. IN WORD StationId,
  1072. IN PLLC_BUFFER pFrame,
  1073. IN LLC_DOS_PARMS UNALIGNED * pDosParms,
  1074. OUT PWORD BufferSize
  1075. );
  1076. LLC_STATUS
  1077. CopyFrame(
  1078. IN PLLC_BUFFER pFrame,
  1079. IN DPLLC_DOS_BUFFER DosBuffers,
  1080. IN WORD UserLength,
  1081. IN WORD BufferSize,
  1082. IN DWORD Flags
  1083. );
  1084. BOOLEAN
  1085. AllBuffersInPool(
  1086. IN DWORD PoolIndex
  1087. );
  1088. //
  1089. // vrdlcpst.c
  1090. //
  1091. VOID
  1092. VrDlcInitialize(
  1093. VOID
  1094. );
  1095. BOOLEAN
  1096. VrDlcHwInterrupt(
  1097. VOID
  1098. );
  1099. BOOLEAN
  1100. ResetEmulatedLocalBusyState(
  1101. IN BYTE AdapterNumber,
  1102. IN WORD StationId,
  1103. IN BYTE DlcCommand
  1104. );
  1105. BOOLEAN
  1106. InitializeEventHandler(
  1107. VOID
  1108. );
  1109. PLLC_CCB
  1110. InitiateRead(
  1111. IN DWORD AdapterNumber,
  1112. OUT LLC_STATUS* ErrorStatus
  1113. );