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.

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