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.

3455 lines
90 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. adapter.c
  5. Abstract:
  6. routines for binding/unbinding to/from underlying miniport drivers
  7. Author:
  8. Charlie Wickham (charlwi) 24-Apr-1996.
  9. Rajesh Sundaram (rajeshsu) 01-Aug-1998.
  10. Environment:
  11. Kernel Mode
  12. Revision History:
  13. --*/
  14. #include "psched.h"
  15. #pragma hdrstop
  16. /* Defines */
  17. /* External */
  18. /* Static */
  19. #define DRIVER_COUNTED_BLOCK \
  20. { \
  21. ++DriverRefCount; \
  22. NdisResetEvent(&DriverUnloadEvent); \
  23. }
  24. #define DRIVER_COUNTED_UNBLOCK \
  25. { \
  26. PS_LOCK(&DriverUnloadLock); \
  27. if( --DriverRefCount == 0) \
  28. NdisSetEvent(&DriverUnloadEvent); \
  29. PS_UNLOCK(&DriverUnloadLock); \
  30. }
  31. /* Forward */
  32. NDIS_STATUS
  33. PsInitializeDeviceInstance(PADAPTER Adapter);
  34. NDIS_STATUS
  35. GetFrameSize(
  36. PADAPTER Adapter
  37. );
  38. NDIS_STATUS
  39. InitializeAdapter(
  40. PADAPTER Adapter,
  41. NDIS_HANDLE BindContext,
  42. PNDIS_STRING MpDeviceName,
  43. PVOID SystemSpecific1);
  44. NDIS_STATUS
  45. UpdateSchedulingPipe(
  46. PADAPTER Adapter
  47. );
  48. VOID
  49. DeleteAdapter(PVOID Adapter, BOOLEAN AdapterListLocked);
  50. VOID
  51. ClUnloadProtocol(
  52. VOID
  53. );
  54. VOID
  55. MpHalt(
  56. IN NDIS_HANDLE MiniportAdapterContext
  57. );
  58. NDIS_STATUS
  59. MpReset(
  60. OUT PBOOLEAN AddressingReset,
  61. IN NDIS_HANDLE MiniportAdapterContext
  62. );
  63. NDIS_STATUS
  64. GetSchedulerPipeContext(
  65. PADAPTER Adapter,
  66. PPS_PIPE_CONTEXT *AdapterPipeContext,
  67. PPSI_INFO *AdapterPsComponent,
  68. PULONG ShutdownMask
  69. );
  70. NDIS_STATUS
  71. FindProfile(
  72. IN PNDIS_STRING ProfileName,
  73. OUT PPS_PROFILE *Profile
  74. );
  75. NDIS_STATUS
  76. RegisterPsComponent(
  77. IN PPSI_INFO PsiComponentInfo,
  78. ULONG Size,
  79. PPS_DEBUG_INFO DebugInfo
  80. );
  81. NDIS_STATUS
  82. FindSchedulingComponent(
  83. IN PNDIS_STRING ComponentName,
  84. OUT PPSI_INFO *Component
  85. );
  86. NDIS_STATUS
  87. PsReadMiniportOIDs(
  88. IN PADAPTER Adapter
  89. );
  90. VOID
  91. CloseAllGpcVcs(
  92. IN PADAPTER Adapter);
  93. /* End Forward */
  94. NTSTATUS
  95. PsIoctl(
  96. IN PDEVICE_OBJECT pdo,
  97. IN PIRP pirp
  98. )
  99. {
  100. PIO_STACK_LOCATION pirpSp;
  101. ULONG ioControlCode;
  102. PLIST_ENTRY NextAdapter;
  103. PADAPTER Adapter;
  104. NTSTATUS Status ;
  105. PGPC_CLIENT_VC Vc;
  106. PLIST_ENTRY NextVc;
  107. PPS_WAN_LINK WanLink;
  108. PVOID pIoBuf;
  109. ULONG InputBufferLength;
  110. ULONG OutputBufferLength;
  111. USHORT Port = 0;
  112. ULONG Ip = 0;
  113. PTIMESTMP_REQ pTsReq = NULL;
  114. #if DBG
  115. KIRQL OldIrql;
  116. KIRQL NewIrql;
  117. OldIrql = KeGetCurrentIrql();
  118. #endif
  119. pirpSp = IoGetCurrentIrpStackLocation(pirp);
  120. ioControlCode = pirpSp->Parameters.DeviceIoControl.IoControlCode;
  121. pirp->IoStatus.Status = Status = STATUS_SUCCESS;
  122. pirp->IoStatus.Information = 0;
  123. /* Both input and output buffers are mapped to "SystemBuffer" in case of direct-IO */
  124. pIoBuf = pirp->AssociatedIrp.SystemBuffer;
  125. InputBufferLength = pirpSp->Parameters.DeviceIoControl.InputBufferLength;
  126. OutputBufferLength = pirpSp->Parameters.DeviceIoControl.OutputBufferLength;
  127. switch(pirpSp->MajorFunction)
  128. {
  129. case IRP_MJ_DEVICE_CONTROL:
  130. switch (ioControlCode)
  131. {
  132. case IOCTL_PSCHED_ZAW_EVENT:
  133. {
  134. while(InterlockedExchange(&gZAWState, ZAW_STATE_IN_USE) != ZAW_STATE_READY)
  135. {
  136. //
  137. // Some other thread is in this loop. Let's wait
  138. //
  139. NdisResetEvent(&gZAWEvent);
  140. NdisWaitEvent(&gZAWEvent, 0);
  141. }
  142. PsReadDriverRegistryData();
  143. //
  144. // Handle the per adapter settings.
  145. //
  146. PS_LOCK(&AdapterListLock);
  147. NextAdapter = AdapterList.Flink;
  148. while(NextAdapter != &AdapterList)
  149. {
  150. Adapter = CONTAINING_RECORD(NextAdapter, ADAPTER, Linkage);
  151. PS_LOCK_DPC(&Adapter->Lock);
  152. if(Adapter->PsMpState != AdapterStateRunning)
  153. {
  154. PS_UNLOCK_DPC(&Adapter->Lock);
  155. NextAdapter = NextAdapter->Flink;
  156. continue;
  157. }
  158. REFADD(&Adapter->RefCount, 'IOTL');
  159. PS_UNLOCK_DPC(&Adapter->Lock);
  160. PS_UNLOCK(&AdapterListLock);
  161. PsReadAdapterRegistryData(Adapter,
  162. &MachineRegistryKey,
  163. &Adapter->RegistryPath
  164. );
  165. //
  166. // This will apply the effects of the following registry parameters.
  167. //
  168. // NonBestEffortLimit
  169. // TimerResolution (since we update the scheduling pipe)
  170. //
  171. if(Adapter->MediaType != NdisMediumWan)
  172. {
  173. UpdateAdapterBandwidthParameters(Adapter);
  174. //
  175. // Set 802.1p/TOS for b/e Vc
  176. //
  177. Adapter->BestEffortVc.UserPriorityConforming = Adapter->UserServiceTypeBestEffort;
  178. Adapter->BestEffortVc.UserPriorityNonConforming = Adapter->UserServiceTypeNonConforming;
  179. Adapter->BestEffortVc.IPPrecedenceNonConforming = Adapter->IPServiceTypeBestEffortNC;
  180. }
  181. else
  182. {
  183. PS_LOCK(&Adapter->Lock);
  184. NextVc = Adapter->WanLinkList.Flink;
  185. while( NextVc != &Adapter->WanLinkList)
  186. {
  187. WanLink = CONTAINING_RECORD(NextVc, PS_WAN_LINK, Linkage);
  188. PS_LOCK_DPC(&WanLink->Lock);
  189. WanLink->BestEffortVc.UserPriorityConforming = Adapter->UserServiceTypeBestEffort;
  190. WanLink->BestEffortVc.UserPriorityNonConforming = Adapter->UserServiceTypeNonConforming;
  191. WanLink->BestEffortVc.IPPrecedenceNonConforming =
  192. Adapter->IPServiceTypeBestEffortNC;
  193. if(WanLink->State == WanStateOpen)
  194. {
  195. REFADD(&WanLink->RefCount, 'IOTL');
  196. PS_UNLOCK_DPC(&WanLink->Lock);
  197. PS_UNLOCK(&Adapter->Lock);
  198. UpdateWanLinkBandwidthParameters(WanLink);
  199. PS_LOCK(&Adapter->Lock);
  200. NextVc = NextVc->Flink;
  201. REFDEL(&WanLink->RefCount, TRUE, 'IOTL');
  202. }
  203. else
  204. {
  205. PS_UNLOCK_DPC(&WanLink->Lock);
  206. NextVc = NextVc->Flink;
  207. }
  208. }
  209. PS_UNLOCK(&Adapter->Lock);
  210. }
  211. //
  212. // Apply the new TOS/802.1p mapping to the VCs.
  213. //
  214. PS_LOCK(&Adapter->Lock);
  215. NextVc = Adapter->GpcClientVcList.Flink;
  216. while ( NextVc != &Adapter->GpcClientVcList )
  217. {
  218. Vc = CONTAINING_RECORD(NextVc, GPC_CLIENT_VC, Linkage);
  219. NextVc = NextVc->Flink;
  220. PS_LOCK_DPC(&Vc->Lock);
  221. if(Vc->ClVcState == CL_CALL_COMPLETE ||
  222. Vc->ClVcState == CL_INTERNAL_CALL_COMPLETE )
  223. {
  224. SetTOSIEEEValues(Vc);
  225. }
  226. PS_UNLOCK_DPC(&Vc->Lock);
  227. }
  228. PS_UNLOCK(&Adapter->Lock);
  229. PS_LOCK(&AdapterListLock);
  230. NextAdapter = NextAdapter->Flink;
  231. REFDEL(&Adapter->RefCount, TRUE, 'IOTL');
  232. }
  233. PS_UNLOCK(&AdapterListLock);
  234. InterlockedExchange(&gZAWState, ZAW_STATE_READY);
  235. NdisSetEvent(&gZAWEvent);
  236. break;
  237. }
  238. case IOCTL_TIMESTMP_REGISTER_IN_PKT:
  239. {
  240. if(InputBufferLength < sizeof(TIMESTMP_REQ))
  241. {
  242. Status = STATUS_INVALID_PARAMETER;
  243. break;
  244. }
  245. pTsReq = (PTIMESTMP_REQ)pIoBuf;
  246. if( !AddRequest( pirpSp->FileObject,
  247. pTsReq->SrcIp,
  248. pTsReq->SrcPort,
  249. pTsReq->DstIp,
  250. pTsReq->DstPort,
  251. pTsReq->Proto,
  252. MARK_IN_PKT,
  253. pTsReq->Direction) )
  254. {
  255. Status = STATUS_INSUFFICIENT_RESOURCES;
  256. }
  257. break;
  258. }
  259. case IOCTL_TIMESTMP_DEREGISTER_IN_PKT:
  260. {
  261. if(InputBufferLength < sizeof(TIMESTMP_REQ))
  262. {
  263. Status = STATUS_INVALID_PARAMETER;
  264. break;
  265. }
  266. pTsReq = (PTIMESTMP_REQ)pIoBuf;
  267. RemoveRequest( pirpSp->FileObject,
  268. pTsReq->SrcIp,
  269. pTsReq->SrcPort,
  270. pTsReq->DstIp,
  271. pTsReq->DstPort,
  272. pTsReq->Proto );
  273. break;
  274. }
  275. case IOCTL_TIMESTMP_REGISTER_IN_BUF:
  276. {
  277. if(InputBufferLength < sizeof(TIMESTMP_REQ))
  278. {
  279. Status = STATUS_INVALID_PARAMETER;
  280. break;
  281. }
  282. pTsReq = (PTIMESTMP_REQ)pIoBuf;
  283. if( !AddRequest( pirpSp->FileObject,
  284. pTsReq->SrcIp,
  285. pTsReq->SrcPort,
  286. pTsReq->DstIp,
  287. pTsReq->DstPort,
  288. pTsReq->Proto,
  289. MARK_IN_BUF,
  290. pTsReq->Direction))
  291. {
  292. Status = STATUS_INSUFFICIENT_RESOURCES;
  293. }
  294. break;
  295. }
  296. case IOCTL_TIMESTMP_DEREGISTER_IN_BUF:
  297. {
  298. if(InputBufferLength < sizeof(TIMESTMP_REQ))
  299. {
  300. Status = STATUS_INVALID_PARAMETER;
  301. break;
  302. }
  303. pTsReq = (PTIMESTMP_REQ)pIoBuf;
  304. RemoveRequest( pirpSp->FileObject,
  305. pTsReq->SrcIp,
  306. pTsReq->SrcPort,
  307. pTsReq->DstIp,
  308. pTsReq->DstPort,
  309. pTsReq->Proto );
  310. break;
  311. }
  312. case IOCTL_TIMESTMP_FINISH_BUFFERING:
  313. {
  314. pirp->IoStatus.Information = CopyTimeStmps( pirpSp->FileObject, pIoBuf, OutputBufferLength);
  315. break;
  316. }
  317. break;
  318. }
  319. break;
  320. case IRP_MJ_CREATE:
  321. break;
  322. case IRP_MJ_CLOSE:
  323. RemoveRequest( pirpSp->FileObject,
  324. UL_ANY,
  325. US_ANY,
  326. UL_ANY,
  327. US_ANY,
  328. US_ANY);
  329. break;
  330. case IRP_MJ_CLEANUP:
  331. break;
  332. case IRP_MJ_READ:
  333. break;
  334. case IRP_MJ_SHUTDOWN:
  335. break;
  336. default:
  337. Status = STATUS_NOT_SUPPORTED;
  338. break;
  339. }
  340. if( Status == STATUS_SUCCESS)
  341. {
  342. pirp->IoStatus.Status = Status;
  343. IoCompleteRequest(pirp, IO_NETWORK_INCREMENT);
  344. }
  345. else
  346. {
  347. pirp->IoStatus.Status = Status;
  348. IoCompleteRequest(pirp, IO_NO_INCREMENT);
  349. }
  350. PsAssert( OldIrql == KeGetCurrentIrql());
  351. return Status;
  352. }
  353. NDIS_STATUS
  354. PsIoctlInit()
  355. {
  356. int i;
  357. NDIS_STATUS Status;
  358. PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
  359. for(i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
  360. {
  361. DispatchTable[i] = PsIoctl;
  362. }
  363. DispatchTable[IRP_MJ_SYSTEM_CONTROL] = WMIDispatch;
  364. Status = NdisMRegisterDevice(MpWrapperHandle,
  365. &PsDriverName,
  366. &PsSymbolicName,
  367. DispatchTable,
  368. &PsDeviceObject,
  369. &PsDeviceHandle);
  370. if(Status == NDIS_STATUS_SUCCESS)
  371. {
  372. InitShutdownMask |= SHUTDOWN_DELETE_DEVICE;
  373. PsDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  374. IoWMIRegistrationControl(PsDeviceObject, WMIREG_ACTION_REGISTER);
  375. }
  376. else
  377. {
  378. PsDeviceHandle = PsDeviceObject = 0;
  379. }
  380. return Status;
  381. }
  382. VOID
  383. PsAddDevice()
  384. {
  385. //
  386. // The first Adapter will create the DeviceObject which will enable us to receive
  387. // irps and become a WMI data provider. The last DeviceObject will unregister from
  388. // WMI and delete the DeviceObject.
  389. //
  390. MUX_ACQUIRE_MUTEX( &CreateDeviceMutex );
  391. ++AdapterCount;
  392. if(AdapterCount == 1)
  393. {
  394. //
  395. // This is the first adapter, so we create a DeviceObject
  396. // that allows us to get irps and registers as a WMI data
  397. // provider.
  398. PsIoctlInit();
  399. }
  400. MUX_RELEASE_MUTEX( &CreateDeviceMutex);
  401. }
  402. NDIS_STATUS
  403. PsInitializeDeviceInstance(PADAPTER Adapter)
  404. {
  405. NDIS_STATUS Status;
  406. PsAssert(KeGetCurrentIrql() < DISPATCH_LEVEL);
  407. PsDbgOut(DBG_INFO,
  408. DBG_PROTOCOL,
  409. ("[PSInitializeDeviceInstance]: Adapter %08X, InitializeDeviceInstance with %ws \n",
  410. Adapter,
  411. Adapter->UpperBinding.Buffer));
  412. Status = NdisIMInitializeDeviceInstanceEx(LmDriverHandle,
  413. &Adapter->UpperBinding,
  414. Adapter);
  415. if (Status != NDIS_STATUS_SUCCESS)
  416. {
  417. PsDbgOut(DBG_FAILURE,
  418. DBG_PROTOCOL,
  419. ("[PsInitializeDeviceInstance]: Adapter %08X, can't init PS device (%08X)\n",
  420. Adapter,
  421. Status));
  422. PsAdapterWriteEventLog(
  423. EVENT_PS_INIT_DEVICE_FAILED,
  424. 0,
  425. &Adapter->MpDeviceName,
  426. sizeof(Status),
  427. &Status);
  428. }
  429. return Status;
  430. }
  431. VOID
  432. PsDeleteDevice()
  433. {
  434. //
  435. // The first Adapter will create the DeviceObject which will enable us to receive
  436. // irps and become a WMI data provider. The last DeviceObject will unregister from
  437. // WMI and delete the DeviceObject. In order to prevent a race condition we prevent
  438. // any mpinitialize threads from looking at the AdapterCount. This is achieved by
  439. // re-setting the WMIAddEvent. It is not sufficient just to do this based on
  440. // interlocked operations on AdapterCount.
  441. //
  442. MUX_ACQUIRE_MUTEX( &CreateDeviceMutex );
  443. --AdapterCount;
  444. if(AdapterCount == 0)
  445. {
  446. //
  447. // Delete the DeviceObject, since this is the last Adapter.
  448. //
  449. if(PsDeviceObject)
  450. {
  451. IoWMIRegistrationControl(PsDeviceObject, WMIREG_ACTION_DEREGISTER);
  452. NdisMDeregisterDevice(PsDeviceHandle);
  453. PsDeviceHandle = PsDeviceObject = 0;
  454. }
  455. }
  456. MUX_RELEASE_MUTEX( &CreateDeviceMutex);
  457. }
  458. // No of retries to query the frame size
  459. #define MAX_GET_FRAME_SIZE_RETRY_COUNT 3
  460. #define WAIT_TIME_FOR_GET_FRAME_SIZE 3
  461. VOID
  462. ClBindToLowerMp(
  463. OUT PNDIS_STATUS Status,
  464. IN NDIS_HANDLE BindContext,
  465. IN PNDIS_STRING MpDeviceName,
  466. IN PVOID SystemSpecific1,
  467. IN PVOID SystemSpecific2
  468. )
  469. /*++
  470. Routine Description:
  471. Bind to the underlying MP. Allocate space for an adapter structure,
  472. initializing its fields. Try to open the adapter indicated in MpDeviceName.
  473. Arguments:
  474. Status : Placeholder for the driver to return a Status to NDIS.
  475. BindContext : Handle represents NDIS's context for the bind request.
  476. This has to be saved and returned when we call
  477. NdisCompleteBindAdapter
  478. SystemSpecific1 : Points to a registy path for the driver to obtain adapter
  479. specific configuration.
  480. MpDeviceName : DeviceName can refer to a NIC managed by an underlying NIC
  481. driver, or it can be the name of a virtual NIC exported by
  482. an intermediate NDIS driver that is layered between the
  483. called intermediate driver and the NIC driver managing the
  484. adapter to which transmit requests are directed.
  485. SystemSpecific2 : Unused, reserved for future use.
  486. Return Values:
  487. None
  488. --*/
  489. {
  490. PADAPTER Adapter;
  491. NDIS_STATUS OpenAdapterStatus;
  492. NDIS_STATUS OpenErrorStatus;
  493. NDIS_STATUS LocalStatus;
  494. UINT MediaIndex;
  495. NDIS_MEDIUM MediumArray[] = {
  496. NdisMediumFddi,
  497. NdisMedium802_5,
  498. NdisMedium802_3,
  499. NdisMediumWan
  500. };
  501. UINT MediumArraySize = sizeof(MediumArray)/sizeof(NDIS_MEDIUM);
  502. UINT GetFrameSizeRetryCount = 0;
  503. PsDbgOut(DBG_INFO,
  504. DBG_PROTOCOL | DBG_INIT,
  505. ("[ClBindToLowerMp]: MpDeviceName %ws\n", MpDeviceName->Buffer));
  506. PS_LOCK(&DriverUnloadLock);
  507. //
  508. // (a) The driver can get unloaded before we complete the bind thread.
  509. // (b) we can get bound as the driver is getting unloaded.
  510. //
  511. // if (a) happens, we block the driver unload and unblock when we finish the bind.
  512. // if (b) happens, we fail the bind call.
  513. if(gDriverState != DriverStateLoaded) {
  514. *Status = NDIS_STATUS_FAILURE;
  515. PS_UNLOCK(&DriverUnloadLock);
  516. PsDbgOut(DBG_FAILURE, DBG_PROTOCOL|DBG_INIT,
  517. ("[ClBindToLowerMp]: Driver is being unloaded \n"));
  518. return;
  519. }
  520. DRIVER_COUNTED_BLOCK;
  521. PS_UNLOCK(&DriverUnloadLock);
  522. //
  523. // Get a new adapter context struct and initialize it with configuration
  524. // data from the registry.
  525. //
  526. PsAllocatePool(Adapter, sizeof(ADAPTER), AdapterTag);
  527. if(Adapter == NULL) {
  528. PsAdapterWriteEventLog(
  529. (ULONG)EVENT_PS_RESOURCE_POOL,
  530. 0,
  531. MpDeviceName,
  532. 0,
  533. NULL);
  534. *Status = NDIS_STATUS_RESOURCES;
  535. DRIVER_COUNTED_UNBLOCK;
  536. return;
  537. }
  538. //
  539. // Initialize the adapter.
  540. //
  541. *Status = InitializeAdapter(Adapter, BindContext, MpDeviceName, SystemSpecific1);
  542. Adapter->ShutdownMask |= SHUTDOWN_BIND_CALLED;
  543. if(*Status != NDIS_STATUS_SUCCESS) {
  544. PsDeleteDevice();
  545. REFDEL(&Adapter->RefCount, FALSE, 'NDOP');
  546. DRIVER_COUNTED_UNBLOCK;
  547. return;
  548. }
  549. NdisOpenAdapter(&OpenAdapterStatus,
  550. &OpenErrorStatus,
  551. &Adapter->LowerMpHandle,
  552. &MediaIndex,
  553. MediumArray,
  554. MediumArraySize,
  555. ClientProtocolHandle,
  556. Adapter,
  557. MpDeviceName,
  558. 0,
  559. NULL);
  560. if(OpenAdapterStatus == NDIS_STATUS_PENDING)
  561. {
  562. NdisWaitEvent(&Adapter->BlockingEvent, 0);
  563. NdisResetEvent(&Adapter->BlockingEvent);
  564. }
  565. else
  566. {
  567. Adapter->FinalStatus = OpenAdapterStatus;
  568. }
  569. if(Adapter->FinalStatus == NDIS_STATUS_SUCCESS)
  570. {
  571. Adapter->MediaType = MediumArray[MediaIndex];
  572. //
  573. // Take a ref for the open
  574. //
  575. REFADD(&Adapter->RefCount, 'NDOP');
  576. }
  577. else
  578. {
  579. PsDbgOut(DBG_FAILURE,
  580. DBG_PROTOCOL,
  581. ("[ClBindToLowerMp]: Adapter %08X, binding failed (Status = %08X) \n",
  582. Adapter,
  583. Status));
  584. *Status = Adapter->FinalStatus;
  585. PsAdapterWriteEventLog(
  586. EVENT_PS_BINDING_FAILED,
  587. 0,
  588. &Adapter->MpDeviceName,
  589. sizeof(Adapter->FinalStatus),
  590. &Adapter->FinalStatus);
  591. PsDeleteDevice();
  592. REFDEL(&Adapter->RefCount, FALSE, 'NDOP');
  593. DRIVER_COUNTED_UNBLOCK;
  594. return;
  595. }
  596. //
  597. // Get the information pertaining to the miniport below us.
  598. //
  599. while(1)
  600. {
  601. *Status = GetFrameSize(Adapter);
  602. if(*Status != NDIS_STATUS_SUCCESS)
  603. {
  604. if( GetFrameSizeRetryCount == MAX_GET_FRAME_SIZE_RETRY_COUNT)
  605. {
  606. goto ErrorCloseOpen;
  607. }
  608. else
  609. {
  610. GetFrameSizeRetryCount++;
  611. DbgPrint("PSCHED: Requery FRAME_SIZE #%d\n",GetFrameSizeRetryCount);
  612. NdisMSleep( WAIT_TIME_FOR_GET_FRAME_SIZE * 1000 * 1000);
  613. }
  614. }
  615. else
  616. {
  617. break;
  618. }
  619. }
  620. Adapter->RawLinkSpeed = (ULONG)UNSPECIFIED_RATE;
  621. *Status = UpdateAdapterBandwidthParameters(Adapter);
  622. if(*Status != NDIS_STATUS_SUCCESS)
  623. {
  624. if(*Status != NDIS_STATUS_ADAPTER_NOT_READY)
  625. {
  626. PsDbgOut(DBG_FAILURE,
  627. DBG_PROTOCOL |
  628. DBG_INIT,
  629. ("[ClBindToLowerMp]: Adapter %08X, couldn't add pipe %08X\n",
  630. Adapter,
  631. Status));
  632. goto ErrorCloseOpen;
  633. }
  634. else
  635. {
  636. // The scheduling components have not registered. Let's not call NdisIMInitializeDeviceInstance.
  637. //
  638. *Status = NDIS_STATUS_SUCCESS;
  639. Adapter->PsMpState = AdapterStateWaiting;
  640. }
  641. }
  642. // Let's move the creation of IM device here, to see what happens.
  643. *Status = PsInitializeDeviceInstance(Adapter);
  644. if(*Status != NDIS_STATUS_SUCCESS)
  645. {
  646. goto ErrorCloseOpen;
  647. }
  648. // Ignore the status
  649. PsReadMiniportOIDs(Adapter);
  650. PsUpdateLinkSpeed(Adapter, Adapter->RawLinkSpeed,
  651. &Adapter->RemainingBandWidth,
  652. &Adapter->LinkSpeed,
  653. &Adapter->NonBestEffortLimit,
  654. &Adapter->Lock);
  655. // This will repro the NetReady bug anywhere, anytime.
  656. // NdisMSleep( 5 * 1000 * 1000 );
  657. REFDEL(&Adapter->RefCount, FALSE, 'NDOP');
  658. DRIVER_COUNTED_UNBLOCK;
  659. return;
  660. ErrorCloseOpen:
  661. //
  662. // if we have opened an underlying call manager, close it now.
  663. //
  664. if(Adapter->MediaType == NdisMediumWan) {
  665. PS_LOCK(&Adapter->Lock);
  666. if(Adapter->ShutdownMask & SHUTDOWN_CLOSE_WAN_ADDR_FAMILY){
  667. Adapter->ShutdownMask &= ~SHUTDOWN_CLOSE_WAN_ADDR_FAMILY;
  668. PS_UNLOCK(&Adapter->Lock);
  669. PsDbgOut(DBG_TRACE, DBG_WAN | DBG_MINIPORT,
  670. ("[ClBindToLowerMp]: Adapter %08X Closing the WAN address family", Adapter));
  671. LocalStatus = NdisClCloseAddressFamily(Adapter->WanCmHandle);
  672. }
  673. else
  674. {
  675. PS_UNLOCK(&Adapter->Lock);
  676. }
  677. }
  678. //
  679. // Close the open since we opened it above
  680. //
  681. if(Adapter->LowerMpHandle)
  682. {
  683. NdisCloseAdapter(&LocalStatus, Adapter->LowerMpHandle);
  684. if(LocalStatus == NDIS_STATUS_PENDING)
  685. {
  686. NdisWaitEvent(&Adapter->BlockingEvent, 0);
  687. NdisResetEvent(&Adapter->BlockingEvent);
  688. }
  689. REFDEL(&Adapter->RefCount, FALSE, 'NDOP');
  690. }
  691. PsDeleteDevice();
  692. REFDEL(&Adapter->RefCount, FALSE, 'NDOP');
  693. DRIVER_COUNTED_UNBLOCK;
  694. return;
  695. } // ClBindToLowerMp
  696. VOID
  697. LinkSpeedQueryComplete(
  698. PADAPTER Adapter,
  699. NDIS_STATUS Status
  700. )
  701. /*++
  702. Routine Description:
  703. Completion routine for link speed query during a status indication. Notify
  704. the scheduling alg. that we have a new adapter
  705. Arguments:
  706. the usual...
  707. Return Value:
  708. None
  709. --*/
  710. {
  711. PsDbgOut(DBG_INFO,
  712. DBG_PROTOCOL,
  713. ("[LinkSpeedQueryComplete]: Adapter %08X, Status %x, Link speed %d\n",
  714. Adapter, Status,
  715. Adapter->LinkSpeed*100));
  716. if ( !NT_SUCCESS( Status ))
  717. {
  718. Adapter->RawLinkSpeed = (ULONG)UNSPECIFIED_RATE;
  719. PsAdapterWriteEventLog(
  720. EVENT_PS_QUERY_OID_GEN_LINK_SPEED,
  721. 0,
  722. &Adapter->MpDeviceName,
  723. sizeof(Status),
  724. &Status);
  725. }
  726. UpdateAdapterBandwidthParameters(Adapter);
  727. }
  728. VOID
  729. PsGetLinkSpeed (
  730. IN PADAPTER Adapter
  731. )
  732. {
  733. NDIS_STATUS Status;
  734. Status = MakeLocalNdisRequest(Adapter,
  735. NULL,
  736. NdisRequestLocalQueryInfo,
  737. OID_GEN_LINK_SPEED,
  738. &Adapter->RawLinkSpeed,
  739. sizeof(Adapter->RawLinkSpeed),
  740. LinkSpeedQueryComplete);
  741. if (Status != NDIS_STATUS_PENDING)
  742. {
  743. LinkSpeedQueryComplete(Adapter, Status);
  744. }
  745. }
  746. NDIS_STATUS
  747. PsReadMiniportOIDs(
  748. IN PADAPTER Adapter
  749. )
  750. /*++
  751. Routine Description:
  752. Complete the binding on the lower miniport. Initialize the
  753. adapter structure, query the MP for certain funtionality and
  754. initialize the associated PS miniport device
  755. Arguments:
  756. see the DDK
  757. Return Values:
  758. None
  759. --*/
  760. {
  761. NDIS_STATUS Status;
  762. PWSTR SecondaryName;
  763. NDIS_HARDWARE_STATUS HwStatus;
  764. NDIS_MEDIA_STATE MediaState = 0xFFFFFFFF;
  765. NDIS_STRING PsDevName;
  766. ULONG MacOptions;
  767. ULONG LinkSpeed;
  768. PsDbgOut(DBG_TRACE,
  769. DBG_PROTOCOL,
  770. ("[PsReadMiniportOIDs]: Adapter %08X \n", Adapter));
  771. Status = MakeLocalNdisRequest(Adapter,
  772. NULL,
  773. NdisRequestLocalQueryInfo,
  774. OID_GEN_MEDIA_CONNECT_STATUS,
  775. &MediaState,
  776. sizeof( MediaState ),
  777. NULL);
  778. PsAssert(Status != NDIS_STATUS_INVALID_OID || Status != NDIS_STATUS_NOT_SUPPORTED);
  779. if(Status == NDIS_STATUS_SUCCESS && MediaState == NdisMediaStateConnected){
  780. Status = MakeLocalNdisRequest(Adapter,
  781. NULL,
  782. NdisRequestLocalQueryInfo,
  783. OID_GEN_LINK_SPEED,
  784. &Adapter->RawLinkSpeed,
  785. sizeof(LinkSpeed),
  786. NULL);
  787. if(Status != NDIS_STATUS_SUCCESS){
  788. PsDbgOut(DBG_INFO,
  789. DBG_PROTOCOL,
  790. ("[PsReadMiniportOIDs]: Adapter %08X, Can't get link "
  791. "speed - Status %08X\n", Adapter, Status));
  792. Adapter->RawLinkSpeed = (ULONG)UNSPECIFIED_RATE;
  793. PsAdapterWriteEventLog(
  794. EVENT_PS_QUERY_OID_GEN_LINK_SPEED,
  795. 0,
  796. &Adapter->MpDeviceName,
  797. sizeof(Status),
  798. &Status);
  799. }
  800. PsDbgOut(DBG_INFO,
  801. DBG_PROTOCOL,
  802. ("[PsReadMiniportOIDs] Adapter %08X, Link speed %d\n",
  803. Adapter,
  804. Adapter->RawLinkSpeed*100));
  805. }
  806. else{
  807. //
  808. // We can continue, even though we don't yet have the
  809. // link speed. We'll update it later.
  810. //
  811. Adapter->RawLinkSpeed = (ULONG)UNSPECIFIED_RATE;
  812. PsDbgOut(DBG_INFO,
  813. DBG_PROTOCOL,
  814. ("[PsReadMiniportOIDs]: Adapter %08X, Media not connected\n",
  815. Adapter));
  816. }
  817. return Status;
  818. } // PsReadMiniportOIDs
  819. VOID
  820. PsUpdateLinkSpeed(
  821. PADAPTER Adapter,
  822. ULONG RawLinkSpeed,
  823. PULONG RemainingBandWidth,
  824. PULONG LinkSpeed,
  825. PULONG NonBestEffortLimit,
  826. PPS_SPIN_LOCK Lock
  827. )
  828. {
  829. ULONG NewNonBestEffortLimit;
  830. PS_LOCK(Lock);
  831. if(RawLinkSpeed == UNSPECIFIED_RATE)
  832. {
  833. //
  834. // It is legit to have an unspecified rate - We pend
  835. // all finite rate flows till we know the link speed.
  836. // Indefinite rate flows will be admitted.
  837. //
  838. *LinkSpeed = UNSPECIFIED_RATE;
  839. Adapter->PipeHasResources = FALSE;
  840. }
  841. else
  842. {
  843. //
  844. // RawLinkSpeed is in 100 bps units. Convert it to 100 Bytes per second
  845. // and then into Bytes Per Second.
  846. //
  847. *LinkSpeed = RawLinkSpeed / 8;
  848. *LinkSpeed = (ULONG)(*LinkSpeed * 100);
  849. PsDbgOut(DBG_TRACE, DBG_PROTOCOL,
  850. ("[PsUpdateLinkSpeed]: Adapter %08X, Link Speed %d \n",
  851. Adapter, *LinkSpeed));
  852. Adapter->PipeHasResources = TRUE;
  853. //
  854. // The NBE is a % of the link speed. If the link speed changes, we need to
  855. // change this value.
  856. //
  857. NewNonBestEffortLimit = Adapter->ReservationLimitValue * (*LinkSpeed / 100);
  858. PsDbgOut(DBG_INFO, DBG_PROTOCOL,
  859. ("[PsUpdateLinkSpeed]: Adapter %08X, LinkSpeed %d, NBE %d, "
  860. " Remaining b/w = %d, New NBE = %d \n",
  861. Adapter, *LinkSpeed, *NonBestEffortLimit,
  862. *RemainingBandWidth, NewNonBestEffortLimit));
  863. if(NewNonBestEffortLimit >= *NonBestEffortLimit) {
  864. //
  865. // The bandwidth has increased - we need not do anything with
  866. // the flows that have already been created. Also, if RemainingBandWidth <
  867. // NonBestEffortLimit, then some of the resources have been allocated to flows
  868. // that were already created - We need to subtract this from the new
  869. // RemainingBandWidth.
  870. //
  871. *RemainingBandWidth = NewNonBestEffortLimit - (*NonBestEffortLimit - *RemainingBandWidth);
  872. *NonBestEffortLimit = NewNonBestEffortLimit;
  873. }
  874. else {
  875. //
  876. // Sigh. The bandwidth has decreased. We may need to delete some of the flows
  877. //
  878. if(*RemainingBandWidth == *NonBestEffortLimit)
  879. {
  880. //
  881. // No flows were created as yet - Just update the 2 values
  882. //
  883. *NonBestEffortLimit = *RemainingBandWidth = NewNonBestEffortLimit;
  884. }
  885. else {
  886. if((*NonBestEffortLimit - *RemainingBandWidth) <= (NewNonBestEffortLimit)) {
  887. //
  888. // The flows that were created are under the new limit.
  889. //
  890. *RemainingBandWidth = NewNonBestEffortLimit - (*NonBestEffortLimit - *RemainingBandWidth);
  891. *NonBestEffortLimit = NewNonBestEffortLimit;
  892. }
  893. else
  894. {
  895. *RemainingBandWidth = NewNonBestEffortLimit - (*NonBestEffortLimit - *RemainingBandWidth);
  896. *NonBestEffortLimit = NewNonBestEffortLimit;
  897. PsAdapterWriteEventLog(
  898. EVENT_PS_ADMISSIONCONTROL_OVERFLOW,
  899. 0,
  900. &Adapter->MpDeviceName,
  901. 0,
  902. NULL);
  903. }
  904. }
  905. }
  906. }
  907. PS_UNLOCK(Lock);
  908. }
  909. NDIS_STATUS
  910. UpdateAdapterBandwidthParameters(
  911. PADAPTER Adapter
  912. )
  913. {
  914. PsUpdateLinkSpeed(Adapter, Adapter->RawLinkSpeed,
  915. &Adapter->RemainingBandWidth,
  916. &Adapter->LinkSpeed,
  917. &Adapter->NonBestEffortLimit,
  918. &Adapter->Lock);
  919. return UpdateSchedulingPipe(Adapter);
  920. }
  921. VOID
  922. ClLowerMpOpenAdapterComplete(
  923. IN PADAPTER Adapter,
  924. IN NDIS_STATUS Status,
  925. IN NDIS_STATUS OpenErrorStatus
  926. )
  927. /*++
  928. Routine Description:
  929. Signal that the binding on the lower miniport is complete
  930. Arguments:
  931. see the DDK
  932. Return Values:
  933. None
  934. --*/
  935. {
  936. PsDbgOut(DBG_TRACE, DBG_PROTOCOL, ("[ClLowerMpOpenAdapterComplete]: Adapter %08X\n",
  937. Adapter));
  938. //
  939. // stuff the final status in the Adapter block and signal
  940. // the bind handler to continue
  941. //
  942. Adapter->FinalStatus = Status;
  943. NdisSetEvent( &Adapter->BlockingEvent );
  944. } // ClLowerMpOpenAdapterComplete
  945. NDIS_STATUS
  946. GetFrameSize(
  947. PADAPTER Adapter
  948. )
  949. /*++
  950. Routine Description:
  951. This routine queries the underlying adapter to derive the total
  952. frame size and the header size. (Total = Frame + Header)
  953. Arguments:
  954. Adapter - pointer to adapter context block
  955. Return Value:
  956. None
  957. --*/
  958. {
  959. NDIS_STATUS Status;
  960. ULONG i;
  961. ULONG FrameSize; // doesn't include the header
  962. //
  963. // max amount of data w/o the MAC header
  964. //
  965. Status = MakeLocalNdisRequest(Adapter,
  966. NULL,
  967. NdisRequestLocalQueryInfo,
  968. OID_GEN_MAXIMUM_FRAME_SIZE,
  969. &FrameSize,
  970. sizeof(FrameSize),
  971. NULL);
  972. if(Status != NDIS_STATUS_SUCCESS){
  973. PsDbgOut(DBG_FAILURE,
  974. DBG_PROTOCOL,
  975. ("[GetFrameSize]: Adapter %08X, Can't get frame size - Status %08X\n",
  976. Adapter,
  977. Status));
  978. PsAdapterWriteEventLog(
  979. EVENT_PS_QUERY_OID_GEN_MAXIMUM_FRAME_SIZE,
  980. 0,
  981. &Adapter->MpDeviceName,
  982. sizeof(Status),
  983. &Status);
  984. return Status;
  985. }
  986. //
  987. // this one includes the header
  988. //
  989. Status = MakeLocalNdisRequest(Adapter,
  990. NULL,
  991. NdisRequestLocalQueryInfo,
  992. OID_GEN_MAXIMUM_TOTAL_SIZE,
  993. &Adapter->TotalSize,
  994. sizeof(Adapter->TotalSize),
  995. NULL);
  996. if(Status != NDIS_STATUS_SUCCESS){
  997. PsDbgOut(DBG_FAILURE,
  998. DBG_PROTOCOL,
  999. ("(%08X) GetFrameSize: Can't get total size - Status %08X\n",
  1000. Adapter,
  1001. Status));
  1002. PsAdapterWriteEventLog(
  1003. EVENT_PS_QUERY_OID_GEN_MAXIMUM_TOTAL_SIZE,
  1004. 0,
  1005. &Adapter->MpDeviceName,
  1006. sizeof(Status),
  1007. &Status);
  1008. return Status;
  1009. }
  1010. //
  1011. // figure the real header size
  1012. //
  1013. Adapter->HeaderSize = Adapter->TotalSize - FrameSize;
  1014. return Status;
  1015. } // GetFrameSize
  1016. NDIS_STATUS
  1017. GetSchedulerPipeContext(
  1018. PADAPTER Adapter,
  1019. PPS_PIPE_CONTEXT *AdapterPipeContext,
  1020. PPSI_INFO *AdapterPsComponent,
  1021. PULONG ShutdownMask
  1022. )
  1023. /*++
  1024. Routine Description:
  1025. Allocate the pipe context area for the scheduler.
  1026. Arguments:
  1027. Adapter - pointer to adapter context struct
  1028. Return Value:
  1029. NDIS_STATUS_SUCCESS, otherwise appropriate error value
  1030. --*/
  1031. {
  1032. ULONG Index = 0;
  1033. PPS_PROFILE ProfileConfig;
  1034. PPSI_INFO PsComponent;
  1035. ULONG ContextLength = 0;
  1036. ULONG FlowContextLength = 0;
  1037. ULONG ClassMapContextLength = 0;
  1038. PPS_PIPE_CONTEXT PipeContext, PrevContext;
  1039. ULONG PacketReservedLength = sizeof(PS_SEND_PACKET_CONTEXT);
  1040. PVOID PipeCxt;
  1041. //
  1042. // If there is no profile defined for this adapter, use defaults.
  1043. //
  1044. if(FindProfile(&Adapter->ProfileName, &ProfileConfig) == NDIS_STATUS_SUCCESS)
  1045. {
  1046. PsDbgOut(DBG_TRACE,
  1047. DBG_PROTOCOL,
  1048. ("[GetSchedulerPipeContext]: Using %ws profile for adapter "
  1049. " 0x%x \n", Adapter->ProfileName.Buffer, Adapter));
  1050. //
  1051. // Need to lock here as there could be a race
  1052. // condition between the RegisterPsComponent
  1053. // Note, however there is no race condition if all
  1054. // components have registered, so we can release the lock.
  1055. //
  1056. PS_LOCK(&PsProfileLock);
  1057. if(ProfileConfig->UnregisteredAddInCnt != 0)
  1058. {
  1059. PS_UNLOCK(&PsProfileLock);
  1060. PsDbgOut(DBG_TRACE, DBG_PROTOCOL,
  1061. ("[GetSchedulerPipeContext]: Adapter 0x%x is not ready\n",
  1062. Adapter));
  1063. return NDIS_STATUS_ADAPTER_NOT_READY;
  1064. }
  1065. PS_UNLOCK(&PsProfileLock);
  1066. }
  1067. else
  1068. {
  1069. PsDbgOut(DBG_TRACE,
  1070. DBG_PROTOCOL,
  1071. ("[GetSchedulerPipeContext]: Profile not supplied / not found"
  1072. " using default for adapter 0x%x \n", Adapter));
  1073. ProfileConfig = &DefaultSchedulerConfig;
  1074. }
  1075. for (Index = 0; Index < ProfileConfig->ComponentCnt; Index++)
  1076. {
  1077. ContextLength +=
  1078. ProfileConfig->ComponentList[Index]->PipeContextLength;
  1079. FlowContextLength +=
  1080. ProfileConfig->ComponentList[Index]->FlowContextLength;
  1081. ClassMapContextLength +=
  1082. ProfileConfig->ComponentList[Index]->ClassMapContextLength;
  1083. PacketReservedLength += ProfileConfig->ComponentList[Index]->PacketReservedLength;
  1084. }
  1085. Adapter->FlowContextLength = FlowContextLength;
  1086. Adapter->ClassMapContextLength = ClassMapContextLength;
  1087. Adapter->PacketContextLength = PacketReservedLength;
  1088. if(AdapterPipeContext)
  1089. {
  1090. PacketReservedLength = sizeof(PS_SEND_PACKET_CONTEXT);
  1091. PsAllocatePool( PipeContext, ContextLength, PipeContextTag );
  1092. *AdapterPipeContext = PipeContext;
  1093. if ( *AdapterPipeContext == NULL ) {
  1094. return NDIS_STATUS_RESOURCES;
  1095. }
  1096. *ShutdownMask |= SHUTDOWN_FREE_PS_CONTEXT;
  1097. // Set up the context buffer
  1098. PrevContext = NULL;
  1099. for (Index = 0; Index < ProfileConfig->ComponentCnt; Index++)
  1100. {
  1101. PsComponent = ProfileConfig->ComponentList[Index];
  1102. PipeContext->NextComponentContext = (PPS_PIPE_CONTEXT)
  1103. ((UINT_PTR)PipeContext + PsComponent->PipeContextLength);
  1104. PipeContext->PrevComponentContext = PrevContext;
  1105. if(Index+1 == ProfileConfig->ComponentCnt)
  1106. {
  1107. PipeContext->NextComponent = 0;
  1108. }
  1109. else
  1110. {
  1111. PipeContext->NextComponent =
  1112. ProfileConfig->ComponentList[Index + 1];
  1113. }
  1114. if (PsComponent->PacketReservedLength > 0)
  1115. {
  1116. PipeContext->PacketReservedOffset = PacketReservedLength;
  1117. PacketReservedLength +=
  1118. PsComponent->PacketReservedLength;
  1119. } else
  1120. {
  1121. PipeContext->PacketReservedOffset = 0;
  1122. }
  1123. PrevContext = PipeContext;
  1124. PipeContext = PipeContext->NextComponentContext;
  1125. }
  1126. *AdapterPsComponent = ProfileConfig->ComponentList[0];
  1127. }
  1128. return NDIS_STATUS_SUCCESS;
  1129. } // GetSchedulerPipeContext
  1130. NDIS_STATUS
  1131. UpdateWanSchedulingPipe(PPS_WAN_LINK WanLink)
  1132. {
  1133. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1134. PS_PIPE_PARAMETERS PipeParameters;
  1135. PADAPTER Adapter = WanLink->Adapter;
  1136. //
  1137. // Initialize pipe parameters.
  1138. // UNSPECIFIED_RATE indicates that the link speed is currently
  1139. // unknown. This is a legitimate initialization value.
  1140. //
  1141. PS_LOCK(&Adapter->Lock);
  1142. PS_LOCK_DPC(&WanLink->Lock);
  1143. PipeParameters.Bandwidth = WanLink->LinkSpeed;
  1144. PipeParameters.MTUSize = Adapter->TotalSize;
  1145. PipeParameters.HeaderSize = Adapter->HeaderSize;
  1146. PipeParameters.Flags = Adapter->PipeFlags;
  1147. PipeParameters.MaxOutstandingSends = Adapter->MaxOutstandingSends;
  1148. PipeParameters.SDModeControlledLoad = Adapter->SDModeControlledLoad;
  1149. PipeParameters.SDModeGuaranteed = Adapter->SDModeGuaranteed;
  1150. PipeParameters.SDModeNetworkControl = Adapter->SDModeNetworkControl;
  1151. PipeParameters.SDModeQualitative = Adapter->SDModeQualitative;
  1152. PipeParameters.RegistryPath = &Adapter->RegistryPath;
  1153. PS_UNLOCK_DPC(&WanLink->Lock);
  1154. PS_UNLOCK(&Adapter->Lock);
  1155. //
  1156. // Initialize the pipe for only the first time
  1157. //
  1158. if ( !(WanLink->ShutdownMask & SHUTDOWN_DELETE_PIPE )) {
  1159. //
  1160. // Allocate and initialize the context buffer for the scheduler.
  1161. //
  1162. Status = GetSchedulerPipeContext( Adapter,
  1163. &WanLink->PsPipeContext,
  1164. &WanLink->PsComponent,
  1165. &WanLink->ShutdownMask );
  1166. if ( !NT_SUCCESS( Status ))
  1167. {
  1168. return Status;
  1169. }
  1170. WanLink->BestEffortVc.PsPipeContext = WanLink->PsPipeContext;
  1171. WanLink->BestEffortVc.PsComponent = WanLink->PsComponent;
  1172. // Need to set the pipe's media type here.. //
  1173. PipeParameters.MediaType = NdisMediumWan;
  1174. Status = (*WanLink->PsComponent->InitializePipe)(
  1175. Adapter,
  1176. &PipeParameters,
  1177. WanLink->PsPipeContext,
  1178. &PsProcs,
  1179. NULL);
  1180. if (NT_SUCCESS(Status))
  1181. {
  1182. WanLink->ShutdownMask |= SHUTDOWN_DELETE_PIPE;
  1183. }
  1184. }
  1185. else{
  1186. // Pipe's already been initialized. This is a modify
  1187. Status = (*WanLink->PsComponent->ModifyPipe)(
  1188. WanLink->PsPipeContext,
  1189. &PipeParameters);
  1190. }
  1191. return Status;
  1192. }
  1193. NDIS_STATUS
  1194. UpdateSchedulingPipe(
  1195. PADAPTER Adapter
  1196. )
  1197. /*++
  1198. Routine Description:
  1199. Initialize a scheduling pipe on the adapter. Always called with a LOCK
  1200. held.
  1201. Arguments:
  1202. Adapter - pointer to adapter context struct
  1203. Return Value:
  1204. NDIS_STATUS_SUCCESS, otherwise appropriate error value
  1205. --*/
  1206. {
  1207. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1208. PS_PIPE_PARAMETERS PipeParameters;
  1209. //
  1210. // Initialize pipe parameters.
  1211. // UNSPECIFIED_RATE indicates that the link speed is currently
  1212. // unknown. This is a legitimate initialization value.
  1213. //
  1214. PS_LOCK(&Adapter->Lock);
  1215. PipeParameters.Bandwidth = Adapter->LinkSpeed;
  1216. PipeParameters.MTUSize = Adapter->TotalSize;
  1217. PipeParameters.HeaderSize = Adapter->HeaderSize;
  1218. PipeParameters.Flags = Adapter->PipeFlags;
  1219. PipeParameters.MaxOutstandingSends = Adapter->MaxOutstandingSends;
  1220. PipeParameters.SDModeControlledLoad = Adapter->SDModeControlledLoad;
  1221. PipeParameters.SDModeGuaranteed = Adapter->SDModeGuaranteed;
  1222. PipeParameters.SDModeNetworkControl = Adapter->SDModeNetworkControl;
  1223. PipeParameters.SDModeQualitative = Adapter->SDModeQualitative;
  1224. PipeParameters.RegistryPath = &Adapter->RegistryPath;
  1225. PS_UNLOCK(&Adapter->Lock);
  1226. //
  1227. // Initialize the pipe for only the first time
  1228. //
  1229. if ( !(Adapter->ShutdownMask & SHUTDOWN_DELETE_PIPE ))
  1230. {
  1231. //
  1232. // We don't run the scheduling components on the Adapter structure for NDISWAN.
  1233. // Each wanlink has its own set of scheduling components. But, we still need to compute the
  1234. // PacketPool Length and allocate the Packet Pool - Hence we have to call GetSchedulerPipeContext
  1235. //
  1236. if(Adapter->MediaType == NdisMediumWan)
  1237. {
  1238. //
  1239. // Allocate and initialize the context buffer for the scheduler.
  1240. //
  1241. Status = GetSchedulerPipeContext( Adapter,
  1242. NULL,
  1243. NULL,
  1244. NULL);
  1245. }
  1246. else
  1247. {
  1248. Status = GetSchedulerPipeContext( Adapter,
  1249. &Adapter->PsPipeContext,
  1250. &Adapter->PsComponent,
  1251. &Adapter->ShutdownMask);
  1252. }
  1253. if ( !NT_SUCCESS( Status ))
  1254. {
  1255. return Status;
  1256. }
  1257. if(Adapter->MediaType == NdisMediumWan)
  1258. {
  1259. Adapter->ShutdownMask |= SHUTDOWN_DELETE_PIPE;
  1260. PsAssert(!(Adapter->ShutdownMask & SHUTDOWN_FREE_PS_CONTEXT));
  1261. PsAssert(!Adapter->PsPipeContext);
  1262. PsAssert(!Adapter->PsComponent);
  1263. }
  1264. else
  1265. {
  1266. // Need to set the pipe's media type here.. //
  1267. PipeParameters.MediaType = Adapter->MediaType;
  1268. Status = (*Adapter->PsComponent->InitializePipe)(
  1269. Adapter,
  1270. &PipeParameters,
  1271. Adapter->PsPipeContext,
  1272. &PsProcs,
  1273. NULL);
  1274. if (NT_SUCCESS(Status)) {
  1275. Adapter->ShutdownMask |= SHUTDOWN_DELETE_PIPE;
  1276. }
  1277. else
  1278. {
  1279. return Status;
  1280. }
  1281. }
  1282. }
  1283. else
  1284. {
  1285. // Pipe's already been initialized. This is a modify
  1286. if(Adapter->MediaType != NdisMediumWan)
  1287. {
  1288. Status = (*Adapter->PsComponent->ModifyPipe)(
  1289. Adapter->PsPipeContext,
  1290. &PipeParameters);
  1291. }
  1292. }
  1293. return Status;
  1294. } // UpdateSchedulingPipe
  1295. NDIS_STATUS
  1296. MpInitialize(
  1297. OUT PNDIS_STATUS OpenErrorStatus,
  1298. OUT PUINT SelectedMediumIndex,
  1299. IN PNDIS_MEDIUM MediumArray,
  1300. IN UINT MediumArraySize,
  1301. IN NDIS_HANDLE MiniportAdapterHandle,
  1302. IN NDIS_HANDLE WrapperConfigurationContext
  1303. )
  1304. /*++
  1305. Routine Description:
  1306. Packet scheduler's device initialization routine. The list of media types is
  1307. checked to be sure it is one that we support. If so, match up the name of
  1308. the device being opened with one of the adapters to which we've bound.
  1309. Arguments:
  1310. See the DDK...
  1311. Return Values:
  1312. None
  1313. --*/
  1314. {
  1315. PADAPTER Adapter;
  1316. NDIS_STATUS Status;
  1317. BOOLEAN FakingIt = FALSE;
  1318. NDIS_STRING MpDeviceName;
  1319. //
  1320. // We're being called to initialize one of our miniport
  1321. // device instances. We triggered this by calling
  1322. // NdisIMInitializeDeviceInstance when we were asked to
  1323. // bind to the adapter below us. We provided a pointer
  1324. // to the ADAPTER struct corresponding to the actual
  1325. // adapter we opened. We can get that back now, with the
  1326. // following call.
  1327. //
  1328. Adapter = NdisIMGetDeviceContext(MiniportAdapterHandle);
  1329. PsStructAssert(Adapter);
  1330. PsDbgOut(DBG_TRACE, DBG_MINIPORT | DBG_INIT, ("[MpInitialize]: Adapter %08X \n", Adapter));
  1331. Adapter->ShutdownMask |= SHUTDOWN_MPINIT_CALLED;
  1332. //
  1333. // We assume that the faster packet APIs will be used, and initialize our per-packet pool. If we don't get a packet-stack,
  1334. // we'll initialize the NDIS packet pool and free the per-packet pool (since the NDIS packet pool will have space for a per-packet
  1335. // pool).
  1336. //
  1337. // We cannot know about the old or new packet stack API at bind time (because even if we did know our position in the packet stack, and
  1338. // initialized the old APIs, we could get a newly allocated packet from an IM above us which will have room for a packet stack).
  1339. //
  1340. Adapter->SendBlockPool = NdisCreateBlockPool((USHORT)Adapter->PacketContextLength,
  1341. FIELD_OFFSET(PS_SEND_PACKET_CONTEXT, FreeList),
  1342. NDIS_PACKET_POOL_TAG_FOR_PSCHED,
  1343. NULL);
  1344. if(!Adapter->SendBlockPool)
  1345. {
  1346. PsDbgOut(DBG_CRITICAL_ERROR,
  1347. DBG_MINIPORT | DBG_INIT,
  1348. ("[MpInitialize]: Adapter %08X, Can't allocate packet pool \n",
  1349. Adapter));
  1350. Status = NDIS_STATUS_RESOURCES;
  1351. PsAdapterWriteEventLog(
  1352. EVENT_PS_RESOURCE_POOL,
  1353. 0,
  1354. &Adapter->MpDeviceName,
  1355. 0,
  1356. NULL);
  1357. goto MpInitializeError;
  1358. }
  1359. //
  1360. // We can also get the instance name for the corresponding
  1361. // adapter. This is the name which WMI will be using to
  1362. // refer to this instance of us.
  1363. //
  1364. Status = NdisMQueryAdapterInstanceName(&Adapter->WMIInstanceName, MiniportAdapterHandle);
  1365. if(Status != NDIS_STATUS_SUCCESS)
  1366. {
  1367. PsDbgOut(DBG_CRITICAL_ERROR,
  1368. DBG_MINIPORT | DBG_INIT,
  1369. ("[MpInitialize]: Adapter %08X, Failed to get WMI instance name.\n",
  1370. Adapter,
  1371. Status));
  1372. PsAdapterWriteEventLog(
  1373. EVENT_PS_WMI_INSTANCE_NAME_FAILED,
  1374. 0,
  1375. &Adapter->MpDeviceName,
  1376. sizeof(Status),
  1377. &Status);
  1378. goto MpInitializeError;
  1379. }
  1380. //
  1381. // lookup our media type in the supplied media array
  1382. //
  1383. // if we're NdisMediumWan, then we have to fake out the
  1384. // protocol and pretend that we're NdisMedium802_3, so
  1385. // fake it for now.
  1386. //
  1387. if(Adapter->MediaType == NdisMediumWan){
  1388. FakingIt = TRUE;
  1389. Adapter->MediaType = NdisMedium802_3;
  1390. }
  1391. for(--MediumArraySize ; MediumArraySize > 0;){
  1392. if(MediumArray[ MediumArraySize ] == Adapter->MediaType){
  1393. break;
  1394. }
  1395. if(MediumArraySize == 0){
  1396. break;
  1397. }
  1398. --MediumArraySize;
  1399. }
  1400. if(MediumArraySize == 0 && MediumArray[ 0 ] != Adapter->MediaType){
  1401. if(FakingIt)
  1402. {
  1403. FakingIt = FALSE;
  1404. Adapter->MediaType = NdisMediumWan;
  1405. }
  1406. PsDbgOut(DBG_CRITICAL_ERROR,
  1407. DBG_MINIPORT | DBG_INIT,
  1408. ("[MpInitialize]: Adapter %08X, Unsupported Media \n",
  1409. Adapter));
  1410. Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
  1411. goto MpInitializeError;
  1412. }
  1413. if(FakingIt){
  1414. FakingIt = FALSE;
  1415. Adapter->MediaType = NdisMediumWan;
  1416. }
  1417. *SelectedMediumIndex = MediumArraySize;
  1418. //
  1419. // finish the initialization process by set our attributes
  1420. //
  1421. NdisMSetAttributesEx(MiniportAdapterHandle,
  1422. Adapter,
  1423. 0xFFFF,
  1424. NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
  1425. NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT |
  1426. NDIS_ATTRIBUTE_DESERIALIZE |
  1427. NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER |
  1428. NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
  1429. 0);
  1430. //
  1431. // Set the default value for the device state flag as PM capable (for both miniport
  1432. // and protocol). Device is ON by default
  1433. //
  1434. Adapter->MPDeviceState = NdisDeviceStateD0;
  1435. Adapter->PTDeviceState = NdisDeviceStateD0;
  1436. Adapter->PsNdisHandle = MiniportAdapterHandle;
  1437. //
  1438. // We create the b/e VC here (rather than the bind handler) because
  1439. // this will be called only after all scheduling components have registered.
  1440. //
  1441. if(Adapter->MediaType != NdisMediumWan) {
  1442. Status = CreateBestEffortVc(Adapter,
  1443. &Adapter->BestEffortVc,
  1444. 0);
  1445. if(Status != NDIS_STATUS_SUCCESS)
  1446. {
  1447. PsDbgOut(DBG_CRITICAL_ERROR, DBG_MINIPORT | DBG_INIT,
  1448. ("[MpInitialize]: Adapter %08X, cannot create b/e VC ! \n",
  1449. Adapter));
  1450. goto MpInitializeError;
  1451. }
  1452. }
  1453. Adapter->PsMpState = AdapterStateRunning;
  1454. //
  1455. // This is for mpinitialize, will be deref'd on mphalt.
  1456. //
  1457. REFADD(&Adapter->RefCount, 'NDHT');
  1458. PS_LOCK(&AdapterListLock);
  1459. if(WMIInitialized && !Adapter->IfcNotification)
  1460. {
  1461. //
  1462. // WMI has been initialized correctly. i.e we can post events
  1463. // at this point.
  1464. //
  1465. Adapter->IfcNotification = TRUE;
  1466. PS_UNLOCK(&AdapterListLock);
  1467. TcIndicateInterfaceChange(Adapter, 0, NDIS_STATUS_INTERFACE_UP);
  1468. }
  1469. else
  1470. {
  1471. //
  1472. // WMI has not been initialized. Since this adapter is already on the
  1473. // list, the interface up event will be posted when IRP_MN_REGINFO
  1474. // completes.
  1475. //
  1476. PS_UNLOCK(&AdapterListLock);
  1477. }
  1478. NdisSetEvent(&Adapter->MpInitializeEvent);
  1479. return NDIS_STATUS_SUCCESS;
  1480. MpInitializeError:
  1481. Adapter->PsNdisHandle = 0;
  1482. NdisSetEvent(&Adapter->MpInitializeEvent);
  1483. return Status;
  1484. } // MpInitialize
  1485. PADAPTER
  1486. FindAdapterByWmiInstanceName(
  1487. USHORT StringLength,
  1488. PWSTR StringStart,
  1489. PPS_WAN_LINK *PsWanLink
  1490. )
  1491. /*++
  1492. Routine Description:
  1493. Find the miniport instance that matches the instance name passed in.
  1494. Arguments:
  1495. StringLength - Number of bytes / 2
  1496. StringStart - pointer to a buffer containing a wide string
  1497. PsWanLink - if this is an interface search, then the WAN link
  1498. representing the interface will be returned in this location.
  1499. If it is not an interface search or no matching WanLink is
  1500. found, NULL will be returned.
  1501. InterfaceSearch - if TRUE, this is a search for an interface. For
  1502. LAN adapters, an interface is equivalent to an adapter. For WAN
  1503. adapters, interfaces are links. Otherwise, it's a search for an
  1504. adapter.
  1505. Return Value:
  1506. pointer to ADAPTER struct, otherwise NULL
  1507. --*/
  1508. {
  1509. PLIST_ENTRY NextAdapter;
  1510. PLIST_ENTRY NextLink;
  1511. PPS_WAN_LINK WanLink;
  1512. PADAPTER AdapterInList;
  1513. *PsWanLink = NULL;
  1514. PS_LOCK(&AdapterListLock);
  1515. NextAdapter = AdapterList.Flink;
  1516. while(NextAdapter != &AdapterList){
  1517. AdapterInList = CONTAINING_RECORD(NextAdapter, ADAPTER, Linkage);
  1518. PS_LOCK_DPC(&AdapterInList->Lock);
  1519. //
  1520. // If it's closing, blow right by it.
  1521. //
  1522. if(AdapterInList->PsMpState != AdapterStateRunning)
  1523. {
  1524. PS_UNLOCK_DPC(&AdapterInList->Lock);
  1525. NextAdapter = NextAdapter->Flink;
  1526. continue;
  1527. }
  1528. if(AdapterInList->MediaType != NdisMediumWan)
  1529. {
  1530. if(StringLength == AdapterInList->WMIInstanceName.Length){
  1531. //
  1532. // At least they are of equal length.
  1533. //
  1534. if(NdisEqualMemory(StringStart,
  1535. AdapterInList->WMIInstanceName.Buffer,
  1536. StringLength)){
  1537. REFADD(&AdapterInList->RefCount, 'ADVC');
  1538. PS_UNLOCK_DPC(&AdapterInList->Lock);
  1539. PS_UNLOCK(&AdapterListLock);
  1540. return(AdapterInList);
  1541. }
  1542. }
  1543. }
  1544. else
  1545. {
  1546. if(AdapterInList->WanBindingState & WAN_ADDR_FAMILY_OPEN)
  1547. {
  1548. //
  1549. // Wan adapters are searched by the name stored with
  1550. // their links.
  1551. //
  1552. NextLink = AdapterInList->WanLinkList.Flink;
  1553. while(NextLink != &AdapterInList->WanLinkList){
  1554. WanLink = CONTAINING_RECORD(NextLink, PS_WAN_LINK, Linkage);
  1555. if(WanLink->State == WanStateOpen)
  1556. {
  1557. if(StringLength == WanLink->InstanceName.Length){
  1558. //
  1559. // At least they are of equal length.
  1560. //
  1561. if(NdisEqualMemory(StringStart,
  1562. WanLink->InstanceName.Buffer,
  1563. StringLength)){
  1564. REFADD(&AdapterInList->RefCount, 'ADVC');
  1565. REFADD(&WanLink->RefCount, 'WANV');
  1566. PS_UNLOCK_DPC(&AdapterInList->Lock);
  1567. PS_UNLOCK(&AdapterListLock);
  1568. *PsWanLink = WanLink;
  1569. return(AdapterInList);
  1570. }
  1571. }
  1572. }
  1573. NextLink = NextLink->Flink;
  1574. }
  1575. }
  1576. }
  1577. PS_UNLOCK_DPC(&AdapterInList->Lock);
  1578. NextAdapter = NextAdapter->Flink;
  1579. }
  1580. PS_UNLOCK(&AdapterListLock);
  1581. return NULL;
  1582. } // FindAdapterByWmiInstanceName
  1583. VOID
  1584. CleanUpAdapter(
  1585. IN PADAPTER Adapter)
  1586. {
  1587. NDIS_STATUS Status;
  1588. PsAssert(KeGetCurrentIrql() < DISPATCH_LEVEL);
  1589. TcIndicateInterfaceChange(Adapter, 0, NDIS_STATUS_INTERFACE_DOWN);
  1590. //
  1591. // Close all the VCs
  1592. //
  1593. CloseAllGpcVcs(Adapter);
  1594. //
  1595. // if we have opened an underlying call manager, close it now.
  1596. //
  1597. if(Adapter->MediaType == NdisMediumWan) {
  1598. PS_LOCK(&Adapter->Lock);
  1599. if(Adapter->ShutdownMask & SHUTDOWN_CLOSE_WAN_ADDR_FAMILY){
  1600. Adapter->ShutdownMask &= ~SHUTDOWN_CLOSE_WAN_ADDR_FAMILY;
  1601. PS_UNLOCK(&Adapter->Lock);
  1602. PsDbgOut(DBG_TRACE, DBG_WAN | DBG_MINIPORT,
  1603. ("[CleanupAdapter]: Adapter %08X Closing the WAN address family", Adapter));
  1604. Status = NdisClCloseAddressFamily(Adapter->WanCmHandle);
  1605. }
  1606. else
  1607. {
  1608. PS_UNLOCK(&Adapter->Lock);
  1609. }
  1610. }
  1611. }
  1612. VOID
  1613. ClUnbindFromLowerMp(
  1614. OUT PNDIS_STATUS Status,
  1615. IN NDIS_HANDLE ProtocolBindingContext,
  1616. IN NDIS_HANDLE UnbindContext
  1617. )
  1618. /*++
  1619. Routine Description:
  1620. Called by NDIS to indicate that an adapter is going away.
  1621. Since this is an integrated call manager/miniport, we will
  1622. have to close the call manager with the adapter. To do so,
  1623. we must first ask the clients of our call manager part to
  1624. close us. We will have to pend until then.
  1625. Release our reference
  1626. on the adapter and set the closing flag to true to prevent any further
  1627. references from being obtained.
  1628. Arguments:
  1629. See the DDK...
  1630. Return Values:
  1631. None
  1632. --*/
  1633. {
  1634. PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
  1635. NDIS_STATUS LocalStatus;
  1636. BOOLEAN VirtualMp;
  1637. PsDbgOut(DBG_INFO,
  1638. DBG_PROTOCOL | DBG_INIT,
  1639. ("[ClUnbindFromLowerMp]: Adapter %08X, %ws, UnbindContext %x \n",
  1640. Adapter,
  1641. Adapter->MpDeviceName.Buffer,
  1642. UnbindContext));
  1643. PsStructAssert( Adapter );
  1644. PsAssert(!(Adapter->ShutdownMask & SHUTDOWN_UNBIND_CALLED));
  1645. //
  1646. // If the unbind is not happening from the context of the unload, we need to Make sure that
  1647. // unload waits for this unbind to complete. We do that by setting the DriverUnloadEvent.
  1648. //
  1649. PS_LOCK(&DriverUnloadLock);
  1650. DRIVER_COUNTED_BLOCK;
  1651. PS_UNLOCK(&DriverUnloadLock);
  1652. PS_LOCK(&Adapter->Lock);
  1653. if(Adapter->PsMpState == AdapterStateWaiting)
  1654. {
  1655. VirtualMp = FALSE;
  1656. }
  1657. else
  1658. {
  1659. VirtualMp = TRUE;
  1660. }
  1661. Adapter->PsMpState = AdapterStateClosing;
  1662. Adapter->ShutdownMask |= SHUTDOWN_UNBIND_CALLED;
  1663. PsAssert(!(Adapter->ShutdownMask & SHUTDOWN_CLEANUP_ADAPTER));
  1664. if(Adapter->PendedNdisRequest)
  1665. {
  1666. PNDIS_REQUEST PendedRequest = (PNDIS_REQUEST)Adapter->PendedNdisRequest;
  1667. Adapter->PendedNdisRequest = NULL;
  1668. ClRequestComplete(Adapter, PendedRequest, NDIS_STATUS_FAILURE);
  1669. }
  1670. Adapter->ShutdownMask |= SHUTDOWN_CLEANUP_ADAPTER;
  1671. PS_UNLOCK(&Adapter->Lock);
  1672. CleanUpAdapter(Adapter);
  1673. //
  1674. // DeInitialize the device instance if we have been called in the MpInitialize handler.
  1675. //
  1676. if(Adapter->PsNdisHandle)
  1677. {
  1678. //
  1679. // Either the mpinitialize has happened or its in progress. If it is in progress,
  1680. // we need to Wait till it completes.
  1681. //
  1682. NdisWaitEvent(&Adapter->MpInitializeEvent, 0);
  1683. //
  1684. // The MpInitialize (that we could have been waiting for in the above step) could have failed :
  1685. // So we need to check this handle again.
  1686. //
  1687. if(Adapter->PsNdisHandle)
  1688. {
  1689. *Status = NdisIMDeInitializeDeviceInstance(Adapter->PsNdisHandle);
  1690. PsDbgOut(DBG_INFO,
  1691. DBG_PROTOCOL | DBG_INIT,
  1692. ("[ClUnbindFromLowerMp]: Adapter %08X, deiniting device, "
  1693. "status %x\n", Adapter, *Status));
  1694. goto Done;
  1695. }
  1696. }
  1697. else
  1698. {
  1699. if(VirtualMp)
  1700. {
  1701. //
  1702. // We have never been called in MpInitialize. Try to cancel the NdisIMInitializeDeviceInstance
  1703. // call.
  1704. //
  1705. PsDbgOut(DBG_INFO,
  1706. DBG_PROTOCOL | DBG_INIT,
  1707. ("[ClUnbindFromLowerMp]: Adapter %08X, calling NdisIMCancelDeviceInstance with %ws \n",
  1708. Adapter, Adapter->UpperBinding.Buffer));
  1709. *Status = NdisIMCancelInitializeDeviceInstance(LmDriverHandle, &Adapter->UpperBinding);
  1710. if(*Status != NDIS_STATUS_SUCCESS)
  1711. {
  1712. //
  1713. // An mpinitialize is in progress or is going to happen soon. Let's wait for it to
  1714. // complete.
  1715. //
  1716. PsDbgOut(DBG_INFO,
  1717. DBG_PROTOCOL | DBG_INIT,
  1718. ("[ClUnbindFromLowerMp]: Adapter %08X, Waiting for MpInitialize to "
  1719. "finish (NdisIMCancelDeviceInstance failed) \n", Adapter));
  1720. NdisWaitEvent(&Adapter->MpInitializeEvent, 0);
  1721. //
  1722. // The MpInitialize (that we could have been waiting for in the above step) could have failed :
  1723. // So we need to check this handle again.
  1724. //
  1725. if(Adapter->PsNdisHandle)
  1726. {
  1727. *Status = NdisIMDeInitializeDeviceInstance(Adapter->PsNdisHandle);
  1728. PsDbgOut(DBG_INFO,
  1729. DBG_PROTOCOL | DBG_INIT,
  1730. ("[ClUnbindFromLowerMp]: Adapter %08X, deiniting device, "
  1731. "status %x\n", Adapter, *Status));
  1732. goto Done;
  1733. }
  1734. }
  1735. else
  1736. {
  1737. //
  1738. // Great. We can be assured that we will never get called in the MpInitializeHandler anymore.
  1739. // Proceed to close the binding below.
  1740. //
  1741. }
  1742. }
  1743. }
  1744. //
  1745. // Close the open. We have to do this only if we don't call NdisIMDeInitializeDeviceInstance. If
  1746. // we ever call NdisIMDeInitializeDeviceInstance, then we close the open in the MpHalt handler.
  1747. //
  1748. if(Adapter->LowerMpHandle)
  1749. {
  1750. NdisCloseAdapter(Status, Adapter->LowerMpHandle);
  1751. PsDbgOut(DBG_INFO,
  1752. DBG_PROTOCOL | DBG_INIT,
  1753. ("[ClUnbindFromLowerMp]: Adapter %08X, closing adapter, "
  1754. "status %x\n", Adapter, *Status));
  1755. if (*Status == NDIS_STATUS_PENDING)
  1756. {
  1757. NdisWaitEvent(&Adapter->BlockingEvent, 0);
  1758. NdisResetEvent(&Adapter->BlockingEvent);
  1759. *Status = Adapter->FinalStatus;
  1760. }
  1761. REFDEL(&Adapter->RefCount, FALSE, 'NDOP');
  1762. }
  1763. else
  1764. {
  1765. PsDbgOut(DBG_CRITICAL_ERROR,
  1766. DBG_PROTOCOL | DBG_INIT,
  1767. ("[ClUnbindFromLowerMp]: Adapter %08X, unbind cannot deinit/close adpater \n",
  1768. Adapter));
  1769. *Status = NDIS_STATUS_FAILURE;
  1770. PsAssert(0);
  1771. }
  1772. Done:
  1773. PsDbgOut(DBG_INFO,
  1774. DBG_PROTOCOL | DBG_INIT,
  1775. ("[ClUnbindFromLowerMp]: Exiting with Status = %08X \n", *Status));
  1776. DRIVER_COUNTED_UNBLOCK;
  1777. } // UnbindAdapter
  1778. VOID
  1779. DeleteAdapter(
  1780. PVOID Handle,
  1781. BOOLEAN AdapterListLocked
  1782. )
  1783. /*++
  1784. Routine Description:
  1785. Decrement the ref counter associated with this structure. When it goes to
  1786. zero, close the adapter, and delete the memory associated with the struct
  1787. Arguments:
  1788. Adapter - pointer to adapter context block
  1789. Return Value:
  1790. number of references remaining associated with this structure
  1791. --*/
  1792. {
  1793. PADAPTER Adapter = (PADAPTER) Handle;
  1794. Adapter->PsMpState = AdapterStateClosed;
  1795. //
  1796. // if we initialized the pipe, tell the scheduler that this pipe is going away
  1797. //
  1798. if ( Adapter->MediaType != NdisMediumWan && Adapter->ShutdownMask & SHUTDOWN_DELETE_PIPE ) {
  1799. (*Adapter->PsComponent->DeletePipe)( Adapter->PsPipeContext );
  1800. }
  1801. if ( Adapter->ShutdownMask & SHUTDOWN_FREE_PS_CONTEXT ) {
  1802. PsFreePool(Adapter->PsPipeContext);
  1803. }
  1804. if(Adapter->pDiffServMapping)
  1805. {
  1806. PsFreePool(Adapter->pDiffServMapping);
  1807. }
  1808. //
  1809. // return packet pool resources
  1810. //
  1811. if(Adapter->SendPacketPool != 0)
  1812. {
  1813. NdisFreePacketPool(Adapter->SendPacketPool);
  1814. }
  1815. if(Adapter->RecvPacketPool != 0)
  1816. {
  1817. NdisFreePacketPool(Adapter->RecvPacketPool);
  1818. }
  1819. if(Adapter->SendBlockPool)
  1820. {
  1821. NdisDestroyBlockPool(Adapter->SendBlockPool);
  1822. }
  1823. //
  1824. // free adapter lock from dispatcher DB
  1825. //
  1826. NdisFreeSpinLock(&Adapter->Lock);
  1827. //
  1828. // Free various allocations for the adapter, then the adapter
  1829. //
  1830. if(Adapter->IpNetAddressList){
  1831. PsFreePool(Adapter->IpNetAddressList);
  1832. }
  1833. if(Adapter->IpxNetAddressList){
  1834. PsFreePool(Adapter->IpxNetAddressList);
  1835. }
  1836. if(Adapter->MpDeviceName.Buffer) {
  1837. PsFreePool(Adapter->MpDeviceName.Buffer);
  1838. }
  1839. if(Adapter->UpperBinding.Buffer) {
  1840. PsFreePool(Adapter->UpperBinding.Buffer);
  1841. }
  1842. if(Adapter->RegistryPath.Buffer) {
  1843. PsFreePool(Adapter->RegistryPath.Buffer);
  1844. }
  1845. if(Adapter->WMIInstanceName.Buffer) {
  1846. //
  1847. // We should not call PsFreePool since this memory is allocated by NDIS
  1848. //
  1849. ExFreePool(Adapter->WMIInstanceName.Buffer);
  1850. }
  1851. if(Adapter->ProfileName.Buffer) {
  1852. PsFreePool(Adapter->ProfileName.Buffer);
  1853. }
  1854. if(!AdapterListLocked)
  1855. {
  1856. PS_LOCK(&AdapterListLock);
  1857. RemoveEntryList(&Adapter->Linkage);
  1858. PS_UNLOCK(&AdapterListLock);
  1859. }
  1860. else
  1861. {
  1862. RemoveEntryList(&Adapter->Linkage);
  1863. }
  1864. NdisSetEvent(&Adapter->RefEvent);
  1865. PsFreePool(Adapter);
  1866. }
  1867. VOID
  1868. ClLowerMpCloseAdapterComplete(
  1869. IN NDIS_HANDLE ProtocolBindingContext,
  1870. IN NDIS_STATUS Status
  1871. )
  1872. /*++
  1873. Routine Description:
  1874. Completion routine for NdisCloseAdapter. All that should be left is to free
  1875. the pool associated with the structure
  1876. Arguments:
  1877. See the DDK...
  1878. Return Values:
  1879. None
  1880. --*/
  1881. {
  1882. PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
  1883. PsDbgOut(DBG_TRACE,
  1884. DBG_PROTOCOL,
  1885. ("[ClLowerMpCloseAdapterComplete]: Adapter %08X \n", Adapter));
  1886. PsStructAssert( Adapter );
  1887. PsAssert(Status == NDIS_STATUS_SUCCESS);
  1888. Adapter->FinalStatus = Status;
  1889. Adapter->LowerMpHandle = 0;
  1890. //
  1891. // Clean up WanLinks. This cannot be done (in CleanUpAdapter) before we call NdisCloseAdapter, because
  1892. // NDIS can unbind us in the middle of an ClStatusIndication, and can cause a race condition. Also, we
  1893. // can all PsDeleteDevice only after this (because we might want to send some status indications.
  1894. //
  1895. AskWanLinksToClose(Adapter);
  1896. PsDeleteDevice();
  1897. NdisSetEvent(&Adapter->BlockingEvent);
  1898. } // LowerMpCloseAdapterComplete
  1899. VOID
  1900. ClUnloadProtocol(
  1901. VOID
  1902. )
  1903. /*++
  1904. Routine Description:
  1905. Arguments:
  1906. None
  1907. Return Value:
  1908. None
  1909. --*/
  1910. {
  1911. }
  1912. VOID
  1913. MpHalt(
  1914. IN NDIS_HANDLE MiniportAdapterContext
  1915. )
  1916. /*++
  1917. Routine Description:
  1918. This handler is called on Memphis. It indicates that the PS MP is no more
  1919. and we should avoid calling NdisIMDeInitializeDeviceInstance...
  1920. Arguments:
  1921. See the DDK...
  1922. Return Values:
  1923. None
  1924. --*/
  1925. {
  1926. PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
  1927. ULONG Status;
  1928. PsDbgOut(DBG_TRACE, DBG_MINIPORT, ("[MpHalt]: Adapter %08X\n", Adapter));
  1929. PsStructAssert(Adapter);
  1930. PsAssert(!(Adapter->ShutdownMask & SHUTDOWN_MPHALT_CALLED));
  1931. PsAssert(!(Adapter->ShutdownMask & SHUTDOWN_PROTOCOL_UNLOAD));
  1932. PS_LOCK(&Adapter->Lock);
  1933. //
  1934. // If we ever get called in our unbind handler, we should not call
  1935. // NdisImDeInitializeDeviceInstance.
  1936. //
  1937. Adapter->ShutdownMask |= SHUTDOWN_MPHALT_CALLED;
  1938. Adapter->PsMpState = AdapterStateClosing;
  1939. if(!(Adapter->ShutdownMask & SHUTDOWN_CLEANUP_ADAPTER))
  1940. {
  1941. Adapter->ShutdownMask |= SHUTDOWN_CLEANUP_ADAPTER;
  1942. PS_UNLOCK(&Adapter->Lock);
  1943. CleanUpAdapter(Adapter);
  1944. }
  1945. else
  1946. {
  1947. PS_UNLOCK(&Adapter->Lock);
  1948. }
  1949. //
  1950. // Close the b/e VC in the mphalt call. This prevents us from taking a lock
  1951. // in the send path. We are assured that we will not get any sends after we
  1952. // get called in the mphalt handler.
  1953. //
  1954. if(Adapter->MediaType != NdisMediumWan)
  1955. {
  1956. PS_LOCK(&Adapter->Lock);
  1957. PS_LOCK_DPC(&Adapter->BestEffortVc.Lock);
  1958. InternalCloseCall(&Adapter->BestEffortVc);
  1959. }
  1960. if(Adapter->LowerMpHandle) {
  1961. NdisCloseAdapter(&Status, Adapter->LowerMpHandle);
  1962. if(Status == NDIS_STATUS_PENDING) {
  1963. NdisWaitEvent(&Adapter->BlockingEvent, 0);
  1964. NdisResetEvent(&Adapter->BlockingEvent);
  1965. Status = Adapter->FinalStatus;
  1966. }
  1967. REFDEL(&Adapter->RefCount, FALSE, 'NDOP');
  1968. }
  1969. //
  1970. // Deref for the MpInitialize
  1971. //
  1972. REFDEL(&Adapter->RefCount, FALSE, 'NDHT');
  1973. }
  1974. NDIS_STATUS
  1975. MpReset(
  1976. OUT PBOOLEAN AddressingReset,
  1977. IN NDIS_HANDLE MiniportAdapterContext
  1978. )
  1979. /*++
  1980. Routine Description:
  1981. Arguments:
  1982. See the DDK...
  1983. Return Values:
  1984. None
  1985. --*/
  1986. {
  1987. PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
  1988. PsStructAssert( Adapter );
  1989. PsDbgOut(DBG_TRACE, DBG_MINIPORT, ("[MpReset]: Adapter %08X\n", Adapter));
  1990. *AddressingReset = FALSE;
  1991. return NDIS_STATUS_SUCCESS;
  1992. }
  1993. HANDLE
  1994. GetNdisPipeHandle (
  1995. IN HANDLE PsPipeContext
  1996. )
  1997. /*++
  1998. Routine Description:
  1999. Return the NDIS handle for the adapter to the requesting scheduling component.
  2000. Arguments:
  2001. PsPipeContext - Pipe context
  2002. Return Values:
  2003. Adapter NDIS handle.
  2004. --*/
  2005. {
  2006. return ((PADAPTER)PsPipeContext)->PsNdisHandle;
  2007. } // GetNdisPipeHandle
  2008. STATIC NDIS_STATUS
  2009. FindProfile(
  2010. PNDIS_STRING ProfileName,
  2011. PPS_PROFILE *Profile
  2012. )
  2013. /*++
  2014. Routine Description:
  2015. Find the named profile in the list of profiles
  2016. Arguments
  2017. ProfileName - Name of the profile to look for.
  2018. Return Value:
  2019. NDIS_STATUS_SUCCESS if everything worked ok
  2020. e--*/
  2021. {
  2022. NDIS_STATUS Status;
  2023. PLIST_ENTRY NextComponent;
  2024. PPS_PROFILE PsiInfo;
  2025. //
  2026. // compare names until we find the right one
  2027. //
  2028. NextComponent = PsProfileList.Flink;
  2029. while ( NextComponent != &PsProfileList ) {
  2030. PsiInfo = CONTAINING_RECORD( NextComponent, PS_PROFILE, Links );
  2031. if ( ProfileName->Length == PsiInfo->ProfileName.Length ) {
  2032. if ( NdisEqualMemory(
  2033. ProfileName->Buffer,
  2034. PsiInfo->ProfileName.Buffer,
  2035. ProfileName->Length )) {
  2036. break;
  2037. }
  2038. }
  2039. NextComponent = NextComponent->Flink;
  2040. }
  2041. if ( NextComponent != &PsProfileList ) {
  2042. *Profile = PsiInfo;
  2043. Status = NDIS_STATUS_SUCCESS;
  2044. } else {
  2045. Status = NDIS_STATUS_FAILURE;
  2046. }
  2047. return Status;
  2048. } // FindProfile
  2049. NDIS_STATUS
  2050. InitializeAdapter(
  2051. PADAPTER Adapter,
  2052. PVOID BindContext,
  2053. PNDIS_STRING MpDeviceName,
  2054. PVOID SystemSpecific1)
  2055. {
  2056. NDIS_STATUS LocalStatus;
  2057. PNDIS_STRING PsParamsKey = (PNDIS_STRING) SystemSpecific1;
  2058. NdisZeroMemory(Adapter, sizeof(ADAPTER));
  2059. PS_INIT_SPIN_LOCK(&Adapter->Lock);
  2060. REFINIT(&Adapter->RefCount, Adapter, DeleteAdapter);
  2061. REFADD(&Adapter->RefCount, 'NDOP');
  2062. Adapter->PsMpState = AdapterStateInitializing;
  2063. Adapter->BindContext = BindContext;
  2064. Adapter->ShutdownMask = 0;
  2065. NdisInitializeEvent(&Adapter->BlockingEvent);
  2066. NdisResetEvent(&Adapter->BlockingEvent);
  2067. NdisInitializeEvent(&Adapter->RefEvent);
  2068. NdisResetEvent(&Adapter->RefEvent);
  2069. NdisInitializeEvent(&Adapter->LocalRequestEvent);
  2070. NdisResetEvent(&Adapter->LocalRequestEvent);
  2071. NdisInitializeEvent(&Adapter->MpInitializeEvent);
  2072. NdisResetEvent(&Adapter->MpInitializeEvent);
  2073. //
  2074. // Initialize the Lists that we are maintaining
  2075. //
  2076. InitializeListHead(&Adapter->WanLinkList);
  2077. InitializeListHead(&Adapter->GpcClientVcList);
  2078. //
  2079. // By default, Adapter comes in RSVP mode
  2080. //
  2081. Adapter->AdapterMode = AdapterModeRsvpFlow;
  2082. //
  2083. // add adapter on list of known adapters
  2084. //
  2085. NdisInterlockedInsertTailList(&AdapterList,
  2086. &Adapter->Linkage,
  2087. &AdapterListLock.Lock );
  2088. PsAddDevice();
  2089. //
  2090. // We maintain a list of network addresses enabled on
  2091. // each adapter, for IP and for IPX, separately.
  2092. //
  2093. PsAllocatePool(Adapter->IpNetAddressList,
  2094. sizeof(NETWORK_ADDRESS_LIST),
  2095. PsMiscTag);
  2096. if(!Adapter->IpNetAddressList)
  2097. {
  2098. goto ERROR_RESOURCES;
  2099. }
  2100. Adapter->IpNetAddressList->AddressCount = 0;
  2101. PsAllocatePool(Adapter->IpxNetAddressList,
  2102. sizeof(NETWORK_ADDRESS_LIST),
  2103. PsMiscTag);
  2104. if(!Adapter->IpxNetAddressList)
  2105. {
  2106. goto ERROR_RESOURCES;
  2107. }
  2108. Adapter->IpxNetAddressList->AddressCount = 0;
  2109. //
  2110. // Allocate a buffer to hold the name of the underlying
  2111. // adpater.
  2112. //
  2113. Adapter->MpDeviceName.Length = MpDeviceName->Length;
  2114. Adapter->MpDeviceName.MaximumLength = MpDeviceName->MaximumLength;
  2115. PsAllocatePool(Adapter->MpDeviceName.Buffer,
  2116. MpDeviceName->MaximumLength,
  2117. PsMiscTag);
  2118. if(Adapter->MpDeviceName.Buffer == NULL)
  2119. {
  2120. goto ERROR_RESOURCES;
  2121. }
  2122. else
  2123. {
  2124. NdisZeroMemory(
  2125. Adapter->MpDeviceName.Buffer,
  2126. Adapter->MpDeviceName.MaximumLength);
  2127. NdisMoveMemory(
  2128. Adapter->MpDeviceName.Buffer,
  2129. MpDeviceName->Buffer,
  2130. MpDeviceName->Length);
  2131. }
  2132. //
  2133. // Allocate a buffer to hold PsParams Key. This will be
  2134. // used by the adapter to read external scheduling component
  2135. // specific interface parameters when they register.
  2136. //
  2137. Adapter->RegistryPath.Length = PsParamsKey->Length;
  2138. Adapter->RegistryPath.MaximumLength = PsParamsKey->MaximumLength;
  2139. PsAllocatePool(Adapter->RegistryPath.Buffer,
  2140. Adapter->RegistryPath.MaximumLength,
  2141. PsMiscTag);
  2142. if(Adapter->RegistryPath.Buffer == NULL)
  2143. {
  2144. goto ERROR_RESOURCES;
  2145. }
  2146. else
  2147. {
  2148. NdisMoveMemory(
  2149. Adapter->RegistryPath.Buffer,
  2150. PsParamsKey->Buffer,
  2151. PsParamsKey->MaximumLength);
  2152. }
  2153. //
  2154. // Read the per adapter registry info
  2155. //
  2156. LocalStatus = PsReadAdapterRegistryDataInit(Adapter,
  2157. (PNDIS_STRING)SystemSpecific1);
  2158. LocalStatus = PsReadAdapterRegistryData(Adapter,
  2159. &MachineRegistryKey,
  2160. (PNDIS_STRING)SystemSpecific1);
  2161. if(LocalStatus != NDIS_STATUS_SUCCESS)
  2162. {
  2163. PsDbgOut(DBG_FAILURE,
  2164. DBG_PROTOCOL | DBG_INIT,
  2165. ("[InitializeAdapter]: Couldn't get registry data %ws (Status = %08X) \n",
  2166. MpDeviceName->Buffer, LocalStatus));
  2167. }
  2168. return LocalStatus;
  2169. ERROR_RESOURCES:
  2170. PsAdapterWriteEventLog(
  2171. (ULONG)EVENT_PS_RESOURCE_POOL,
  2172. 0,
  2173. MpDeviceName,
  2174. 0,
  2175. NULL);
  2176. return NDIS_STATUS_RESOURCES;
  2177. }
  2178. NDIS_STATUS
  2179. RegisterPsComponent(
  2180. PPSI_INFO PsiComponentInfo,
  2181. ULONG Size,
  2182. PPS_DEBUG_INFO DebugInfo
  2183. )
  2184. /*++
  2185. Routine Description:
  2186. Called by an external scheduling component to register itself with the PS.
  2187. This function is exported by the PS driver. At present, all scheduling
  2188. components are internal to the PS, so this entry is not used.
  2189. Arguments:
  2190. PsiComponentInfo - pointer to component info
  2191. Return Value:
  2192. STATUS_SUCCESS if everything worked ok
  2193. --*/
  2194. {
  2195. PPSI_INFO comp;
  2196. PLIST_ENTRY NextComponent;
  2197. PPS_PROFILE PsiInfo;
  2198. UINT i;
  2199. PLIST_ENTRY NextAdapter;
  2200. PADAPTER AdapterInList;
  2201. NDIS_STATUS Status;
  2202. //
  2203. // sanitize it somewhat
  2204. //
  2205. if ( Size != sizeof( PSI_INFO ))
  2206. {
  2207. PsDbgOut(DBG_FAILURE, DBG_PROTOCOL,
  2208. ("[RegisterPsComponent]: Size mismatch \n"));
  2209. return NDIS_STATUS_FAILURE;
  2210. }
  2211. if(PsiComponentInfo->Version != PS_COMPONENT_CURRENT_VERSION)
  2212. {
  2213. return NDIS_STATUS_FAILURE;
  2214. }
  2215. if(FindSchedulingComponent(&PsiComponentInfo->ComponentName, &comp) ==
  2216. NDIS_STATUS_FAILURE)
  2217. {
  2218. //
  2219. // This component was not a part of any profile in the registry
  2220. // and hence is likely to be unused.
  2221. //
  2222. PsDbgOut(DBG_FAILURE, DBG_PROTOCOL,
  2223. ("[RegisterPsComponent]: Add-in component %ws is not "
  2224. " a part of any profile \n",
  2225. PsiComponentInfo->ComponentName.Buffer));
  2226. return NDIS_STATUS_FAILURE;
  2227. }
  2228. // Component has registered. See if it requires DEBUG_INFO
  2229. //
  2230. if(DebugInfo)
  2231. {
  2232. #if DBG
  2233. DebugInfo->DebugLevel = &DbgTraceLevel;
  2234. DebugInfo->DebugMask = &DbgTraceMask;
  2235. DebugInfo->LogId = LogId ++;
  2236. DebugInfo->LogTraceLevel = &LogTraceLevel;
  2237. DebugInfo->LogTraceMask = &LogTraceMask;
  2238. DebugInfo->GetCurrentTime = PsGetCurrentTime;
  2239. DebugInfo->LogString = DbugSchedString;
  2240. DebugInfo->LogSched = DbugSched;
  2241. DebugInfo->LogRec = DbugComponentSpecificRec;
  2242. #else
  2243. DebugInfo->DebugLevel = 0;
  2244. DebugInfo->LogId = 0;
  2245. DebugInfo->DebugMask = 0;
  2246. DebugInfo->LogTraceLevel = 0;
  2247. DebugInfo->LogTraceMask = 0;
  2248. DebugInfo->GetCurrentTime = 0;
  2249. DebugInfo->LogString = 0;
  2250. DebugInfo->LogSched = 0;
  2251. DebugInfo->LogRec = 0;
  2252. #endif
  2253. }
  2254. //
  2255. // We need to lock the component as we could get two "RegisterPsComponent"
  2256. // calls for the same component. We don't really need a component level
  2257. // lock as we can do with PsComponentListLock & this is not a performance
  2258. // critical piece.
  2259. //
  2260. PS_LOCK(&PsComponentListLock);
  2261. if(comp->AddIn == FALSE)
  2262. {
  2263. //
  2264. // Registering a system component! Bail out
  2265. //
  2266. PS_UNLOCK(&PsComponentListLock);
  2267. PsDbgOut(DBG_FAILURE, DBG_PROTOCOL,
  2268. ("[RegisterPsComponent]: %ws is already a system"
  2269. " component \n",
  2270. PsiComponentInfo->ComponentName.Buffer));
  2271. return NDIS_STATUS_FAILURE;
  2272. }
  2273. if(comp->Registered == TRUE)
  2274. {
  2275. //
  2276. // Re-registering a component.
  2277. //
  2278. PS_UNLOCK(&PsComponentListLock);
  2279. PsDbgOut(DBG_FAILURE, DBG_PROTOCOL,
  2280. ("[RegisterPsComponent]: %ws already registered\n",
  2281. PsiComponentInfo->ComponentName.Buffer));
  2282. return NDIS_STATUS_FAILURE;
  2283. }
  2284. //
  2285. // Update this component in the list.
  2286. //
  2287. //
  2288. // make sure the packet reserved area is sane so our context struct
  2289. // is aligned
  2290. //
  2291. if ( PsiComponentInfo->PacketReservedLength & 3 ) {
  2292. PsiComponentInfo->PacketReservedLength =
  2293. ( PsiComponentInfo->PacketReservedLength & ~3 ) + 4;
  2294. }
  2295. //
  2296. // Update the component in the list
  2297. //
  2298. comp->PacketReservedLength = PsiComponentInfo->PacketReservedLength;
  2299. comp->PipeContextLength = PsiComponentInfo->PipeContextLength;
  2300. comp->FlowContextLength = PsiComponentInfo->FlowContextLength;
  2301. comp->ClassMapContextLength = PsiComponentInfo->ClassMapContextLength;
  2302. comp->SupportedOidsLength = PsiComponentInfo->SupportedOidsLength;
  2303. comp->SupportedOidList = PsiComponentInfo->SupportedOidList;
  2304. comp->SupportedGuidsLength = PsiComponentInfo->SupportedGuidsLength;
  2305. comp->SupportedGuidList = PsiComponentInfo->SupportedGuidList;
  2306. comp->InitializePipe = PsiComponentInfo->InitializePipe;
  2307. comp->ModifyPipe = PsiComponentInfo->ModifyPipe;
  2308. comp->DeletePipe = PsiComponentInfo->DeletePipe;
  2309. comp->CreateFlow = PsiComponentInfo->CreateFlow;
  2310. comp->ModifyFlow = PsiComponentInfo->ModifyFlow;
  2311. comp->DeleteFlow = PsiComponentInfo->DeleteFlow;
  2312. comp->EmptyFlow = PsiComponentInfo->EmptyFlow;
  2313. comp->SubmitPacket = PsiComponentInfo->SubmitPacket;
  2314. comp->SetInformation = PsiComponentInfo->SetInformation;
  2315. comp->QueryInformation = PsiComponentInfo->QueryInformation;
  2316. comp->CreateClassMap = PsiComponentInfo->CreateClassMap;
  2317. comp->DeleteClassMap = PsiComponentInfo->DeleteClassMap;
  2318. //
  2319. // Right now, only one component uses this...
  2320. // This hack is being made for characterization work
  2321. //
  2322. if (PsiComponentInfo->ReceivePacket) {
  2323. TimeStmpRecvPacket = PsiComponentInfo->ReceivePacket;
  2324. }
  2325. if (PsiComponentInfo->ReceiveIndication) {
  2326. TimeStmpRecvIndication = PsiComponentInfo->ReceiveIndication;
  2327. }
  2328. PS_UNLOCK(&PsComponentListLock);
  2329. PsDbgOut(DBG_TRACE, DBG_PROTOCOL,
  2330. ("[RegisterPsComponent]: Component %ws has "
  2331. "registered \n",
  2332. PsiComponentInfo->ComponentName.Buffer));
  2333. //
  2334. // Update the ProfileList
  2335. //
  2336. NextComponent = PsProfileList.Flink;
  2337. while ( NextComponent != &PsProfileList )
  2338. {
  2339. PsiInfo = CONTAINING_RECORD( NextComponent, PS_PROFILE, Links );
  2340. //
  2341. // We have to worry only about those profiles
  2342. // that have unregistered components.
  2343. //
  2344. PS_LOCK(&PsProfileLock);
  2345. if(PsiInfo->UnregisteredAddInCnt != 0)
  2346. {
  2347. for(i=0; i<PsiInfo->ComponentCnt; i++)
  2348. {
  2349. if(PsiInfo->ComponentList[i] == comp)
  2350. {
  2351. PsiInfo->UnregisteredAddInCnt --;
  2352. break;
  2353. }
  2354. }
  2355. }
  2356. PS_UNLOCK( &PsProfileLock );
  2357. NextComponent = NextComponent->Flink;
  2358. }
  2359. // Need to walk the adapter list & see if we can
  2360. // service the waiting adapters.
  2361. PS_LOCK(&AdapterListLock);
  2362. NextAdapter = AdapterList.Flink;
  2363. while(NextAdapter != &AdapterList)
  2364. {
  2365. AdapterInList = CONTAINING_RECORD(NextAdapter, ADAPTER, Linkage);
  2366. PS_LOCK(&AdapterInList->Lock);
  2367. //
  2368. // If it's not waiting, we don't care
  2369. //
  2370. if(AdapterInList->PsMpState != AdapterStateWaiting ){
  2371. PS_UNLOCK(&AdapterInList->Lock);
  2372. NextAdapter = NextAdapter->Flink;
  2373. continue;
  2374. }
  2375. //
  2376. // If it is waiting, we can try to build the scheduling pipe.
  2377. //
  2378. PS_UNLOCK(&AdapterInList->Lock);
  2379. PS_UNLOCK(&AdapterListLock);
  2380. Status = UpdateAdapterBandwidthParameters(AdapterInList);
  2381. if(Status == NDIS_STATUS_ADAPTER_NOT_READY)
  2382. {
  2383. PsDbgOut(DBG_TRACE, DBG_PROTOCOL,
  2384. ("[RegisterPsComponent]: Adapter %08X, Waiting for add-in components to register \n",
  2385. AdapterInList));
  2386. }
  2387. else
  2388. {
  2389. if(Status == NDIS_STATUS_SUCCESS)
  2390. {
  2391. PsDbgOut(DBG_TRACE, DBG_PROTOCOL,
  2392. ("[RegisterPsComponent]: Adapter %08X, all add-in components have registered \n",
  2393. AdapterInList));
  2394. PsInitializeDeviceInstance(AdapterInList);
  2395. }
  2396. else
  2397. {
  2398. PsDbgOut(DBG_CRITICAL_ERROR, DBG_PROTOCOL,
  2399. ("[RegisterPsComponent]: Adapter %08X, Failed to update scheduling pipe, Status %08X\n",
  2400. AdapterInList, Status));
  2401. }
  2402. }
  2403. PS_LOCK(&AdapterListLock);
  2404. NextAdapter = NextAdapter->Flink;
  2405. }
  2406. PS_UNLOCK(&AdapterListLock);
  2407. return NDIS_STATUS_SUCCESS;
  2408. } // RegisterPsComponent
  2409. NDIS_STATUS
  2410. FindSchedulingComponent(
  2411. PNDIS_STRING ComponentName,
  2412. PPSI_INFO *Component
  2413. )
  2414. /*++
  2415. Routine Description:
  2416. Find the named component in the list of external scheduling components
  2417. Arguments:
  2418. ComponentName - name of component to look for
  2419. Return Value:
  2420. NDIS_STATUS_SUCCESS if everything worked ok
  2421. --*/
  2422. {
  2423. NDIS_STATUS Status;
  2424. PLIST_ENTRY NextComponent;
  2425. PPSI_INFO PsiInfo;
  2426. //
  2427. // get the list lock and compare names until we find the right one
  2428. //
  2429. PS_LOCK( &PsComponentListLock );
  2430. NextComponent = PsComponentList.Flink;
  2431. while ( NextComponent != &PsComponentList ) {
  2432. PsiInfo = CONTAINING_RECORD( NextComponent, PSI_INFO, Links );
  2433. if ( ComponentName->Length == PsiInfo->ComponentName.Length ) {
  2434. if ( NdisEqualMemory(
  2435. ComponentName->Buffer,
  2436. PsiInfo->ComponentName.Buffer,
  2437. ComponentName->Length )) {
  2438. break;
  2439. }
  2440. }
  2441. NextComponent = NextComponent->Flink;
  2442. }
  2443. PS_UNLOCK( &PsComponentListLock );
  2444. if ( NextComponent != &PsComponentList ) {
  2445. *Component = PsiInfo;
  2446. Status = NDIS_STATUS_SUCCESS;
  2447. } else {
  2448. Status = NDIS_STATUS_FAILURE;
  2449. }
  2450. return Status;
  2451. } // FindSchedulingComponent
  2452. VOID
  2453. CloseAllGpcVcs(
  2454. PADAPTER Adapter
  2455. )
  2456. /*++
  2457. Routine Description:
  2458. Close all the VCs associated with an adapter
  2459. Return Value:
  2460. None
  2461. --*/
  2462. {
  2463. PGPC_CLIENT_VC Vc;
  2464. PLIST_ENTRY NextVc;
  2465. //
  2466. // Close all the GPC client VCs.
  2467. //
  2468. PS_LOCK(&Adapter->Lock);
  2469. NextVc = Adapter->GpcClientVcList.Flink;
  2470. while(NextVc != &Adapter->GpcClientVcList)
  2471. {
  2472. Vc = CONTAINING_RECORD(NextVc, GPC_CLIENT_VC, Linkage);
  2473. PsAssert(Vc);
  2474. PS_LOCK_DPC(&Vc->Lock);
  2475. if(Vc->ClVcState == CL_INTERNAL_CLOSE_PENDING || Vc->Flags & INTERNAL_CLOSE_REQUESTED)
  2476. {
  2477. PS_UNLOCK_DPC(&Vc->Lock);
  2478. NextVc = NextVc->Flink;
  2479. }
  2480. else
  2481. {
  2482. InternalCloseCall(Vc);
  2483. PS_LOCK(&Adapter->Lock);
  2484. //
  2485. // Sigh. We can't really get hold to the NextVc in a reliable manner. When we call
  2486. // InternalCloseCall on the Vc, it releases the Adapter Lock (since it might have to
  2487. // make calls into NDIS). Now, in this window, the next Vc could go away, and we
  2488. // could point to a stale Vc. So, we start at the head of the list.
  2489. // Note that this can never lead to a infinite loop, since we don't process the
  2490. // internal close'd VCs repeatedly.
  2491. //
  2492. NextVc = Adapter->GpcClientVcList.Flink;
  2493. }
  2494. }
  2495. PS_UNLOCK(&Adapter->Lock);
  2496. } // CloseAllGpcVcs
  2497. VOID
  2498. PsAdapterWriteEventLog(
  2499. IN NDIS_STATUS EventCode,
  2500. IN ULONG UniqueEventValue,
  2501. IN PNDIS_STRING DeviceName,
  2502. IN ULONG DataSize,
  2503. IN PVOID Data OPTIONAL
  2504. )
  2505. {
  2506. //
  2507. // The String List is the device name, and it has a \Device against it.
  2508. //
  2509. PWCHAR StringList[1];
  2510. NDIS_STRING Prefix = NDIS_STRING_CONST("\\Device\\");
  2511. if(DeviceName->Length > Prefix.Length)
  2512. {
  2513. StringList[0] = (PWCHAR) ((PUCHAR) DeviceName->Buffer + Prefix.Length);
  2514. NdisWriteEventLogEntry(PsDriverObject,
  2515. EventCode,
  2516. UniqueEventValue,
  2517. 1,
  2518. &StringList,
  2519. DataSize,
  2520. Data);
  2521. }
  2522. }
  2523. /* end adapter.c */