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.

2517 lines
60 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. Ndiswan.c
  5. Abstract:
  6. This is the initialization file for the NdisWan driver. This driver
  7. is a shim between the protocols, where it conforms to the NDIS 3.1
  8. Miniport interface spec, and the WAN Miniport drivers, where it exports
  9. the WAN Extensions for Miniports (it looks like a protocol to the WAN
  10. Miniport drivers).
  11. Author:
  12. Tony Bell (TonyBe) June 06, 1995
  13. Environment:
  14. Kernel Mode
  15. Revision History:
  16. TonyBe 06/06/95 Created
  17. --*/
  18. #include "wan.h"
  19. #define __FILE_SIG__ MEMORY_FILESIG
  20. #ifdef ALLOC_PRAGMA
  21. #pragma alloc_text(INIT, NdisWanCreateProtocolInfoTable)
  22. #endif
  23. EXPORT
  24. VOID
  25. NdisTapiDeregisterProvider(
  26. IN NDIS_HANDLE
  27. );
  28. //
  29. // Local function prototypes
  30. //
  31. PVOID
  32. AllocateWanPacket(
  33. IN POOL_TYPE PoolType,
  34. IN SIZE_T NumberOfBytes,
  35. IN ULONG Tag
  36. );
  37. VOID
  38. FreeWanPacket(
  39. PVOID WanPacket
  40. );
  41. //
  42. // End local function prototypes
  43. //
  44. PMINIPORTCB
  45. NdisWanAllocateMiniportCB(
  46. IN PNDIS_STRING AdapterName
  47. )
  48. /*++
  49. Routine Name:
  50. NdisWanAllocateMiniportCB
  51. Routine Description:
  52. This routine creates and initializes an MiniportCB
  53. Arguments:
  54. Return Values:
  55. --*/
  56. {
  57. PMINIPORTCB LocalMiniportCB;
  58. ULONG ulAllocationSize, i;
  59. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateMiniportCB: Enter"));
  60. //
  61. // Allocate and zero out the memory block
  62. //
  63. NdisWanAllocateMemory(&LocalMiniportCB, MINIPORTCB_SIZE, MINIPORTCB_TAG);
  64. if (LocalMiniportCB == NULL) {
  65. return (NULL);
  66. }
  67. NdisZeroMemory(LocalMiniportCB, MINIPORTCB_SIZE);
  68. //
  69. // setup the new control block
  70. //
  71. NdisAllocateSpinLock(&LocalMiniportCB->Lock);
  72. #ifdef MINIPORT_NAME
  73. NdisWanAllocateAdapterName(&LocalMiniportCB->AdapterName, AdapterName);
  74. #endif
  75. #if DBG
  76. InitializeListHead(&LocalMiniportCB->SendPacketList);
  77. InitializeListHead(&LocalMiniportCB->RecvPacketList);
  78. #endif
  79. InitializeListHead(&LocalMiniportCB->ProtocolCBList);
  80. InitializeListHead(&LocalMiniportCB->AfSapCBList);
  81. NdisWanInitializeSyncEvent(&LocalMiniportCB->HaltEvent);
  82. NdisWanClearSyncEvent(&LocalMiniportCB->HaltEvent);
  83. //
  84. // Add to global list
  85. //
  86. InsertTailGlobalList(MiniportCBList, &(LocalMiniportCB->Linkage));
  87. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("%ls MiniportCB: 0x%x, Number: %d",
  88. LocalMiniportCB->AdapterName.Buffer, LocalMiniportCB, MiniportCBList.ulCount));
  89. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateMiniportCB: Exit"));
  90. return (LocalMiniportCB);
  91. }
  92. VOID
  93. NdisWanFreeMiniportCB(
  94. IN PMINIPORTCB pMiniportCB
  95. )
  96. /*++
  97. Routine Name:
  98. NdisWanFreeMiniportCB
  99. Routine Description:
  100. This frees a MiniportCB
  101. Arguments:
  102. pMiniportCB - Pointer to to the MiniportCB that is being destroyed
  103. Return Values:
  104. None
  105. --*/
  106. {
  107. PMINIPORTCB mcb;
  108. BOOLEAN Found = FALSE;
  109. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanFreeMiniportCB: Enter"));
  110. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("MiniportCB: 0x%x", pMiniportCB));
  111. #ifdef MINIPORT_NAME
  112. NdisWanFreeNdisString(&pMiniportCB->AdapterName);
  113. #endif
  114. NdisFreeSpinLock(&pMiniportCB->Lock);
  115. NdisAcquireSpinLock(&MiniportCBList.Lock);
  116. RemoveEntryList(&pMiniportCB->Linkage);
  117. MiniportCBList.ulCount--;
  118. //
  119. // Walk the miniportcb list and see if this is the only
  120. // instance of this protocol. If it is we need to notify
  121. // user-mode that a protocol has been removed.
  122. //
  123. mcb = (PMINIPORTCB)MiniportCBList.List.Flink;
  124. while ((PVOID)mcb != (PVOID)&MiniportCBList.List) {
  125. if (mcb->ProtocolType == pMiniportCB->ProtocolType) {
  126. Found = TRUE;
  127. break;
  128. }
  129. mcb = (PMINIPORTCB)mcb->Linkage.Flink;
  130. }
  131. NdisReleaseSpinLock(&MiniportCBList.Lock);
  132. if (Found == FALSE) {
  133. PROTOCOL_INFO pinfo;
  134. NdisZeroMemory(&pinfo, sizeof(pinfo));
  135. pinfo.ProtocolType = pMiniportCB->ProtocolType;
  136. pinfo.Flags = PROTOCOL_UNBOUND;
  137. SetProtocolInfo(&pinfo);
  138. }
  139. NdisWanFreeMemory(pMiniportCB);
  140. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanFreeMiniportCB: Exit"));
  141. }
  142. POPENCB
  143. NdisWanAllocateOpenCB(
  144. IN PUNICODE_STRING BindName
  145. )
  146. /*++
  147. Routine Name:
  148. NdisWanAllocateOpenCB
  149. Routine Description:
  150. This routine creates and initializes a OpenCB
  151. Arguments:
  152. BindName - Pointer to an NDIS_STRING that has the name of the WAN Miniport
  153. that will be used in the NdisOpenAdapter call when we bind to
  154. the WAN Miniport.
  155. Return Values:
  156. --*/
  157. {
  158. POPENCB pOpenCB;
  159. ULONG ulAllocationSize;
  160. USHORT i;
  161. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateOpenCB: Enter"));
  162. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("BindName: %ls", BindName));
  163. //
  164. // Allocate memory for OpenCB
  165. //
  166. NdisWanAllocateMemory(&pOpenCB, OPENCB_SIZE, OPENCB_TAG);
  167. if (pOpenCB == NULL) {
  168. return (NULL);
  169. }
  170. NdisZeroMemory(pOpenCB, OPENCB_SIZE);
  171. NdisWanInitializeNotificationEvent(&pOpenCB->InitEvent);
  172. //
  173. // Parse out the GUID for this miniport
  174. //
  175. //
  176. // Setup new control block
  177. //
  178. NdisWanAllocateMemory(&pOpenCB->MiniportName.Buffer, BindName->MaximumLength, NDISSTRING_TAG);
  179. pOpenCB->MiniportName.MaximumLength = BindName->MaximumLength;
  180. pOpenCB->MiniportName.Length = BindName->Length;
  181. NdisWanCopyUnicodeString(&pOpenCB->MiniportName, BindName);
  182. //
  183. // Go to the end of the string and work back until we find
  184. // the first "{". Now start parsing the string converting
  185. // and copying from WCHAR to CHAR all digits until we hit
  186. // the closing "}".
  187. //
  188. for (i = pOpenCB->MiniportName.Length/sizeof(WCHAR); i > 0; i--) {
  189. if (pOpenCB->MiniportName.Buffer[i-1] == (WCHAR)L'{') {
  190. break;
  191. }
  192. }
  193. if (i != 0) {
  194. NDIS_STRING Src;
  195. Src.Length =
  196. BindName->Length - ((i-1)*sizeof(WCHAR));
  197. Src.MaximumLength =
  198. BindName->Length - ((i-1)*sizeof(WCHAR));
  199. Src.Buffer = &BindName->Buffer[i-1];
  200. RtlGUIDFromString(&Src, &pOpenCB->Guid);
  201. }
  202. NdisAllocateSpinLock(&pOpenCB->Lock);
  203. InitializeListHead(&pOpenCB->AfSapCBList);
  204. InitializeListHead(&pOpenCB->AfSapCBClosing);
  205. InitializeListHead(&pOpenCB->WanRequestList);
  206. #if DBG
  207. InitializeListHead(&pOpenCB->SendPacketList);
  208. #endif
  209. //
  210. // Put OpenCB on global list
  211. //
  212. InsertTailGlobalList(OpenCBList, &(pOpenCB->Linkage));
  213. pOpenCB->RefCount = 1;
  214. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("WanMiniport %ls OpenCB: 0x%x",
  215. pOpenCB->MiniportName.Buffer, pOpenCB));
  216. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateOpenCB: Exit"));
  217. return(pOpenCB);
  218. }
  219. VOID
  220. NdisWanFreeOpenCB(
  221. IN POPENCB pOpenCB
  222. )
  223. /*++
  224. Routine Name:
  225. NdisWanFreeOpenCB
  226. Routine Description:
  227. This routine frees a OpenCB
  228. Arguments:
  229. pOpenCB - Pointer to the OpenCB that is being destroyed
  230. Return Values:
  231. None
  232. --*/
  233. {
  234. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanFreeOpenCB: Enter - OpenCB: 0x%p", pOpenCB));
  235. if (pOpenCB->Flags & OPEN_LEGACY &&
  236. pOpenCB->Flags & SEND_RESOURCES) {
  237. NdisWanFreeSendResources(pOpenCB);
  238. }
  239. //
  240. // Remove from OpenCB global list
  241. //
  242. RemoveEntryGlobalList(OpenCBList, &(pOpenCB->Linkage));
  243. //
  244. // Free the memory allocated for the NDIS_STRING
  245. //
  246. NdisWanFreeNdisString(&pOpenCB->MiniportName);
  247. //
  248. // Free the memory allocated for the control block
  249. //
  250. NdisWanFreeMemory(pOpenCB);
  251. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanFreeOpenCB: Exit"));
  252. }
  253. PPROTOCOLCB
  254. NdisWanAllocateProtocolCB(
  255. IN PNDISWAN_ROUTE Route
  256. )
  257. /*++
  258. Routine Name:
  259. Routine Description:
  260. Arguments:
  261. Return Values:
  262. --*/
  263. {
  264. PPROTOCOLCB LocalProtocolCB;
  265. PUCHAR AllocatedMemory;
  266. PROTOCOL_INFO ProtocolInfo = {0};
  267. LocalProtocolCB =
  268. NdisAllocateFromNPagedLookasideList(&LinkProtoCBList);
  269. if (LocalProtocolCB == NULL) {
  270. return(NULL);
  271. }
  272. NdisZeroMemory(LocalProtocolCB, PROTOCOLCB_SIZE);
  273. LocalProtocolCB->Signature = PROTOCB_SIG;
  274. if (Route->ulBufferLength > 0) {
  275. NdisWanAllocateMemory(&AllocatedMemory,
  276. Route->ulBufferLength,
  277. PROTOCOLCB_TAG);
  278. if (AllocatedMemory == NULL) {
  279. NdisFreeToNPagedLookasideList(&LinkProtoCBList, LocalProtocolCB);
  280. return (NULL);
  281. }
  282. LocalProtocolCB->LineUpInfo = AllocatedMemory;
  283. }
  284. //
  285. // Copy the bindingname
  286. //
  287. if (Route->usBindingNameLength != 0) {
  288. USHORT usBindingNameLength;
  289. WCHAR BindingName[MAX_NAME_LENGTH+1] = {0};
  290. usBindingNameLength = Route->usBindingNameLength;
  291. //
  292. // We will limit the binding name string to 256 wchars
  293. //
  294. if (usBindingNameLength > (MAX_NAME_LENGTH * sizeof(WCHAR))) {
  295. usBindingNameLength = MAX_NAME_LENGTH * sizeof(WCHAR);
  296. }
  297. NdisMoveMemory((PUCHAR)BindingName,
  298. (PUCHAR)Route->BindingName,
  299. usBindingNameLength);
  300. NdisWanStringToNdisString(&LocalProtocolCB->BindingName, BindingName);
  301. }
  302. if (Route->usDeviceNameLength != 0) {
  303. USHORT usDeviceNameLength;
  304. usDeviceNameLength = Route->usDeviceNameLength;
  305. //
  306. // We will limit the binding name string to 256 wchars
  307. //
  308. if (usDeviceNameLength > (MAX_NAME_LENGTH * sizeof(WCHAR))) {
  309. usDeviceNameLength = (MAX_NAME_LENGTH * sizeof(WCHAR));
  310. }
  311. NdisWanAllocateMemory(&(LocalProtocolCB->InDeviceName.Buffer),
  312. usDeviceNameLength,
  313. NDISSTRING_TAG);
  314. if (LocalProtocolCB->InDeviceName.Buffer != NULL) {
  315. LocalProtocolCB->InDeviceName.MaximumLength = usDeviceNameLength;
  316. LocalProtocolCB->InDeviceName.Length = usDeviceNameLength;
  317. RtlCopyMemory((PUCHAR)LocalProtocolCB->InDeviceName.Buffer,
  318. (PUCHAR)Route->DeviceName,
  319. usDeviceNameLength);
  320. }
  321. }
  322. //
  323. // Copy over the protocol info
  324. //
  325. LocalProtocolCB->ulLineUpInfoLength = Route->ulBufferLength;
  326. if (Route->ulBufferLength != 0) {
  327. NdisMoveMemory(LocalProtocolCB->LineUpInfo,
  328. Route->Buffer,
  329. Route->ulBufferLength);
  330. }
  331. //
  332. // Setup the protocol type
  333. //
  334. LocalProtocolCB->ProtocolType = Route->usProtocolType;
  335. //
  336. // Get the PPP protocol value for this protocol type
  337. //
  338. ProtocolInfo.ProtocolType = Route->usProtocolType;
  339. if (GetProtocolInfo(&ProtocolInfo) != TRUE) {
  340. if (LocalProtocolCB->BindingName.Length != 0) {
  341. NdisWanFreeNdisString(&LocalProtocolCB->BindingName);
  342. }
  343. if (LocalProtocolCB->LineUpInfo != NULL) {
  344. NdisWanFreeMemory(LocalProtocolCB->LineUpInfo);
  345. }
  346. if (LocalProtocolCB->InDeviceName.Length != 0) {
  347. NdisWanFreeMemory(LocalProtocolCB->InDeviceName.Buffer);
  348. }
  349. NdisFreeToNPagedLookasideList(&LinkProtoCBList, LocalProtocolCB);
  350. return (NULL);
  351. }
  352. InitializeListHead(&LocalProtocolCB->VcList);
  353. NdisWanInitializeSyncEvent(&LocalProtocolCB->UnrouteEvent);
  354. LocalProtocolCB->PPPProtocolID = ProtocolInfo.PPPId;
  355. LocalProtocolCB->MTU = ProtocolInfo.MTU;
  356. LocalProtocolCB->TunnelMTU = ProtocolInfo.TunnelMTU;
  357. LocalProtocolCB->State = PROTOCOL_ROUTING;
  358. LocalProtocolCB->RefCount = 1;
  359. switch (Route->usProtocolType) {
  360. case PROTOCOL_IP:
  361. LocalProtocolCB->NonIdleDetectFunc = IpIsDataFrame;
  362. break;
  363. case PROTOCOL_IPX:
  364. LocalProtocolCB->NonIdleDetectFunc = IpxIsDataFrame;
  365. break;
  366. case PROTOCOL_NBF:
  367. LocalProtocolCB->NonIdleDetectFunc = NbfIsDataFrame;
  368. break;
  369. default:
  370. LocalProtocolCB->NonIdleDetectFunc = NULL;
  371. break;
  372. }
  373. NdisWanGetSystemTime(&LocalProtocolCB->LastNonIdleData);
  374. return(LocalProtocolCB);
  375. }
  376. VOID
  377. NdisWanFreeProtocolCB(
  378. IN PPROTOCOLCB ProtocolCB
  379. )
  380. /*++
  381. Routine Name:
  382. Routine Description:
  383. Arguments:
  384. Return Values:
  385. --*/
  386. {
  387. #if DBG
  388. {
  389. ULONG i;
  390. for (i = 0; i < MAX_MCML; i++) {
  391. ASSERT(ProtocolCB->PacketQueue[i].HeadQueue == NULL);
  392. ASSERT(ProtocolCB->PacketQueue[i].TailQueue == NULL);
  393. }
  394. }
  395. #endif
  396. if (ProtocolCB->InDeviceName.Length != 0) {
  397. NdisWanFreeMemory(ProtocolCB->InDeviceName.Buffer);
  398. }
  399. if (ProtocolCB->OutDeviceName.Length != 0) {
  400. NdisWanFreeNdisString(&ProtocolCB->OutDeviceName);
  401. }
  402. if (ProtocolCB->BindingName.Length != 0) {
  403. NdisWanFreeNdisString(&ProtocolCB->BindingName);
  404. }
  405. if (ProtocolCB->LineUpInfo != NULL) {
  406. NdisWanFreeMemory(ProtocolCB->LineUpInfo);
  407. }
  408. NdisFreeSpinLock(&ProtocolCB->Lock);
  409. NdisFreeToNPagedLookasideList(&LinkProtoCBList, ProtocolCB);
  410. }
  411. PLINKCB
  412. NdisWanAllocateLinkCB(
  413. IN POPENCB OpenCB,
  414. IN ULONG SendWindow
  415. )
  416. /*++
  417. Routine Name:
  418. NdisWanGetLinkCB
  419. Routine Description:
  420. This function returns a pointer to a LinkCB. The LinkCB is either retrieved
  421. from the WanAdapters free list or, if this list is empty, it is allocated.
  422. Arguments:
  423. OpenCB - Pointer to the WanAdapter control block that this Link is
  424. associated with
  425. Return Values:
  426. None
  427. --*/
  428. {
  429. PLINKCB LocalLinkCB;
  430. //
  431. // Figure out how much we need to allocate
  432. //
  433. LocalLinkCB =
  434. NdisAllocateFromNPagedLookasideList(&LinkProtoCBList);
  435. if (LocalLinkCB == NULL) {
  436. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for LinkCB"));
  437. return (NULL);
  438. }
  439. NdisZeroMemory(LocalLinkCB, LINKCB_SIZE);
  440. //
  441. // Initialize the control block
  442. //
  443. NdisWanInitializeSyncEvent(&LocalLinkCB->OutstandingFramesEvent);
  444. LocalLinkCB->Signature = LINKCB_SIG;
  445. LocalLinkCB->hLinkContext = NULL;
  446. LocalLinkCB->State = LINK_UP;
  447. LocalLinkCB->OpenCB = OpenCB;
  448. LocalLinkCB->OutstandingFrames = 0;
  449. LocalLinkCB->SendWindowOpen = TRUE;
  450. LocalLinkCB->SBandwidth = 100;
  451. LocalLinkCB->RBandwidth = 100;
  452. LocalLinkCB->SFlowSpec.MaxSduSize = glMaxMTU;
  453. LocalLinkCB->RFlowSpec.MaxSduSize = glMRRU;
  454. LocalLinkCB->LinkInfo.HeaderPadding = OpenCB->WanInfo.HeaderPadding;
  455. LocalLinkCB->LinkInfo.TailPadding = OpenCB->WanInfo.TailPadding;
  456. LocalLinkCB->LinkInfo.SendACCM =
  457. LocalLinkCB->LinkInfo.RecvACCM = OpenCB->WanInfo.DesiredACCM;
  458. LocalLinkCB->LinkInfo.MaxSendFrameSize = glMaxMTU;
  459. LocalLinkCB->LinkInfo.MaxRecvFrameSize = glMRU;
  460. if (OpenCB->Flags & OPEN_LEGACY) {
  461. LocalLinkCB->SendHandler = SendOnLegacyLink;
  462. } else {
  463. LocalLinkCB->SendHandler = SendOnLink;
  464. }
  465. if (OpenCB->MediumType == NdisMediumAtm ||
  466. (OpenCB->MediumType == NdisMediumWan &&
  467. (OpenCB->MediumSubType == NdisWanMediumAtm ||
  468. OpenCB->MediumSubType == NdisWanMediumPppoe)) ||
  469. (OpenCB->MediumType == NdisMediumCoWan &&
  470. (OpenCB->MediumSubType == NdisWanMediumAtm ||
  471. OpenCB->MediumSubType == NdisWanMediumPppoe))) {
  472. LocalLinkCB->RecvHandler = DetectBroadbandFraming;
  473. LocalLinkCB->LinkInfo.SendFramingBits =
  474. PPP_FRAMING | PPP_COMPRESS_ADDRESS_CONTROL;
  475. LocalLinkCB->LinkInfo.RecvFramingBits =
  476. PPP_FRAMING | PPP_COMPRESS_ADDRESS_CONTROL;
  477. } else {
  478. LocalLinkCB->RecvHandler = DetectFraming;
  479. }
  480. LocalLinkCB->SendWindow =
  481. (SendWindow == 0 || SendWindow > OpenCB->WanInfo.MaxTransmit) ?
  482. OpenCB->WanInfo.MaxTransmit : SendWindow;
  483. if (LocalLinkCB->SendWindow == 0) {
  484. LocalLinkCB->SendWindow = 1;
  485. }
  486. if (OpenCB->Flags & OPEN_LEGACY) {
  487. LocalLinkCB->SendResources = OpenCB->SendResources;
  488. } else {
  489. LocalLinkCB->SendResources = 1000;
  490. }
  491. NdisAllocateSpinLock(&LocalLinkCB->Lock);
  492. LocalLinkCB->RefCount = 1;
  493. REF_OPENCB(OpenCB);
  494. InterlockedIncrement(&OpenCB->ActiveLinkCount);
  495. return (LocalLinkCB);
  496. }
  497. VOID
  498. NdisWanFreeLinkCB(
  499. PLINKCB LinkCB
  500. )
  501. /*++
  502. Routine Name:
  503. Routine Description:
  504. Arguments:
  505. Return Values:
  506. --*/
  507. {
  508. POPENCB pOpenCB = LinkCB->OpenCB;
  509. ASSERT(LinkCB->OutstandingFrames == 0);
  510. LinkCB->State = LINK_DOWN;
  511. NdisFreeSpinLock(&LocalLinkCB->Lock);
  512. NdisFreeToNPagedLookasideList(&LinkProtoCBList, LinkCB);
  513. InterlockedDecrement(&pOpenCB->ActiveLinkCount);
  514. DEREF_OPENCB(pOpenCB);
  515. }
  516. NDIS_STATUS
  517. NdisWanAllocateSendResources(
  518. POPENCB OpenCB
  519. )
  520. /*++
  521. Routine Name:
  522. NdisWanAllocateSendResources
  523. Routine Description:
  524. Allocates all resources (SendDescriptors, WanPackets, ...)
  525. required for sending data. Should be called at line up time.
  526. Arguments:
  527. LinkCB - Pointer to the linkcb that the send resources will be attached to.
  528. SendWindow - Maximum number of sends that this link can handle
  529. Return Values:
  530. NDIS_STATUS_SUCCESS
  531. NDIS_STATUS_RESOURCES
  532. --*/
  533. {
  534. ULONG SendWindow;
  535. ULONG Endpoints;
  536. ULONG NumberOfPackets;
  537. ULONG BufferSize;
  538. ULONG WanPacketSize;
  539. PNDIS_WAN_PACKET WanPacket;
  540. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  541. do {
  542. //
  543. // We have to have atleast of sendwindow+1 of packets for
  544. // each link on the open. In the case of MCML we need
  545. // this amount for each fragment queue and for the
  546. // single non-fragment queue. So this leaves us with...
  547. //
  548. //
  549. // SendWindow + 1 + (glMaxMTU/glMinFragSize * MAX_MCML) *
  550. // number of links on the open
  551. //
  552. SendWindow = OpenCB->WanInfo.MaxTransmit;
  553. Endpoints = OpenCB->WanInfo.Endpoints;
  554. //
  555. // Sendwindow
  556. //
  557. NumberOfPackets = SendWindow;
  558. //
  559. // We keep track of how many fragmenting resources we have
  560. // available for each link
  561. //
  562. NumberOfPackets += ((glMaxMTU/glMinFragSize) * MAX_MCML);
  563. OpenCB->SendResources = NumberOfPackets;
  564. //
  565. // Add one for compression data manipulation
  566. //
  567. NumberOfPackets += 1;
  568. //
  569. // multiplied by the # of links on this open
  570. //
  571. NumberOfPackets *= Endpoints;
  572. //
  573. // The size of the buffer that we create is
  574. //
  575. BufferSize = OpenCB->WanInfo.MaxFrameSize +
  576. OpenCB->WanInfo.HeaderPadding +
  577. OpenCB->WanInfo.TailPadding +
  578. 40 + sizeof(PVOID);
  579. //
  580. // We assume compression is always on so we pad out 12%
  581. // incase the compressor expands. I don't know where the
  582. // 12% figure comes from.
  583. //
  584. BufferSize += (OpenCB->WanInfo.MaxFrameSize + 7) / 8;
  585. //
  586. // Make sure that the buffer is dword aligned.
  587. //
  588. BufferSize &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  589. OpenCB->BufferSize = BufferSize;
  590. WanPacketSize =
  591. sizeof(DATA_DESC) + sizeof(NDIS_WAN_PACKET) +
  592. 3*sizeof(PVOID) + BufferSize;
  593. //
  594. // If this device needs some special memory flags
  595. // we need to allocate memory for it's WanPackets now.
  596. // Otherwise we will intialize a lookaside list and
  597. // retrieve the packets as needed.
  598. if (OpenCB->WanInfo.MemoryFlags == 0) {
  599. NdisInitializeNPagedLookasideList(&OpenCB->WanPacketPool,
  600. AllocateWanPacket,
  601. FreeWanPacket,
  602. 0,
  603. WanPacketSize,
  604. WANPACKET_TAG,
  605. 0);
  606. } else {
  607. ULONG PacketMemorySize;
  608. PUCHAR PacketMemory;
  609. ULONG n;
  610. PacketMemorySize =
  611. WanPacketSize * NumberOfPackets;
  612. //
  613. // Allocate the memory for the wan packet buffer pool
  614. //
  615. NdisAllocateMemory(&PacketMemory,
  616. PacketMemorySize,
  617. OpenCB->WanInfo.MemoryFlags,
  618. OpenCB->WanInfo.HighestAcceptableAddress);
  619. if (PacketMemory == NULL) {
  620. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for BufferPool, AllocationSize: %d",
  621. PacketMemorySize));
  622. Status = NDIS_STATUS_RESOURCES;
  623. break;
  624. }
  625. OpenCB->PacketMemory = PacketMemory;
  626. OpenCB->PacketMemorySize = PacketMemorySize;
  627. NdisInitializeSListHead(&OpenCB->WanPacketList);
  628. for (n = 0; n < NumberOfPackets; n++) {
  629. PDATA_DESC DataDesc;
  630. //
  631. // Point to the DataDesc
  632. //
  633. DataDesc =
  634. (PDATA_DESC)PacketMemory;
  635. PacketMemory =
  636. ((PUCHAR)(DataDesc + 1) + sizeof(PVOID));
  637. (ULONG_PTR)PacketMemory &=
  638. ~((ULONG_PTR)sizeof(PVOID) - 1);
  639. //
  640. // Point to the WanPacket
  641. //
  642. WanPacket =
  643. (PNDIS_WAN_PACKET)PacketMemory;
  644. PacketMemory =
  645. ((PUCHAR)(WanPacket + 1) + sizeof(PVOID));
  646. (ULONG_PTR)PacketMemory &=
  647. ~((ULONG_PTR)sizeof(PVOID) - 1);
  648. //
  649. // Point to the begining of the data buffer
  650. //
  651. WanPacket->StartBuffer = PacketMemory;
  652. WanPacket->EndBuffer =
  653. PacketMemory + BufferSize - sizeof(PVOID);
  654. NdisInterlockedPushEntrySList(&OpenCB->WanPacketList,
  655. (PSINGLE_LIST_ENTRY)DataDesc,
  656. &OpenCB->Lock);
  657. PacketMemory += BufferSize + sizeof(PVOID);
  658. (ULONG_PTR)PacketMemory &=
  659. ~((ULONG_PTR)sizeof(PVOID) - 1);
  660. }
  661. }
  662. } while ( FALSE );
  663. if (Status == NDIS_STATUS_SUCCESS) {
  664. OpenCB->Flags |= SEND_RESOURCES;
  665. }
  666. return (Status);
  667. }
  668. VOID
  669. NdisWanFreeSendResources(
  670. POPENCB OpenCB
  671. )
  672. /*++
  673. Routine Name:
  674. NdisWanFreeSendResources
  675. Routine Description:
  676. This routine removes the WanPackets from this opencb's send list
  677. and free's the memory allocated for these packets. Should be called
  678. when we are cleaningup an opencb.
  679. Arguments:
  680. OpenCB - Pointer to the opencb that the resources are being freed from.
  681. Return Values:
  682. None
  683. --*/
  684. {
  685. PUCHAR PacketMemory;
  686. ULONG PacketMemorySize, Flags;
  687. PacketMemory = OpenCB->PacketMemory;
  688. PacketMemorySize = OpenCB->PacketMemorySize;
  689. Flags = OpenCB->WanInfo.MemoryFlags;
  690. if (OpenCB->WanInfo.MemoryFlags == 0) {
  691. NdisDeleteNPagedLookasideList(&OpenCB->WanPacketPool);
  692. return;
  693. }
  694. //
  695. // Remove the packets from the wan packet pool
  696. //
  697. for (; ;) {
  698. PDATA_DESC DataDesc;
  699. DataDesc = (PDATA_DESC)
  700. NdisInterlockedPopEntrySList(&OpenCB->WanPacketList,
  701. &OpenCB->Lock);
  702. if (DataDesc == NULL) {
  703. break;
  704. }
  705. }
  706. ASSERT(NdisQueryDepthSList(&OpenCB->WanPacketList) == 0);
  707. //
  708. // Free the block of memory allocated for this send
  709. //
  710. if (PacketMemory != NULL) {
  711. NdisFreeMemory(OpenCB->PacketMemory,
  712. OpenCB->PacketMemorySize,
  713. OpenCB->Flags);
  714. }
  715. }
  716. PBUNDLECB
  717. NdisWanAllocateBundleCB(
  718. VOID
  719. )
  720. /*++
  721. Routine Name:
  722. Routine Description:
  723. Arguments:
  724. Return Values:
  725. --*/
  726. {
  727. PBUNDLECB LocalBundleCB = NULL;
  728. PWSTR IOName = L"I/O ProtocolCB";
  729. PPROTOCOLCB ProtocolCB;
  730. PSAMPLE_TABLE SampleTable;
  731. PBOND_INFO BonDInfo;
  732. UINT Class;
  733. PUCHAR pMem;
  734. //
  735. // Allocation size is the size of the control block plus the size
  736. // of a table of pointers to protocolcb's that might be routed to
  737. // this bundle.
  738. //
  739. pMem =
  740. NdisAllocateFromNPagedLookasideList(&BundleCBList);
  741. if (pMem == NULL) {
  742. return (NULL);
  743. }
  744. NdisZeroMemory(pMem, BUNDLECB_SIZE);
  745. LocalBundleCB = (PBUNDLECB)pMem;
  746. pMem += sizeof(BUNDLECB) + sizeof(PVOID);
  747. //
  748. // This is the memory used for the I/O protocolcb
  749. //
  750. (PUCHAR)ProtocolCB = pMem;
  751. (ULONG_PTR)ProtocolCB &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  752. pMem += sizeof(PROTOCOLCB) + sizeof(PVOID);
  753. //
  754. // This is the protocolcb table
  755. //
  756. (PUCHAR)LocalBundleCB->ProtocolCBTable = pMem;
  757. (ULONG_PTR)LocalBundleCB->ProtocolCBTable &=
  758. ~((ULONG_PTR)sizeof(PVOID) - 1);
  759. pMem += (MAX_PROTOCOLS * sizeof(PPROTOCOLCB)) + sizeof(PVOID);
  760. //
  761. // Initialize the BundleCB
  762. //
  763. NdisAllocateSpinLock(&LocalBundleCB->Lock);
  764. InitializeListHead(&LocalBundleCB->LinkCBList);
  765. for (Class = 0; Class < MAX_MCML; Class++) {
  766. PRECV_DESC RecvDescHole;
  767. PSEND_FRAG_INFO FragInfo;
  768. PBUNDLE_RECV_INFO RecvInfo;
  769. FragInfo = &LocalBundleCB->SendFragInfo[Class];
  770. RecvInfo = &LocalBundleCB->RecvInfo[Class];
  771. InitializeListHead(&FragInfo->FragQueue);
  772. FragInfo->MinFragSize = glMinFragSize;
  773. FragInfo->MaxFragSize = glMaxFragSize;
  774. InitializeListHead(&RecvInfo->AssemblyList);
  775. //
  776. // Init the recv hole desc
  777. //
  778. RecvDescHole =
  779. NdisWanAllocateRecvDesc(0);
  780. if (RecvDescHole == NULL) {
  781. UINT i;
  782. for (i = 0; i < MAX_MCML; i++) {
  783. RecvInfo = &LocalBundleCB->RecvInfo[i];
  784. if (RecvInfo->RecvDescHole != NULL) {
  785. NdisWanFreeRecvDesc(RecvInfo->RecvDescHole);
  786. }
  787. }
  788. NdisFreeToNPagedLookasideList(&BundleCBList, LocalBundleCB);
  789. return (NULL);
  790. }
  791. RecvDescHole->Flags = MULTILINK_HOLE_FLAG;
  792. RecvInfo->RecvDescHole = RecvDescHole;
  793. InsertHeadList(&RecvInfo->AssemblyList, &RecvDescHole->Linkage);
  794. RecvInfo->AssemblyCount++;
  795. }
  796. InitializeListHead(&LocalBundleCB->ProtocolCBList);
  797. NdisWanInitializeSyncEvent(&LocalBundleCB->OutstandingFramesEvent);
  798. LocalBundleCB->State = BUNDLE_UP;
  799. LocalBundleCB->FramingInfo.MaxRSendFrameSize = glMaxMTU;
  800. LocalBundleCB->FramingInfo.MaxRRecvFrameSize = glMRRU;
  801. LocalBundleCB->SFlowSpec.MaxSduSize = glMaxMTU;
  802. LocalBundleCB->RFlowSpec.MaxSduSize = glMRRU;
  803. NdisWanGetSystemTime(&LocalBundleCB->LastNonIdleData);
  804. LocalBundleCB->SendCompInfo.CompType =
  805. LocalBundleCB->RecvCompInfo.CompType = COMPTYPE_NONE;
  806. //
  807. // Add the protocolcb to the bundle's table and list
  808. //
  809. ProtocolCB->ProtocolType = PROTOCOL_PRIVATE_IO;
  810. ProtocolCB->PPPProtocolID = PPP_PROTOCOL_PRIVATE_IO;
  811. ProtocolCB->BundleCB = LocalBundleCB;
  812. ProtocolCB->State = PROTOCOL_ROUTED;
  813. NdisWanStringToNdisString(&ProtocolCB->InDeviceName, IOName);
  814. LocalBundleCB->IoProtocolCB = ProtocolCB;
  815. return (LocalBundleCB);
  816. }
  817. VOID
  818. NdisWanFreeBundleCB(
  819. IN PBUNDLECB BundleCB
  820. )
  821. /*++
  822. Routine Name:
  823. Routine Description:
  824. Arguments:
  825. Return Values:
  826. --*/
  827. {
  828. UINT Class;
  829. PPROTOCOLCB IoProtocolCB;
  830. PPACKET_QUEUE PacketQueue;
  831. FlushAssemblyLists(BundleCB);
  832. if (BundleCB->Flags & BOND_ENABLED) {
  833. RemoveEntryGlobalList(BonDWorkList, &BundleCB->BonDLinkage);
  834. }
  835. //
  836. // Free the hole place holders
  837. //
  838. for (Class = 0; Class < MAX_MCML; Class++) {
  839. PBUNDLE_RECV_INFO RecvInfo =
  840. &BundleCB->RecvInfo[Class];
  841. ASSERT(RecvInfo->RecvDescHole != NULL);
  842. NdisWanFreeRecvDesc(RecvInfo->RecvDescHole);
  843. RecvInfo->RecvDescHole = NULL;
  844. }
  845. #if 0
  846. KeCancelTimer(&BundleCB->BonDTimer);
  847. #endif
  848. IoProtocolCB = BundleCB->IoProtocolCB;
  849. PacketQueue = &IoProtocolCB->PacketQueue[MAX_MCML];
  850. ASSERT(IsPacketQueueEmpty(PacketQueue));
  851. //
  852. // If we have ppp packets queued we need
  853. // to flush them and free the memory!
  854. //
  855. while (!IsPacketQueueEmpty(PacketQueue)) {
  856. PNDIS_PACKET Packet;
  857. Packet =
  858. RemoveHeadPacketQueue(PacketQueue)
  859. CompleteNdisPacket(IoProtocolCB->MiniportCB,
  860. IoProtocolCB,
  861. Packet);
  862. }
  863. sl_compress_terminate(&BundleCB->VJCompress);
  864. if (BundleCB->Flags & SEND_CCP_ALLOCATED) {
  865. WanDeallocateCCP(BundleCB,
  866. &BundleCB->SendCompInfo,
  867. TRUE);
  868. BundleCB->Flags &= ~SEND_CCP_ALLOCATED;
  869. }
  870. if (BundleCB->Flags & RECV_CCP_ALLOCATED) {
  871. WanDeallocateCCP(BundleCB,
  872. &BundleCB->RecvCompInfo,
  873. FALSE);
  874. BundleCB->Flags &= ~RECV_CCP_ALLOCATED;
  875. }
  876. if (BundleCB->Flags & SEND_ECP_ALLOCATED) {
  877. WanDeallocateECP(BundleCB,
  878. &BundleCB->SendCompInfo,
  879. &BundleCB->SendCryptoInfo);
  880. BundleCB->Flags &= ~SEND_ECP_ALLOCATED;
  881. }
  882. if (BundleCB->Flags & RECV_ECP_ALLOCATED) {
  883. WanDeallocateECP(BundleCB,
  884. &BundleCB->RecvCompInfo,
  885. &BundleCB->RecvCryptoInfo);
  886. BundleCB->Flags &= ~RECV_ECP_ALLOCATED;
  887. }
  888. if (BundleCB->BonDAllocation != NULL) {
  889. NdisWanFreeMemory(BundleCB->BonDAllocation);
  890. BundleCB->BonDAllocation = NULL;
  891. }
  892. BundleCB->State = BUNDLE_DOWN;
  893. NdisFreeSpinLock(&BundleCB->Lock);
  894. NdisWanFreeNdisString(&BundleCB->IoProtocolCB->InDeviceName);
  895. NdisFreeToNPagedLookasideList(&BundleCBList, BundleCB);
  896. }
  897. NDIS_STATUS
  898. NdisWanCreateProtocolInfoTable(
  899. VOID
  900. )
  901. /*++
  902. Routine Name:
  903. Routine Description:
  904. Arguments:
  905. Return Values:
  906. --*/
  907. {
  908. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  909. ULONG ulAllocationSize = 0;
  910. PUCHAR AllocatedMemory;
  911. PROTOCOL_INFO ProtocolInfo;
  912. //
  913. // Allocate ProtocolLookupTable. This table is used to match protocol values
  914. // with their corresponding PPP Protocol values. The table size is set to
  915. // MAX_PROTOCOLS.
  916. //
  917. ulAllocationSize = sizeof(PROTOCOL_INFO_TABLE) +
  918. (sizeof(PROTOCOL_INFO) * MAX_PROTOCOLS);
  919. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize, PROTOCOLTABLE_TAG);
  920. if (AllocatedMemory == NULL) {
  921. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  922. ("Failed allocating memory for ProtocolLookupTable! TableSize: %d",
  923. ulAllocationSize));
  924. return (NDIS_STATUS_RESOURCES);
  925. }
  926. ProtocolInfoTable = (PPROTOCOL_INFO_TABLE)AllocatedMemory;
  927. //
  928. // Save the allocation size
  929. //
  930. ProtocolInfoTable->ulAllocationSize = ulAllocationSize;
  931. //
  932. // Store the array size. This should be read from the registry
  933. //
  934. ProtocolInfoTable->ulArraySize = MAX_PROTOCOLS;
  935. NdisAllocateSpinLock(&ProtocolInfoTable->Lock);
  936. //
  937. // Setup the pointer to the ProtocolValue array
  938. //
  939. AllocatedMemory += sizeof(PROTOCOL_INFO_TABLE);
  940. ProtocolInfoTable->ProtocolInfo = (PPROTOCOL_INFO)(AllocatedMemory);
  941. //
  942. // Insert default values for Netbuei, IP, IPX
  943. //
  944. ProtocolInfo.ProtocolType = PROTOCOL_PRIVATE_IO;
  945. ProtocolInfo.PPPId = PPP_PROTOCOL_PRIVATE_IO;
  946. ProtocolInfo.MTU = DEFAULT_MTU;
  947. ProtocolInfo.TunnelMTU = DEFAULT_MTU;
  948. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  949. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  950. SetProtocolInfo(&ProtocolInfo);
  951. ProtocolInfo.ProtocolType = PROTOCOL_IP;
  952. ProtocolInfo.PPPId = PPP_PROTOCOL_IP;
  953. ProtocolInfo.MTU = DEFAULT_MTU;
  954. ProtocolInfo.TunnelMTU = DEFAULT_TUNNEL_MTU;
  955. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  956. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  957. SetProtocolInfo(&ProtocolInfo);
  958. ProtocolInfo.ProtocolType = PROTOCOL_IPX;
  959. ProtocolInfo.PPPId = PPP_PROTOCOL_IPX;
  960. ProtocolInfo.MTU = DEFAULT_MTU;
  961. ProtocolInfo.TunnelMTU = DEFAULT_MTU;
  962. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  963. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  964. SetProtocolInfo(&ProtocolInfo);
  965. ProtocolInfo.ProtocolType = PROTOCOL_NBF;
  966. ProtocolInfo.PPPId = PPP_PROTOCOL_NBF;
  967. ProtocolInfo.MTU = DEFAULT_MTU;
  968. ProtocolInfo.TunnelMTU = DEFAULT_MTU;
  969. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  970. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  971. SetProtocolInfo(&ProtocolInfo);
  972. ProtocolInfo.ProtocolType = PROTOCOL_APPLETALK;
  973. ProtocolInfo.PPPId = PPP_PROTOCOL_APPLETALK;
  974. ProtocolInfo.MTU = DEFAULT_MTU;
  975. ProtocolInfo.TunnelMTU = DEFAULT_MTU;
  976. ProtocolInfo.PacketQueueDepth = DEFAULT_PACKETQUEUE_DEPTH;
  977. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  978. SetProtocolInfo(&ProtocolInfo);
  979. return (Status);
  980. }
  981. VOID
  982. NdisWanDestroyProtocolInfoTable(
  983. VOID
  984. )
  985. /*++
  986. Routine Name:
  987. Routine Description:
  988. Arguments:
  989. Return Values:
  990. --*/
  991. {
  992. NdisFreeSpinLock(&ProtocolInfoTable->Lock);
  993. NdisWanFreeMemory(ProtocolInfoTable);
  994. }
  995. NDIS_STATUS
  996. NdisWanCreateConnectionTable(
  997. ULONG TableSize
  998. )
  999. /*++
  1000. Routine Name:
  1001. Routine Description:
  1002. Arguments:
  1003. Return Values:
  1004. --*/
  1005. {
  1006. ULONG ulAllocationSize = 0;
  1007. ULONG ulArraySize;
  1008. PUCHAR AllocatedMemory;
  1009. PCONNECTION_TABLE NewTable;
  1010. //
  1011. // Since we skip the first place in the tables we increase the
  1012. // size by one.
  1013. //
  1014. ulArraySize = TableSize + 1;
  1015. //
  1016. // Allocate the Bundle and Link Arrays based on the number of possible connections
  1017. // that we have in the system. This should be grown if we get called
  1018. // to reinitialize and gain new ports.
  1019. //
  1020. ulAllocationSize = sizeof(CONNECTION_TABLE) +
  1021. (sizeof(PBUNDLECB) * ulArraySize) +
  1022. (sizeof(PLINKCB) * ulArraySize);
  1023. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize, CONNECTIONTABLE_TAG);
  1024. if (AllocatedMemory == NULL) {
  1025. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1026. ("Failed allocating memory for ConnectionTable! Size: %d, Links: %d",
  1027. ulAllocationSize, TableSize));
  1028. return (NDIS_STATUS_RESOURCES);
  1029. }
  1030. NewTable = (PCONNECTION_TABLE)AllocatedMemory;
  1031. //
  1032. // This is the amount of memory we allocated
  1033. //
  1034. NewTable->ulAllocationSize = ulAllocationSize;
  1035. NewTable->ulArraySize = TableSize;
  1036. NewTable->ulNextLink =
  1037. NewTable->ulNextBundle = 1;
  1038. InitializeListHead(&NewTable->BundleList);
  1039. InitializeListHead(&NewTable->LinkList);
  1040. //
  1041. // Setup pointer to the linkcb array
  1042. //
  1043. AllocatedMemory += sizeof(CONNECTION_TABLE);
  1044. NewTable->LinkArray = (PLINKCB*)(AllocatedMemory);
  1045. //
  1046. // Setup the pointer to the bundlecb array
  1047. //
  1048. AllocatedMemory += (sizeof(PLINKCB) * ulArraySize);
  1049. NewTable->BundleArray = (PBUNDLECB*)(AllocatedMemory);
  1050. if (ConnectionTable != NULL) {
  1051. PCONNECTION_TABLE FreeTable;
  1052. //
  1053. // We must be growing the table. This will be
  1054. // called with the current connectiontable lock
  1055. // held!
  1056. //
  1057. NewTable->ulNumActiveLinks = ConnectionTable->ulNumActiveLinks;
  1058. NewTable->ulNumActiveBundles = ConnectionTable->ulNumActiveBundles;
  1059. NewTable->ulNextLink = ConnectionTable->ulNextLink;
  1060. NewTable->ulNextBundle = ConnectionTable->ulNextBundle;
  1061. NdisMoveMemory((PUCHAR)NewTable->LinkArray,
  1062. (PUCHAR)ConnectionTable->LinkArray,
  1063. ConnectionTable->ulArraySize * sizeof(PLINKCB));
  1064. NdisMoveMemory((PUCHAR)NewTable->BundleArray,
  1065. (PUCHAR)ConnectionTable->BundleArray,
  1066. ConnectionTable->ulArraySize * sizeof(PBUNDLECB));
  1067. while (!IsListEmpty(&ConnectionTable->BundleList)) {
  1068. PBUNDLECB BundleCB;
  1069. BundleCB = (PBUNDLECB)RemoveHeadList(&ConnectionTable->BundleList);
  1070. InsertTailList(&NewTable->BundleList, &BundleCB->Linkage);
  1071. }
  1072. while (!IsListEmpty(&ConnectionTable->LinkList)) {
  1073. PLIST_ENTRY Entry;
  1074. PLINKCB LinkCB;
  1075. Entry = RemoveHeadList(&ConnectionTable->LinkList);
  1076. LinkCB =
  1077. (PLINKCB)CONTAINING_RECORD(Entry, LINKCB, ConnTableLinkage);
  1078. InsertTailList(&NewTable->LinkList, &LinkCB->ConnTableLinkage);
  1079. }
  1080. FreeTable = ConnectionTable;
  1081. ConnectionTable = NewTable;
  1082. //
  1083. // Destroy the old table
  1084. //
  1085. NdisWanFreeMemory(FreeTable);
  1086. } else {
  1087. ConnectionTable = NewTable;
  1088. }
  1089. return (NDIS_STATUS_SUCCESS);
  1090. }
  1091. PNDIS_PACKET
  1092. NdisWanAllocateNdisPacket(
  1093. ULONG MagicNumber
  1094. )
  1095. {
  1096. PNDIS_PACKET ReturnPacket = NULL;
  1097. PPOOL_DESC PoolDesc;
  1098. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1099. ULONG i;
  1100. PSINGLE_LIST_ENTRY p = NULL;
  1101. PNDISWAN_PROTOCOL_RESERVED pres;
  1102. NdisAcquireSpinLock(&PacketPoolList.Lock);
  1103. //
  1104. // Walk the pool desc list and try to allocate a packet
  1105. //
  1106. PoolDesc = (PPOOL_DESC)PacketPoolList.List.Flink;
  1107. while (PoolDesc != (PPOOL_DESC)&PacketPoolList.List) {
  1108. p = PopEntryList(&PoolDesc->Head);
  1109. if (p != NULL) {
  1110. break;
  1111. }
  1112. PoolDesc = (PPOOL_DESC)PoolDesc->Linkage.Flink;
  1113. }
  1114. if (p == NULL) {
  1115. //
  1116. // We have walked the pool list and did not find any
  1117. // free packets on any of the free pools, so allocate
  1118. // a new pool and get a packet from it.
  1119. //
  1120. NdisWanAllocatePriorityMemory(&PoolDesc,
  1121. sizeof(POOL_DESC),
  1122. POOLDESC_TAG,
  1123. NormalPoolPriority);
  1124. if (PoolDesc == NULL) {
  1125. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1126. return (NULL);
  1127. }
  1128. NdisAllocatePacketPoolEx(&Status,
  1129. &PoolDesc->PoolHandle,
  1130. glPacketPoolCount,
  1131. 0,
  1132. sizeof(NDISWAN_PROTOCOL_RESERVED));
  1133. if (Status != NDIS_STATUS_SUCCESS) {
  1134. NdisWanFreeMemory(PoolDesc);
  1135. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1136. return (NULL);
  1137. }
  1138. for (i = 0; i < glPacketPoolCount; i++) {
  1139. PNDIS_PACKET np;
  1140. NdisAllocatePacket(&Status,
  1141. &np,
  1142. PoolDesc->PoolHandle);
  1143. ASSERT(np != NULL);
  1144. pres = PPROTOCOL_RESERVED_FROM_NDIS(np);
  1145. PushEntryList(&PoolDesc->Head, &pres->SLink);
  1146. PoolDesc->FreeCount++;
  1147. }
  1148. InsertTailList(&PacketPoolList.List, &PoolDesc->Linkage);
  1149. PacketPoolList.TotalDescCount++;
  1150. PacketPoolList.FreeCount += PoolDesc->FreeCount;
  1151. if (PacketPoolList.TotalDescCount >
  1152. PacketPoolList.MaxDescCount) {
  1153. PacketPoolList.MaxDescCount = PacketPoolList.TotalDescCount;
  1154. }
  1155. p = PopEntryList(&PoolDesc->Head);
  1156. }
  1157. ASSERT(p != NULL);
  1158. pres = CONTAINING_RECORD(p, NDISWAN_PROTOCOL_RESERVED, SLink);
  1159. ReturnPacket = CONTAINING_RECORD(pres, NDIS_PACKET, ProtocolReserved);
  1160. NdisReinitializePacket(ReturnPacket);
  1161. PoolDesc->AllocatedCount++;
  1162. PoolDesc->FreeCount--;
  1163. ASSERT((PoolDesc->AllocatedCount + PoolDesc->FreeCount) == glPacketPoolCount);
  1164. if (PoolDesc->AllocatedCount >
  1165. PoolDesc->MaxAllocatedCount) {
  1166. PoolDesc->MaxAllocatedCount =
  1167. PoolDesc->AllocatedCount;
  1168. }
  1169. PacketPoolList.AllocatedCount++;
  1170. PacketPoolList.FreeCount--;
  1171. #if DBG
  1172. {
  1173. PPOOL_DESC pdesc;
  1174. ULONG FreeCount, AllocatedCount;
  1175. pdesc = (PPOOL_DESC)PacketPoolList.List.Flink;
  1176. FreeCount = AllocatedCount = 0;
  1177. while ((PVOID)pdesc != (PVOID)&PacketPoolList.List) {
  1178. FreeCount += pdesc->FreeCount;
  1179. AllocatedCount += pdesc->AllocatedCount;
  1180. pdesc = (PPOOL_DESC)pdesc->Linkage.Flink;
  1181. }
  1182. if (PacketPoolList.AllocatedCount != AllocatedCount ||
  1183. PacketPoolList.FreeCount != FreeCount){
  1184. DbgPrint("NDISWAN: AllocatePacket - PacketPool counts out of sync!\n");
  1185. DbgBreakPoint();
  1186. }
  1187. #if 0
  1188. if (PacketPoolList.AllocatedCount > 200) {
  1189. DbgPrint("NDISWAN: AllocatePacket - Over 200 outstanding packets!\n");
  1190. DbgBreakPoint();
  1191. }
  1192. #endif
  1193. }
  1194. #endif
  1195. if (PacketPoolList.AllocatedCount >
  1196. PacketPoolList.MaxAllocatedCount) {
  1197. PacketPoolList.MaxAllocatedCount =
  1198. PacketPoolList.AllocatedCount;
  1199. }
  1200. pres->MagicNumber = MagicNumber;
  1201. pres->PoolDesc = PoolDesc;
  1202. NDIS_SET_PACKET_HEADER_SIZE(ReturnPacket,
  1203. MAC_HEADER_LENGTH);
  1204. NDIS_SET_PACKET_STATUS(ReturnPacket,
  1205. NDIS_STATUS_SUCCESS);
  1206. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1207. return (ReturnPacket);
  1208. }
  1209. VOID
  1210. NdisWanFreeNdisPacket(
  1211. PNDIS_PACKET NdisPacket
  1212. )
  1213. {
  1214. PNDISWAN_PROTOCOL_RESERVED pres;
  1215. PPOOL_DESC PoolDesc;
  1216. PNDIS_BUFFER NdisBuffer;
  1217. PUCHAR DataBuffer;
  1218. pres = PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket);
  1219. ASSERT(pres->MagicNumber == MAGIC_INTERNAL_ALLOC ||
  1220. pres->MagicNumber == MAGIC_INTERNAL_IO ||
  1221. pres->MagicNumber == MAGIC_INTERNAL_SEND ||
  1222. pres->MagicNumber == MAGIC_INTERNAL_RECV ||
  1223. pres->MagicNumber == MAGIC_INTERNAL_ALLOC);
  1224. PoolDesc = pres->PoolDesc;
  1225. NdisAcquireSpinLock(&PacketPoolList.Lock);
  1226. #if DBG
  1227. {
  1228. PPOOL_DESC pdesc;
  1229. pdesc = (PPOOL_DESC)PacketPoolList.List.Flink;
  1230. while ((PVOID)pdesc != (PVOID)&PacketPoolList.List) {
  1231. if (PoolDesc == pdesc) {
  1232. //
  1233. // We found the correct pool
  1234. //
  1235. break;
  1236. }
  1237. pdesc = (PPOOL_DESC)pdesc->Linkage.Flink;
  1238. }
  1239. if((PVOID)PoolDesc == (PVOID)&PacketPoolList.List){
  1240. DbgPrint("NDISWAN: FreePacket PoolDesc %x not on PacketPoolList!\n",
  1241. PoolDesc);
  1242. DbgBreakPoint();
  1243. }
  1244. }
  1245. #endif
  1246. PushEntryList(&PoolDesc->Head, &pres->SLink);
  1247. PoolDesc->AllocatedCount--;
  1248. PoolDesc->FreeCount++;
  1249. ASSERT((PoolDesc->AllocatedCount + PoolDesc->FreeCount) == glPacketPoolCount);
  1250. PacketPoolList.AllocatedCount--;
  1251. PacketPoolList.FreeCount++;
  1252. #if DBG
  1253. {
  1254. PPOOL_DESC pdesc;
  1255. ULONG FreeCount, AllocatedCount;
  1256. pdesc = (PPOOL_DESC)PacketPoolList.List.Flink;
  1257. FreeCount = AllocatedCount = 0;
  1258. while ((PVOID)pdesc != (PVOID)&PacketPoolList.List) {
  1259. FreeCount += pdesc->FreeCount;
  1260. AllocatedCount += pdesc->AllocatedCount;
  1261. pdesc = (PPOOL_DESC)pdesc->Linkage.Flink;
  1262. }
  1263. if (PacketPoolList.AllocatedCount != AllocatedCount ||
  1264. PacketPoolList.FreeCount != FreeCount){
  1265. DbgPrint("NDISWAN: FreePacket - PacketPool counts out of sync!\n");
  1266. DbgBreakPoint();
  1267. }
  1268. }
  1269. #endif
  1270. //
  1271. // If all of the packets have been returned to this pool desc
  1272. // and this is not the only pool desc then free it!
  1273. //
  1274. if (PoolDesc->AllocatedCount == 0 &&
  1275. PacketPoolList.TotalDescCount > 1 &&
  1276. PacketPoolList.FreeCount > PoolDesc->FreeCount) {
  1277. PSINGLE_LIST_ENTRY p = NULL;
  1278. RemoveEntryList(&PoolDesc->Linkage);
  1279. PacketPoolList.TotalDescCount--;
  1280. PacketPoolList.FreeCount -= PoolDesc->FreeCount;
  1281. p = PopEntryList(&PoolDesc->Head);
  1282. while (p != NULL) {
  1283. PNDIS_PACKET ReturnPacket;
  1284. pres = CONTAINING_RECORD(p, NDISWAN_PROTOCOL_RESERVED, SLink);
  1285. ReturnPacket = CONTAINING_RECORD(pres, NDIS_PACKET, ProtocolReserved);
  1286. NdisFreePacket(ReturnPacket);
  1287. p = PopEntryList(&PoolDesc->Head);
  1288. }
  1289. NdisFreePacketPool(PoolDesc->PoolHandle);
  1290. NdisWanFreeMemory(PoolDesc);
  1291. }
  1292. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1293. }
  1294. PVOID
  1295. AllocateDataDesc(
  1296. POOL_TYPE PoolType,
  1297. SIZE_T NumberOfBytes,
  1298. ULONG Tag
  1299. )
  1300. /*++
  1301. Routine Name:
  1302. AllocateDataDesc
  1303. Routine Description:
  1304. This routine is called by the lookasidelist manager if there are not
  1305. any descriptors available. It will allocated memory for: DATA_DESC,
  1306. NDIS_BUFFER, NDIS_PACKET, and a block of memory of size.
  1307. Arguments:
  1308. Return Values:
  1309. --*/
  1310. {
  1311. PDATA_DESC DataDesc;
  1312. PUCHAR DataBuffer;
  1313. NDIS_STATUS Status;
  1314. NdisWanAllocatePriorityMemory(&DataDesc,
  1315. NumberOfBytes,
  1316. Tag,
  1317. NormalPoolPriority);
  1318. if (DataDesc == NULL) {
  1319. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1320. ("AllocateDataDesc failed! Size %d",
  1321. NumberOfBytes));
  1322. return (NULL);
  1323. }
  1324. DataBuffer =
  1325. ((PUCHAR)(DataDesc + 1) + sizeof(PVOID));
  1326. (ULONG_PTR)DataBuffer &=
  1327. ~((ULONG_PTR)sizeof(PVOID) - 1);
  1328. DataDesc->DataBuffer = DataBuffer;
  1329. DataDesc->DataBufferLength =
  1330. (ULONG)(((PUCHAR)DataDesc + NumberOfBytes) - DataBuffer);
  1331. // This is not portable to Win95! I need to allocate a buffer
  1332. // pool and use a valid handle.
  1333. //
  1334. NdisAllocateBuffer(&Status,
  1335. &DataDesc->NdisBuffer,
  1336. NULL,
  1337. DataDesc->DataBuffer,
  1338. DataDesc->DataBufferLength);
  1339. if (Status != NDIS_STATUS_SUCCESS) {
  1340. NdisWanFreeMemory(DataDesc);
  1341. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1342. ("NdisAllocateBuffer failed! DataBufferSize %d",
  1343. DataDesc->DataBufferLength));
  1344. return (NULL);
  1345. }
  1346. DataDesc->NdisPacket =
  1347. NdisWanAllocateNdisPacket(MAGIC_INTERNAL_ALLOC);
  1348. if (DataDesc->NdisPacket == NULL) {
  1349. NdisFreeBuffer(DataDesc->NdisBuffer);
  1350. NdisWanFreeMemory(DataDesc);
  1351. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1352. ("NdisWanAllocateNdisPacket failed! DataBufferSize %d"));
  1353. return (NULL);
  1354. }
  1355. NdisChainBufferAtFront(DataDesc->NdisPacket,
  1356. DataDesc->NdisBuffer);
  1357. return(DataDesc);
  1358. }
  1359. VOID
  1360. FreeDataDesc(
  1361. PVOID Buffer
  1362. )
  1363. /*++
  1364. Routine Name:
  1365. Routine Description:
  1366. Arguments:
  1367. Return Values:
  1368. --*/
  1369. {
  1370. PDATA_DESC DataDesc;
  1371. DataDesc = (PDATA_DESC)Buffer;
  1372. NdisReinitializePacket(DataDesc->NdisPacket);
  1373. NdisWanFreeNdisPacket(DataDesc->NdisPacket);
  1374. NdisFreeBuffer(DataDesc->NdisBuffer);
  1375. NdisWanFreeMemory(Buffer);
  1376. }
  1377. PRECV_DESC
  1378. NdisWanAllocateRecvDesc(
  1379. ULONG SizeNeeded
  1380. )
  1381. /*++
  1382. Routine Name:
  1383. Routine Description:
  1384. Arguments:
  1385. Return Values:
  1386. --*/
  1387. {
  1388. PDATA_DESC DataDesc;
  1389. PRECV_DESC RecvDesc;
  1390. ULONG Length;
  1391. PNPAGED_LOOKASIDE_LIST LookasideList;
  1392. if (SizeNeeded > glLargeDataBufferSize) {
  1393. DbgPrint("NDISWAN: Error Allocating RecvDesc Size %d\n",
  1394. SizeNeeded);
  1395. return (NULL);
  1396. } else if (SizeNeeded > glSmallDataBufferSize) {
  1397. LookasideList = &LargeDataDescList;
  1398. } else {
  1399. LookasideList = &SmallDataDescList;
  1400. }
  1401. DataDesc =
  1402. NdisAllocateFromNPagedLookasideList(LookasideList);
  1403. if (DataDesc == NULL) {
  1404. return (NULL);
  1405. }
  1406. PPROTOCOL_RESERVED_FROM_NDIS(DataDesc->NdisPacket)->MagicNumber =
  1407. MAGIC_INTERNAL_RECV;
  1408. DataDesc->LookasideList = LookasideList;
  1409. RecvDesc = &DataDesc->RecvDesc;
  1410. NdisZeroMemory(RecvDesc, sizeof(RECV_DESC));
  1411. RecvDesc->Signature = RECVDESC_SIG;
  1412. RecvDesc->DataBuffer =
  1413. DataDesc->DataBuffer;
  1414. RecvDesc->NdisBuffer =
  1415. DataDesc->NdisBuffer;
  1416. RecvDesc->NdisPacket =
  1417. DataDesc->NdisPacket;
  1418. NdisQueryBuffer(RecvDesc->NdisBuffer,
  1419. &RecvDesc->StartBuffer,
  1420. &Length);
  1421. RecvDesc->CurrentBuffer =
  1422. RecvDesc->StartBuffer + MAC_HEADER_LENGTH + PROTOCOL_HEADER_LENGTH;
  1423. return (RecvDesc);
  1424. }
  1425. VOID
  1426. NdisWanFreeRecvDesc(
  1427. PRECV_DESC RecvDesc
  1428. )
  1429. /*++
  1430. Routine Name:
  1431. Routine Description:
  1432. Arguments:
  1433. Return Values:
  1434. --*/
  1435. {
  1436. PDATA_DESC DataDesc;
  1437. PNDIS_BUFFER NdisBuffer;
  1438. PNDIS_PACKET NdisPacket;
  1439. PNPAGED_LOOKASIDE_LIST LookasideList;
  1440. if (RecvDesc->OriginalPacket != NULL) {
  1441. NdisReturnPackets(&RecvDesc->OriginalPacket, 1);
  1442. RecvDesc->OriginalPacket = NULL;
  1443. }
  1444. DataDesc =
  1445. CONTAINING_RECORD(RecvDesc, DATA_DESC, RecvDesc);
  1446. NdisBuffer =
  1447. DataDesc->NdisBuffer;
  1448. NdisPacket =
  1449. DataDesc->NdisPacket;
  1450. LookasideList =
  1451. DataDesc->LookasideList;
  1452. #if DBG
  1453. {
  1454. ULONG BufferCount;
  1455. NdisQueryPacket(NdisPacket,
  1456. NULL,
  1457. &BufferCount,
  1458. NULL,
  1459. NULL);
  1460. ASSERT(BufferCount == 1);
  1461. }
  1462. #endif
  1463. NdisAdjustBufferLength(NdisBuffer,
  1464. DataDesc->DataBufferLength);
  1465. NdisRecalculatePacketCounts(NdisPacket);
  1466. NDIS_SET_PACKET_HEADER_SIZE(NdisPacket,
  1467. MAC_HEADER_LENGTH);
  1468. NDIS_SET_PACKET_STATUS(NdisPacket,
  1469. NDIS_STATUS_SUCCESS);
  1470. ASSERT(PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket)->MagicNumber == MAGIC_INTERNAL_RECV);
  1471. NdisFreeToNPagedLookasideList(LookasideList, DataDesc);
  1472. }
  1473. PSEND_DESC
  1474. NdisWanAllocateSendDesc(
  1475. PLINKCB LinkCB,
  1476. ULONG SizeNeeded
  1477. )
  1478. /*++
  1479. Routine Name:
  1480. Routine Description:
  1481. Arguments:
  1482. Return Values:
  1483. --*/
  1484. {
  1485. POPENCB OpenCB;
  1486. PSEND_DESC SendDesc;
  1487. //
  1488. // Need to determine if this link represents a legacy
  1489. // wan miniport or a NDIS 5.0 miniport and get the
  1490. // appropriate buffer descriptor.
  1491. //
  1492. OpenCB = LinkCB->OpenCB;
  1493. if (OpenCB->Flags & OPEN_LEGACY) {
  1494. PDATA_DESC DataDesc;
  1495. PNDIS_WAN_PACKET WanPacket;
  1496. //
  1497. // Get a buffer desriptor off of the open block
  1498. //
  1499. if (OpenCB->WanInfo.MemoryFlags == 0) {
  1500. PNPAGED_LOOKASIDE_LIST LookasideList;
  1501. LookasideList = &OpenCB->WanPacketPool;
  1502. DataDesc =
  1503. NdisAllocateFromNPagedLookasideList(LookasideList);
  1504. if (DataDesc == NULL) {
  1505. return(NULL);
  1506. }
  1507. DataDesc->LookasideList = LookasideList;
  1508. WanPacket = (PNDIS_WAN_PACKET)
  1509. ((PUCHAR)(DataDesc + 1) + sizeof(PVOID));
  1510. (ULONG_PTR)WanPacket &=
  1511. ~((ULONG_PTR)sizeof(PVOID) - 1);
  1512. //
  1513. // Point to the begining of the data.
  1514. //
  1515. WanPacket->StartBuffer =
  1516. ((PUCHAR)(WanPacket + 1) + sizeof(PVOID));
  1517. (ULONG_PTR)WanPacket->StartBuffer &=
  1518. ~((ULONG_PTR)sizeof(PVOID) - 1);
  1519. WanPacket->EndBuffer = WanPacket->StartBuffer +
  1520. OpenCB->BufferSize - sizeof(PVOID);
  1521. } else {
  1522. DataDesc = (PDATA_DESC)
  1523. NdisInterlockedPopEntrySList(&OpenCB->WanPacketList,
  1524. &OpenCB->Lock);
  1525. if (DataDesc == NULL) {
  1526. return (NULL);
  1527. }
  1528. }
  1529. SendDesc = &DataDesc->SendDesc;
  1530. NdisZeroMemory(SendDesc, sizeof(SEND_DESC));
  1531. SendDesc->Signature = SENDESC_SIG;
  1532. SendDesc->LinkCB = LinkCB;
  1533. SendDesc->WanPacket = WanPacket;
  1534. WanPacket->CurrentBuffer =
  1535. WanPacket->StartBuffer + OpenCB->WanInfo.HeaderPadding;
  1536. SendDesc->StartBuffer =
  1537. WanPacket->CurrentBuffer;
  1538. } else {
  1539. PDATA_DESC DataDesc;
  1540. ULONG Length;
  1541. PNPAGED_LOOKASIDE_LIST LookasideList;
  1542. if (SizeNeeded > glLargeDataBufferSize) {
  1543. DbgPrint("NDISWAN: Error Allocating SendDesc Size %d\n",
  1544. SizeNeeded);
  1545. return (NULL);
  1546. } else if (SizeNeeded > glSmallDataBufferSize) {
  1547. LookasideList = &LargeDataDescList;
  1548. } else {
  1549. LookasideList = &SmallDataDescList;
  1550. }
  1551. DataDesc =
  1552. NdisAllocateFromNPagedLookasideList(LookasideList);
  1553. if (DataDesc == NULL) {
  1554. return (NULL);
  1555. }
  1556. DataDesc->LookasideList = LookasideList;
  1557. PPROTOCOL_RESERVED_FROM_NDIS(DataDesc->NdisPacket)->MagicNumber =
  1558. MAGIC_INTERNAL_SEND;
  1559. SendDesc = &DataDesc->SendDesc;
  1560. NdisZeroMemory(SendDesc, sizeof(SEND_DESC));
  1561. SendDesc->Signature = SENDESC_SIG;
  1562. SendDesc->LinkCB = LinkCB;
  1563. SendDesc->NdisPacket =
  1564. DataDesc->NdisPacket;
  1565. SendDesc->NdisBuffer =
  1566. DataDesc->NdisBuffer;
  1567. NdisQueryBuffer(SendDesc->NdisBuffer,
  1568. &SendDesc->StartBuffer,
  1569. &Length);
  1570. }
  1571. LinkCB->SendResources -= 1;
  1572. LinkCB->BundleCB->SendResources -= 1;
  1573. return (SendDesc);
  1574. }
  1575. VOID
  1576. NdisWanFreeSendDesc(
  1577. PSEND_DESC SendDesc
  1578. )
  1579. /*++
  1580. Routine Name:
  1581. Routine Description:
  1582. Arguments:
  1583. Return Values:
  1584. --*/
  1585. {
  1586. POPENCB OpenCB;
  1587. PDATA_DESC DataDesc;
  1588. PLINKCB LinkCB;
  1589. PNPAGED_LOOKASIDE_LIST LookasideList;
  1590. LinkCB =
  1591. SendDesc->LinkCB;
  1592. OpenCB = LinkCB->OpenCB;
  1593. DataDesc =
  1594. CONTAINING_RECORD(SendDesc, DATA_DESC, SendDesc);
  1595. LookasideList = DataDesc->LookasideList;
  1596. if (OpenCB->Flags & OPEN_LEGACY) {
  1597. if (OpenCB->WanInfo.MemoryFlags == 0) {
  1598. NdisFreeToNPagedLookasideList(LookasideList, DataDesc);
  1599. } else {
  1600. NdisInterlockedPushEntrySList(&OpenCB->WanPacketList,
  1601. (PSINGLE_LIST_ENTRY)DataDesc,
  1602. &OpenCB->Lock);
  1603. }
  1604. } else {
  1605. PNDIS_BUFFER NdisBuffer;
  1606. PNDIS_PACKET NdisPacket;
  1607. NdisBuffer =
  1608. DataDesc->NdisBuffer;
  1609. NdisPacket =
  1610. DataDesc->NdisPacket;
  1611. #if DBG
  1612. {
  1613. ULONG BufferCount;
  1614. NdisQueryPacket(NdisPacket,
  1615. NULL,
  1616. &BufferCount,
  1617. NULL,
  1618. NULL);
  1619. ASSERT(BufferCount == 1);
  1620. }
  1621. #endif
  1622. NdisAdjustBufferLength(NdisBuffer,
  1623. DataDesc->DataBufferLength);
  1624. NdisRecalculatePacketCounts(NdisPacket);
  1625. NDIS_SET_PACKET_HEADER_SIZE(NdisPacket,
  1626. MAC_HEADER_LENGTH);
  1627. NDIS_SET_PACKET_STATUS(NdisPacket,
  1628. NDIS_STATUS_SUCCESS);
  1629. ASSERT(PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket)->MagicNumber == MAGIC_INTERNAL_SEND);
  1630. NdisFreeToNPagedLookasideList(LookasideList, DataDesc);
  1631. }
  1632. LinkCB->SendResources += 1;
  1633. LinkCB->BundleCB->SendResources += 1;
  1634. }
  1635. PCL_AFSAPCB
  1636. NdisWanAllocateClAfSapCB(
  1637. POPENCB OpenCB,
  1638. PCO_ADDRESS_FAMILY AddressFamily
  1639. )
  1640. {
  1641. PCL_AFSAPCB AfSapCB;
  1642. AfSapCB =
  1643. NdisAllocateFromNPagedLookasideList(&AfSapVcCBList);
  1644. if (AfSapCB == NULL) {
  1645. return (NULL);
  1646. }
  1647. NdisZeroMemory(AfSapCB, sizeof(CL_AFSAPCB));
  1648. AfSapCB->Signature = CLAFSAP_SIG;
  1649. AfSapCB->OpenCB = OpenCB;
  1650. AfSapCB->Af.AddressFamily = AddressFamily->AddressFamily;
  1651. AfSapCB->Af.MajorVersion = AddressFamily->MajorVersion;
  1652. AfSapCB->Af.MinorVersion = AddressFamily->MinorVersion;
  1653. AfSapCB->RefCount = 1;
  1654. AfSapCB->Flags = AF_OPENING;
  1655. return (AfSapCB);
  1656. }
  1657. VOID
  1658. NdisWanFreeClAfSapCB(
  1659. PCL_AFSAPCB AfSapCB
  1660. )
  1661. {
  1662. NdisFreeToNPagedLookasideList(&AfSapVcCBList,
  1663. AfSapCB);
  1664. }
  1665. PCM_AFSAPCB
  1666. NdisWanAllocateCmAfSapCB(
  1667. PMINIPORTCB MiniportCB
  1668. )
  1669. {
  1670. PCM_AFSAPCB AfSapCB;
  1671. AfSapCB =
  1672. NdisAllocateFromNPagedLookasideList(&AfSapVcCBList);
  1673. if (AfSapCB == NULL) {
  1674. return (NULL);
  1675. }
  1676. NdisZeroMemory(AfSapCB, sizeof(CM_AFSAPCB));
  1677. AfSapCB->Signature = CMAFSAP_SIG;
  1678. AfSapCB->MiniportCB = MiniportCB;
  1679. REF_MINIPORTCB(MiniportCB);
  1680. NdisAcquireSpinLock(&MiniportCB->Lock);
  1681. InsertHeadList(&MiniportCB->AfSapCBList,
  1682. &AfSapCB->Linkage);
  1683. NdisWanInitializeNotificationEvent(&AfSapCB->NotificationEvent);
  1684. NdisWanInterlockedInc(&MiniportCB->AfRefCount);
  1685. NdisReleaseSpinLock(&MiniportCB->Lock);
  1686. return (AfSapCB);
  1687. }
  1688. VOID
  1689. NdisWanFreeCmAfSapCB(
  1690. PCM_AFSAPCB AfSapCB
  1691. )
  1692. {
  1693. PMINIPORTCB MiniportCB = AfSapCB->MiniportCB;
  1694. NdisAcquireSpinLock(&MiniportCB->Lock);
  1695. NdisWanInterlockedDec(&MiniportCB->AfRefCount);
  1696. RemoveEntryList(&AfSapCB->Linkage);
  1697. NdisReleaseSpinLock(&MiniportCB->Lock);
  1698. DEREF_MINIPORTCB(MiniportCB);
  1699. NdisFreeToNPagedLookasideList(&AfSapVcCBList,
  1700. AfSapCB);
  1701. }
  1702. PCM_VCCB
  1703. NdisWanAllocateCmVcCB(
  1704. PCM_AFSAPCB AfSapCB,
  1705. NDIS_HANDLE NdisVcHandle
  1706. )
  1707. {
  1708. PCM_VCCB CmVcCB;
  1709. CmVcCB =
  1710. NdisAllocateFromNPagedLookasideList(&AfSapVcCBList);
  1711. if (CmVcCB == NULL) {
  1712. return (NULL);
  1713. }
  1714. NdisZeroMemory(CmVcCB, sizeof(CM_VCCB));
  1715. CmVcCB->AfSapCB = AfSapCB;
  1716. CmVcCB->Signature = CMVC_SIG;
  1717. CmVcCB->NdisVcHandle = NdisVcHandle;
  1718. return (CmVcCB);
  1719. }
  1720. VOID
  1721. NdisWanFreeCmVcCB(
  1722. PCM_VCCB CmVcCB
  1723. )
  1724. {
  1725. NdisFreeToNPagedLookasideList(&AfSapVcCBList, CmVcCB);
  1726. }
  1727. NDIS_STATUS
  1728. AllocateIoNdisPacket(
  1729. ULONG SizeNeeded,
  1730. PNDIS_PACKET *NdisPacket,
  1731. PNDIS_BUFFER *NdisBuffer,
  1732. PUCHAR *DataBuffer
  1733. )
  1734. /*++
  1735. Routine Name:
  1736. AllocateIoNdisPacket
  1737. Routine Description:
  1738. This routine will alocate a packet used to send a PPP control
  1739. packet over a wan endpoint. The routine is written with the
  1740. assumption that there will only ever be a single NDIS_BUFFER
  1741. attached to the packet. This buffer is attached immediately
  1742. to the front of the packet. Before calling a miniport the
  1743. NDIS_BUFFER must have it's length adjusted and the packet must
  1744. recalculate all counts.
  1745. Arguments:
  1746. Return Values:
  1747. --*/
  1748. {
  1749. PDATA_DESC DataDesc;
  1750. ULONG Length;
  1751. PNPAGED_LOOKASIDE_LIST LookasideList;
  1752. if (SizeNeeded > glLargeDataBufferSize) {
  1753. DbgPrint("NDISWAN: Error Allocating IoNdisPacket Size %d\n",
  1754. SizeNeeded);
  1755. return (NDIS_STATUS_FAILURE);
  1756. } else if (SizeNeeded > glSmallDataBufferSize) {
  1757. LookasideList = &LargeDataDescList;
  1758. } else {
  1759. LookasideList = &SmallDataDescList;
  1760. }
  1761. DataDesc =
  1762. NdisAllocateFromNPagedLookasideList(LookasideList);
  1763. if (DataDesc == NULL) {
  1764. return (NDIS_STATUS_RESOURCES);
  1765. }
  1766. DataDesc->LookasideList = LookasideList;
  1767. *NdisPacket =
  1768. DataDesc->NdisPacket;
  1769. PPROTOCOL_RESERVED_FROM_NDIS(DataDesc->NdisPacket)->MagicNumber =
  1770. MAGIC_INTERNAL_IO;
  1771. PPROTOCOL_RESERVED_FROM_NDIS(DataDesc->NdisPacket)->DataDesc =
  1772. DataDesc;
  1773. *NdisBuffer =
  1774. DataDesc->NdisBuffer;
  1775. NdisQueryBuffer(DataDesc->NdisBuffer,
  1776. &DataDesc->DataBuffer,
  1777. &Length);
  1778. *DataBuffer =
  1779. DataDesc->DataBuffer;
  1780. return (NDIS_STATUS_SUCCESS);
  1781. }
  1782. VOID
  1783. FreeIoNdisPacket(
  1784. PNDIS_PACKET NdisPacket
  1785. )
  1786. /*++
  1787. Routine Name:
  1788. FreeIoNdisPacket
  1789. Routine Description:
  1790. This routine will free a packet used to send a PPP control
  1791. packet over a wan endpoint. The routine is written with the
  1792. assumption that there will only ever be a single NDIS_BUFFER
  1793. attached to the packet. This buffer does not have to be
  1794. explicitly removed from the packet here as a pointer to it
  1795. is stored in the DATA_DESC itself and will be freed when
  1796. the DATA_DESC is freed.
  1797. Arguments:
  1798. Return Values:
  1799. --*/
  1800. {
  1801. PDATA_DESC DataDesc;
  1802. PNDIS_BUFFER NdisBuffer;
  1803. PNPAGED_LOOKASIDE_LIST LookasideList;
  1804. DataDesc =
  1805. PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket)->DataDesc;
  1806. ASSERT(PPROTOCOL_RESERVED_FROM_NDIS(NdisPacket)->MagicNumber == MAGIC_INTERNAL_IO);
  1807. LookasideList =
  1808. DataDesc->LookasideList;
  1809. NdisAdjustBufferLength(DataDesc->NdisBuffer,
  1810. DataDesc->DataBufferLength);
  1811. NdisRecalculatePacketCounts(NdisPacket);
  1812. NDIS_SET_PACKET_HEADER_SIZE(NdisPacket,
  1813. MAC_HEADER_LENGTH);
  1814. NDIS_SET_PACKET_STATUS(NdisPacket,
  1815. NDIS_STATUS_SUCCESS);
  1816. NdisFreeToNPagedLookasideList(LookasideList, DataDesc);
  1817. }
  1818. PVOID
  1819. AllocateWanPacket(
  1820. IN POOL_TYPE PoolType,
  1821. IN SIZE_T NumberOfBytes,
  1822. IN ULONG Tag
  1823. )
  1824. {
  1825. PVOID pMem;
  1826. NdisWanAllocatePriorityMemory(&pMem,
  1827. NumberOfBytes,
  1828. Tag,
  1829. NormalPoolPriority);
  1830. return(pMem);
  1831. }
  1832. VOID
  1833. FreeWanPacket(
  1834. PVOID WanPacket
  1835. )
  1836. {
  1837. NdisWanFreeMemory(WanPacket);
  1838. }