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.

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