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.

2831 lines
60 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. ndis.c
  5. Abstract:
  6. This file contains the code to implement the initialization
  7. functions for the atmarp server.
  8. Author:
  9. Jameel Hyder (jameelh@microsoft.com) July 1996
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #include <precomp.h>
  15. #define _FILENUM_ FILENUM_NDIS
  16. NTSTATUS
  17. ArpSInitializeNdis(
  18. VOID
  19. )
  20. /*++
  21. Routine Description:
  22. Arguments:
  23. Return Value:
  24. --*/
  25. {
  26. NDIS_STATUS Status;
  27. NDIS_PROTOCOL_CHARACTERISTICS Chars;
  28. UINT i, j;
  29. PUCHAR pTmp;
  30. do
  31. {
  32. INITIALIZE_SPIN_LOCK(&ArpSPktListLock);
  33. ExInitializeSListHead(&ArpSPktList);
  34. //
  35. // Start off by allocating packets, mdls and buffer space
  36. //
  37. NdisAllocatePacketPoolEx(&Status,
  38. &ArpSPktPoolHandle,
  39. ArpSBuffers,
  40. ArpSBuffers * (MAX_DESC_MULTIPLE-1),
  41. sizeof(PROTOCOL_RESD));
  42. if (Status != NDIS_STATUS_SUCCESS)
  43. {
  44. break;
  45. }
  46. #if 0
  47. {
  48. INT SkipAll = 0;
  49. DBGPRINT(DBG_LEVEL_ERROR, ("SkipAll = 0x%p.\n", &SkipAll));
  50. DbgBreakPoint();
  51. if (SkipAll)
  52. {
  53. DBGPRINT(DBG_LEVEL_ERROR, ("ABORTING ATMARPS\n"));
  54. Status = STATUS_UNSUCCESSFUL;
  55. break;
  56. }
  57. }
  58. #endif // 0
  59. NdisAllocateBufferPool(&Status,
  60. &ArpSBufPoolHandle,
  61. ArpSBuffers);
  62. if (Status != NDIS_STATUS_SUCCESS)
  63. {
  64. break;
  65. }
  66. NdisAllocatePacketPoolEx(&Status,
  67. &MarsPktPoolHandle,
  68. MarsPackets,
  69. MarsPackets * (MAX_DESC_MULTIPLE-1),
  70. sizeof(PROTOCOL_RESD));
  71. if (Status != NDIS_STATUS_SUCCESS)
  72. {
  73. break;
  74. }
  75. NdisAllocateBufferPool(&Status,
  76. &MarsBufPoolHandle,
  77. ArpSBuffers);
  78. if (Status != NDIS_STATUS_SUCCESS)
  79. {
  80. break;
  81. }
  82. ArpSBufferSpace = ALLOC_NP_MEM(ArpSBuffers*PKT_SPACE, POOL_TAG_BUF);
  83. if (ArpSBufferSpace == NULL)
  84. {
  85. Status = NDIS_STATUS_RESOURCES;
  86. break;
  87. }
  88. //
  89. // Now that we have the packets and the buffer descriptors, allocate memory for the each of the packets
  90. // and queue them up in the global list. Fail only if no packets initialized.
  91. //
  92. for (i = 0, pTmp = ArpSBufferSpace;
  93. i < ArpSBuffers;
  94. i++, pTmp += PKT_SPACE)
  95. {
  96. PNDIS_PACKET Pkt;
  97. PNDIS_BUFFER Buf;
  98. PPROTOCOL_RESD Resd;
  99. //
  100. // The packet pool is already allocated. NdisAllocatePacket cannot fail.
  101. //
  102. NdisAllocatePacket(&Status, &Pkt, ArpSPktPoolHandle);
  103. ASSERT (Status == NDIS_STATUS_SUCCESS);
  104. if (Status != NDIS_STATUS_SUCCESS)
  105. {
  106. DbgPrint("ATMARPS: failed to alloc pkt from %p\n", ArpSPktPoolHandle);
  107. DbgBreakPoint();
  108. DbgBreakPoint();
  109. }
  110. Resd = RESD_FROM_PKT(Pkt);
  111. InitializeListHead(&Resd->ReqList);
  112. NdisAllocateBuffer(&Status,
  113. &Buf,
  114. ArpSBufPoolHandle,
  115. pTmp,
  116. PKT_SPACE);
  117. if (Status == NDIS_STATUS_SUCCESS)
  118. {
  119. NdisChainBufferAtFront(Pkt, Buf);
  120. ExInterlockedPushEntrySList(&ArpSPktList,
  121. &Resd->FreeList,
  122. &ArpSPktListLock);
  123. }
  124. else
  125. {
  126. NdisFreePacket(Pkt);
  127. break;
  128. }
  129. }
  130. if (i == 0)
  131. {
  132. //
  133. // We could not initialize even one packet, quit.
  134. //
  135. break;
  136. }
  137. //
  138. // Now register with NDIS as a protocol. We do this last since we
  139. // must be ready to accept incoming bind notifications
  140. //
  141. RtlZeroMemory(&Chars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  142. Chars.MajorNdisVersion = 5;
  143. Chars.MinorNdisVersion = 0;
  144. Chars.OpenAdapterCompleteHandler = ArpSOpenAdapterComplete;
  145. Chars.CloseAdapterCompleteHandler = ArpSCloseAdapterComplete;
  146. Chars.StatusHandler = ArpSStatus;
  147. Chars.RequestCompleteHandler = ArpSRequestComplete;
  148. Chars.ReceiveCompleteHandler = ArpSReceiveComplete;
  149. Chars.StatusCompleteHandler = ArpSStatusComplete;
  150. Chars.BindAdapterHandler = ArpSBindAdapter;
  151. Chars.UnbindAdapterHandler = ArpSUnbindAdapter;
  152. Chars.PnPEventHandler = ArpSPnPEventHandler;
  153. Chars.CoSendCompleteHandler = ArpSCoSendComplete;
  154. Chars.CoStatusHandler = ArpSCoStatus;
  155. Chars.CoReceivePacketHandler = ArpSHandleArpRequest;
  156. Chars.CoAfRegisterNotifyHandler = ArpSCoAfRegisterNotify;
  157. RtlInitUnicodeString(&Chars.Name, SERVICE_NAME);
  158. NdisRegisterProtocol(&Status, &ArpSProtocolHandle, &Chars, sizeof(Chars));
  159. } while (FALSE);
  160. if (Status != NDIS_STATUS_SUCCESS)
  161. {
  162. ArpSDeinitializeNdis();
  163. }
  164. return Status;
  165. }
  166. VOID
  167. ArpSDeinitializeNdis(
  168. VOID
  169. )
  170. {
  171. NDIS_STATUS Status;
  172. PNDIS_PACKET Packet;
  173. PSLIST_ENTRY Entry;
  174. PPROTOCOL_RESD Resd;
  175. if (ArpSProtocolHandle != NULL)
  176. {
  177. NdisDeregisterProtocol(&Status, ArpSProtocolHandle);
  178. ArpSProtocolHandle = NULL;
  179. }
  180. while ((Entry = ExInterlockedPopEntrySList(&ArpSPktList, &ArpSPktListLock)) != NULL)
  181. {
  182. Resd = CONTAINING_RECORD(Entry, PROTOCOL_RESD, FreeList);
  183. Packet = CONTAINING_RECORD(Resd, NDIS_PACKET, ProtocolReserved);
  184. NdisFreeBuffer(Packet->Private.Head);
  185. NdisFreePacket(Packet);
  186. }
  187. if (ArpSBufPoolHandle != NULL)
  188. {
  189. NdisFreeBufferPool(ArpSBufPoolHandle);
  190. ArpSBufPoolHandle = NULL;
  191. }
  192. if (ArpSPktPoolHandle != NULL)
  193. {
  194. NdisFreePacketPool(ArpSPktPoolHandle);
  195. ArpSPktPoolHandle = NULL;
  196. }
  197. if (MarsBufPoolHandle != NULL)
  198. {
  199. NdisFreeBufferPool(MarsBufPoolHandle);
  200. MarsBufPoolHandle = NULL;
  201. }
  202. if (MarsPktPoolHandle != NULL)
  203. {
  204. NdisFreePacketPool(MarsPktPoolHandle);
  205. MarsPktPoolHandle = NULL;
  206. }
  207. if (ArpSBufferSpace != NULL)
  208. {
  209. FREE_MEM(ArpSBufferSpace);
  210. ArpSBufferSpace = NULL;
  211. }
  212. }
  213. VOID
  214. ArpSBindAdapter(
  215. OUT PNDIS_STATUS Status,
  216. IN NDIS_HANDLE BindContext,
  217. IN PNDIS_STRING DeviceName,
  218. IN PVOID SystemSpecific1,
  219. IN PVOID SystemSpecific2
  220. )
  221. /*++
  222. Routine Description:
  223. Handle incoming bind requests here. Open the adapter, read the per-adapter registry and
  224. initialize the binding.
  225. Arguments:
  226. Status Placeholder for returning status
  227. BindContext Opaque blob to call NdisBindAdapterComplete if we pend this
  228. DeviceName The adapter name which we should bind to
  229. SystemSpecific1 To be used with NdisOpenProtocolConfiguration, if the per-adapter
  230. configuration information is stored with the adapter
  231. SystemSpecific2 Not currently used.
  232. Return Value:
  233. Status of the per-adapter initialization
  234. --*/
  235. {
  236. PINTF pIntF;
  237. NDIS_STATUS OpenErrorStatus;
  238. UINT SelectedMedium;
  239. NDIS_MEDIUM SupportedMedium = NdisMediumAtm;
  240. KIRQL EntryIrql;
  241. ARPS_GET_IRQL(&EntryIrql);
  242. //
  243. // Allocate an Interface block and initialize it
  244. //
  245. pIntF = ArpSCreateIntF(DeviceName, (PNDIS_STRING)SystemSpecific1, BindContext);
  246. if (pIntF != NULL)
  247. {
  248. //
  249. // Save the binding context
  250. //
  251. pIntF->NdisBindContext = BindContext;
  252. *Status = ArpSReadAdapterConfiguration(pIntF);
  253. if (*Status == NDIS_STATUS_SUCCESS)
  254. {
  255. //
  256. // Read the Arp cache in now. We prime the arp table to start off.
  257. //
  258. if (ArpSFlushTime != 0)
  259. {
  260. ArpSReadArpCache(pIntF);
  261. }
  262. //
  263. // Open the adapter and see if it is interesting to us (mediatype should be atm)
  264. //
  265. NdisOpenAdapter(Status,
  266. &OpenErrorStatus,
  267. &pIntF->NdisBindingHandle,
  268. &SelectedMedium,
  269. &pIntF->SupportedMedium,
  270. sizeof(NDIS_MEDIUM),
  271. ArpSProtocolHandle,
  272. pIntF,
  273. DeviceName,
  274. 0,
  275. NULL);
  276. ARPS_CHECK_IRQL(EntryIrql);
  277. if (*Status != NDIS_STATUS_PENDING)
  278. {
  279. ArpSOpenAdapterComplete(pIntF, *Status, OpenErrorStatus);
  280. }
  281. ARPS_CHECK_IRQL(EntryIrql);
  282. *Status = NDIS_STATUS_PENDING;
  283. }
  284. else
  285. {
  286. //
  287. // Could not read per-adapter registry. Use defaults.
  288. //
  289. LOG_ERROR(*Status);
  290. }
  291. }
  292. else
  293. {
  294. *Status = NDIS_STATUS_RESOURCES;
  295. LOG_ERROR(Status);
  296. }
  297. }
  298. VOID
  299. ArpSOpenAdapterComplete(
  300. IN NDIS_HANDLE ProtocolBindingContext,
  301. IN NDIS_STATUS Status,
  302. IN NDIS_STATUS OpenErrorStatus
  303. )
  304. /*++
  305. Routine Description:
  306. Upcall from NDIS to signal completion of a NdisOpenAdapter() call.
  307. Arguments:
  308. ProtocolBindingContext Pointer to the pIntF
  309. Status Status of NdisOpenAdapter
  310. OpenErrorStatus Adapter's code
  311. Return Value:
  312. --*/
  313. {
  314. PINTF pIntF = (PINTF)ProtocolBindingContext;
  315. KIRQL OldIrql;
  316. //
  317. // First complete the pending bind call.
  318. //
  319. NdisCompleteBindAdapter(pIntF->NdisBindContext, Status, OpenErrorStatus);
  320. pIntF->NdisBindContext = NULL; // We do not need this anymore
  321. if (Status != NDIS_STATUS_SUCCESS)
  322. {
  323. //
  324. // NdisOpenAdapter() failed - log an error and exit
  325. //
  326. LOG_ERROR(Status);
  327. ArpSCloseAdapterComplete(pIntF, Status);
  328. }
  329. else
  330. {
  331. //
  332. // Insert this into the global adapter list
  333. //
  334. ACQUIRE_SPIN_LOCK(&ArpSIfListLock, &OldIrql);
  335. {
  336. PINTF pTmpIntF;
  337. for (pTmpIntF = ArpSIfList;
  338. pTmpIntF != NULL;
  339. pTmpIntF = pTmpIntF->Next)
  340. {
  341. if (pTmpIntF == pIntF)
  342. {
  343. DbgPrint("ATMARPS: OpenAdComp: IntF %p already in list!\n",
  344. pTmpIntF);
  345. DbgBreakPoint();
  346. }
  347. }
  348. }
  349. ACQUIRE_SPIN_LOCK_DPC(&pIntF->Lock);
  350. pIntF->Flags |= INTF_ADAPTER_OPENED;
  351. pIntF->Next = ArpSIfList;
  352. ArpSIfList = pIntF;
  353. ArpSIfListSize++;
  354. RELEASE_SPIN_LOCK_DPC(&pIntF->Lock);
  355. RELEASE_SPIN_LOCK(&ArpSIfListLock, OldIrql);
  356. ArpSQueryAdapter(pIntF);
  357. }
  358. }
  359. VOID
  360. ArpSCoAfRegisterNotify(
  361. IN NDIS_HANDLE ProtocolBindingContext,
  362. IN PCO_ADDRESS_FAMILY AddressFamily
  363. )
  364. /*++
  365. Routine Description:
  366. Arguments:
  367. Return Value:
  368. None.
  369. --*/
  370. {
  371. PINTF pIntF = (PINTF)ProtocolBindingContext;
  372. NDIS_STATUS Status;
  373. NDIS_CLIENT_CHARACTERISTICS Chars;
  374. KIRQL EntryIrql;
  375. ARPS_GET_IRQL(&EntryIrql);
  376. if ((AddressFamily->AddressFamily == CO_ADDRESS_FAMILY_Q2931) &&
  377. (AddressFamily->MajorVersion == 3) &&
  378. (AddressFamily->MinorVersion == 1) &&
  379. (pIntF->NdisAfHandle == NULL) )
  380. {
  381. DBGPRINT(DBG_LEVEL_NOTICE,
  382. ("AfNotify: IntF %x, Name %Z\n", pIntF, &pIntF->InterfaceName));
  383. if (ArpSReferenceIntF(pIntF))
  384. {
  385. //
  386. // We successfully opened the adapter. Now open the address-family
  387. //
  388. pIntF->AddrFamily.AddressFamily = CO_ADDRESS_FAMILY_Q2931;
  389. pIntF->AddrFamily.MajorVersion = 3;
  390. pIntF->AddrFamily.MinorVersion = 1;
  391. ZERO_MEM(&Chars, sizeof(NDIS_CLIENT_CHARACTERISTICS));
  392. Chars.MajorVersion = 5;
  393. Chars.MinorVersion = 0;
  394. Chars.ClCreateVcHandler = ArpSCreateVc;
  395. Chars.ClDeleteVcHandler = ArpSDeleteVc;
  396. Chars.ClRequestHandler = ArpSCoRequest;
  397. Chars.ClRequestCompleteHandler = ArpSCoRequestComplete;
  398. Chars.ClOpenAfCompleteHandler = ArpSOpenAfComplete;
  399. Chars.ClCloseAfCompleteHandler = ArpSCloseAfComplete;
  400. Chars.ClRegisterSapCompleteHandler = ArpSRegisterSapComplete;
  401. Chars.ClDeregisterSapCompleteHandler = ArpSDeregisterSapComplete;
  402. Chars.ClMakeCallCompleteHandler = ArpSMakeCallComplete;
  403. Chars.ClModifyCallQoSCompleteHandler = NULL;
  404. Chars.ClCloseCallCompleteHandler = ArpSCloseCallComplete;
  405. Chars.ClAddPartyCompleteHandler = ArpSAddPartyComplete;
  406. Chars.ClDropPartyCompleteHandler = ArpSDropPartyComplete;
  407. Chars.ClIncomingCallHandler = ArpSIncomingCall;
  408. Chars.ClIncomingCallQoSChangeHandler = ArpSIncomingCallQoSChange;
  409. Chars.ClIncomingCloseCallHandler = ArpSIncomingCloseCall;
  410. Chars.ClIncomingDropPartyHandler = ArpSIncomingDropParty;
  411. Chars.ClCallConnectedHandler = ArpSCallConnected;
  412. Status = NdisClOpenAddressFamily(pIntF->NdisBindingHandle,
  413. &pIntF->AddrFamily,
  414. pIntF, // Use this as the Af context too
  415. &Chars,
  416. sizeof(NDIS_CLIENT_CHARACTERISTICS),
  417. &pIntF->NdisAfHandle);
  418. ARPS_CHECK_IRQL(EntryIrql);
  419. if (Status != NDIS_STATUS_PENDING)
  420. {
  421. ARPS_CHECK_IRQL(EntryIrql);
  422. ArpSOpenAfComplete(Status, pIntF, pIntF->NdisAfHandle);
  423. ARPS_CHECK_IRQL(EntryIrql);
  424. }
  425. }
  426. else
  427. {
  428. ARPS_CHECK_IRQL(EntryIrql);
  429. ArpSTryCloseAdapter(pIntF);
  430. ARPS_CHECK_IRQL(EntryIrql);
  431. }
  432. }
  433. ARPS_CHECK_IRQL(EntryIrql);
  434. }
  435. VOID
  436. ArpSOpenAfComplete(
  437. IN NDIS_STATUS Status,
  438. IN NDIS_HANDLE ProtocolAfContext,
  439. IN NDIS_HANDLE NdisAfHandle
  440. )
  441. /*++
  442. Routine Description:
  443. Completion processing for the OpenAf call.
  444. Arguments:
  445. Status Status of OpenAf
  446. ProtocolAfContext Pointer to the pIntF
  447. NdisAfHandle Ndis Handle to refer to this Af
  448. Return Value:
  449. --*/
  450. {
  451. PINTF pIntF = (PINTF)ProtocolAfContext;
  452. PCO_SAP Sap;
  453. NDIS_HANDLE OldAfHandle;
  454. KIRQL OldIrql;
  455. if (Status == NDIS_STATUS_SUCCESS)
  456. {
  457. if (pIntF->NdisAfHandle != NULL)
  458. {
  459. DbgPrint("ATMARPS: OpenAfComp: IntF %p, NdisAfHandle %p is NOT NULL!\n",
  460. pIntF, pIntF->NdisAfHandle);
  461. DbgBreakPoint();
  462. DbgBreakPoint();
  463. DbgBreakPoint();
  464. }
  465. OldAfHandle = pIntF->NdisAfHandle;
  466. pIntF->NdisAfHandle = NdisAfHandle;
  467. if (ArpSReferenceIntF(pIntF))
  468. {
  469. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  470. pIntF->Flags |= INTF_AF_OPENED;
  471. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  472. //
  473. // Now register a SAP on this interface
  474. //
  475. ArpSRegisterSap(pIntF);
  476. }
  477. else
  478. {
  479. NDIS_STATUS Sts;
  480. Sts = NdisClCloseAddressFamily(pIntF->NdisAfHandle);
  481. if (Status != NDIS_STATUS_PENDING)
  482. {
  483. ArpSCloseAfComplete(Status, pIntF);
  484. }
  485. }
  486. }
  487. else
  488. {
  489. //
  490. // Failed to open the Address family. Cleanup and exit
  491. //
  492. LOG_ERROR(Status);
  493. ArpSTryCloseAdapter(pIntF);
  494. }
  495. }
  496. VOID
  497. ArpSRegisterSap(
  498. IN PINTF pIntF
  499. )
  500. /*++
  501. Routine Description:
  502. Register the Sap for receiving incoming calls. De-register any existing saps (this can
  503. happen if an address change happens).
  504. Arguments:
  505. Return Value:
  506. --*/
  507. {
  508. NDIS_STATUS Status;
  509. PATM_SAP pAtmSap;
  510. PATM_ADDRESS pAtmAddress;
  511. //
  512. // Kill previous sap if any and register a new one. Save this while we
  513. // register the new one. We kill this regardless of whether the new one
  514. // successfully registers or not - since the address has potentially changed
  515. //
  516. if (pIntF->NdisSapHandle != NULL)
  517. {
  518. Status = NdisClDeregisterSap(pIntF->NdisSapHandle);
  519. pIntF->NdisSapHandle = NULL;
  520. if (Status != NDIS_STATUS_PENDING)
  521. {
  522. ArpSDeregisterSapComplete(Status, pIntF);
  523. }
  524. }
  525. do
  526. {
  527. //
  528. // Allocate memory for registering the SAP, if doing it for the first time.
  529. //
  530. if (pIntF->Sap == NULL)
  531. {
  532. pIntF->Sap = (PCO_SAP)ALLOC_NP_MEM(sizeof(CO_SAP) + sizeof(ATM_SAP) + sizeof(ATM_ADDRESS), POOL_TAG_SAP);
  533. }
  534. if (pIntF->Sap == NULL)
  535. {
  536. LOG_ERROR(Status);
  537. Status = NDIS_STATUS_RESOURCES;
  538. break;
  539. }
  540. else
  541. {
  542. ZERO_MEM(pIntF->Sap, sizeof(CO_SAP) + sizeof(ATM_SAP) + sizeof(ATM_ADDRESS));
  543. pAtmSap = (PATM_SAP)pIntF->Sap->Sap;
  544. pAtmAddress = (PATM_ADDRESS)(pAtmSap->Addresses);
  545. pIntF->Sap->SapType = SAP_TYPE_NSAP;
  546. pIntF->Sap->SapLength = sizeof(ATM_SAP) + sizeof(ATM_ADDRESS);
  547. //
  548. // Fill in the ATM SAP with default values
  549. //
  550. COPY_MEM(&pAtmSap->Blli, &ArpSDefaultBlli, sizeof(ATM_BLLI_IE));
  551. COPY_MEM(&pAtmSap->Bhli, &ArpSDefaultBhli, sizeof(ATM_BHLI_IE));
  552. //
  553. // ATM Address to "listen" on: Wild card everything except the SEL.
  554. //
  555. pAtmSap->NumberOfAddresses = 1;
  556. pAtmAddress->AddressType = SAP_FIELD_ANY_AESA_REST;
  557. pAtmAddress->NumberOfDigits = 20;
  558. pAtmAddress->Address[20-1] = pIntF->SelByte;
  559. Status = NdisClRegisterSap(pIntF->NdisAfHandle,
  560. pIntF,
  561. pIntF->Sap,
  562. &pIntF->NdisSapHandle);
  563. if (Status != NDIS_STATUS_PENDING)
  564. {
  565. ArpSRegisterSapComplete(Status,
  566. pIntF,
  567. pIntF->Sap,
  568. pIntF->NdisSapHandle);
  569. }
  570. }
  571. } while (FALSE);
  572. if ((Status != NDIS_STATUS_SUCCESS) && (Status != NDIS_STATUS_PENDING))
  573. {
  574. Status = NdisClCloseAddressFamily(pIntF->NdisAfHandle);
  575. if (Status != NDIS_STATUS_PENDING)
  576. {
  577. ArpSCloseAfComplete(Status, pIntF);
  578. }
  579. }
  580. }
  581. VOID
  582. ArpSRegisterSapComplete(
  583. IN NDIS_STATUS Status,
  584. IN NDIS_HANDLE ProtocolSapContext,
  585. IN PCO_SAP Sap,
  586. IN NDIS_HANDLE NdisSapHandle
  587. )
  588. /*++
  589. Routine Description:
  590. Arguments:
  591. Return Value:
  592. --*/
  593. {
  594. PINTF pIntF = (PINTF)ProtocolSapContext;
  595. ASSERT (Sap == pIntF->Sap);
  596. if (Status != NDIS_STATUS_SUCCESS)
  597. {
  598. DBGPRINT(DBG_LEVEL_WARN,
  599. ("RegisterSapComplete failed (%x): Intf %x, Name %Z\n",
  600. Status, pIntF, &pIntF->InterfaceName));
  601. LOG_ERROR(Status);
  602. FREE_MEM(pIntF->Sap);
  603. pIntF->Sap = NULL;
  604. ArpSDereferenceIntF(pIntF);
  605. }
  606. else
  607. {
  608. KIRQL OldIrql;
  609. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  610. pIntF->Flags |= INTF_SAP_REGISTERED;
  611. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  612. pIntF->NdisSapHandle = NdisSapHandle;
  613. }
  614. }
  615. VOID
  616. ArpSDeregisterSapComplete(
  617. IN NDIS_STATUS Status,
  618. IN NDIS_HANDLE ProtocolSapContext
  619. )
  620. /*++
  621. Routine Description:
  622. Arguments:
  623. Return Value:
  624. --*/
  625. {
  626. PINTF pIntF = (PINTF)ProtocolSapContext;
  627. DBGPRINT(DBG_LEVEL_INFO,
  628. ("DeregisterSapComplete: Intf %Z\n", &pIntF->InterfaceName));
  629. pIntF->NdisSapHandle = NULL;
  630. if (pIntF->Sap)
  631. {
  632. FREE_MEM(pIntF->Sap);
  633. pIntF->Sap = NULL;
  634. }
  635. //
  636. // Nothing to do here except deref the IntF block here.
  637. //
  638. ArpSDereferenceIntF(pIntF);
  639. }
  640. VOID
  641. ArpSCloseAfComplete(
  642. IN NDIS_STATUS Status,
  643. IN NDIS_HANDLE ProtocolAfContext
  644. )
  645. /*++
  646. Routine Description:
  647. Arguments:
  648. Return Value:
  649. --*/
  650. {
  651. PINTF pIntF = (PINTF)ProtocolAfContext;
  652. KIRQL OldIrql;
  653. DBGPRINT(DBG_LEVEL_NOTICE,
  654. ("CloseAfComplete: pIntF %x, Flags %x, Ref %x, Intf %Z\n",
  655. pIntF, pIntF->Flags, pIntF->RefCount, &pIntF->InterfaceName));
  656. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  657. pIntF->NdisAfHandle = NULL;
  658. pIntF->Flags &= ~INTF_STOPPING;
  659. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  660. //
  661. // Nothing much to do except dereference the pIntF
  662. //
  663. ArpSDereferenceIntF(pIntF);
  664. }
  665. VOID
  666. ArpSCloseAdapterComplete(
  667. IN NDIS_HANDLE ProtocolBindingContext,
  668. IN NDIS_STATUS Status
  669. )
  670. /*++
  671. Routine Description:
  672. Arguments:
  673. Return Value:
  674. --*/
  675. {
  676. PINTF pIntF = (PINTF)ProtocolBindingContext;
  677. KIRQL OldIrql;
  678. DBGPRINT(DBG_LEVEL_INFO,
  679. ("CloseAdapterComplete: Intf %Z\n", &pIntF->InterfaceName));
  680. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  681. //
  682. // Set the interface to closing
  683. //
  684. ASSERT ((pIntF->Flags & INTF_CLOSING) == 0);
  685. pIntF->Flags |= INTF_CLOSING;
  686. pIntF->NdisBindingHandle = NULL;
  687. //
  688. // Stop the timer thread
  689. //
  690. KeSetEvent(&pIntF->TimerThreadEvent, IO_NETWORK_INCREMENT, FALSE);
  691. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  692. //
  693. // Finally dereference it
  694. //
  695. ArpSDereferenceIntF(pIntF);
  696. }
  697. NDIS_STATUS
  698. ArpSCreateVc(
  699. IN NDIS_HANDLE ProtocolAfContext,
  700. IN NDIS_HANDLE NdisVcHandle,
  701. OUT PNDIS_HANDLE ProtocolVcContext
  702. )
  703. /*++
  704. Routine Description:
  705. Arguments:
  706. Return Value:
  707. --*/
  708. {
  709. PINTF pIntF = (PINTF)ProtocolAfContext;
  710. PARP_VC Vc;
  711. KIRQL OldIrql;
  712. NDIS_STATUS Status;
  713. DBGPRINT(DBG_LEVEL_INFO,
  714. ("CreateVc: NdisVcHandle %lx, Intf %Z\n", NdisVcHandle, &pIntF->InterfaceName));
  715. //
  716. // Allocate a Vc, initialize it and link it into the IntF
  717. //
  718. *ProtocolVcContext = NULL; // Assume failure
  719. Status = NDIS_STATUS_RESOURCES;
  720. Vc = (PARP_VC)ALLOC_NP_MEM(sizeof(ARP_VC), POOL_TAG_VC);
  721. if (Vc != NULL)
  722. {
  723. ZERO_MEM(Vc, sizeof(ARP_VC));
  724. Vc->NdisVcHandle = NdisVcHandle;
  725. Vc->IntF = pIntF;
  726. Vc->RefCount = 1; // Dereferenced when DeleteVc is called.
  727. Vc->VcType = VC_TYPE_INCOMING;
  728. if (ArpSReferenceIntF(pIntF))
  729. {
  730. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  731. if (++(pIntF->ArpStats.CurrentClientVCs) > pIntF->ArpStats.MaxClientVCs)
  732. {
  733. pIntF->ArpStats.MaxClientVCs = pIntF->ArpStats.CurrentClientVCs;
  734. }
  735. InsertHeadList(&pIntF->InactiveVcHead, &Vc->List);
  736. Vc->VcId = pIntF->LastVcId;
  737. pIntF->LastVcId ++;
  738. if (pIntF->LastVcId == -1)
  739. {
  740. pIntF->LastVcId = 1;
  741. }
  742. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  743. *ProtocolVcContext = Vc;
  744. DBGPRINT(DBG_LEVEL_INFO,
  745. ("CreateVc: Created Vc %lx, Id %lx\n", Vc, Vc->VcId));
  746. Status = NDIS_STATUS_SUCCESS;
  747. }
  748. else
  749. {
  750. FREE_MEM(Vc);
  751. Status = NDIS_STATUS_CLOSING;
  752. }
  753. }
  754. return Status;
  755. }
  756. NDIS_STATUS
  757. ArpSDeleteVc(
  758. IN NDIS_HANDLE ProtocolVcContext
  759. )
  760. /*++
  761. Routine Description:
  762. Arguments:
  763. Return Value:
  764. --*/
  765. {
  766. PARP_VC Vc = (PARP_VC)ProtocolVcContext;
  767. DBGPRINT(DBG_LEVEL_INFO,
  768. ("DeleteVc: For Vc %lx, Id %lx\n", Vc, Vc->VcId));
  769. Vc->IntF->ArpStats.CurrentClientVCs--;
  770. Vc->NdisVcHandle = NULL;
  771. ArpSDereferenceVc(Vc, FALSE, FALSE);
  772. return NDIS_STATUS_SUCCESS;
  773. }
  774. VOID
  775. ArpSCoSendComplete(
  776. IN NDIS_STATUS Status,
  777. IN NDIS_HANDLE ProtocolVcContext,
  778. IN PNDIS_PACKET Packet
  779. )
  780. /*++
  781. Routine Description:
  782. Completion routine for the previously pended send. Just return the packet to the pool of free packets.
  783. Arguments:
  784. Status Status of Completion
  785. ProtocolVcContext Pointer to the Vc
  786. Packet The packet in question
  787. Return Value:
  788. --*/
  789. {
  790. PARP_VC Vc = (PARP_VC)ProtocolVcContext;
  791. PPROTOCOL_RESD Resd;
  792. Resd = RESD_FROM_PKT(Packet);
  793. DBGPRINT(DBG_LEVEL_INFO,
  794. ("ArpSCoSendComplete: Packet %lx, Vc %lx, ResdVc %lx, Id %lx\n",
  795. Packet, Vc, Resd->Vc, Vc->VcId));
  796. if (Status != NDIS_STATUS_SUCCESS)
  797. {
  798. DBGPRINT(DBG_LEVEL_ERROR,
  799. ("ArpSCoSendComplete: Failed for Vc = %lx, status = %lx\n", Vc, Status));
  800. }
  801. if ((Resd->Flags & RESD_FLAG_MARS_PKT) == 0)
  802. {
  803. if (Packet->Private.Head == NULL)
  804. {
  805. DbgPrint("ATMARPS: sendcomplete: pkt %p head is NULL!\n",
  806. Packet->Private.Head);
  807. DbgBreakPoint();
  808. DbgBreakPoint();
  809. }
  810. ExInterlockedPushEntrySList(&ArpSPktList,
  811. &Resd->FreeList,
  812. &ArpSPktListLock);
  813. ArpSDereferenceVc(Resd->Vc, FALSE, TRUE);
  814. }
  815. else
  816. {
  817. MarsFreePacket(Packet);
  818. }
  819. }
  820. NDIS_STATUS
  821. ArpSIncomingCall(
  822. IN NDIS_HANDLE ProtocolSapContext,
  823. IN NDIS_HANDLE ProtocolVcContext,
  824. IN OUT PCO_CALL_PARAMETERS CallParameters
  825. )
  826. /*++
  827. Routine Description:
  828. Handler for incoming call. We accept the call unless we are shutting down and then
  829. do the actual processing when the call processing completes.
  830. Arguments:
  831. ProtocolSapContext Pointer to the IntF
  832. ProtocolVcContext Pointer to the Vc
  833. CallParameters Call Parameters
  834. Return Value:
  835. --*/
  836. {
  837. PINTF pIntF = (PINTF)ProtocolSapContext;
  838. PARP_VC Vc = (PARP_VC)ProtocolVcContext;
  839. Q2931_CALLMGR_PARAMETERS UNALIGNED * CallMgrSpecific;
  840. KIRQL OldIrql;
  841. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  842. ASSERT (Vc->IntF == pIntF);
  843. DBGPRINT(DBG_LEVEL_INFO,
  844. ("ArpSIncomingCall: On Vc %lx, Id %lx\n", Vc, Vc->VcId));
  845. //
  846. // Mark the Vc to indicate the call processing is underway
  847. //
  848. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  849. pIntF->ArpStats.TotalIncomingCalls++;
  850. ASSERT ((Vc->Flags & (ARPVC_CALLPROCESSING | ARPVC_ACTIVE | ARPVC_CALLPROCESSING)) == 0);
  851. Vc->Flags |= ARPVC_CALLPROCESSING;
  852. //
  853. // Get the remote atm address from the call-parameters
  854. //
  855. CallMgrSpecific = (PQ2931_CALLMGR_PARAMETERS)&CallParameters->CallMgrParameters->CallMgrSpecific.Parameters[0];
  856. Vc->HwAddr.Address = CallMgrSpecific->CallingParty;
  857. //
  858. // Get the max size of packets we can send on this VC, from the
  859. // AAL5 parameters. Limit it to the size our miniport can support.
  860. //
  861. Vc->MaxSendSize = pIntF->MaxPacketSize; // default
  862. if (CallMgrSpecific->InfoElementCount > 0)
  863. {
  864. Q2931_IE UNALIGNED * pIe;
  865. AAL5_PARAMETERS UNALIGNED * pAal5;
  866. ULONG IeCount;
  867. pIe = (PQ2931_IE)CallMgrSpecific->InfoElements;
  868. for (IeCount = CallMgrSpecific->InfoElementCount;
  869. IeCount != 0;
  870. IeCount--)
  871. {
  872. if (pIe->IEType == IE_AALParameters)
  873. {
  874. pAal5 = &(((PAAL_PARAMETERS_IE)pIe->IE)->AALSpecificParameters.AAL5Parameters);
  875. //
  876. // Make sure we don't send more than what the caller can handle.
  877. //
  878. if (pAal5->ForwardMaxCPCSSDUSize < Vc->MaxSendSize)
  879. {
  880. Vc->MaxSendSize = pAal5->ForwardMaxCPCSSDUSize;
  881. }
  882. //
  883. // Make sure this greater than the min allowed.
  884. //
  885. if (pAal5->ForwardMaxCPCSSDUSize < ARPS_MIN_MAX_PKT_SIZE)
  886. {
  887. DBGPRINT(DBG_LEVEL_WARN,
  888. ("ArpSIncomingCall: Vc %lx max pkt size too small(%lu)\n",
  889. Vc, Vc->MaxSendSize));
  890. Status = NDIS_STATUS_RESOURCES;
  891. }
  892. //
  893. // Make sure the caller doesn't send more than what our
  894. // miniport can handle.
  895. //
  896. if (pAal5->BackwardMaxCPCSSDUSize > pIntF->MaxPacketSize)
  897. {
  898. pAal5->BackwardMaxCPCSSDUSize = pIntF->MaxPacketSize;
  899. }
  900. break;
  901. }
  902. pIe = (PQ2931_IE)((PUCHAR)pIe + pIe->IELength);
  903. }
  904. }
  905. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  906. return Status;
  907. }
  908. VOID
  909. ArpSCallConnected(
  910. IN NDIS_HANDLE ProtocolVcContext
  911. )
  912. /*++
  913. Routine Description:
  914. Last hand-shake in the incoming call path. Move the Vc to the list of active calls.
  915. Arguments:
  916. ProtocolVcContext Pointer to VC
  917. Return Value:
  918. None.
  919. --*/
  920. {
  921. PARP_VC Vc = (PARP_VC)ProtocolVcContext;
  922. PINTF pIntF;
  923. KIRQL OldIrql;
  924. DBGPRINT(DBG_LEVEL_INFO,
  925. ("ArpSCallConnected: On Vc %lx, Id %lx\n", Vc, Vc->VcId));
  926. pIntF = Vc->IntF;
  927. pIntF->ArpStats.TotalActiveVCs++;
  928. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  929. ASSERT((Vc->Flags & ARPVC_ACTIVE) == 0);
  930. ASSERT(Vc->Flags & ARPVC_CALLPROCESSING);
  931. Vc->Flags |= ARPVC_ACTIVE;
  932. Vc->Flags &= ~ARPVC_CALLPROCESSING;
  933. RemoveEntryList(&Vc->List);
  934. InsertHeadList(&pIntF->ActiveVcHead, &Vc->List);
  935. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  936. }
  937. VOID
  938. ArpSMakeCallComplete(
  939. IN NDIS_STATUS Status,
  940. IN NDIS_HANDLE ProtocolVcContext,
  941. IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
  942. IN PCO_CALL_PARAMETERS CallParameters
  943. )
  944. /*++
  945. Routine Description:
  946. Handle completion of an earlier call to NdisClMakeCall. The only
  947. outgoing call is for ClusterControlVc. If the status indicates
  948. success, AddParty's are initiated for all pending Cluster members.
  949. Otherwise, this cluster member is deleted, and if there are any
  950. other cluster members in the list, we initiate a MakeCall with
  951. one of them.
  952. Arguments:
  953. Status Result of NdisClMakeCall
  954. ProtocolVcContext Pointer to ClusterControlVc
  955. NdisPartyHandle If successful, the handle for this party
  956. CallParameters Pointer to Call parameters
  957. Return Value:
  958. None.
  959. --*/
  960. {
  961. KIRQL OldIrql;
  962. PINTF pIntF;
  963. PMARS_VC pVc;
  964. PCLUSTER_MEMBER pMember;
  965. PCLUSTER_MEMBER pNextMember;
  966. NDIS_HANDLE NdisVcHandle;
  967. pVc = (PMARS_VC)ProtocolVcContext;
  968. if (pVc->VcType == VC_TYPE_CHECK_REGADDR)
  969. {
  970. ArpSMakeRegAddrCallComplete(
  971. Status,
  972. (PREG_ADDR_CTXT) ProtocolVcContext
  973. );
  974. return; // ****** EARLY RETURN ****************
  975. }
  976. pIntF = pVc->pIntF;
  977. MARSDBGPRINT(DBG_LEVEL_LOUD,
  978. ("MakeCallComplete: Status %x, pVc %x, VC ConnState %x\n",
  979. Status, pVc, MARS_GET_VC_CONN_STATE(pVc)));
  980. FREE_MEM(CallParameters);
  981. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  982. //
  983. // Get the Cluster member we were trying to connect to.
  984. //
  985. for (pMember = pIntF->ClusterMembers;
  986. pMember != NULL_PCLUSTER_MEMBER;
  987. pMember = (PCLUSTER_MEMBER)pMember->Next)
  988. {
  989. if (MARS_GET_CM_CONN_STATE(pMember) == CM_CONN_SETUP_IN_PROGRESS)
  990. {
  991. break;
  992. }
  993. }
  994. ASSERT(pMember != NULL_PCLUSTER_MEMBER);
  995. pIntF->CCAddingParties--;
  996. if (Status == NDIS_STATUS_SUCCESS)
  997. {
  998. ASSERT(NdisPartyHandle != NULL);
  999. MARS_SET_CM_CONN_STATE(pMember, CM_CONN_ACTIVE);
  1000. pMember->NdisPartyHandle = NdisPartyHandle;
  1001. pIntF->CCActiveParties++;
  1002. if (pMember->Flags & CM_INVALID)
  1003. {
  1004. //
  1005. // Deleting was deferred because the connection was being
  1006. // setup. Now that it's up, strictly speaking we should
  1007. // try to delete it again, BUT we don't because we
  1008. // may also need to add other members now, and we can't really
  1009. // drop the call itself while we're adding other parties!
  1010. //
  1011. MARSDBGPRINT(DBG_LEVEL_WARN,
  1012. ("pMember 0x%p is INVALID, but NOT dropping CCVC call.\n",
  1013. pMember));
  1014. // do nothing...
  1015. }
  1016. if (MARS_GET_VC_CONN_STATE(pVc) == MVC_CONN_SETUP_IN_PROGRESS)
  1017. {
  1018. MARS_SET_VC_CONN_STATE(pVc, MVC_CONN_ACTIVE);
  1019. //
  1020. // Add all pending cluster members as parties
  1021. //
  1022. for (pMember = pIntF->ClusterMembers;
  1023. pMember != NULL_PCLUSTER_MEMBER;
  1024. pMember = pNextMember)
  1025. {
  1026. pNextMember = (PCLUSTER_MEMBER)pMember->Next;
  1027. if (MARS_GET_CM_CONN_STATE(pMember) == CM_CONN_IDLE)
  1028. {
  1029. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1030. MarsAddMemberToClusterControlVc(pIntF, pMember);
  1031. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1032. if (!MarsIsValidClusterMember(pIntF, pNextMember))
  1033. {
  1034. //
  1035. // Oops, the next member has gone away in the
  1036. // mean time. In this unlikely case, we simply
  1037. // quit processing the list early.
  1038. //
  1039. break;
  1040. }
  1041. }
  1042. }
  1043. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1044. //
  1045. // Send off any queued packets, if we can.
  1046. //
  1047. MarsSendOnClusterControlVc(pIntF, NULL);
  1048. }
  1049. else
  1050. {
  1051. BOOLEAN fLocked;
  1052. //
  1053. // We are closing down.
  1054. //
  1055. MARS_SET_VC_CONN_STATE(pVc, MVC_CONN_ACTIVE);
  1056. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1057. fLocked = MarsDelMemberFromClusterControlVc(pIntF, pMember, FALSE, 0);
  1058. ASSERT(!fLocked);
  1059. }
  1060. }
  1061. else
  1062. {
  1063. MARSDBGPRINT(DBG_LEVEL_WARN,
  1064. ("MakeCall error %x, pMember %x to addr:", Status, pMember));
  1065. MARSDUMPATMADDR(DBG_LEVEL_WARN, &pMember->HwAddr.Address, "");
  1066. #if DBG
  1067. if (Status == NDIS_STATUS_CALL_ACTIVE)
  1068. {
  1069. MARSDBGPRINT(DBG_LEVEL_WARN,
  1070. ("ATMARPS: MakeCallComp: Intf %p, VC %p, pMember %p, call active!\n",
  1071. pIntF, pVc, pMember));
  1072. DbgBreakPoint();
  1073. DbgBreakPoint();
  1074. }
  1075. #endif // DBG
  1076. //
  1077. // Connection failed. Delete this member from our Cluster member list.
  1078. //
  1079. pIntF->MarsStats.FailedCCVCAddParties++;
  1080. MarsDeleteClusterMember(pIntF, pMember);
  1081. MARS_SET_VC_CONN_STATE(pVc, MVC_CONN_IDLE);
  1082. //
  1083. // See if we have other Cluster members. If so, pick up one
  1084. // of them and re-initiate the ClusterControlVc.
  1085. //
  1086. for (pMember = pIntF->ClusterMembers;
  1087. pMember != NULL_PCLUSTER_MEMBER;
  1088. pMember = (PCLUSTER_MEMBER)pMember->Next)
  1089. {
  1090. if (MARS_GET_CM_CONN_STATE(pMember) == CM_CONN_IDLE)
  1091. {
  1092. break;
  1093. }
  1094. }
  1095. if (pMember == NULL_PCLUSTER_MEMBER)
  1096. {
  1097. //
  1098. // No other cluster members, so we'll tear down the CC VC.
  1099. //
  1100. NdisVcHandle = pIntF->ClusterControlVc->NdisVcHandle;
  1101. DBGPRINT(DBG_LEVEL_ERROR,
  1102. ("ATMARPS: pIntF %x, deleting CC VC, VcHandle %x\n", pIntF, NdisVcHandle));
  1103. FREE_MEM(pIntF->ClusterControlVc);
  1104. pIntF->ClusterControlVc = NULL;
  1105. }
  1106. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1107. if (pMember != NULL_PCLUSTER_MEMBER)
  1108. {
  1109. MarsAddMemberToClusterControlVc(pIntF, pMember);
  1110. }
  1111. else
  1112. {
  1113. Status = NdisCoDeleteVc(NdisVcHandle);
  1114. ASSERT(Status == NDIS_STATUS_SUCCESS);
  1115. MarsFreePacketsQueuedForClusterControlVc(pIntF);
  1116. }
  1117. }
  1118. }
  1119. VOID
  1120. ArpSIncomingCloseCall(
  1121. IN NDIS_STATUS CloseStatus,
  1122. IN NDIS_HANDLE ProtocolVcContext,
  1123. IN PVOID CloseData OPTIONAL,
  1124. IN UINT Size OPTIONAL
  1125. )
  1126. /*++
  1127. Routine Description:
  1128. Indication of an incoming close call from the network. If this
  1129. is not on ClusterControlVc, then we mark the VC as inactive, and
  1130. move it to the Inactive VC list. If this is on ClusterControlVc,
  1131. there must be only one party on the PMP connection. We update
  1132. that member's state.
  1133. In any case, we call NdisClCloseCall to complete the handshake.
  1134. Arguments:
  1135. CloseStatus Status of Close
  1136. ProtocolVcContext Pointer to VC (ARP_VC or MARS_VC)
  1137. CloseData Optional Close data (IGNORED)
  1138. Size Size of Optional Close Data (OPTIONAL)
  1139. Return Value:
  1140. None
  1141. --*/
  1142. {
  1143. PARP_VC Vc = (PARP_VC)ProtocolVcContext;
  1144. PMARS_VC pMarsVc;
  1145. PINTF pIntF;
  1146. NDIS_STATUS Status;
  1147. if (Vc->VcType == VC_TYPE_INCOMING)
  1148. {
  1149. DBGPRINT(DBG_LEVEL_INFO,
  1150. ("ArpSIncomingCloseCall: On Vc %lx, Id %lx\n",
  1151. ProtocolVcContext, Vc->VcId));
  1152. ArpSInitiateCloseCall(Vc);
  1153. }
  1154. else if (Vc->VcType == VC_TYPE_CHECK_REGADDR)
  1155. {
  1156. ArpSIncomingRegAddrCloseCall(
  1157. CloseStatus,
  1158. (PREG_ADDR_CTXT) ProtocolVcContext
  1159. );
  1160. }
  1161. else
  1162. {
  1163. ASSERT(Vc->VcType == VC_TYPE_MARS_CC);
  1164. pMarsVc = (PMARS_VC)ProtocolVcContext;
  1165. pIntF = pMarsVc->pIntF;
  1166. #if DBG
  1167. if (pIntF->CCAddingParties != 0)
  1168. {
  1169. PCLUSTER_MEMBER pMember;
  1170. MARSDBGPRINT(DBG_LEVEL_WARN,
  1171. ("ATMARPS: pIntF %p, InClose on CCVC %p/%x/%p with %d adding parties\n",
  1172. pIntF, pMarsVc, pMarsVc->Flags, pMarsVc->NdisVcHandle,
  1173. pIntF->CCAddingParties));
  1174. for (pMember = pIntF->ClusterMembers; pMember != NULL; pMember = pMember->Next)
  1175. {
  1176. MARSDBGPRINT(DBG_LEVEL_WARN,
  1177. ("ATMARPS: pIntF %p, InClose, pMember %p/%x\n",
  1178. pIntF, pMember, pMember->Flags));
  1179. }
  1180. }
  1181. #endif // DBG
  1182. MARS_SET_VC_CONN_STATE(pMarsVc, MVC_CONN_CLOSE_RECEIVED);
  1183. {
  1184. PPROTOCOL_RESD Resd;
  1185. Resd = ALLOC_NP_MEM(sizeof(PROTOCOL_RESD), POOL_TAG_MARS);
  1186. if (Resd != NULL)
  1187. {
  1188. Resd->Flags = RESD_FLAG_KILL_CCVC;
  1189. Resd->Vc = (PARP_VC)pIntF;
  1190. KeInsertQueue(&MarsReqQueue, &Resd->ReqList);
  1191. }
  1192. else
  1193. {
  1194. MarsAbortAllMembers(pIntF);
  1195. }
  1196. }
  1197. }
  1198. }
  1199. VOID
  1200. ArpSCloseCallComplete(
  1201. IN NDIS_STATUS Status,
  1202. IN NDIS_HANDLE ProtocolVcContext,
  1203. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL
  1204. )
  1205. /*++
  1206. Routine Description:
  1207. This is called to complete our call to NdisClCloseCall. If the VC
  1208. is other than ClusterControlVc, we simply update its state.
  1209. If this is on ClusterControlVc, we delete the last member.
  1210. Arguments:
  1211. CloseStatus Status of Close
  1212. Status Status of NdisClCloseCall
  1213. ProtocolVcContext Pointer to our VC structure
  1214. ProtocolPartyContext If the VC is ClusterControlVc, this is a pointer
  1215. to the Cluster Member that was disconnected.
  1216. Return Value:
  1217. None
  1218. --*/
  1219. {
  1220. PARP_VC Vc = (PARP_VC)ProtocolVcContext;
  1221. PMARS_VC pMarsVc;
  1222. PCLUSTER_MEMBER pMember;
  1223. PINTF pIntF;
  1224. KIRQL OldIrql;
  1225. BOOLEAN bStopping;
  1226. NDIS_HANDLE NdisVcHandle;
  1227. ASSERT(Status == NDIS_STATUS_SUCCESS);
  1228. if (Status != NDIS_STATUS_SUCCESS)
  1229. {
  1230. DbgPrint("ATMARPS: CloseCall failed %x on VC %p\n", Status, Vc);
  1231. DbgBreakPoint();
  1232. DbgBreakPoint();
  1233. }
  1234. if (Vc->VcType == VC_TYPE_INCOMING)
  1235. {
  1236. pIntF = Vc->IntF;
  1237. DBGPRINT(DBG_LEVEL_INFO,
  1238. ("ArpSCloseCallComplete: On Vc %lx\n", Vc));
  1239. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1240. ASSERT ((Vc->Flags & ARPVC_CLOSING) != 0);
  1241. Vc->Flags &= ~ARPVC_CLOSING;
  1242. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1243. }
  1244. else if (Vc->VcType == VC_TYPE_CHECK_REGADDR)
  1245. {
  1246. ArpSCloseRegAddrCallComplete(
  1247. Status,
  1248. (PREG_ADDR_CTXT) ProtocolVcContext
  1249. );
  1250. }
  1251. else
  1252. {
  1253. //
  1254. // Must be ClusterControlVc
  1255. //
  1256. pMarsVc = (PMARS_VC)ProtocolVcContext;
  1257. pIntF = pMarsVc->pIntF;
  1258. ASSERT(pMarsVc == pIntF->ClusterControlVc);
  1259. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1260. MARS_SET_VC_CONN_STATE(pMarsVc, MVC_CONN_IDLE);
  1261. pMember = (PCLUSTER_MEMBER)ProtocolPartyContext;
  1262. MARS_SET_CM_CONN_STATE(pMember, CM_CONN_IDLE);
  1263. ASSERT(pIntF->CCAddingParties == 0);
  1264. pIntF->CCActiveParties = pIntF->CCDroppingParties = pIntF->CCAddingParties = 0;
  1265. bStopping = ((pIntF->Flags & INTF_STOPPING) != 0);
  1266. MarsDeleteClusterMember(pIntF, pMember);
  1267. ARPS_ASSERT(pIntF->ClusterControlVc);
  1268. NdisVcHandle = pIntF->ClusterControlVc->NdisVcHandle;
  1269. FREE_MEM(pIntF->ClusterControlVc);
  1270. pIntF->ClusterControlVc = NULL;
  1271. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1272. if (NdisVcHandle != NULL)
  1273. {
  1274. NDIS_STATUS DeleteStatus;
  1275. DeleteStatus = NdisCoDeleteVc(NdisVcHandle);
  1276. if (DeleteStatus != NDIS_STATUS_SUCCESS)
  1277. {
  1278. DbgPrint("ATMARPS: CloseCallComp: DeleteVc %p failed %x\n",
  1279. NdisVcHandle, DeleteStatus);
  1280. DbgBreakPoint();
  1281. }
  1282. }
  1283. }
  1284. }
  1285. VOID
  1286. ArpSAddPartyComplete(
  1287. IN NDIS_STATUS Status,
  1288. IN NDIS_HANDLE ProtocolPartyContext,
  1289. IN NDIS_HANDLE NdisPartyHandle,
  1290. IN PCO_CALL_PARAMETERS CallParameters
  1291. )
  1292. /*++
  1293. Routine Description:
  1294. Completion of NdisClAddParty to add a new party to ClusterControlVc.
  1295. If successful, update the member's state. Otherwise, delete it.
  1296. Arguments:
  1297. Status Status of AddParty
  1298. ProtocolPartyContext Pointer to Cluster Member being added
  1299. NdisPartyHandle Valid if AddParty successful
  1300. CallParameters Pointer to AddParty call parameters
  1301. Return Value:
  1302. None
  1303. --*/
  1304. {
  1305. PCLUSTER_MEMBER pMember;
  1306. PINTF pIntF;
  1307. KIRQL OldIrql;
  1308. FREE_MEM(CallParameters);
  1309. pMember = (PCLUSTER_MEMBER)ProtocolPartyContext;
  1310. pIntF = pMember->pIntF;
  1311. MARSDBGPRINT(DBG_LEVEL_LOUD,
  1312. ("AddPartyComplete: Status %x, pMember %x, NdisPartyHandle %x\n",
  1313. Status, pMember, NdisPartyHandle));
  1314. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1315. ASSERT(pMember->pGroupList == NULL_PGROUP_MEMBER);
  1316. pIntF->CCAddingParties--; // AddPartyComplete
  1317. if (Status == NDIS_STATUS_SUCCESS)
  1318. {
  1319. MARS_SET_CM_CONN_STATE(pMember, CM_CONN_ACTIVE);
  1320. pMember->NdisPartyHandle = NdisPartyHandle;
  1321. pIntF->CCActiveParties++; // AddPartyComplete
  1322. if (pMember->Flags & CM_INVALID)
  1323. {
  1324. //
  1325. // Deleting was deferred because the connection was being
  1326. // setup. Now that it's up, we will try to delete it again
  1327. // (should have better luck this time!).
  1328. //
  1329. BOOLEAN fLocked;
  1330. fLocked = MarsDelMemberFromClusterControlVc(
  1331. pIntF,
  1332. pIntF->ClusterMembers,
  1333. TRUE,
  1334. OldIrql
  1335. );
  1336. if(!fLocked)
  1337. {
  1338. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1339. }
  1340. }
  1341. }
  1342. else
  1343. {
  1344. MARSDBGPRINT(DBG_LEVEL_WARN,
  1345. ("AddParty Failed: pMember %x, Status %x, Addr: ",
  1346. pMember, Status));
  1347. MARSDUMPATMADDR(DBG_LEVEL_WARN, &pMember->HwAddr.Address, "");
  1348. pIntF->MarsStats.FailedCCVCAddParties++;
  1349. MARS_SET_CM_CONN_STATE(pMember, CM_CONN_IDLE);
  1350. MarsDeleteClusterMember(pIntF, pMember);
  1351. }
  1352. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1353. //
  1354. // Send any queued packets, if appropriate.
  1355. //
  1356. MarsSendOnClusterControlVc(pIntF, NULL);
  1357. }
  1358. VOID
  1359. ArpSDropPartyComplete(
  1360. IN NDIS_STATUS Status,
  1361. IN NDIS_HANDLE ProtocolPartyContext
  1362. )
  1363. /*++
  1364. Routine Description:
  1365. This is called to signify completion of a previous NdisClDropParty,
  1366. to drop a cluster member off the ClusterControlVc. Delete the member.
  1367. Arguments:
  1368. Status Status of DropParty
  1369. ProtocolPartyContext Pointer to Cluster Member being dropped
  1370. Return Value:
  1371. None.
  1372. --*/
  1373. {
  1374. KIRQL OldIrql;
  1375. PCLUSTER_MEMBER pMember;
  1376. PINTF pIntF;
  1377. PMARS_VC pVc;
  1378. BOOLEAN IsVcClosing;
  1379. ASSERT(Status == NDIS_STATUS_SUCCESS);
  1380. pMember = (PCLUSTER_MEMBER)ProtocolPartyContext;
  1381. pIntF = pMember->pIntF;
  1382. ASSERT(pIntF->ClusterControlVc != NULL_PMARS_VC);
  1383. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1384. MARS_SET_CM_CONN_STATE(pMember, CM_CONN_IDLE);
  1385. pIntF->CCDroppingParties--;
  1386. //
  1387. // Check if we are closing ClusterControlVc, and just one party is left.
  1388. //
  1389. pVc = pIntF->ClusterControlVc;
  1390. IsVcClosing = ((MARS_GET_VC_CONN_STATE(pVc) == MVC_CONN_NEED_CLOSE) &&
  1391. (pIntF->CCActiveParties == 1) &&
  1392. (pIntF->CCAddingParties + pIntF->CCDroppingParties == 0));
  1393. MarsDeleteClusterMember(pIntF, pMember);
  1394. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1395. if (IsVcClosing)
  1396. {
  1397. BOOLEAN fLocked;
  1398. fLocked = MarsDelMemberFromClusterControlVc(
  1399. pIntF,
  1400. pIntF->ClusterMembers,
  1401. FALSE,
  1402. 0
  1403. );
  1404. ASSERT(!fLocked);
  1405. }
  1406. }
  1407. VOID
  1408. ArpSIncomingDropParty(
  1409. IN NDIS_STATUS DropStatus,
  1410. IN NDIS_HANDLE ProtocolPartyContext,
  1411. IN PVOID CloseData OPTIONAL,
  1412. IN UINT Size OPTIONAL
  1413. )
  1414. /*++
  1415. Routine Description:
  1416. Indication that a Cluster Member has dropped off the ClusterControlVc.
  1417. We complete this handshake by calling NdisClDropParty.
  1418. Arguments:
  1419. DropStatus Status
  1420. ProtocolPartyContext Pointer to Cluster Member
  1421. CloseData Optional Close data (IGNORED)
  1422. Size Size of Optional Close Data (OPTIONAL)
  1423. Return Value:
  1424. None
  1425. --*/
  1426. {
  1427. PCLUSTER_MEMBER pMember;
  1428. PINTF pIntF;
  1429. KIRQL OldIrql;
  1430. pMember = (PCLUSTER_MEMBER)ProtocolPartyContext;
  1431. pIntF = pMember->pIntF;
  1432. ASSERT(MARS_GET_CM_CONN_STATE(pMember) == CM_CONN_ACTIVE);
  1433. MARSDBGPRINT(DBG_LEVEL_NOTICE,
  1434. ("IncomingDropParty: pIntF %x, pMember %x, Addr: ", pIntF, pMember));
  1435. MARSDUMPATMADDR(DBG_LEVEL_NOTICE, &pMember->HwAddr.Address, "");
  1436. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1437. //
  1438. // Remove its membership from all groups.
  1439. // AND disable further groups from being added.
  1440. //
  1441. MarsUnlinkAllGroupsOnClusterMember(pIntF, pMember);
  1442. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1443. {
  1444. BOOLEAN fLocked;
  1445. fLocked = MarsDelMemberFromClusterControlVc(pIntF, pMember, FALSE, 0);
  1446. ASSERT(!fLocked);
  1447. }
  1448. }
  1449. NDIS_STATUS
  1450. ArpSCoRequest(
  1451. IN NDIS_HANDLE ProtocolAfContext,
  1452. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  1453. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  1454. IN OUT PNDIS_REQUEST NdisRequest
  1455. )
  1456. /*++
  1457. Routine Description:
  1458. Arguments:
  1459. Return Value:
  1460. --*/
  1461. {
  1462. PINTF pIntF = (PINTF)ProtocolAfContext;
  1463. KIRQL OldIrql;
  1464. BOOLEAN ValidAf;
  1465. DBGPRINT(DBG_LEVEL_INFO,
  1466. ("CallMgrRequest: Request %lx, Type %d, OID %lx\n",
  1467. NdisRequest, NdisRequest->RequestType, NdisRequest->DATA.SET_INFORMATION.Oid));
  1468. switch(NdisRequest->DATA.SET_INFORMATION.Oid)
  1469. {
  1470. case OID_CO_ADDRESS_CHANGE:
  1471. ValidAf = FALSE;
  1472. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1473. pIntF->Flags |= INTF_ADDRESS_VALID;
  1474. ValidAf = ((pIntF->Flags & INTF_AF_OPENED) != 0);
  1475. pIntF->NumAddressesRegd = 0;
  1476. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1477. if (ValidAf)
  1478. {
  1479. ArpSQueryAndSetAddresses(pIntF);
  1480. }
  1481. break;
  1482. case OID_CO_AF_CLOSE:
  1483. #if DBG
  1484. DbgPrint("atmarps: OID_CO_AF_CLOSE\n");
  1485. #endif
  1486. if (ArpSReferenceIntF(pIntF))
  1487. {
  1488. //
  1489. // ArpSStopInterface dereferences the pIntF
  1490. //
  1491. (VOID)ArpSStopInterface(pIntF, FALSE);
  1492. }
  1493. break;
  1494. default:
  1495. break;
  1496. }
  1497. return NDIS_STATUS_SUCCESS;
  1498. }
  1499. VOID
  1500. ArpSCoRequestComplete(
  1501. IN NDIS_STATUS Status,
  1502. IN NDIS_HANDLE ProtocolAfContext,
  1503. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  1504. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  1505. IN PNDIS_REQUEST NdisRequest
  1506. )
  1507. /*++
  1508. Routine Description:
  1509. Completion routine for the NdisCoRequest api.
  1510. Arguments:
  1511. Status Status of completion
  1512. ProtocolAfContext Pointer to the IntF structure
  1513. ProtocolVcContext Pointer to the VC structure
  1514. ProtocolPartyContext Not used by us since we do not make calls
  1515. NdisRequest Pointer to the request structure
  1516. Return Value:
  1517. None
  1518. --*/
  1519. {
  1520. PINTF pIntF = (PINTF)ProtocolAfContext;
  1521. BOOLEAN FreeReq = TRUE;
  1522. KIRQL OldIrql;
  1523. PKEVENT pEvent = NULL;
  1524. DBGPRINT(DBG_LEVEL_INFO,
  1525. ("CoRequestComplete: Request %lx, Type %d, OID %lx\n",
  1526. NdisRequest, NdisRequest->RequestType, NdisRequest->DATA.QUERY_INFORMATION.Oid));
  1527. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1528. switch(NdisRequest->DATA.SET_INFORMATION.Oid)
  1529. {
  1530. case OID_CO_ADD_ADDRESS:
  1531. if (Status == NDIS_STATUS_SUCCESS)
  1532. {
  1533. DBGPRINT(DBG_LEVEL_INFO,
  1534. ("CoRequestComplete: Registered address # %d\n", pIntF->NumAddressesRegd+1));
  1535. if (pIntF->NumAddressesRegd < pIntF->NumAllocedRegdAddresses)
  1536. {
  1537. PCO_ADDRESS pCoAddr;
  1538. PATM_ADDRESS pAddress;
  1539. // Copy the registered address from the ndis request into the
  1540. // array of registered addresses.
  1541. //
  1542. pCoAddr = NdisRequest->DATA.SET_INFORMATION.InformationBuffer;
  1543. pAddress = (PATM_ADDRESS)(pCoAddr->Address);
  1544. pIntF->RegAddresses[pIntF->NumAddressesRegd] = *pAddress;
  1545. pIntF->NumAddressesRegd ++;
  1546. }
  1547. else
  1548. {
  1549. //
  1550. // 12/22/1998 JosephJ
  1551. // We could potentially get here if the total number of outstanding add address requests
  1552. // is greater then NumAllocedRegAddresses. One way this could happen is if ArpSQueryAndSetAddresses
  1553. // is called multiple times in quick succession. Note that ArpSQueryAndSetAddresses is called from
  1554. // two places: ArpSCoRequest and ArpSReqdAdaprConfiguration.
  1555. //
  1556. // Previously, we would increment NumAddressRegd in this condition. Now we simply ignore this.
  1557. //
  1558. }
  1559. }
  1560. else
  1561. {
  1562. DBGPRINT(DBG_LEVEL_INFO,
  1563. ("CoRequestComplete: CO_ADD_ADDRESS Failed %lx\n", Status));
  1564. }
  1565. //
  1566. // Try registering the next address. ArpSValidateOneRegAddress will
  1567. // unlink and free pIntF->pRegAddrCtxt if there are no more addresses
  1568. // to be registered.
  1569. //
  1570. if (pIntF->pRegAddrCtxt != NULL)
  1571. {
  1572. ArpSValidateOneRegdAddress(
  1573. pIntF,
  1574. OldIrql
  1575. );
  1576. //
  1577. // Lock released by above call.
  1578. //
  1579. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1580. }
  1581. else
  1582. {
  1583. ASSERT(FALSE); // can't get here.
  1584. }
  1585. // We don't want to free this ndis request here, because it's actually
  1586. // part of pIntF->pRegAddrCtxt.
  1587. //
  1588. FreeReq = FALSE;
  1589. break;
  1590. case OID_CO_GET_ADDRESSES:
  1591. //
  1592. // (On success) We just got our configured address value.
  1593. // We save this value AND THEN move on the next stage of initialization --
  1594. // validating and setting the "registered" addresses -- these are the
  1595. // addresses we read from the registry. See 05/14/1999 notes.txt entry
  1596. // for details.
  1597. //
  1598. if (Status == NDIS_STATUS_SUCCESS)
  1599. {
  1600. PCO_ADDRESS_LIST pCoAddrList;
  1601. UINT i;
  1602. pCoAddrList = (PCO_ADDRESS_LIST)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
  1603. ASSERT(pCoAddrList->NumberOfAddresses == 1);
  1604. DBGPRINT(DBG_LEVEL_INFO,
  1605. ("CoRequestComplete: Configured address, %d/%d Size %d\n",
  1606. pCoAddrList->NumberOfAddresses,
  1607. pCoAddrList->NumberOfAddressesAvailable,
  1608. pCoAddrList->AddressList.AddressSize));
  1609. ASSERT(pCoAddrList->AddressList.AddressSize == (sizeof(CO_ADDRESS) + sizeof(ATM_ADDRESS)));
  1610. COPY_MEM(&pIntF->ConfiguredAddress,
  1611. pCoAddrList->AddressList.Address,
  1612. sizeof(ATM_ADDRESS));
  1613. DBGPRINT(DBG_LEVEL_INFO,
  1614. ("CoRequestComplete: Configured Address (%s): ",
  1615. (pIntF->ConfiguredAddress.AddressType == ATM_E164) ? "E164" : "NSAP"));
  1616. for (i = 0; i < pIntF->ConfiguredAddress.NumberOfDigits; i++)
  1617. {
  1618. DBGPRINT(DBG_LEVEL_INFO + DBG_NO_HDR,
  1619. ("%02x ", pIntF->ConfiguredAddress.Address[i]));
  1620. }
  1621. DBGPRINT(DBG_LEVEL_INFO | DBG_NO_HDR, ("\n"));
  1622. }
  1623. else
  1624. {
  1625. DBGPRINT(DBG_LEVEL_INFO,
  1626. ("CoRequestComplete: CO_GET_ADDRESS Failed %lx\n", Status));
  1627. }
  1628. //
  1629. // Validate and set the registered addresses.
  1630. //
  1631. ArpSValidateAndSetRegdAddresses(pIntF, OldIrql);
  1632. // IntF lock released by the above.
  1633. //
  1634. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1635. break;
  1636. case OID_CO_DELETE_ADDRESS:
  1637. DBGPRINT(DBG_LEVEL_INFO,
  1638. ("CoRequestComplete: Deleted address. Status=%x\n", Status));
  1639. if (pIntF->DelAddressesEvent != NULL)
  1640. {
  1641. // Someone's waiting for all the addresses to be deleted...
  1642. //
  1643. ASSERT(pIntF->NumPendingDelAddresses > 0);
  1644. if (--(pIntF->NumPendingDelAddresses) == 0)
  1645. {
  1646. // Deletion of all addresses is over, signal the event.
  1647. //
  1648. pEvent = pIntF->DelAddressesEvent;
  1649. pIntF->DelAddressesEvent = NULL;
  1650. }
  1651. }
  1652. break;
  1653. }
  1654. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1655. if (pEvent != NULL)
  1656. {
  1657. KeSetEvent(pEvent, IO_NETWORK_INCREMENT, FALSE);
  1658. }
  1659. if (FreeReq)
  1660. {
  1661. FREE_MEM(NdisRequest);
  1662. }
  1663. }
  1664. VOID
  1665. ArpSIncomingCallQoSChange(
  1666. IN NDIS_HANDLE ProtocolVcContext,
  1667. IN PCO_CALL_PARAMETERS CallParameters
  1668. )
  1669. /*++
  1670. Routine Description:
  1671. Arguments:
  1672. Return Value:
  1673. --*/
  1674. {
  1675. DBGPRINT(DBG_LEVEL_WARN, ("QoSChange: Ignored\n"));
  1676. }
  1677. VOID
  1678. ArpSQueryAdapter(
  1679. IN PINTF pIntF
  1680. )
  1681. /*++
  1682. Routine Description:
  1683. Query the miniport we are bound to for the following info:
  1684. 1. Line rate
  1685. 2. Max packet size
  1686. These will overwrite the defaults we set up in ArpSCreateIntF.
  1687. Arguments:
  1688. pIntF Pointer to Interface
  1689. Return Value:
  1690. None
  1691. --*/
  1692. {
  1693. ArpSSendNdisRequest(pIntF,
  1694. OID_GEN_CO_LINK_SPEED,
  1695. (PVOID)&(pIntF->LinkSpeed),
  1696. sizeof(NDIS_CO_LINK_SPEED));
  1697. ArpSSendNdisRequest(pIntF,
  1698. OID_ATM_MAX_AAL5_PACKET_SIZE,
  1699. (PVOID)&(pIntF->MaxPacketSize),
  1700. sizeof(ULONG));
  1701. }
  1702. VOID
  1703. ArpSSendNdisRequest(
  1704. IN PINTF pIntF,
  1705. IN NDIS_OID Oid,
  1706. IN PVOID pBuffer,
  1707. IN ULONG BufferLength
  1708. )
  1709. /*++
  1710. Routine Description:
  1711. NDIS Request generator, for sending NDIS requests to the miniport.
  1712. Arguments:
  1713. pIntF Ptr to Interface
  1714. Oid The parameter being queried
  1715. pBuffer Points to parameter
  1716. BufferLength Length of above
  1717. Return Value:
  1718. None
  1719. --*/
  1720. {
  1721. NDIS_STATUS Status;
  1722. PNDIS_REQUEST pRequest;
  1723. pRequest = (PNDIS_REQUEST)ALLOC_NP_MEM(sizeof(NDIS_REQUEST), POOL_TAG_INTF);
  1724. if (pRequest == (PNDIS_REQUEST)NULL)
  1725. {
  1726. return;
  1727. }
  1728. ZERO_MEM(pRequest, sizeof(NDIS_REQUEST));
  1729. //
  1730. // Query for the line rate.
  1731. //
  1732. pRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  1733. pRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  1734. pRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
  1735. pRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
  1736. pRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
  1737. NdisRequest(&Status,
  1738. pIntF->NdisBindingHandle,
  1739. pRequest);
  1740. if (Status != NDIS_STATUS_PENDING)
  1741. {
  1742. ArpSRequestComplete(
  1743. (NDIS_HANDLE)pIntF,
  1744. pRequest,
  1745. Status);
  1746. }
  1747. }
  1748. VOID
  1749. ArpSRequestComplete(
  1750. IN NDIS_HANDLE ProtocolBindingContext,
  1751. IN PNDIS_REQUEST pRequest,
  1752. IN NDIS_STATUS Status
  1753. )
  1754. /*++
  1755. Routine Description:
  1756. Completion of our call to NdisRequest(). Do some follow-up.
  1757. Arguments:
  1758. ProtocolBindingContext Pointer to IntF
  1759. pRequest The request that just completed
  1760. Status Status of NdisRequest()
  1761. Return Value:
  1762. None
  1763. --*/
  1764. {
  1765. PINTF pIntF;
  1766. pIntF = (PINTF)ProtocolBindingContext;
  1767. switch (pRequest->DATA.QUERY_INFORMATION.Oid)
  1768. {
  1769. case OID_ATM_MAX_AAL5_PACKET_SIZE:
  1770. if (pIntF->MaxPacketSize < pIntF->CCFlowSpec.SendMaxSize)
  1771. {
  1772. pIntF->CCFlowSpec.SendMaxSize =
  1773. pIntF->CCFlowSpec.ReceiveMaxSize = pIntF->MaxPacketSize;
  1774. }
  1775. DBGPRINT(DBG_LEVEL_INFO,
  1776. ("Miniport Max AAL5 Packet Size: %d (decimal)\n",
  1777. pIntF->MaxPacketSize));
  1778. break;
  1779. case OID_GEN_CO_LINK_SPEED:
  1780. //
  1781. // Convert to bytes/sec
  1782. //
  1783. pIntF->LinkSpeed.Outbound = (pIntF->LinkSpeed.Outbound * 100 / 8);
  1784. pIntF->LinkSpeed.Inbound = (pIntF->LinkSpeed.Inbound * 100 / 8);
  1785. if (pIntF->LinkSpeed.Outbound < pIntF->CCFlowSpec.SendBandwidth)
  1786. {
  1787. pIntF->CCFlowSpec.SendBandwidth = pIntF->LinkSpeed.Outbound;
  1788. }
  1789. if (pIntF->LinkSpeed.Inbound < pIntF->CCFlowSpec.ReceiveBandwidth)
  1790. {
  1791. pIntF->CCFlowSpec.ReceiveBandwidth = pIntF->LinkSpeed.Inbound;
  1792. }
  1793. DBGPRINT(DBG_LEVEL_INFO,
  1794. ("Miniport Link Speed (decimal, bytes/sec): In %d, Out %d\n",
  1795. pIntF->LinkSpeed.Inbound, pIntF->LinkSpeed.Outbound));
  1796. break;
  1797. default:
  1798. ASSERT(FALSE);
  1799. break;
  1800. }
  1801. FREE_MEM(pRequest);
  1802. }
  1803. VOID
  1804. ArpSUnbindAdapter(
  1805. OUT PNDIS_STATUS UnbindStatus,
  1806. IN NDIS_HANDLE ProtocolBindingContext,
  1807. IN NDIS_HANDLE UnbindContext
  1808. )
  1809. /*++
  1810. Routine Description:
  1811. Arguments:
  1812. Return Value:
  1813. --*/
  1814. {
  1815. PINTF pIntF = (PINTF)ProtocolBindingContext;
  1816. DBGPRINT(DBG_LEVEL_WARN,
  1817. ("UnbindAdapter: Intf %x, Name %Z\n", pIntF, &pIntF->InterfaceName));
  1818. if (ArpSReferenceIntF(pIntF))
  1819. {
  1820. //
  1821. // ArpSStopInterface dereferences the pIntF
  1822. //
  1823. *UnbindStatus = ArpSStopInterface(pIntF, TRUE);
  1824. }
  1825. }
  1826. NDIS_STATUS
  1827. ArpSStopInterface(
  1828. IN PINTF pIntF,
  1829. IN BOOLEAN bCloseAdapter
  1830. )
  1831. //
  1832. // NOTE: ArpSStopInterface MAY be called concurrently multiple times.
  1833. //
  1834. {
  1835. KEVENT CleanupEvent;
  1836. NDIS_STATUS Status;
  1837. KIRQL OldIrql;
  1838. BOOLEAN bWaitForClose;
  1839. DBGPRINT(DBG_LEVEL_NOTICE,
  1840. ("StopInterface: Intf %x, Flags %x, Name %Z, bClose %d\n",
  1841. pIntF, pIntF->Flags, &pIntF->InterfaceName, bCloseAdapter));
  1842. bWaitForClose = FALSE;
  1843. if (bCloseAdapter)
  1844. {
  1845. //
  1846. // Event to be set when the IntF cleanup is complete
  1847. //
  1848. if (pIntF->CleanupEvent == NULL)
  1849. {
  1850. KeInitializeEvent(&CleanupEvent, NotificationEvent, FALSE);
  1851. pIntF->CleanupEvent = &CleanupEvent;
  1852. bWaitForClose = TRUE;
  1853. }
  1854. else
  1855. {
  1856. ASSERT(FALSE);
  1857. }
  1858. }
  1859. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1860. //
  1861. // NOTE: we can't simply skip the shutdown steps if
  1862. // INTF_STOPPING is already set, because we need to make sure all the steps
  1863. // are complete before we call NdisCloseAdapter.
  1864. //
  1865. pIntF->Flags |= INTF_STOPPING;
  1866. //
  1867. // Start off by de-registering the Sap
  1868. //
  1869. if (pIntF->Flags & INTF_SAP_REGISTERED)
  1870. {
  1871. pIntF->Flags &= ~INTF_SAP_REGISTERED;
  1872. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1873. Status = NdisClDeregisterSap(pIntF->NdisSapHandle);
  1874. if (Status != NDIS_STATUS_PENDING)
  1875. {
  1876. ArpSDeregisterSapComplete(Status, pIntF);
  1877. }
  1878. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1879. }
  1880. //
  1881. // Walk the list of Active Vcs and close them down
  1882. //
  1883. while (!IsListEmpty(&pIntF->ActiveVcHead))
  1884. {
  1885. PARP_VC Vc;
  1886. Vc = CONTAINING_RECORD(pIntF->ActiveVcHead.Flink, ARP_VC, List);
  1887. if ((Vc->Flags & ARPVC_CLOSING) == 0)
  1888. {
  1889. Vc->Flags |= ARPVC_CLOSING;
  1890. Vc->Flags &= ~ARPVC_ACTIVE;
  1891. //
  1892. // The ArpEntry part of the Vc gets cleaned up seperately.
  1893. //
  1894. Vc->ArpEntry = NULL;
  1895. ASSERT(Vc->HwAddr.SubAddress == NULL);
  1896. RemoveEntryList(&Vc->List);
  1897. InsertHeadList(&pIntF->InactiveVcHead, &Vc->List);
  1898. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1899. Status = NdisClCloseCall(Vc->NdisVcHandle, NULL, NULL, 0);
  1900. if (Status != NDIS_STATUS_PENDING)
  1901. {
  1902. ArpSCloseCallComplete(Status, Vc, NULL);
  1903. }
  1904. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  1905. }
  1906. }
  1907. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  1908. MarsStopInterface(pIntF);
  1909. //
  1910. // Deregister all registered addresses...
  1911. //
  1912. DeregisterAllAddresses(pIntF);
  1913. //
  1914. // Now close Address family
  1915. //
  1916. if (pIntF->Flags & INTF_AF_OPENED)
  1917. {
  1918. pIntF->Flags &= ~INTF_AF_OPENED;
  1919. Status = NdisClCloseAddressFamily(pIntF->NdisAfHandle);
  1920. if (Status != NDIS_STATUS_PENDING)
  1921. {
  1922. ArpSCloseAfComplete(Status, pIntF);
  1923. }
  1924. }
  1925. if (bCloseAdapter)
  1926. {
  1927. //
  1928. // Now close the adapter.
  1929. //
  1930. ArpSTryCloseAdapter(pIntF);
  1931. }
  1932. //
  1933. // Take away reference added by caller.
  1934. //
  1935. ArpSDereferenceIntF(pIntF);
  1936. if (bWaitForClose)
  1937. {
  1938. //
  1939. // Wait for the cleanup to complete, i.e. last reference on the Interface
  1940. // to go away.
  1941. //
  1942. WAIT_FOR_OBJECT(Status, &CleanupEvent, NULL);
  1943. }
  1944. return NDIS_STATUS_SUCCESS;
  1945. }
  1946. NDIS_STATUS
  1947. ArpSPnPEventHandler(
  1948. IN NDIS_HANDLE ProtocolBindingContext,
  1949. IN PNET_PNP_EVENT pNetPnPEvent
  1950. )
  1951. {
  1952. PINTF pIntF;
  1953. NDIS_STATUS Status;
  1954. PNET_DEVICE_POWER_STATE pPowerState = (PNET_DEVICE_POWER_STATE)pNetPnPEvent->Buffer;
  1955. pIntF = (PINTF)ProtocolBindingContext;
  1956. do
  1957. {
  1958. switch (pNetPnPEvent->NetEvent)
  1959. {
  1960. case NetEventSetPower:
  1961. switch (*pPowerState)
  1962. {
  1963. case NetDeviceStateD0:
  1964. Status = NDIS_STATUS_SUCCESS;
  1965. break;
  1966. default:
  1967. //
  1968. // We can't suspend, so we ask NDIS to Unbind us by
  1969. // returning this status:
  1970. //
  1971. Status = NDIS_STATUS_NOT_SUPPORTED;
  1972. break;
  1973. }
  1974. break;
  1975. case NetEventQueryPower: // FALLTHRU
  1976. case NetEventQueryRemoveDevice: // FALLTHRU
  1977. case NetEventCancelRemoveDevice:
  1978. Status = NDIS_STATUS_SUCCESS;
  1979. break;
  1980. case NetEventReconfigure:
  1981. if (pIntF)
  1982. {
  1983. Status = ArpSReadAdapterConfiguration(pIntF);
  1984. }
  1985. else
  1986. {
  1987. //
  1988. // Global changes
  1989. //
  1990. Status = NDIS_STATUS_SUCCESS;
  1991. }
  1992. break;
  1993. case NetEventBindList:
  1994. default:
  1995. Status = NDIS_STATUS_NOT_SUPPORTED;
  1996. break;
  1997. }
  1998. break;
  1999. }
  2000. while (FALSE);
  2001. return (Status);
  2002. }
  2003. VOID
  2004. ArpSStatus(
  2005. IN NDIS_HANDLE ProtocolBindingContext,
  2006. IN NDIS_STATUS GeneralStatus,
  2007. IN PVOID StatusBuffer,
  2008. IN UINT StatusBufferSize
  2009. )
  2010. /*++
  2011. Routine Description:
  2012. Arguments:
  2013. Return Value:
  2014. --*/
  2015. {
  2016. DBGPRINT(DBG_LEVEL_WARN, ("StatusIndication: Ignored\n"));
  2017. }
  2018. VOID
  2019. ArpSReceiveComplete(
  2020. IN NDIS_HANDLE ProtocolBindingContext
  2021. )
  2022. /*++
  2023. Routine Description:
  2024. Arguments:
  2025. Return Value:
  2026. --*/
  2027. {
  2028. return;
  2029. }
  2030. VOID
  2031. ArpSStatusComplete(
  2032. IN NDIS_HANDLE ProtocolBindingContext
  2033. )
  2034. /*++
  2035. Routine Description:
  2036. Arguments:
  2037. Return Value:
  2038. --*/
  2039. {
  2040. DBGPRINT(DBG_LEVEL_WARN, ("StatusComplete: Ignored\n"));
  2041. }
  2042. VOID
  2043. ArpSCoStatus(
  2044. IN NDIS_HANDLE ProtocolBindingContext,
  2045. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  2046. IN NDIS_STATUS GeneralStatus,
  2047. IN PVOID StatusBuffer,
  2048. IN UINT StatusBufferSize
  2049. )
  2050. /*++
  2051. Routine Description:
  2052. Arguments:
  2053. Return Value:
  2054. --*/
  2055. {
  2056. DBGPRINT(DBG_LEVEL_WARN, ("CoStatus: Ignored\n"));
  2057. }
  2058. VOID
  2059. ArpSInitiateCloseCall(
  2060. IN PARP_VC Vc
  2061. )
  2062. /*++
  2063. Routine Description:
  2064. Start off an NDIS Call Closing sequence on the ARP VC, if all
  2065. conditions are right.
  2066. Arguments:
  2067. Vc - Pointer to ARP Vc
  2068. Return Value:
  2069. None
  2070. --*/
  2071. {
  2072. PINTF pIntF;
  2073. NDIS_HANDLE NdisVcHandle;
  2074. NDIS_HANDLE NdisPartyHandle;
  2075. NDIS_STATUS Status;
  2076. KIRQL OldIrql;
  2077. pIntF = Vc->IntF;
  2078. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  2079. DBGPRINT(DBG_LEVEL_NOTICE,
  2080. ("InitiateClose: VC %x, ref %d, flags %x, Pending %d, ArpEntry %x\n",
  2081. Vc, Vc->RefCount, Vc->Flags, Vc->PendingSends, Vc->ArpEntry));
  2082. if (Vc->PendingSends == 0)
  2083. {
  2084. //
  2085. // No outstanding packets, we can start closing this call.
  2086. //
  2087. NdisVcHandle = Vc->NdisVcHandle;
  2088. NdisPartyHandle = NULL;
  2089. Vc->Flags |= ARPVC_CLOSING;
  2090. Vc->Flags &= ~ARPVC_CLOSE_PENDING;
  2091. Vc->Flags &= ~ARPVC_ACTIVE;
  2092. //
  2093. // The ArpEntry part of the Vc gets cleaned up seperately.
  2094. //
  2095. Vc->ArpEntry = NULL;
  2096. ASSERT(Vc->HwAddr.SubAddress == NULL);
  2097. RemoveEntryList(&Vc->List);
  2098. InsertHeadList(&pIntF->InactiveVcHead, &Vc->List);
  2099. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  2100. Status = NdisClCloseCall(NdisVcHandle, NdisPartyHandle, NULL, 0);
  2101. if (Status != NDIS_STATUS_PENDING)
  2102. {
  2103. ArpSCloseCallComplete(Status, Vc, (NDIS_HANDLE)NULL);
  2104. }
  2105. }
  2106. else
  2107. {
  2108. //
  2109. // Mark this Vc as needing CloseCall.
  2110. //
  2111. Vc->Flags &= ~ARPVC_ACTIVE;
  2112. Vc->Flags |= ARPVC_CLOSE_PENDING;
  2113. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  2114. }
  2115. }
  2116. VOID
  2117. DeregisterAllAddresses(
  2118. IN PINTF pIntF
  2119. )
  2120. {
  2121. //
  2122. // Deregister any registered addresses from the switch.
  2123. //
  2124. ULONG NumAllocedRegdAddresses;
  2125. PATM_ADDRESS RegAddresses;
  2126. KIRQL OldIrql;
  2127. NDIS_STATUS Status;
  2128. ULONG NumAddressesRegd;
  2129. // Clear the registered address field.
  2130. //
  2131. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  2132. NumAllocedRegdAddresses = pIntF->NumAllocedRegdAddresses;
  2133. RegAddresses = pIntF->RegAddresses;
  2134. pIntF->NumAllocedRegdAddresses = 0;
  2135. pIntF->RegAddresses = NULL;
  2136. NumAddressesRegd = pIntF->NumAddressesRegd;
  2137. pIntF->NumAddressesRegd = 0;
  2138. // Deregister all registered addresses with the switch.
  2139. //
  2140. if (NumAddressesRegd)
  2141. {
  2142. KEVENT DelAddressesEvent;
  2143. BOOLEAN fRet;
  2144. KeInitializeEvent(&DelAddressesEvent, NotificationEvent, FALSE);
  2145. ASSERT(pIntF->DelAddressesEvent == NULL);
  2146. ASSERT(pIntF->NumPendingDelAddresses == 0);
  2147. pIntF->DelAddressesEvent = &DelAddressesEvent;
  2148. pIntF->NumPendingDelAddresses = NumAllocedRegdAddresses;
  2149. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  2150. DBGPRINT(DBG_LEVEL_WARN, ("DeregisterAllAddresses: Going to derigester addresses\n"));
  2151. fRet = ArpSDeleteIntFAddresses(
  2152. pIntF,
  2153. NumAllocedRegdAddresses,
  2154. RegAddresses
  2155. );
  2156. if (fRet == FALSE)
  2157. {
  2158. // This means that deregistration was not started for ALL addresses
  2159. // This is a bad situation, and in this case, we don't wait.
  2160. //
  2161. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  2162. pIntF->DelAddressesEvent = NULL;
  2163. pIntF->NumPendingDelAddresses = 0;
  2164. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  2165. }
  2166. else
  2167. {
  2168. DBGPRINT(DBG_LEVEL_WARN, ("DeregisterAllAddresses: Waiting for addresses to be deleted\n"));
  2169. WAIT_FOR_OBJECT(Status, &DelAddressesEvent, NULL);
  2170. }
  2171. }
  2172. else
  2173. {
  2174. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  2175. }
  2176. // Free RegAddresses.
  2177. //
  2178. if (RegAddresses)
  2179. {
  2180. FREE_MEM(RegAddresses);
  2181. }
  2182. }
  2183. VOID
  2184. ArpSTryCloseAdapter(
  2185. IN PINTF pIntF // NOLOCKIN LOLOCKOUT
  2186. )
  2187. //
  2188. // Close adapter if it's still in the "open" state. Need to
  2189. // guard against closing the adapter more than once.
  2190. //
  2191. {
  2192. KIRQL OldIrql;
  2193. BOOLEAN bCloseAdapter;
  2194. NDIS_STATUS Status;
  2195. bCloseAdapter = FALSE;
  2196. ACQUIRE_SPIN_LOCK(&pIntF->Lock, &OldIrql);
  2197. if (pIntF->Flags & INTF_ADAPTER_OPENED)
  2198. {
  2199. pIntF->Flags &= ~INTF_ADAPTER_OPENED;
  2200. bCloseAdapter = TRUE;
  2201. }
  2202. RELEASE_SPIN_LOCK(&pIntF->Lock, OldIrql);
  2203. if (bCloseAdapter)
  2204. {
  2205. NdisCloseAdapter(&Status, pIntF->NdisBindingHandle);
  2206. if (Status != NDIS_STATUS_PENDING)
  2207. {
  2208. ArpSCloseAdapterComplete(pIntF, Status);
  2209. }
  2210. }
  2211. }