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.

866 lines
23 KiB

  1. /*++
  2. Copyright (c) 1990-1997 Microsoft Corporation
  3. Module Name:
  4. cl.c
  5. Abstract:
  6. This file contains the functions that implement the ndiswan
  7. NDIS 5.0 client interface. These functions are used to interface
  8. with NDIS 5.0 miniports/call managers.
  9. Author:
  10. Tony Bell (TonyBe) January 9, 1997
  11. Environment:
  12. Kernel Mode
  13. Revision History:
  14. TonyBe 01/09/97 Created
  15. --*/
  16. //
  17. // We want to initialize all of the global variables now!
  18. //
  19. #include "wan.h"
  20. #include "atm.h"
  21. #define __FILE_SIG__ CL_FILESIG
  22. NDIS_STATUS
  23. ClCreateVc(
  24. IN NDIS_HANDLE ProtocolAfContext,
  25. IN NDIS_HANDLE NdisVcHandle,
  26. OUT PNDIS_HANDLE ProtocolVcContext
  27. )
  28. {
  29. PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolAfContext;
  30. POPENCB OpenCB = AfSapCB->OpenCB;
  31. PLINKCB LinkCB;
  32. PBUNDLECB BundleCB;
  33. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCreateVc: Enter"));
  34. //
  35. // Get a linkcb
  36. //
  37. LinkCB = NdisWanAllocateLinkCB(OpenCB, 0);
  38. if (LinkCB == NULL) {
  39. //
  40. // Error getting LinkCB!
  41. //
  42. return (NDIS_STATUS_RESOURCES);
  43. }
  44. LinkCB->NdisLinkHandle = NdisVcHandle;
  45. LinkCB->ConnectionWrapperID = NdisVcHandle;
  46. LinkCB->AfSapCB = AfSapCB;
  47. //
  48. // Set some default values
  49. //
  50. LinkCB->RFlowSpec.PeakBandwidth =
  51. LinkCB->SFlowSpec.PeakBandwidth = 28800 / 8;
  52. LinkCB->SendWindow = OpenCB->WanInfo.MaxTransmit;
  53. //
  54. // Get a bundlecb
  55. //
  56. BundleCB = NdisWanAllocateBundleCB();
  57. if (BundleCB == NULL) {
  58. NdisWanFreeLinkCB(LinkCB);
  59. //
  60. // Error getting BundleCB!
  61. //
  62. return (NDIS_STATUS_RESOURCES);
  63. }
  64. //
  65. // Add LinkCB to BundleCB
  66. //
  67. AcquireBundleLock(BundleCB);
  68. AddLinkToBundle(BundleCB, LinkCB);
  69. ReleaseBundleLock(BundleCB);
  70. //
  71. // Place BundleCB in active connection table
  72. //
  73. if (NULL == InsertBundleInConnectionTable(BundleCB)) {
  74. //
  75. // Error inserting link in ConnectionTable
  76. //
  77. RemoveLinkFromBundle(BundleCB, LinkCB, FALSE);
  78. NdisWanFreeLinkCB(LinkCB);
  79. return (NDIS_STATUS_RESOURCES);
  80. }
  81. //
  82. // Place LinkCB in active connection table
  83. //
  84. if (NULL == InsertLinkInConnectionTable(LinkCB)) {
  85. //
  86. // Error inserting bundle in connectiontable
  87. //
  88. RemoveLinkFromBundle(BundleCB, LinkCB, FALSE);
  89. NdisWanFreeLinkCB(LinkCB);
  90. return (NDIS_STATUS_RESOURCES);
  91. }
  92. *ProtocolVcContext = LinkCB->hLinkHandle;
  93. NdisAcquireSpinLock(&AfSapCB->Lock);
  94. REF_CLAFSAPCB(AfSapCB);
  95. NdisReleaseSpinLock(&AfSapCB->Lock);
  96. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCreateVc: Exit"));
  97. return (NDIS_STATUS_SUCCESS);
  98. }
  99. NDIS_STATUS
  100. ClDeleteVc(
  101. IN NDIS_HANDLE ProtocolVcContext
  102. )
  103. {
  104. PLINKCB LinkCB;
  105. PBUNDLECB BundleCB;
  106. PCL_AFSAPCB AfSapCB;
  107. if (!IsLinkValid(ProtocolVcContext, FALSE, &LinkCB)) {
  108. NdisWanDbgOut(DBG_FAILURE, DBG_CL,
  109. ("NDISWAN: Possible double delete of VcContext %x\n",
  110. ProtocolVcContext));
  111. return (NDIS_STATUS_FAILURE);
  112. }
  113. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClDeleteVc: Enter %p", LinkCB));
  114. NdisAcquireSpinLock(&LinkCB->Lock);
  115. AfSapCB = LinkCB->AfSapCB;
  116. //
  117. // For the ref applied in IsLinkValid. We
  118. // don't have to use the full deref code here as we know the ref
  119. // applied at CreateVc will keep the link around.
  120. //
  121. LinkCB->RefCount--;
  122. //
  123. // For the createvc reference
  124. //
  125. DEREF_LINKCB_LOCKED(LinkCB);
  126. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClDeleteVc: Exit"));
  127. DEREF_CLAFSAPCB(AfSapCB);
  128. return(NDIS_STATUS_SUCCESS);
  129. }
  130. VOID
  131. ClOpenAfComplete(
  132. IN NDIS_STATUS Status,
  133. IN NDIS_HANDLE ProtocolAfContext,
  134. IN NDIS_HANDLE NdisAfHandle
  135. )
  136. {
  137. PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolAfContext;
  138. POPENCB OpenCB = AfSapCB->OpenCB;
  139. PCO_SAP Sap;
  140. NDIS_HANDLE SapHandle;
  141. UCHAR SapBuffer[CLSAP_BUFFERSIZE];
  142. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClOpenAfComplete: Enter %p %x", AfSapCB, Status));
  143. NdisAcquireSpinLock(&AfSapCB->Lock);
  144. AfSapCB->Flags &= ~(AF_OPENING);
  145. if (Status == NDIS_STATUS_SUCCESS) {
  146. AfSapCB->Flags |=
  147. (AF_OPENED | SAP_REGISTERING);
  148. AfSapCB->AfHandle = NdisAfHandle;
  149. NdisReleaseSpinLock(&AfSapCB->Lock);
  150. //
  151. // If we successfully opened the AddressFamily we
  152. // need to register our SAP.
  153. //
  154. NdisAcquireSpinLock(&OpenCB->Lock);
  155. InsertHeadList(&OpenCB->AfSapCBList,
  156. &AfSapCB->Linkage);
  157. NdisReleaseSpinLock(&OpenCB->Lock);
  158. Sap = (PCO_SAP)SapBuffer;
  159. //
  160. // Register our SAP
  161. //
  162. Sap->SapType = SAP_TYPE_NDISWAN_PPP;
  163. Sap->SapLength = sizeof(DEVICECLASS_NDISWAN_SAP);
  164. NdisMoveMemory(Sap->Sap,
  165. DEVICECLASS_NDISWAN_SAP,
  166. sizeof(DEVICECLASS_NDISWAN_SAP));
  167. Status =
  168. NdisClRegisterSap(AfSapCB->AfHandle,
  169. AfSapCB,
  170. Sap,
  171. &SapHandle);
  172. if (Status != NDIS_STATUS_PENDING) {
  173. ClRegisterSapComplete(Status, AfSapCB, Sap, SapHandle);
  174. }
  175. NdisWanDbgOut(DBG_TRACE, DBG_PROTOCOL,
  176. ("ClRegisterSap SapHandle 0x%x status: 0x%x", SapHandle, Status));
  177. } else {
  178. AfSapCB->Flags |= AF_OPEN_FAILED;
  179. NdisReleaseSpinLock(&AfSapCB->Lock);
  180. //
  181. // We failed to register the address family so free
  182. // associated memory.
  183. //
  184. NdisWanFreeClAfSapCB(AfSapCB);
  185. //
  186. // Since the open af was initiated from the notification
  187. // of a new af from ndis we have to decrement the af
  188. // registering count.
  189. //
  190. NdisAcquireSpinLock(&OpenCB->Lock);
  191. if (--OpenCB->AfRegisteringCount == 0) {
  192. NdisWanSetNotificationEvent(&OpenCB->AfRegisteringEvent);
  193. }
  194. NdisReleaseSpinLock(&OpenCB->Lock);
  195. }
  196. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClOpenAfComplete: Exit"));
  197. }
  198. VOID
  199. ClCloseAfComplete(
  200. IN NDIS_STATUS Status,
  201. IN NDIS_HANDLE ProtocolAfContext
  202. )
  203. {
  204. PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolAfContext;
  205. POPENCB OpenCB = AfSapCB->OpenCB;
  206. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCloseAfComplete: Enter %p %x", AfSapCB, Status));
  207. //
  208. // BUG 494260
  209. // NDIS should not be invoking this deregister handler at a raised
  210. // IRQL (i.e while holding a spinlock). Bug 494260 documents this
  211. // this issue.
  212. //
  213. // This assert has been commented out to prevent breaks on checked build.
  214. // When 494260 is fixed, this ASSERT should be uncommented.
  215. //
  216. // ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  217. do {
  218. //
  219. // If the close attempt failed there must be another
  220. // thread that is already doing the close. Let the
  221. // other thread cleanup the afsapcb.
  222. //
  223. if (Status != NDIS_STATUS_SUCCESS) {
  224. break;
  225. }
  226. NdisAcquireSpinLock(&AfSapCB->Lock);
  227. AfSapCB->Flags &= ~(AF_CLOSING);
  228. AfSapCB->Flags |= (AF_CLOSED);
  229. NdisReleaseSpinLock(&AfSapCB->Lock);
  230. NdisAcquireSpinLock(&OpenCB->Lock);
  231. RemoveEntryList(&AfSapCB->Linkage);
  232. NdisReleaseSpinLock(&OpenCB->Lock);
  233. NdisWanFreeClAfSapCB(AfSapCB);
  234. } while (FALSE);
  235. //
  236. // Refer comment above
  237. //
  238. // ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  239. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCloseAfComplete: Exit"));
  240. }
  241. VOID
  242. ClRegisterSapComplete(
  243. IN NDIS_STATUS Status,
  244. IN NDIS_HANDLE ProtocolSapContext,
  245. IN PCO_SAP Sap,
  246. IN NDIS_HANDLE NdisSapHandle
  247. )
  248. {
  249. PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolSapContext;
  250. POPENCB OpenCB = AfSapCB->OpenCB;
  251. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClRegisterSapComplete: Enter %p %x", AfSapCB, Status));
  252. NdisAcquireSpinLock(&AfSapCB->Lock);
  253. AfSapCB->Flags &= ~(SAP_REGISTERING);
  254. if (Status == NDIS_STATUS_SUCCESS) {
  255. AfSapCB->Flags |= SAP_REGISTERED;
  256. AfSapCB->SapHandle = NdisSapHandle;
  257. NdisReleaseSpinLock(&AfSapCB->Lock);
  258. } else {
  259. //
  260. // We failed to register our sap so close the address family
  261. //
  262. AfSapCB->Flags &= ~(AF_OPENED);
  263. AfSapCB->Flags |=
  264. (SAP_REGISTER_FAILED | AF_CLOSING);
  265. NdisReleaseSpinLock(&AfSapCB->Lock);
  266. NdisAcquireSpinLock(&OpenCB->Lock);
  267. RemoveEntryList(&AfSapCB->Linkage);
  268. InsertTailList(&OpenCB->AfSapCBClosing, &AfSapCB->Linkage);
  269. NdisReleaseSpinLock(&OpenCB->Lock);
  270. NdisClCloseAddressFamily(AfSapCB->AfHandle);
  271. if (Status != NDIS_STATUS_PENDING) {
  272. ClCloseAfComplete(Status, AfSapCB);
  273. }
  274. }
  275. //
  276. // Since the open af was initiated from the notification
  277. // of a new af from ndis we have to decrement the af
  278. // registering count.
  279. //
  280. NdisAcquireSpinLock(&OpenCB->Lock);
  281. if (--OpenCB->AfRegisteringCount == 0) {
  282. NdisWanSetNotificationEvent(&OpenCB->AfRegisteringEvent);
  283. }
  284. NdisReleaseSpinLock(&OpenCB->Lock);
  285. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClRegisterSapComplete: Exit"));
  286. }
  287. VOID
  288. ClDeregisterSapComplete(
  289. IN NDIS_STATUS Status,
  290. IN NDIS_HANDLE ProtocolSapContext
  291. )
  292. {
  293. PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolSapContext;
  294. POPENCB OpenCB = AfSapCB->OpenCB;
  295. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClDeregisterSapComplete: Enter %p %x", AfSapCB, Status));
  296. //
  297. // BUG 494260
  298. // NDIS should not be invoking this deregister handler at a raised
  299. // IRQL (i.e while holding a spinlock). Bug 494260 documents this
  300. // this issue.
  301. //
  302. // This assert has been commented out to prevent breaks on checked build.
  303. // When 494260 is fixed, this ASSERT should be uncommented.
  304. //
  305. // ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  306. NdisAcquireSpinLock(&AfSapCB->Lock);
  307. ASSERT(AfSapCB->Flags & AF_OPENED);
  308. AfSapCB->Flags &= ~(AF_OPENED | SAP_DEREGISTERING);
  309. AfSapCB->Flags |= (AF_CLOSING);
  310. NdisReleaseSpinLock(&AfSapCB->Lock);
  311. Status =
  312. NdisClCloseAddressFamily(AfSapCB->AfHandle);
  313. if (Status != NDIS_STATUS_PENDING) {
  314. ClCloseAfComplete(Status, AfSapCB);
  315. }
  316. //
  317. // Refer comment above
  318. //
  319. // ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  320. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClDeregisterSapComplete: Exit"));
  321. }
  322. VOID
  323. ClMakeCallComplete(
  324. IN NDIS_STATUS Status,
  325. IN NDIS_HANDLE ProtocolVcContext,
  326. IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
  327. IN PCO_CALL_PARAMETERS CallParameters
  328. )
  329. {
  330. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClMakeCallComplete: Enter %p %x", ProtocolVcContext, Status));
  331. DbgBreakPoint();
  332. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClMakeCallComplete: Exit"));
  333. }
  334. VOID
  335. ClModifyQoSComplete(
  336. IN NDIS_STATUS Status,
  337. IN NDIS_HANDLE ProtocolVcContext,
  338. IN PCO_CALL_PARAMETERS CallParameters
  339. )
  340. {
  341. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClModifyQoSComplete: Enter %p %x", ProtocolVcContext, Status));
  342. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClModifyQoSComplete: Exit"));
  343. }
  344. VOID
  345. ClCloseCallComplete(
  346. IN NDIS_STATUS Status,
  347. IN NDIS_HANDLE ProtocolVcContext,
  348. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL
  349. )
  350. {
  351. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCloseCallComplete: Enter %p %x", ProtocolVcContext, Status));
  352. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCloseCallComplete: Exit"));
  353. }
  354. NDIS_STATUS
  355. ClIncomingCall(
  356. IN NDIS_HANDLE ProtocolSapContext,
  357. IN NDIS_HANDLE ProtocolVcContext,
  358. IN OUT PCO_CALL_PARAMETERS CallParameters
  359. )
  360. {
  361. PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolSapContext;
  362. PLINKCB LinkCB;
  363. POPENCB OpenCB = AfSapCB->OpenCB;
  364. PBUNDLECB BundleCB;
  365. BOOLEAN AtmUseLLC = FALSE;
  366. BOOLEAN MediaBroadband = FALSE;
  367. PWAN_LINK_INFO LinkInfo;
  368. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  369. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCall: Enter %p %p", AfSapCB, ProtocolVcContext));
  370. do {
  371. if (!AreLinkAndBundleValid(ProtocolVcContext,
  372. TRUE,
  373. &LinkCB,
  374. &BundleCB)) {
  375. Status = NDIS_STATUS_FAILURE;
  376. break;
  377. }
  378. NdisAcquireSpinLock(&LinkCB->Lock);
  379. LinkCB->ClCallState = CL_CALL_CONNECTED;
  380. NdisReleaseSpinLock(&LinkCB->Lock);
  381. AcquireBundleLock(BundleCB);
  382. NdisMoveMemory(&LinkCB->SFlowSpec,
  383. &CallParameters->CallMgrParameters->Transmit,
  384. sizeof(FLOWSPEC));
  385. NdisMoveMemory(&LinkCB->RFlowSpec,
  386. &CallParameters->CallMgrParameters->Receive,
  387. sizeof(FLOWSPEC));
  388. if (LinkCB->SFlowSpec.PeakBandwidth == 0) {
  389. LinkCB->SFlowSpec.PeakBandwidth = 28800 / 8;
  390. }
  391. if (LinkCB->RFlowSpec.PeakBandwidth == 0) {
  392. LinkCB->RFlowSpec.PeakBandwidth = LinkCB->SFlowSpec.PeakBandwidth;
  393. }
  394. LinkInfo = &LinkCB->LinkInfo;
  395. //
  396. // Assume all CoNDIS miniports support PPP framing
  397. //
  398. LinkInfo->SendFramingBits =
  399. LinkInfo->RecvFramingBits = PPP_FRAMING;
  400. LinkCB->RecvHandler = ReceivePPP;
  401. if (OpenCB->MediumType == NdisMediumAtm ||
  402. (OpenCB->MediumType == NdisMediumWan &&
  403. (OpenCB->MediumSubType == NdisWanMediumAtm ||
  404. OpenCB->MediumSubType == NdisWanMediumPppoe)) ||
  405. (OpenCB->MediumType == NdisMediumCoWan &&
  406. (OpenCB->MediumSubType == NdisWanMediumAtm ||
  407. OpenCB->MediumSubType == NdisWanMediumPppoe))) {
  408. MediaBroadband = TRUE;
  409. LinkCB->RecvHandler = DetectBroadbandFraming;
  410. }
  411. if (MediaBroadband) {
  412. if (CallParameters->Flags & PERMANENT_VC) {
  413. //
  414. // Per TomF we are going to use NULL encap as
  415. // our default PVC encapsulation
  416. //
  417. if (gbAtmUseLLCOnPVC) {
  418. AtmUseLLC = TRUE;
  419. }
  420. } else {
  421. //
  422. // If this is an ATM SVC we need to see
  423. // if the SVC needs LLC framing or not
  424. //
  425. if (gbAtmUseLLCOnSVC) {
  426. AtmUseLLC = TRUE;
  427. } else {
  428. ULONG IeCount;
  429. Q2931_IE UNALIGNED *Ie;
  430. ATM_BLLI_IE UNALIGNED *Bli;
  431. Q2931_CALLMGR_PARAMETERS *cmparams;
  432. cmparams = (Q2931_CALLMGR_PARAMETERS*)
  433. &(CallParameters->CallMgrParameters->CallMgrSpecific.Parameters[0]);
  434. Bli = NULL;
  435. Ie = (Q2931_IE UNALIGNED *)&cmparams->InfoElements[0];
  436. for (IeCount = 0;
  437. IeCount < cmparams->InfoElementCount;
  438. IeCount++) {
  439. if (Ie->IEType == IE_BLLI) {
  440. Bli = (ATM_BLLI_IE UNALIGNED*)&Ie->IE[0];
  441. break;
  442. }
  443. Ie = (Q2931_IE UNALIGNED *)((ULONG_PTR)Ie + Ie->IELength);
  444. }
  445. if (Bli != NULL) {
  446. AtmUseLLC = (Bli->Layer2Protocol == BLLI_L2_LLC);
  447. }
  448. }
  449. }
  450. if (AtmUseLLC) {
  451. LinkInfo->SendFramingBits |= LLC_ENCAPSULATION;
  452. LinkInfo->RecvFramingBits |= LLC_ENCAPSULATION;
  453. LinkCB->RecvHandler = ReceiveLLC;
  454. }
  455. if (!(LinkInfo->SendFramingBits & LLC_ENCAPSULATION)) {
  456. LinkInfo->SendFramingBits |= PPP_COMPRESS_ADDRESS_CONTROL;
  457. LinkInfo->RecvFramingBits |= PPP_COMPRESS_ADDRESS_CONTROL;
  458. }
  459. }
  460. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("SPeakBandwidth %d SendWindow %d",
  461. LinkCB->SFlowSpec.PeakBandwidth,
  462. LinkCB->SendWindow));
  463. if (CallParameters->Flags & PERMANENT_VC) {
  464. //
  465. // This is a PVC so we will disable idle data detection
  466. // thus allowing the connection to remain active
  467. //
  468. BundleCB->Flags |= DISABLE_IDLE_DETECT;
  469. }
  470. BundleCB->FramingInfo.RecvFramingBits =
  471. BundleCB->FramingInfo.SendFramingBits = PPP_FRAMING;
  472. UpdateBundleInfo(BundleCB);
  473. //
  474. // Deref for the ref applied by AreLinkAndBundleValid. This
  475. // will release the BundleCB->Lock!
  476. //
  477. DEREF_BUNDLECB_LOCKED(BundleCB);
  478. //
  479. // Deref for the ref applied by AreLinkAndBundleValid.
  480. //
  481. DEREF_LINKCB(LinkCB);
  482. } while (0);
  483. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCall: Exit"));
  484. return (Status);
  485. }
  486. VOID
  487. ClIncomingCallQoSChange(
  488. IN NDIS_HANDLE ProtocolVcContext,
  489. IN PCO_CALL_PARAMETERS CallParameters
  490. )
  491. {
  492. PLINKCB LinkCB;
  493. PBUNDLECB BundleCB;
  494. POPENCB OpenCB;
  495. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCallQoSChange: Enter %p", ProtocolVcContext));
  496. do {
  497. if (!AreLinkAndBundleValid(ProtocolVcContext,
  498. TRUE,
  499. &LinkCB,
  500. &BundleCB)) {
  501. break;
  502. }
  503. AcquireBundleLock(BundleCB);
  504. OpenCB = LinkCB->OpenCB;
  505. //
  506. // Do I need to pass this info to 5.0 Clients?????
  507. //
  508. NdisMoveMemory(&LinkCB->SFlowSpec,
  509. &CallParameters->CallMgrParameters->Transmit,
  510. sizeof(FLOWSPEC));
  511. NdisMoveMemory(&LinkCB->RFlowSpec,
  512. &CallParameters->CallMgrParameters->Receive,
  513. sizeof(FLOWSPEC));
  514. if (LinkCB->SFlowSpec.PeakBandwidth == 0) {
  515. LinkCB->SFlowSpec.PeakBandwidth = 28800 / 8;
  516. }
  517. if (LinkCB->RFlowSpec.PeakBandwidth == 0) {
  518. LinkCB->RFlowSpec.PeakBandwidth = LinkCB->SFlowSpec.PeakBandwidth;
  519. }
  520. UpdateBundleInfo(BundleCB);
  521. //
  522. // Deref for the ref applied by AreLinkAndBundleValid. This will
  523. // release the BundleCB->Lock.
  524. //
  525. DEREF_BUNDLECB_LOCKED(BundleCB);
  526. //
  527. // Deref for the ref applied by AreLinkAndBundleValid.
  528. //
  529. DEREF_LINKCB(LinkCB);
  530. } while (0);
  531. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCallQoSChange: Exit"));
  532. }
  533. VOID
  534. ClIncomingCloseCall(
  535. IN NDIS_STATUS CloseStatus,
  536. IN NDIS_HANDLE ProtocolVcContext,
  537. IN PVOID CloseData OPTIONAL,
  538. IN UINT Size OPTIONAL
  539. )
  540. {
  541. PLINKCB LinkCB;
  542. PBUNDLECB BundleCB;
  543. PRECV_DESC RecvDesc;
  544. NDIS_STATUS Status;
  545. ULONG i;
  546. BOOLEAN FreeBundle = FALSE;
  547. BOOLEAN FreeLink = FALSE;
  548. NdisWanDbgOut(DBG_TRACE, DBG_CL,
  549. ("ClIncomingCloseCall: Enter %p %x", ProtocolVcContext, CloseStatus));
  550. do {
  551. if (!AreLinkAndBundleValid(ProtocolVcContext,
  552. TRUE,
  553. &LinkCB,
  554. &BundleCB)) {
  555. #if DBG
  556. DbgPrint("NDISWAN: CloseCall after link has gone down VcContext %x\n",
  557. ProtocolVcContext);
  558. DbgBreakPoint();
  559. #endif
  560. break;
  561. }
  562. NdisAcquireSpinLock(&LinkCB->Lock);
  563. //
  564. // Link is now going down
  565. //
  566. LinkCB->State = LINK_GOING_DOWN;
  567. if (LinkCB->VcRefCount == 0) {
  568. LinkCB->ClCallState = CL_CALL_CLOSED;
  569. NdisReleaseSpinLock(&LinkCB->Lock);
  570. Status =
  571. NdisClCloseCall(LinkCB->NdisLinkHandle,
  572. NULL,
  573. NULL,
  574. 0);
  575. if (Status != NDIS_STATUS_PENDING) {
  576. ClCloseCallComplete(Status,
  577. LinkCB,
  578. NULL);
  579. }
  580. } else {
  581. LinkCB->ClCallState = CL_CALL_CLOSE_PENDING;
  582. NdisReleaseSpinLock(&LinkCB->Lock);
  583. }
  584. NdisAcquireSpinLock(&IoRecvList.Lock);
  585. RecvDesc = (PRECV_DESC)IoRecvList.DescList.Flink;
  586. while ((PVOID)RecvDesc != (PVOID)&IoRecvList.DescList) {
  587. PRECV_DESC Next;
  588. Next = (PRECV_DESC)RecvDesc->Linkage.Flink;
  589. if (RecvDesc->LinkCB == LinkCB) {
  590. RemoveEntryList(&RecvDesc->Linkage);
  591. LinkCB->RecvDescCount--;
  592. IoRecvList.ulDescCount--;
  593. NdisWanFreeRecvDesc(RecvDesc);
  594. }
  595. RecvDesc = Next;
  596. }
  597. NdisReleaseSpinLock(&IoRecvList.Lock);
  598. //
  599. // Flush the Bundle's fragment send queues that
  600. // have sends pending on this link
  601. //
  602. AcquireBundleLock(BundleCB);
  603. for (i = 0; i < MAX_MCML; i++) {
  604. PSEND_DESC SendDesc;
  605. PSEND_FRAG_INFO FragInfo;
  606. FragInfo = &BundleCB->SendFragInfo[i];
  607. SendDesc = (PSEND_DESC)FragInfo->FragQueue.Flink;
  608. while ((PVOID)SendDesc != (PVOID)&FragInfo->FragQueue) {
  609. if (SendDesc->LinkCB == LinkCB) {
  610. PSEND_DESC NextSendDesc;
  611. NextSendDesc = (PSEND_DESC)SendDesc->Linkage.Flink;
  612. RemoveEntryList(&SendDesc->Linkage);
  613. FragInfo->FragQueueDepth--;
  614. (*LinkCB->SendHandler)(SendDesc);
  615. SendDesc = NextSendDesc;
  616. } else {
  617. SendDesc = (PSEND_DESC)SendDesc->Linkage.Flink;
  618. }
  619. }
  620. }
  621. UpdateBundleInfo(BundleCB);
  622. ReleaseBundleLock(BundleCB);
  623. //
  624. // Deref's for the refs applied by AreLinkAndBundleValid.
  625. //
  626. DEREF_LINKCB(LinkCB);
  627. DEREF_BUNDLECB(BundleCB);
  628. } while (0);
  629. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCloseCall: Exit"));
  630. }
  631. VOID
  632. ClCallConnected(
  633. IN NDIS_HANDLE ProtocolVcContext
  634. )
  635. {
  636. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCallConnected: Enter %p", ProtocolVcContext));
  637. NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCallConnected: Exit"));
  638. }