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.

1218 lines
30 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved.
  3. Module Name:
  4. callmgr.c
  5. Abstract:
  6. This module contains the interface of the driver with the Call Manager.
  7. Author:
  8. Anil Francis Thomas (10/98)
  9. Environment:
  10. Kernel
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #define MODULE_ID MODULE_CALLMGR
  16. VOID
  17. AtmSmCoAfRegisterNotify(
  18. IN NDIS_HANDLE ProtocolBindingContext,
  19. IN PCO_ADDRESS_FAMILY pAddressFamily
  20. )
  21. /*++
  22. Routine Description:
  23. This routine is called by NDIS when a Call manager registers its support
  24. for an Address Family over an adapter. If this is the Address Family we
  25. are interested in (UNI 3.1), then we register our SAP on this adapter.
  26. Arguments:
  27. ProtocolBindingContext - our context passed in NdisOpenAdapter, which is
  28. a pointer to our Adapter structure.
  29. pAddressFamily - points to a structure describing the
  30. Address Family registered by a Call Manager.
  31. Return Value:
  32. None
  33. --*/
  34. {
  35. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)
  36. ProtocolBindingContext;
  37. NDIS_STATUS Status;
  38. NDIS_CLIENT_CHARACTERISTICS Chars;
  39. TraceIn(AtmSmCoAfRegisterNotify);
  40. if(!AtmSmReferenceAdapter(pAdapt))
  41. return;
  42. if ((pAddressFamily->AddressFamily == CO_ADDRESS_FAMILY_Q2931) &&
  43. (pAddressFamily->MajorVersion == 3) &&
  44. (pAddressFamily->MinorVersion == 1) &&
  45. (pAdapt->NdisAfHandle == NULL))
  46. {
  47. DbgInfo(("AfNotify: Adapter %X\n", pAdapt));
  48. //
  49. // We successfully opened the adapter. Now open the address-family
  50. //
  51. pAdapt->AddrFamily.AddressFamily = CO_ADDRESS_FAMILY_Q2931;
  52. pAdapt->AddrFamily.MajorVersion = 3;
  53. pAdapt->AddrFamily.MinorVersion = 1;
  54. NdisZeroMemory(&Chars, sizeof(NDIS_CLIENT_CHARACTERISTICS));
  55. Chars.MajorVersion = 5;
  56. Chars.MinorVersion = 0;
  57. Chars.ClCreateVcHandler = AtmSmCreateVc;
  58. Chars.ClDeleteVcHandler = AtmSmDeleteVc;
  59. Chars.ClRequestHandler = AtmSmCoRequest;
  60. Chars.ClRequestCompleteHandler = AtmSmCoRequestComplete;
  61. Chars.ClOpenAfCompleteHandler = AtmSmOpenAfComplete;
  62. Chars.ClCloseAfCompleteHandler = AtmSmCloseAfComplete;
  63. Chars.ClRegisterSapCompleteHandler = AtmSmRegisterSapComplete;
  64. Chars.ClDeregisterSapCompleteHandler = AtmSmDeregisterSapComplete;
  65. Chars.ClMakeCallCompleteHandler = AtmSmMakeCallComplete;
  66. Chars.ClModifyCallQoSCompleteHandler = NULL;
  67. Chars.ClCloseCallCompleteHandler = AtmSmCloseCallComplete;
  68. Chars.ClAddPartyCompleteHandler = AtmSmAddPartyComplete;
  69. Chars.ClDropPartyCompleteHandler = AtmSmDropPartyComplete;
  70. Chars.ClIncomingCallHandler = AtmSmIncomingCall;
  71. Chars.ClIncomingCallQoSChangeHandler = AtmSmIncomingCallQoSChange;
  72. Chars.ClIncomingCloseCallHandler = AtmSmIncomingCloseCall;
  73. Chars.ClIncomingDropPartyHandler = AtmSmIncomingDropParty;
  74. Chars.ClCallConnectedHandler = AtmSmCallConnected;
  75. Status = NdisClOpenAddressFamily(pAdapt->NdisBindingHandle,
  76. &pAdapt->AddrFamily,
  77. pAdapt, // Use this as the Af context
  78. &Chars,
  79. sizeof(NDIS_CLIENT_CHARACTERISTICS),
  80. &pAdapt->NdisAfHandle);
  81. if (NDIS_STATUS_PENDING != Status)
  82. {
  83. AtmSmOpenAfComplete(Status, pAdapt, pAdapt->NdisAfHandle);
  84. }
  85. } else {
  86. // Not UNI3.1, hence remove the reference we added above
  87. AtmSmDereferenceAdapter(pAdapt);
  88. }
  89. TraceOut(AtmSmCoAfRegisterNotify);
  90. }
  91. VOID
  92. AtmSmOpenAfComplete(
  93. IN NDIS_STATUS Status,
  94. IN NDIS_HANDLE ProtocolAfContext,
  95. IN NDIS_HANDLE NdisAfHandle
  96. )
  97. /*++
  98. Routine Description:
  99. Completion processing for the OpenAf call.
  100. Arguments:
  101. Status Status of OpenAf
  102. ProtocolAfContext Pointer to the pAdapt
  103. NdisAfHandle Ndis Handle to refer to this Af
  104. Return Value:
  105. --*/
  106. {
  107. PATMSM_ADAPTER pAdapt= (PATMSM_ADAPTER)ProtocolAfContext;
  108. TraceIn(AtmSmOpenAfComplete);
  109. if (NDIS_STATUS_SUCCESS == Status){
  110. pAdapt->NdisAfHandle = NdisAfHandle;
  111. pAdapt->ulFlags |= ADAPT_AF_OPENED;
  112. //
  113. // Now register our SAP on this interface
  114. //
  115. Status = AtmSmRegisterSap(pAdapt);
  116. } else {
  117. DbgErr(("Opening of Address Family Failed! Status - 0x%X\n", Status));
  118. }
  119. if ((Status != NDIS_STATUS_SUCCESS) &&
  120. (Status != NDIS_STATUS_PENDING)){
  121. //
  122. // Close Address family (This results in a dereference)
  123. //
  124. Status = NdisClCloseAddressFamily(pAdapt->NdisAfHandle);
  125. if (NDIS_STATUS_PENDING != Status){
  126. AtmSmCloseAfComplete(Status, pAdapt);
  127. }
  128. //
  129. // Close Adapter (This results in a dereference)
  130. //
  131. NdisCloseAdapter(&Status, pAdapt->NdisBindingHandle);
  132. if (NDIS_STATUS_PENDING != Status){
  133. AtmSmCloseAdapterComplete(pAdapt, Status);
  134. }
  135. // if synchronous - by now the adapter structure wll be freed
  136. }
  137. TraceOut(AtmSmOpenAfComplete);
  138. }
  139. NDIS_STATUS
  140. AtmSmRegisterSap(
  141. IN PATMSM_ADAPTER pAdapt
  142. )
  143. /*++
  144. Routine Description:
  145. Register the Sap for receiving incoming calls.
  146. Arguments:
  147. Return Value:
  148. --*/
  149. {
  150. ULONG ulSize;
  151. NDIS_STATUS Status;
  152. PATM_SAP pAtmSap;
  153. PATM_ADDRESS pAtmAddress;
  154. TraceIn(AtmSmRegisterSap);
  155. do
  156. {
  157. //
  158. // Allocate memory for registering the SAP, if doing it for the
  159. // first time.
  160. //
  161. ulSize = sizeof(CO_SAP) + sizeof(ATM_SAP) + sizeof(ATM_ADDRESS);
  162. if (NULL == pAdapt->pSap){
  163. AtmSmAllocMem(&pAdapt->pSap, PCO_SAP, ulSize);
  164. }
  165. if (NULL == pAdapt->pSap){
  166. Status = NDIS_STATUS_RESOURCES;
  167. DbgErr(("Failed to allocate memory for Sap\n"));
  168. break;
  169. }
  170. NdisZeroMemory(pAdapt->pSap, ulSize);
  171. pAdapt->pSap->SapType = SAP_TYPE_NSAP;
  172. pAdapt->pSap->SapLength = sizeof(ATM_SAP) + sizeof(ATM_ADDRESS);
  173. pAtmSap = (PATM_SAP)pAdapt->pSap->Sap;
  174. pAtmAddress = (PATM_ADDRESS)(pAtmSap->Addresses);
  175. //
  176. // Fill in the ATM SAP with default values
  177. //
  178. NdisMoveMemory(&pAtmSap->Blli, &AtmSmDefaultBlli, sizeof(ATM_BLLI_IE));
  179. NdisMoveMemory(&pAtmSap->Bhli, &AtmSmDefaultBhli, sizeof(ATM_BHLI_IE));
  180. //
  181. // ATM Address to "listen" on: Wild card everything except the SEL.
  182. //
  183. pAtmSap->NumberOfAddresses = 1;
  184. pAtmAddress->AddressType = SAP_FIELD_ANY_AESA_REST;
  185. pAtmAddress->NumberOfDigits = ATM_ADDRESS_LENGTH;
  186. pAtmAddress->Address[ATM_ADDRESS_LENGTH-1] = pAdapt->SelByte;
  187. Status = NdisClRegisterSap(pAdapt->NdisAfHandle,
  188. pAdapt,
  189. pAdapt->pSap,
  190. &pAdapt->NdisSapHandle);
  191. if (Status != NDIS_STATUS_PENDING){
  192. AtmSmRegisterSapComplete(Status,
  193. pAdapt,
  194. pAdapt->pSap,
  195. pAdapt->NdisSapHandle);
  196. }
  197. } while (FALSE);
  198. if ((Status != NDIS_STATUS_SUCCESS) &&
  199. (Status != NDIS_STATUS_PENDING)){
  200. DbgErr(("Registering Sap Failed! Status - 0x%X\n", Status));
  201. // cleanup done after return
  202. }
  203. TraceOut(AtmSmRegisterSap);
  204. return Status;
  205. }
  206. VOID
  207. AtmSmRegisterSapComplete(
  208. IN NDIS_STATUS Status,
  209. IN NDIS_HANDLE ProtocolSapContext,
  210. IN PCO_SAP pSap,
  211. IN NDIS_HANDLE NdisSapHandle
  212. )
  213. /*++
  214. Routine Description:
  215. Called by NDIS or us when the Sap registration completes.
  216. Arguments:
  217. Return Value:
  218. --*/
  219. {
  220. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolSapContext;
  221. TraceIn(AtmSmRegisterSapComplete);
  222. ASSERT (pSap == pAdapt->pSap);
  223. if (NDIS_STATUS_SUCCESS != Status){
  224. DbgErr(("RegisterSapComplete failed (%x): Adapter %x\n",
  225. Status, pAdapt));
  226. AtmSmFreeMem(pAdapt->pSap);
  227. pAdapt->pSap = NULL;
  228. } else {
  229. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  230. pAdapt->NdisSapHandle = NdisSapHandle;
  231. pAdapt->ulFlags |= ADAPT_SAP_REGISTERED;
  232. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  233. }
  234. TraceOut(AtmSmRegisterSapComplete);
  235. }
  236. VOID
  237. AtmSmDeregisterSapComplete(
  238. IN NDIS_STATUS Status,
  239. IN NDIS_HANDLE ProtocolSapContext
  240. )
  241. /*++
  242. Routine Description:
  243. Called by NDIS or us when the Sap Deregistration completes.
  244. Arguments:
  245. Return Value:
  246. --*/
  247. {
  248. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolSapContext;
  249. TraceIn(AtmSmDeregisterSapComplete);
  250. pAdapt->ulFlags &= ~ADAPT_SAP_REGISTERED;
  251. pAdapt->NdisSapHandle = NULL;
  252. AtmSmFreeMem(pAdapt->pSap);
  253. pAdapt->pSap = NULL;
  254. TraceOut(AtmSmDeregisterSapComplete);
  255. }
  256. VOID
  257. AtmSmCloseAfComplete(
  258. IN NDIS_STATUS Status,
  259. IN NDIS_HANDLE ProtocolAfContext
  260. )
  261. /*++
  262. Routine Description:
  263. Called by NDIS or us when closing of AF completes.
  264. Arguments:
  265. Return Value:
  266. --*/
  267. {
  268. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolAfContext;
  269. pAdapt->ulFlags &= ~ADAPT_AF_OPENED;
  270. pAdapt->NdisAfHandle = NULL;
  271. DbgInfo(("CloseAfComplete: pAdapt %x, Flags %x, Ref %x\n",
  272. pAdapt, pAdapt->ulFlags, pAdapt->ulRefCount));
  273. //
  274. // Nothing much to do except dereference the pAdapt
  275. //
  276. AtmSmDereferenceAdapter(pAdapt);
  277. }
  278. NDIS_STATUS
  279. AtmSmCreateVc(
  280. IN NDIS_HANDLE ProtocolAfContext,
  281. IN NDIS_HANDLE NdisVcHandle,
  282. OUT PNDIS_HANDLE ProtocolVcContext
  283. )
  284. /*++
  285. Routine Description:
  286. Entry point called by NDIS when the Call Manager wants to create
  287. a new endpoint (VC). We allocate a new VC structure, and return
  288. a pointer to it as our VC context.
  289. Arguments:
  290. ProtocolAfContext - Actually a pointer to the ATMSM adapter structure
  291. NdisVcHandle - Handle for this VC for all future references
  292. ProtocolVcContext - Place where we (protocol) return our context for the VC
  293. Return Value:
  294. NDIS_STATUS_SUCCESS if we could create a VC
  295. NDIS_STATUS_RESOURCES otherwise
  296. --*/
  297. {
  298. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolAfContext;
  299. PATMSM_VC pVc;
  300. NDIS_STATUS Status;
  301. DbgInfo(("CreateVc: NdisVcHandle %x, Adapt - %x\n", NdisVcHandle, pAdapt));
  302. *ProtocolVcContext = NULL;
  303. Status = AtmSmAllocVc(pAdapt, &pVc, VC_TYPE_INCOMING, NdisVcHandle);
  304. if(NDIS_STATUS_SUCCESS == Status){
  305. *ProtocolVcContext = pVc;
  306. }
  307. return Status;
  308. }
  309. NDIS_STATUS
  310. AtmSmDeleteVc(
  311. IN NDIS_HANDLE ProtocolVcContext
  312. )
  313. /*++
  314. Routine Description:
  315. Our Delete VC handler. This VC would have been allocated as a result
  316. of a previous entry into our CreateVcHandler, and possibly used for
  317. an incoming call.
  318. We dereference the VC here.
  319. Arguments:
  320. ProtocolVcContext - pointer to our VC structure
  321. Return Value:
  322. NDIS_STATUS_SUCCESS always
  323. --*/
  324. {
  325. PATMSM_VC pVc = (PATMSM_VC)ProtocolVcContext;
  326. DbgInfo(("DeleteVc: For Vc %lx\n", pVc));
  327. pVc->NdisVcHandle = NULL;
  328. AtmSmDereferenceVc(pVc);
  329. return NDIS_STATUS_SUCCESS;
  330. }
  331. NDIS_STATUS
  332. AtmSmIncomingCall(
  333. IN NDIS_HANDLE ProtocolSapContext,
  334. IN NDIS_HANDLE ProtocolVcContext,
  335. IN OUT PCO_CALL_PARAMETERS CallParameters
  336. )
  337. /*++
  338. Routine Description:
  339. Handler for incoming call. We accept the call unless we are shutting down
  340. and then do the actual processing when the call processing completes.
  341. Arguments:
  342. ProtocolSapContext Pointer to the pAdapt
  343. ProtocolVcContext Pointer to the Vc
  344. CallParameters Call Parameters
  345. Return Value:
  346. --*/
  347. {
  348. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolSapContext;
  349. PATMSM_VC pVc = (PATMSM_VC)ProtocolVcContext;
  350. Q2931_CALLMGR_PARAMETERS UNALIGNED * CallMgrSpecific;
  351. ASSERT (pVc->pAdapt == pAdapt);
  352. DbgInfo(("AtmSmIncomingCall: On Vc %lx\n", pVc));
  353. //
  354. // Mark the Vc to indicate the call processing is underway
  355. //
  356. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  357. ASSERT ((pVc->ulFlags & (ATMSM_VC_ACTIVE | ATMSM_VC_CALLPROCESSING)) == 0);
  358. ATMSM_SET_VC_STATE(pVc, ATMSM_VC_CALLPROCESSING);
  359. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  360. //
  361. // Get the remote atm address from the call-parameters
  362. //
  363. CallMgrSpecific = (PQ2931_CALLMGR_PARAMETERS)&CallParameters->
  364. CallMgrParameters->CallMgrSpecific.Parameters[0];
  365. pVc->HwAddr.Address = CallMgrSpecific->CallingParty;
  366. //
  367. // Get the max size of packets we can send on this VC, from the
  368. // AAL5 parameters. Limit it to the size our miniport can support.
  369. //
  370. pVc->MaxSendSize = pAdapt->MaxPacketSize; // default
  371. if (CallMgrSpecific->InfoElementCount > 0) {
  372. Q2931_IE UNALIGNED * pIe;
  373. AAL5_PARAMETERS UNALIGNED * pAal5;
  374. ULONG IeCount;
  375. pIe = (PQ2931_IE)CallMgrSpecific->InfoElements;
  376. for (IeCount = CallMgrSpecific->InfoElementCount;
  377. IeCount != 0;
  378. IeCount--) {
  379. if (pIe->IEType == IE_AALParameters) {
  380. pAal5 = &(((PAAL_PARAMETERS_IE)pIe->IE)->
  381. AALSpecificParameters.AAL5Parameters);
  382. //
  383. // Make sure we don't send more than what the caller can handle.
  384. //
  385. if (pAal5->ForwardMaxCPCSSDUSize < pVc->MaxSendSize) {
  386. pVc->MaxSendSize = pAal5->ForwardMaxCPCSSDUSize;
  387. }
  388. //
  389. // Make sure the caller doesn't send more than what our
  390. // miniport can handle.
  391. //
  392. if (pAal5->BackwardMaxCPCSSDUSize > pAdapt->MaxPacketSize) {
  393. pAal5->BackwardMaxCPCSSDUSize = pAdapt->MaxPacketSize;
  394. }
  395. break;
  396. }
  397. pIe = (PQ2931_IE)((PUCHAR)pIe + pIe->IELength);
  398. }
  399. }
  400. return NDIS_STATUS_SUCCESS;
  401. }
  402. VOID
  403. AtmSmCallConnected(
  404. IN NDIS_HANDLE ProtocolVcContext
  405. )
  406. /*++
  407. Routine Description:
  408. Last hand-shake in the incoming call path. Move the Vc to the list of
  409. active calls.
  410. Arguments:
  411. ProtocolVcContext Pointer to VC
  412. Return Value:
  413. None.
  414. --*/
  415. {
  416. PATMSM_VC pVc = (PATMSM_VC)ProtocolVcContext;
  417. PATMSM_ADAPTER pAdapt = pVc->pAdapt;
  418. DbgInfo(("AtmSmCallConnected: On pVc %x pAdapt %x\n", pVc, pAdapt));
  419. pAdapt = pVc->pAdapt;
  420. // now we add a reference to the VC
  421. AtmSmReferenceVc(pVc);
  422. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  423. ASSERT(ATMSM_GET_VC_STATE(pVc) != ATMSM_VC_ACTIVE);
  424. ASSERT(ATMSM_GET_VC_STATE(pVc) == ATMSM_VC_CALLPROCESSING);
  425. ATMSM_SET_VC_STATE(pVc, ATMSM_VC_ACTIVE);
  426. // remove the Vc from the inactive list
  427. RemoveEntryList(&pVc->List);
  428. // insert the vc into the active list
  429. InsertHeadList(&pAdapt->ActiveVcHead, &pVc->List);
  430. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  431. }
  432. VOID
  433. AtmSmMakeCallComplete(
  434. IN NDIS_STATUS Status,
  435. IN NDIS_HANDLE ProtocolVcContext,
  436. IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
  437. IN PCO_CALL_PARAMETERS CallParameters
  438. )
  439. /*++
  440. Routine Description:
  441. Handle completion of an earlier call to NdisClMakeCall. If the call has
  442. succeeded and if this is a point to multipoint call, initiate Addparty on
  443. the rest of the addresses. If it is not multipoint, then send any packets
  444. pending on the call.
  445. Arguments:
  446. Status Result of NdisClMakeCall
  447. ProtocolVcContext Pointer to P-P or PMP Vc
  448. NdisPartyHandle If successful, the handle for this party
  449. CallParameters Pointer to Call parameters
  450. Return Value:
  451. None.
  452. --*/
  453. {
  454. PATMSM_VC pVc = (PATMSM_VC)ProtocolVcContext;
  455. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)pVc->pAdapt;
  456. PATMSM_PMP_MEMBER pMember;
  457. BOOLEAN bLockReleased = FALSE;
  458. DbgInfo(("MakeCallComplete: Status %x, pVc %x, VC flag %x\n",
  459. Status, pVc, pVc->ulFlags));
  460. // Free the call parameters
  461. AtmSmFreeMem(CallParameters);
  462. //
  463. // If this is a point to point connection and we succeeded in connecting
  464. // then send the packets pending on the VC.
  465. //
  466. if(VC_TYPE_PMP_OUTGOING != pVc->VcType){
  467. PIRP pIrp;
  468. if(NDIS_STATUS_SUCCESS == Status){
  469. // successfully connected the P-P call, send any pending packets
  470. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  471. ATMSM_SET_VC_STATE(pVc, ATMSM_VC_ACTIVE);
  472. DbgInfo(("PP VC 0x%x successfully connected to destination\n",
  473. pVc));
  474. // now complete IRP that started this connect call
  475. pIrp = pVc->pConnectIrp;
  476. pVc->pConnectIrp = NULL;
  477. ASSERT(pIrp);
  478. // remove the Vc from the inactive list
  479. RemoveEntryList(&pVc->List);
  480. // insert the vc into the active list
  481. InsertHeadList(&pAdapt->ActiveVcHead, &pVc->List);
  482. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  483. if(pIrp){
  484. pIrp->IoStatus.Status = STATUS_SUCCESS;
  485. // now set the connect context
  486. *(PHANDLE)(pIrp->AssociatedIrp.SystemBuffer) = (HANDLE)pVc;
  487. pIrp->IoStatus.Information = sizeof(HANDLE);
  488. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  489. }
  490. AtmSmSendQueuedPacketsOnVc(pVc);
  491. } else {
  492. // failed to connect the call.
  493. // now complete IRP that started this connect call
  494. PIRP pIrp = pVc->pConnectIrp;
  495. pVc->pConnectIrp = NULL;
  496. ASSERT(pIrp);
  497. if(pIrp){
  498. pIrp->IoStatus.Status = Status;
  499. pIrp->IoStatus.Information = 0;
  500. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  501. }
  502. DbgInfo(("PP VC 0x%x failed to connect to destination - Status - "
  503. "0x%x\n", pVc, Status));
  504. // Cleanup the VC - remove the reference added at create
  505. AtmSmDereferenceVc(pVc);
  506. }
  507. return;
  508. }
  509. //
  510. // This is the completion of the first Make call on a PMP. If the first
  511. // has succeeded, we add the rest. If the first one failed, we remove it
  512. // and try to make a call on another one.
  513. //
  514. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  515. //
  516. // Get the member we were trying to connect to.
  517. //
  518. for (pMember = pVc->pPMPMembers; pMember; pMember = pMember->pNext)
  519. if(ATMSM_GET_MEMBER_STATE(pMember) == ATMSM_MEMBER_CONNECTING)
  520. break;
  521. ASSERT(NULL != pMember);
  522. pVc->ulNumConnectingMembers--;
  523. if (NDIS_STATUS_SUCCESS == Status){
  524. ASSERT(NULL != NdisPartyHandle);
  525. ATMSM_SET_MEMBER_STATE(pMember, ATMSM_MEMBER_CONNECTED);
  526. pMember->NdisPartyHandle = NdisPartyHandle;
  527. pVc->ulNumActiveMembers++;
  528. //
  529. // check if the member was invalidated during the call setup
  530. // if so, remove this guy
  531. //
  532. if(ATMSM_IS_MEMBER_INVALID(pMember)){
  533. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  534. bLockReleased = TRUE;
  535. // This member was invalidated, now drop him off
  536. AtmSmDropMemberFromVc(pVc, pMember);
  537. }
  538. }
  539. else
  540. {
  541. DbgWarn(("MakeCall error %x, pMember %x to addr:", Status, pMember));
  542. DumpATMAddress(ATMSMD_ERR, "", &pMember->HwAddr.Address);
  543. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  544. bLockReleased = TRUE;
  545. //
  546. // Connection failed. Delete this member from our list of members.
  547. //
  548. DeleteMemberInfoFromVc(pVc, pMember);
  549. }
  550. if(!bLockReleased) {
  551. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  552. }
  553. //
  554. // Add anymore members remaining
  555. //
  556. AtmSmConnectToPMPDestinations(pVc);
  557. return;
  558. }
  559. VOID
  560. AtmSmIncomingCloseCall(
  561. IN NDIS_STATUS CloseStatus,
  562. IN NDIS_HANDLE ProtocolVcContext,
  563. IN PVOID CloseData OPTIONAL,
  564. IN UINT Size OPTIONAL
  565. )
  566. /*++
  567. Routine Description:
  568. Indication of an incoming close call from the network. If this
  569. is not an outgoing PMP VC, then we mark the VC as inactive, and
  570. move it to the Inactive VC list. If this is on PMP Vc,
  571. there must be only one party on the PMP connection. We update
  572. that member's state.
  573. In any case, we call NdisClCloseCall to complete the handshake.
  574. Arguments:
  575. CloseStatus Status of Close
  576. ProtocolVcContext Pointer to VC
  577. CloseData Optional Close data (IGNORED)
  578. Size Size of Optional Close Data (OPTIONAL)
  579. Return Value:
  580. None
  581. --*/
  582. {
  583. PATMSM_VC pVc = (PATMSM_VC)ProtocolVcContext;
  584. PATMSM_ADAPTER pAdapt = pVc->pAdapt;
  585. NDIS_HANDLE NdisVcHandle = pVc->NdisVcHandle;
  586. NDIS_HANDLE NdisPartyHandle;
  587. PATMSM_PMP_MEMBER pMember;
  588. NDIS_STATUS Status;
  589. if (VC_TYPE_PMP_OUTGOING != pVc->VcType){
  590. DbgInfo(("AtmSmIncomingCloseCall: On Vc 0x%x\n",
  591. ProtocolVcContext));
  592. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  593. ASSERT (ATMSM_GET_VC_STATE(pVc) != ATMSM_VC_CLOSING);
  594. NdisPartyHandle = NULL;
  595. ATMSM_SET_VC_STATE(pVc, ATMSM_VC_CLOSING);
  596. ASSERT(pVc->HwAddr.SubAddress == NULL);
  597. RemoveEntryList(&pVc->List);
  598. InsertHeadList(&pAdapt->InactiveVcHead, &pVc->List);
  599. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  600. pMember = NULL;
  601. Status = NdisClCloseCall(NdisVcHandle, NdisPartyHandle, NULL, 0);
  602. DbgInfo(("NdisCloseCall Status - 0x%X Vc - 0x%X\n", Status, pVc));
  603. if (Status != NDIS_STATUS_PENDING){
  604. AtmSmCloseCallComplete(Status, pVc, (NDIS_HANDLE)pMember);
  605. }
  606. } else {
  607. //
  608. // May be the net has gone bad
  609. //
  610. DbgInfo(("PMP IncomingCloseCall: On Vc %x\n", ProtocolVcContext));
  611. AtmSmDisconnectVc(pVc);
  612. }
  613. }
  614. VOID
  615. AtmSmCloseCallComplete(
  616. IN NDIS_STATUS Status,
  617. IN NDIS_HANDLE ProtocolVcContext,
  618. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL
  619. )
  620. /*++
  621. Routine Description:
  622. This is called to complete our call to NdisClCloseCall. If the VC
  623. is other than outgoing PMP, we update its state and dereference it
  624. If this is an outgoing PMP, we delete the last member
  625. Arguments:
  626. Status Status of NdisClCloseCall
  627. ProtocolVcContext Pointer to our VC structure
  628. ProtocolPartyContext If the VC is PMP Vc, this is a pointer
  629. to the Member that was disconnected.
  630. Return Value:
  631. None
  632. --*/
  633. {
  634. PATMSM_VC pVc = (PATMSM_VC)ProtocolVcContext;
  635. PATMSM_ADAPTER pAdapt = pVc->pAdapt;
  636. BOOLEAN bStopping;
  637. DbgInfo(("AtmSmCloseCallComplete: On Vc %lx\n", pVc));
  638. ASSERT(Status == NDIS_STATUS_SUCCESS);
  639. switch(pVc->VcType){
  640. case VC_TYPE_INCOMING:
  641. case VC_TYPE_PP_OUTGOING:
  642. // Both incoming call and outgoing PP calls
  643. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  644. ASSERT (ATMSM_GET_VC_STATE(pVc) == ATMSM_VC_CLOSING);
  645. ATMSM_SET_VC_STATE(pVc, ATMSM_VC_CLOSED);
  646. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  647. // Now dereference the VC
  648. AtmSmDereferenceVc(pVc);
  649. break;
  650. case VC_TYPE_PMP_OUTGOING: {
  651. // Outgoing PMP
  652. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  653. pVc->ulNumDroppingMembers--;
  654. ATMSM_SET_VC_STATE(pVc, ATMSM_VC_CLOSED);
  655. ASSERT(1 == pVc->ulNumTotalMembers);
  656. ASSERT((0 == pVc->ulNumActiveMembers) &&
  657. (0 == pVc->ulNumConnectingMembers) &&
  658. (0 == pVc->ulNumDroppingMembers));
  659. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  660. if(DeleteMemberInfoFromVc(pVc,
  661. (PATMSM_PMP_MEMBER)ProtocolPartyContext)){
  662. }
  663. }
  664. break;
  665. default:
  666. ASSERT(FALSE);
  667. }
  668. }
  669. VOID
  670. AtmSmAddPartyComplete(
  671. IN NDIS_STATUS Status,
  672. IN NDIS_HANDLE ProtocolPartyContext,
  673. IN NDIS_HANDLE NdisPartyHandle,
  674. IN PCO_CALL_PARAMETERS CallParameters
  675. )
  676. /*++
  677. Routine Description:
  678. Completion of NdisClAddParty to add a new party to PMP Vc.
  679. If successful, update the member's state. Otherwise, delete it.
  680. Arguments:
  681. Status Status of AddParty
  682. ProtocolPartyContext Pointer to Member being added
  683. NdisPartyHandle Valid if AddParty successful
  684. CallParameters Pointer to AddParty call parameters
  685. Return Value:
  686. None
  687. --*/
  688. {
  689. PATMSM_PMP_MEMBER pMember = (PATMSM_PMP_MEMBER)ProtocolPartyContext;
  690. PATMSM_VC pVc = (PATMSM_VC)pMember->pVc;
  691. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)pVc->pAdapt;
  692. BOOLEAN bLockReleased = FALSE;
  693. // Free the memory for CallParameters
  694. AtmSmFreeMem(CallParameters);
  695. DbgLoud(("AddPartyComplete: Status %x, pMember %x, NdisPartyHandle %x\n",
  696. Status, pMember, NdisPartyHandle));
  697. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  698. pVc->ulNumConnectingMembers--;
  699. if (NDIS_STATUS_SUCCESS == Status){
  700. ATMSM_SET_MEMBER_STATE(pMember, ATMSM_MEMBER_CONNECTED);
  701. ASSERT(NdisPartyHandle);
  702. pMember->NdisPartyHandle = NdisPartyHandle;
  703. pVc->ulNumActiveMembers++;
  704. //
  705. // check if the member was invalidated during the call setup
  706. // if so, remove this guy
  707. //
  708. if(ATMSM_IS_MEMBER_INVALID(pMember)){
  709. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  710. bLockReleased = TRUE;
  711. // This member was invalidated, now drop him off
  712. AtmSmDropMemberFromVc(pVc, pMember);
  713. }
  714. } else {
  715. DbgWarn(("MakeCall error %x, pMember %x to addr:", Status, pMember));
  716. DumpATMAddress(ATMSMD_ERR, "", &pMember->HwAddr.Address);
  717. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  718. bLockReleased = TRUE;
  719. //
  720. // Connection failed. Delete this member from our list of members.
  721. //
  722. DeleteMemberInfoFromVc(pVc,
  723. (PATMSM_PMP_MEMBER)ProtocolPartyContext);
  724. }
  725. if(!bLockReleased) {
  726. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  727. }
  728. //
  729. // Add anymore members remaining
  730. //
  731. AtmSmConnectToPMPDestinations(pVc);
  732. }
  733. VOID
  734. AtmSmDropPartyComplete(
  735. IN NDIS_STATUS Status,
  736. IN NDIS_HANDLE ProtocolPartyContext
  737. )
  738. /*++
  739. Routine Description:
  740. This is called to signify completion of a previous NdisClDropParty,
  741. to drop a member off a PMP Vc. Delete the member.
  742. Arguments:
  743. Status Status of DropParty
  744. ProtocolPartyContext Pointer to Member being dropped
  745. Return Value:
  746. None.
  747. --*/
  748. {
  749. PATMSM_PMP_MEMBER pMember = (PATMSM_PMP_MEMBER)ProtocolPartyContext;
  750. PATMSM_VC pVc = (PATMSM_VC)pMember->pVc;
  751. PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)pVc->pAdapt;
  752. BOOLEAN IsVcClosing;
  753. DbgInfo(("DropPartyComplete: Vc - %x Member - %x\n", pVc, pMember));
  754. ASSERT(Status == NDIS_STATUS_SUCCESS);
  755. ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
  756. pVc->ulNumDroppingMembers--;
  757. IsVcClosing = ((ATMSM_GET_VC_STATE(pVc) == ATMSM_VC_NEED_CLOSING) &&
  758. (pVc->ulNumActiveMembers == 1) &&
  759. ((pVc->ulNumDroppingMembers + pVc->ulNumConnectingMembers)
  760. == 0));
  761. RELEASE_ADAPTER_GEN_LOCK(pAdapt);
  762. //
  763. // Delete this member info structure
  764. //
  765. DeleteMemberInfoFromVc(pVc, pMember);
  766. //
  767. // If this VC is closing remove the last member in it
  768. // (This member will issue a close call).
  769. //
  770. if(IsVcClosing){
  771. ASSERT(1 == pVc->ulNumTotalMembers);
  772. AtmSmDropMemberFromVc(pVc, pVc->pPMPMembers);
  773. }
  774. }
  775. VOID
  776. AtmSmIncomingDropParty(
  777. IN NDIS_STATUS DropStatus,
  778. IN NDIS_HANDLE ProtocolPartyContext,
  779. IN PVOID CloseData OPTIONAL,
  780. IN UINT Size OPTIONAL
  781. )
  782. /*++
  783. Routine Description:
  784. Indication that a Member has dropped off the PMP Vc
  785. We complete this handshake by calling NdisClDropParty.
  786. Arguments:
  787. DropStatus Status
  788. ProtocolPartyContext Pointer to Member
  789. CloseData Optional Close data (IGNORED)
  790. Size Size of Optional Close Data (OPTIONAL)
  791. Return Value:
  792. None
  793. --*/
  794. {
  795. PATMSM_PMP_MEMBER pMember = (PATMSM_PMP_MEMBER)ProtocolPartyContext;
  796. PATMSM_VC pVc = (PATMSM_VC)pMember->pVc;
  797. ASSERT(DropStatus == NDIS_STATUS_SUCCESS);
  798. ASSERT(ATMSM_GET_MEMBER_STATE(pMember) == ATMSM_MEMBER_CONNECTED);
  799. DbgInfo(("IncomingDropParty: pVc %x, pMember %x, Addr: ",
  800. pVc, pMember));
  801. DumpATMAddress(ATMSMD_INFO, "", &pMember->HwAddr.Address);
  802. AtmSmDropMemberFromVc(pVc, pMember);
  803. }
  804. VOID
  805. AtmSmIncomingCallQoSChange(
  806. IN NDIS_HANDLE ProtocolVcContext,
  807. IN PCO_CALL_PARAMETERS CallParameters
  808. )
  809. /*++
  810. Routine Description:
  811. Arguments:
  812. Return Value:
  813. --*/
  814. {
  815. DbgWarn(("QoSChange: Ignored\n"));
  816. }