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.

758 lines
20 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. asyncsft.h
  5. Abstract:
  6. Author:
  7. Environment:
  8. This driver is expected to work in DOS, OS2 and NT at the equivalent
  9. of kernal mode.
  10. Architecturally, there is an assumption in this driver that we are
  11. on a little endian machine.
  12. Notes:
  13. optional-notes
  14. Revision History:
  15. --*/
  16. #ifndef _ASYNCSFT_
  17. #define _ASYNCSFT_
  18. //
  19. // Memory tags
  20. //
  21. #define ASYNC_IOCTX_TAG '1ysA'
  22. #define ASYNC_INFO_TAG '2ysA'
  23. #define ASYNC_ADAPTER_TAG '3ysA'
  24. #define ASYNC_FRAME_TAG '4ysA'
  25. #define ASYNC_WORKITEM_TAG '5ysA'
  26. #define INLINE __inline
  27. //
  28. // UINT min(UINT a, UINT b)
  29. //
  30. #ifndef min
  31. #define min(a, b) ((a) <= (b) ? (a) : (b))
  32. #endif
  33. //
  34. // UINT max(UINT a, UINT b)
  35. //
  36. #ifndef max
  37. #define max(a, b) ((a) >= (b) ? (a) : (b))
  38. #endif
  39. #define MAKEWORD(l, h) ((USHORT) ((l) | ((h) << 8)))
  40. #define MAKELONG(l, h) ((ULONG) ((l) | ((h) << 16)))
  41. #define MAKE_SIGNATURE(a, b, c, d) MAKELONG(MAKEWORD(a, b), MAKEWORD(c, d))
  42. #define ASYNC_NDIS_MAJOR_VERSION 4
  43. #define ASYNC_NDIS_MINOR_VERSION 0
  44. // change these, just added these to compile.
  45. #define ETHERNET_HEADER_SIZE 14
  46. // what window size to request on the line-up indication
  47. #define ASYNC_WINDOW_SIZE 2
  48. //
  49. // PPP uses CIPX, and VJ TCP/IP header compression
  50. // the frame gets expanded inplace when decompressed.
  51. //
  52. #define PPP_PADDING 128
  53. #define MAC_NAME_SIZE 256
  54. //
  55. // ZZZ These macros are peculiar to NT.
  56. //
  57. #define ASYNC_MOVE_MEMORY(Destination,Source,Length) NdisMoveMemory(Destination,Source,Length)
  58. #define ASYNC_ZERO_MEMORY(Destination,Length) NdisZeroMemory(Destination,Length)
  59. /* Added this macro to eliminate problems caused by Tommy's redefinition and
  60. ** hard-coding of MaxFrameSize for PPP.
  61. */
  62. #define MaxFrameSizeWithPppExpansion(x) (((x)*2)+PPP_PADDING+100)
  63. typedef struct _OID_WORK_ITEM {
  64. WORK_QUEUE_ITEM WorkQueueItem;
  65. PVOID Context;
  66. } OID_WORK_ITEM, *POID_WORK_ITEM;
  67. //
  68. // Used to contain a queued operation.
  69. //
  70. typedef struct _ASYNC_PEND_DATA {
  71. PNDIS_REQUEST Next;
  72. struct _ASYNC_OPEN * Open;
  73. NDIS_REQUEST_TYPE RequestType;
  74. } ASYNC_PEND_DATA, * PASYNC_PEND_DATA;
  75. // o CRC errors are when the 16bit V.41 CRC check fails
  76. // o TimeoutErrors occur when inter-character delays within
  77. // a frame are exceeded
  78. // o AlignmentErrors occur when the SYN byte or ETX bytes which
  79. // mark the beginning and end of frames are not found.
  80. // o The other errors are standard UART errors returned by the serial driver
  81. typedef struct SERIAL_STATS SERIAL_STATS, *PSERIAL_STATS;
  82. struct SERIAL_STATS {
  83. ULONG CRCErrors; // Serial-like info only
  84. ULONG TimeoutErrors; // Serial-like info only
  85. ULONG AlignmentErrors; // Serial-like info only
  86. ULONG SerialOverrunErrors; // Serial-like info only
  87. ULONG FramingErrors; // Serial-like info only
  88. ULONG BufferOverrunErrors; // Serial-like info only
  89. };
  90. // The bytes transmitted, bytes received, frames received, frame transmitted
  91. // are monitored for frame and bytes going to the output device or
  92. // coming from the output device. If software compression used, it
  93. // is on top of this layer.
  94. typedef struct GENERIC_STATS GENERIC_STATS, *PGENERIC_STATS;
  95. struct GENERIC_STATS {
  96. ULONG BytesTransmitted; // Generic info
  97. ULONG BytesReceived; // Generic info
  98. ULONG FramesTransmitted; // Generic info
  99. ULONG FramesReceived; // Generic info
  100. };
  101. //
  102. // This macro will return a pointer to the reserved area of
  103. // a PNDIS_REQUEST.
  104. //
  105. #define PASYNC_PEND_DATA_FROM_PNDIS_REQUEST(Request) \
  106. ((PASYNC_PEND_DATA)((PVOID)((Request)->MacReserved)))
  107. //
  108. // This macros returns the enclosing NdisRequest.
  109. //
  110. #define PNDIS_REQUEST_FROM_PASYNC_PEND_DATA(PendOp)\
  111. ((PNDIS_REQUEST)((PVOID)(PendOp)))
  112. typedef struct ASYNC_CCB ASYNC_CCB, *PASYNC_CCB;
  113. // Every port will be atomically at some state. Typically states go into
  114. // intermediate states when they go from from closed to open and vice-versa.
  115. typedef enum _ASYNC_PORT_STATE {
  116. PORT_BOGUS, // PORT_BOGUS gets assigned the NULL value
  117. PORT_OPEN, // Port opened
  118. PORT_CLOSED, // Port closed
  119. PORT_CLOSING, // Port closing (cleaning up, deallocating)
  120. PORT_OPENING, // Port opening (checking arguments, allocating)
  121. PORT_FRAMING, // Port opened and sending/reading frames
  122. } ASYNC_PORT_STATE;
  123. #if DBG
  124. typedef struct _PENDING_REQUEST
  125. {
  126. LIST_ENTRY le;
  127. VOID *pvContext;
  128. ULONG Sig;
  129. ULONG lineNum;
  130. } PENDING_REQUEST;
  131. #define REF_ASYNCINFO(_pai, _context) \
  132. { \
  133. PENDING_REQUEST * _Request; \
  134. ASSERT((_pai)->RefCount > 0); \
  135. InterlockedIncrement(&(_pai)->RefCount); \
  136. _Request = ExAllocatePoolWithTag(NonPagedPool, \
  137. sizeof(PENDING_REQUEST), \
  138. 'nepA'); \
  139. if(NULL != _Request) \
  140. { \
  141. _Request->pvContext = _context; \
  142. _Request->Sig = __FILE_SIG__; \
  143. _Request->lineNum = __LINE__; \
  144. InsertTailList(&_pai->lePendingRequests, &_Request->le); \
  145. } \
  146. } \
  147. #define DEREF_ASYNCINFO(_pai, _context) \
  148. { \
  149. if(NULL != (_pai)) \
  150. { \
  151. LIST_ENTRY *_ple; \
  152. NdisAcquireSpinLock(&(_pai)->Lock); \
  153. ASSERT((_pai)->RefCount > 0); \
  154. InterlockedDecrement(&(_pai)->RefCount); \
  155. if((_pai)->RefCount == 0) \
  156. { \
  157. KeSetEvent(&(_pai)->AsyncEvent, 1, \
  158. FALSE); \
  159. } \
  160. for (_ple = _pai->lePendingRequests.Flink; \
  161. _ple != &_pai->lePendingRequests; \
  162. _ple = _ple->Flink) \
  163. { \
  164. if(((PENDING_REQUEST *)_ple)->pvContext == _context) \
  165. { \
  166. RemoveEntryList(_ple); \
  167. ExFreePoolWithTag(_ple, 'nepA'); \
  168. break; \
  169. } \
  170. } \
  171. NdisReleaseSpinLock(&(_pai)->Lock); \
  172. } \
  173. } \
  174. #else
  175. #define REF_ASYNCINFO(_pai, _context) \
  176. { \
  177. ASSERT((_pai)->RefCount > 0); \
  178. InterlockedIncrement(&(_pai)->RefCount); \
  179. } \
  180. #define DEREF_ASYNCINFO(_pai, _context) \
  181. { \
  182. if(NULL != (_pai)) \
  183. { \
  184. NdisAcquireSpinLock(&(_pai)->Lock); \
  185. ASSERT((_pai)->RefCount > 0); \
  186. InterlockedDecrement(&(_pai)->RefCount); \
  187. if((_pai)->RefCount == 0) \
  188. { \
  189. KeSetEvent(&(_pai)->AsyncEvent, 1, \
  190. FALSE); \
  191. } \
  192. NdisReleaseSpinLock(&(_pai)->Lock); \
  193. } \
  194. } \
  195. #endif
  196. //
  197. // The ASYNC_INFO structure is a per port field. The ASYNC_CONNECTION
  198. // field is embedded in it because it also a per port field.
  199. //
  200. struct ASYNC_INFO {
  201. LIST_ENTRY Linkage;
  202. ULONG RefCount;
  203. ULONG Flags;
  204. #define OID_WORK_SCHEDULED 0x00000001
  205. #define ASYNC_FLAG_CHECK_COMM_STATUS 0x00000002
  206. #define ASYNC_FLAG_ASYNCMAC_OPEN 0x00000004
  207. #define ASYNC_FLAG_SET_LINK_INFO 0x00000008
  208. #define ASYNC_FLAG_SEND_PACKET 0x00000010
  209. #define ASYNC_FLAG_SLIP_READ 0x00000020
  210. #define ASYNC_FLAG_PPP_READ 0x00000040
  211. #define ASYNC_FLAG_WAIT_MASK 0x00000080
  212. PASYNC_ADAPTER Adapter; // Back pointer to ADAPTER struct.
  213. PDEVICE_OBJECT DeviceObject; // Pointer to device object.
  214. ASYNC_PORT_STATE PortState; // OPEN, CLOSED, CLOSING, OPENING
  215. HANDLE Handle; // Port handle
  216. PFILE_OBJECT FileObject; // handle is dereferenced for IRPs
  217. KEVENT ClosingEvent; // we use this event to synch closing
  218. KEVENT DetectEvent; // sync the detect worker
  219. KEVENT AsyncEvent; // async event
  220. UINT QualOfConnect; // Defined by NDIS
  221. ULONG LinkSpeed; // in 100bps
  222. NDIS_HANDLE hNdisEndPoint;
  223. NDIS_HANDLE NdisLinkContext;
  224. LIST_ENTRY DDCDQueue;
  225. ULONG WaitMaskToUse ; // Wait mask used for reads.
  226. union {
  227. NDIS_WAN_GET_LINK_INFO GetLinkInfo; //... For OID requests.
  228. NDIS_WAN_SET_LINK_INFO SetLinkInfo;
  229. };
  230. // use for reading frames
  231. PASYNC_FRAME AsyncFrame; // allocated for READs (one frame only)
  232. WORK_QUEUE_ITEM WorkItem; // use to queue up first read thread
  233. UINT BytesWanted;
  234. UINT BytesRead;
  235. //... Statistics tracking
  236. SERIAL_STATS SerialStats; // Keep track of serial stats
  237. ULONG In;
  238. ULONG Out;
  239. UINT ReadStackCounter;
  240. ULONG ExtendedACCM[8]; //Extended ACCM bit masks (256 bits)
  241. NDIS_SPIN_LOCK Lock;
  242. #if DBG
  243. ULONG Pppreads;
  244. ULONG PppreadsCompleted;
  245. LIST_ENTRY lePendingRequests;
  246. #endif
  247. };
  248. //
  249. // This structure, and it corresponding per port structures are
  250. // allocated when we get AddAdapter.
  251. //
  252. struct ASYNC_ADAPTER {
  253. //
  254. // WAN information. for OID_WAN_GET_INFO request.
  255. //
  256. NDIS_WAN_INFO WanInfo;
  257. //
  258. // Keeps a reference count on the current number of uses of
  259. // this adapter block. Uses is defined to be the number of
  260. // routines currently within the "external" interface.
  261. //
  262. LONG RefCount;
  263. //
  264. // List of active ports
  265. //
  266. LIST_ENTRY ActivePorts;
  267. //
  268. // Spinlock to protect fields in this structure..
  269. //
  270. NDIS_SPIN_LOCK Lock;
  271. //
  272. // Handle given by NDIS at MPInit
  273. //
  274. NDIS_HANDLE MiniportHandle;
  275. //
  276. // Flag that when enabled lets routines know that a reset
  277. // is in progress.
  278. //
  279. BOOLEAN ResetInProgress;
  280. /*
  281. LIST_ENTRY FramePoolHead;
  282. LIST_ENTRY AllocPoolHead;
  283. */
  284. // It will handle most file operations and transport
  285. // operations known today. You pay about 44 bytes
  286. // per stacksize. The registry parameter 'IrpStackSize'
  287. // will change this default if it exists.
  288. UCHAR IrpStackSize;
  289. // Here we default to the ethernet max frame size
  290. // The regsitry parameter 'MaxFrameSize' will change
  291. // this default if it exists.
  292. /* Note: This is meaningful only for non-PPP framing. For PPP framing the
  293. ** value is currently the hard-coded DEFAULT_PPP_MAX_FRAME_SIZE.
  294. ** See also DEFAULT_EXPANDED_PPP_MAX_FRAME_SIZE;
  295. */
  296. ULONG MaxFrameSize;
  297. //
  298. // Number of ports this adapter owns.
  299. //
  300. USHORT NumPorts;
  301. // How many frames to allocate per port.
  302. // The registry parameter 'FramesPerPort' can change this value
  303. USHORT FramesPerPort;
  304. // Minimum inter character timeout
  305. ULONG TimeoutBase;
  306. // Tacked on to TimeoutBase based on the baud rate
  307. ULONG TimeoutBaud;
  308. // Timeout to use to resync if a frame is dropped
  309. ULONG TimeoutReSync;
  310. //
  311. // Serial driver should only complete sends when the
  312. // data hits the wire
  313. //
  314. ULONG WriteBufferingEnabled;
  315. //
  316. // Used to flag if we should escape the XON/XOFF characters
  317. // with the parity bit set (0x91, 0x93)
  318. //
  319. ULONG ExtendedXOnXOff;
  320. NPAGED_LOOKASIDE_LIST AsyncFrameList;
  321. };
  322. //
  323. // Define Maximum number of bytes a protocol can read during a
  324. // receive data indication.
  325. //
  326. #define ASYNC_MAX_LOOKAHEAD DEFAULT_MAX_FRAME_SIZE
  327. typedef struct _ASYNC_IO_CTX {
  328. BOOLEAN Sync;
  329. KEVENT Event; // use this event to signal completion
  330. IO_STATUS_BLOCK IoStatus; // use this to store Irp status
  331. PVOID Context;
  332. union {
  333. SERIAL_STATUS SerialStatus;
  334. SERIAL_QUEUE_SIZE SerialQueueSize;
  335. SERIAL_TIMEOUTS SerialTimeouts;
  336. SERIAL_CHARS SerialChars;
  337. SERIAL_COMMPROP CommProperties;
  338. UCHAR EscapeChar;
  339. UCHAR SerialPurge;
  340. ULONG WaitMask;
  341. ULONG WriteBufferingEnabled;
  342. };
  343. } ASYNC_IO_CTX, *PASYNC_IO_CTX;
  344. //
  345. // This macro will act a "epilogue" to every routine in the
  346. // *interface*. It will check whether any requests need
  347. // to defer their processing. It will also decrement the reference
  348. // count on the adapter.
  349. //
  350. // NOTE: This really does nothing now since there is no DPC for the AsyncMac.
  351. // --tommyd
  352. //
  353. // Note that we don't need to include checking for blocked receives
  354. // since blocked receives imply that there will eventually be an
  355. // interrupt.
  356. //
  357. // NOTE: This macro assumes that it is called with the lock acquired.
  358. //
  359. // ZZZ This routine is NT specific.
  360. //
  361. #define ASYNC_DO_DEFERRED(Adapter) \
  362. { \
  363. PASYNC_ADAPTER _A = (Adapter); \
  364. _A->References--; \
  365. NdisReleaseSpinLock(&_A->Lock); \
  366. }
  367. //
  368. // We define the external interfaces to the async driver.
  369. // These routines are only external to permit separate
  370. // compilation. Given a truely fast compiler they could
  371. // all reside in a single file and be static.
  372. //
  373. NTSTATUS
  374. AsyncSendPacket(
  375. IN PASYNC_INFO AsyncInfo,
  376. IN PNDIS_WAN_PACKET WanPacket);
  377. VOID
  378. AsyncIndicateFragment(
  379. IN PASYNC_INFO pInfo,
  380. IN ULONG Error);
  381. NTSTATUS
  382. AsyncStartReads(
  383. PASYNC_INFO pInfo);
  384. NTSTATUS
  385. AsyncSetupIrp(
  386. IN PASYNC_FRAME Frame,
  387. IN PIRP irp);
  388. VOID
  389. SetSerialStuff(
  390. PIRP irp,
  391. PASYNC_INFO pInfo,
  392. ULONG linkSpeed);
  393. VOID
  394. CancelSerialRequests(
  395. PASYNC_INFO pInfo);
  396. VOID
  397. SetSerialTimeouts(
  398. PASYNC_INFO pInfo,
  399. ULONG linkSpeed);
  400. VOID
  401. SerialSetEscapeChar(
  402. PASYNC_INFO pInfo,
  403. UCHAR EscapeChar);
  404. VOID
  405. SerialSetWaitMask(
  406. PASYNC_INFO pInfo,
  407. ULONG WaitMask);
  408. VOID
  409. SerialSetEventChar(
  410. PASYNC_INFO pInfo,
  411. UCHAR EventChar);
  412. VOID
  413. InitSerialIrp(
  414. PIRP irp,
  415. PASYNC_INFO pInfo,
  416. ULONG IoControlCode,
  417. ULONG InputBufferLength);
  418. NTSTATUS
  419. AsyncAllocateFrames(
  420. IN PASYNC_ADAPTER Adapter,
  421. IN UINT NumOfFrames);
  422. VOID
  423. AsyncSendLineUp(
  424. PASYNC_INFO pInfo);
  425. //
  426. // mp.c
  427. //
  428. VOID
  429. MpHalt(
  430. IN NDIS_HANDLE MiniportAdapterContext
  431. );
  432. NDIS_STATUS
  433. MpInit(
  434. OUT PNDIS_STATUS OpenErrorStatus,
  435. OUT PUINT SelectedMediumIndex,
  436. IN PNDIS_MEDIUM MediumArray,
  437. IN UINT MediumArraySize,
  438. IN NDIS_HANDLE MiniportAdapterContext,
  439. IN NDIS_HANDLE WrapperConfigurationContext
  440. );
  441. NDIS_STATUS
  442. MpQueryInfo(
  443. IN NDIS_HANDLE MiniportAdapterContext,
  444. IN NDIS_OID Oid,
  445. IN PVOID InformationBuffer,
  446. IN ULONG InformationBufferLength,
  447. OUT PULONG BytesWritten,
  448. OUT PULONG BytesNeeded
  449. );
  450. NDIS_STATUS
  451. MpReconfigure(
  452. OUT PNDIS_STATUS OpenErrorStatus,
  453. IN NDIS_HANDLE MiniportAdapterContext,
  454. IN NDIS_HANDLE WrapperConfigurationContext
  455. );
  456. NDIS_STATUS
  457. MpReset(
  458. OUT PBOOLEAN AddressingReset,
  459. IN NDIS_HANDLE MiniportAdapterContext
  460. );
  461. NDIS_STATUS
  462. MpSend(
  463. IN NDIS_HANDLE MiniportAdapterContext,
  464. IN NDIS_HANDLE NdisLinkHandle,
  465. IN PNDIS_WAN_PACKET Packet
  466. );
  467. NDIS_STATUS
  468. MpSetInfo(
  469. IN NDIS_HANDLE MiniportAdapterContext,
  470. IN NDIS_OID Oid,
  471. IN PVOID InformationBuffer,
  472. IN ULONG InformationBufferLength,
  473. OUT PULONG BytesRead,
  474. OUT PULONG BytesNeeded
  475. );
  476. //
  477. // crc.c
  478. //
  479. USHORT
  480. CalcCRC(
  481. PUCHAR Frame,
  482. UINT FrameSize);
  483. //
  484. // pppcrc.c
  485. //
  486. USHORT
  487. CalcCRCPPP(
  488. PUCHAR cp,
  489. UINT len);
  490. //
  491. // init.c
  492. //
  493. VOID
  494. AsyncSetupExternalNaming(
  495. PDRIVER_OBJECT DriverObject
  496. );
  497. VOID
  498. AsyncCleanupExternalNaming(VOID);
  499. //
  500. // io.c
  501. //
  502. PASYNC_IO_CTX
  503. AsyncAllocateIoCtx(
  504. BOOLEAN AllocateSync,
  505. PVOID Context
  506. );
  507. VOID
  508. AsyncFreeIoCtx(
  509. PASYNC_IO_CTX AsyncIoCtx
  510. );
  511. //
  512. // chkcomm.c
  513. //
  514. VOID
  515. AsyncCheckCommStatus(
  516. IN PASYNC_INFO pInfo);
  517. //
  518. // send.c
  519. //
  520. NDIS_STATUS
  521. AsyncTryToSendPacket(
  522. IN NDIS_HANDLE MacBindingHandle,
  523. IN PASYNC_INFO AsyncInfo,
  524. IN PASYNC_ADAPTER Adapter);
  525. //
  526. // pppread.c
  527. //
  528. NTSTATUS
  529. AsyncPPPWaitMask(
  530. IN PASYNC_INFO Info);
  531. NTSTATUS
  532. AsyncPPPRead(
  533. IN PASYNC_INFO Info);
  534. //
  535. // irps.c
  536. //
  537. VOID
  538. AsyncCancelQueued(
  539. PDEVICE_OBJECT DeviceObject,
  540. PIRP Irp);
  541. VOID
  542. AsyncCancelAllQueued(
  543. PLIST_ENTRY QueueToCancel);
  544. VOID
  545. AsyncQueueIrp(
  546. PLIST_ENTRY Queue,
  547. PIRP Irp);
  548. BOOLEAN
  549. TryToCompleteDDCDIrp(
  550. PASYNC_INFO pInfo);
  551. //
  552. // pppframe.c
  553. //
  554. VOID
  555. AssemblePPPFrame(
  556. PNDIS_WAN_PACKET Packet);
  557. //
  558. // slipframe.c
  559. //
  560. VOID
  561. AssembleSLIPFrame(
  562. PNDIS_WAN_PACKET Packet);
  563. VOID
  564. AssembleRASFrame(
  565. PNDIS_WAN_PACKET Packet);
  566. //
  567. // serial.c
  568. //
  569. NTSTATUS
  570. SerialIoSyncCompletionRoutine(
  571. IN PDEVICE_OBJECT DeviceObject,
  572. IN PIRP Irp,
  573. IN PVOID Context);
  574. NTSTATUS
  575. SerialIoAsyncCompletionRoutine(
  576. IN PDEVICE_OBJECT DeviceObject,
  577. IN PIRP Irp,
  578. IN PVOID Context);
  579. //
  580. // asyncmac.c
  581. //
  582. NTSTATUS
  583. AsyncDriverDispatch(
  584. IN PDEVICE_OBJECT DeviceObject,
  585. IN PIRP Irp);
  586. NTSTATUS
  587. AsyncDriverCreate(
  588. IN PDEVICE_OBJECT pDeviceObject,
  589. IN PIRP pIrp
  590. );
  591. NTSTATUS
  592. AsyncDriverCleanup(
  593. IN PDEVICE_OBJECT pDeviceObject,
  594. IN PIRP pIrp
  595. );
  596. #endif // _ASYNCSFT_