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.

749 lines
18 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include "macros.h"
  4. VOID
  5. EpvcCoOpenAfComplete(
  6. IN NDIS_STATUS Status,
  7. IN NDIS_HANDLE ProtocolAfContext,
  8. IN NDIS_HANDLE NdisAfHandle
  9. )
  10. {
  11. ENTER("OpenAdapterComplete", 0x5d75dabd)
  12. PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT)ProtocolAfContext;
  13. PTASK_AF pAfTask = (PTASK_AF )pMiniport->af.pAfTask;
  14. RM_DECLARE_STACK_RECORD(sr)
  15. TRACE (TL_T, TM_Cl, (" == EpvcCoOpenAfComplete Context %p Status %x AfHAndle %x",
  16. pMiniport, Status, NdisAfHandle) );
  17. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  18. //
  19. // Store the Af Handle
  20. //
  21. if (NDIS_STATUS_SUCCESS == Status)
  22. {
  23. LOCKOBJ (pMiniport, &sr);
  24. pMiniport->af.AfHandle = NdisAfHandle;
  25. //
  26. // Update variables on the miniport structure
  27. // as this task has been given the go ahead
  28. //
  29. MiniportSetFlag (pMiniport, fMP_AddressFamilyOpened);
  30. MiniportClearFlag (pMiniport, fMP_InfoAfClosed);
  31. epvcLinkToExternal(
  32. &pMiniport->Hdr, // pObject
  33. 0x5546d299,
  34. (UINT_PTR)pMiniport->af.AfHandle , // Instance1
  35. EPVC_ASSOC_MINIPORT_OPEN_AF, // AssociationID
  36. " Open AF NdisHandle=%p\n",// szFormat
  37. &sr
  38. );
  39. UNLOCKOBJ(pMiniport, &sr);
  40. }
  41. else
  42. {
  43. ASSERT (pMiniport->af.AfHandle == NULL);
  44. pMiniport->af.AfHandle = NULL;
  45. }
  46. pAfTask ->ReturnStatus = Status;
  47. //
  48. // Add an association between
  49. //
  50. RmResumeTask (&pAfTask->TskHdr , 0, &sr);
  51. RM_ASSERT_CLEAR(&sr);
  52. EXIT();
  53. }
  54. VOID
  55. epvcCoCloseAfCompleteWorkItem(
  56. PRM_OBJECT_HEADER pObj,
  57. NDIS_STATUS Status,
  58. PRM_STACK_RECORD pSR
  59. )
  60. /*++
  61. Routine Description:
  62. Resuming the Af task
  63. Arguments:
  64. --*/
  65. {
  66. ENTER("epvcCoCloseAfCompleteWorkItem", 0xf6edfcb8)
  67. PEPVC_I_MINIPORT pMiniport = NULL ;
  68. PTASK_AF pAfTask = NULL;
  69. pMiniport = (PEPVC_I_MINIPORT)pObj ;
  70. LOCKOBJ (pMiniport, pSR);
  71. MiniportSetFlag (pMiniport, fMP_InfoAfClosed);
  72. UNLOCKOBJ (pMiniport, pSR);
  73. pAfTask = (PTASK_AF )pMiniport->af.pAfTask;
  74. if (NDIS_STATUS_SUCCESS==Status )
  75. {
  76. LOCKOBJ (pMiniport, pSR);
  77. epvcUnlinkFromExternal(
  78. &pMiniport->Hdr, // pObject
  79. 0x5546d299,
  80. (UINT_PTR)pMiniport->af.AfHandle , // Instance1
  81. EPVC_ASSOC_MINIPORT_OPEN_AF, // AssociationID
  82. pSR
  83. );
  84. pMiniport->af.AfHandle = NULL;
  85. UNLOCKOBJ(pMiniport, pSR);
  86. }
  87. RmResumeTask (&pAfTask->TskHdr , 0, pSR);
  88. EXIT();
  89. return;
  90. }
  91. VOID
  92. EpvcCoCloseAfComplete(
  93. IN NDIS_STATUS Status,
  94. IN NDIS_HANDLE ProtocolAfContext
  95. )
  96. /*++
  97. Routine Description:
  98. Signifies that the AF has been closed.
  99. Resume the Af task - through a workitem
  100. Arguments:
  101. --*/
  102. {
  103. ENTER("EpvcCoCloseAfComplete ", 0x5d75dabd)
  104. PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT)ProtocolAfContext;
  105. PTASK_AF pAfTask = (PTASK_AF )pMiniport->af.pAfTask;
  106. RM_DECLARE_STACK_RECORD(sr)
  107. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  108. TRACE (TL_T, TM_Cl, (" == EpvcCoCloseAfComplete Context %p Status %x ",
  109. pMiniport, Status) );
  110. //
  111. // Store the Status
  112. //
  113. pAfTask->ReturnStatus = Status;
  114. //
  115. // Queue the WorkItem
  116. //
  117. epvcMiniportQueueWorkItem (
  118. &pMiniport->af.CloseAfWorkItem,
  119. pMiniport,
  120. epvcCoCloseAfCompleteWorkItem,
  121. Status,
  122. &sr
  123. );
  124. EXIT();
  125. RM_ASSERT_CLEAR(&sr);
  126. return;
  127. }
  128. VOID
  129. EpvcCoMakeCallComplete(
  130. IN NDIS_STATUS Status,
  131. IN NDIS_HANDLE ProtocolVcContext,
  132. IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
  133. IN PCO_CALL_PARAMETERS pCallParameters
  134. )
  135. /*++
  136. Routine Description:
  137. This is a notification from Ndis that the Make Call has completed.
  138. We need to pass the Status back to the original thread, so use the Vc
  139. Task as a context
  140. Arguments:
  141. --*/
  142. {
  143. ENTER ("EpvcCoMakeCallComplete", 0x1716ee4b)
  144. PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT) ProtocolVcContext;
  145. PTASK_VC pTaskVc = pMiniport->vc.pTaskVc;
  146. RM_DECLARE_STACK_RECORD(SR);
  147. //ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  148. TRACE (TL_T, TM_Cl, (" == EpvcCoMakeCallComplete Status %x", Status) );
  149. pTaskVc->ReturnStatus = Status;
  150. ASSERT (pCallParameters != NULL);
  151. epvcFreeMemory (pCallParameters ,CALL_PARAMETER_SIZE, 0);
  152. RmResumeTask (&pTaskVc->TskHdr, 0 , &SR);
  153. EXIT();
  154. RM_ASSERT_CLEAR(&SR);
  155. }
  156. VOID
  157. epvcCoCloseCallCompleteWorkItem(
  158. PRM_OBJECT_HEADER pObj,
  159. NDIS_STATUS Status,
  160. PRM_STACK_RECORD pSR
  161. )
  162. {
  163. ENTER ("EpvcCoCloseCallComplete", 0xbd67524a)
  164. PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT) pObj;
  165. PTASK_VC pTaskVc = pMiniport->vc.pTaskVc;
  166. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  167. TRACE (TL_T, TM_Cl, (" == EpvcCoCloseCallComplete") );
  168. pTaskVc->ReturnStatus = Status;
  169. RmResumeTask (&pTaskVc->TskHdr, 0 , pSR);
  170. RM_ASSERT_CLEAR(pSR);
  171. }
  172. VOID
  173. EpvcCoCloseCallComplete(
  174. IN NDIS_STATUS Status,
  175. IN NDIS_HANDLE ProtocolVcContext,
  176. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL
  177. )
  178. {
  179. ENTER ("EpvcCoCloseCallComplete", 0xbd67524a)
  180. PEPVC_I_MINIPORT pMiniport = (PEPVC_I_MINIPORT) ProtocolVcContext;
  181. RM_DECLARE_STACK_RECORD(SR);
  182. TRACE (TL_T, TM_Cl, (" == EpvcCoCloseCallComplete") );
  183. epvcMiniportQueueWorkItem (&pMiniport->vc.CallVcWorkItem,
  184. pMiniport,
  185. epvcCoCloseCallCompleteWorkItem,
  186. Status,
  187. &SR
  188. );
  189. RM_ASSERT_CLEAR(&SR);
  190. }
  191. NDIS_STATUS
  192. EpvcCoIncomingCall(
  193. IN NDIS_HANDLE ProtocolSapContext,
  194. IN NDIS_HANDLE ProtocolVcContext,
  195. IN OUT PCO_CALL_PARAMETERS CallParameters
  196. )
  197. {
  198. TRACE (TL_T, TM_Cl, (" == EpvcCoIncomingCall") );
  199. return NDIS_STATUS_FAILURE;
  200. }
  201. VOID
  202. EpvcCoCallConnected(
  203. IN NDIS_HANDLE ProtocolVcContext
  204. )
  205. {
  206. TRACE (TL_T, TM_Cl, (" == EpvcCoCallConnected") );
  207. }
  208. VOID
  209. EpvcCoIncomingClose(
  210. IN NDIS_STATUS CloseStatus,
  211. IN NDIS_HANDLE ProtocolVcContext,
  212. IN PVOID CloseData OPTIONAL,
  213. IN UINT Size OPTIONAL
  214. )
  215. {
  216. TRACE (TL_T, TM_Cl, (" == EpvcCoIncomingClose") );
  217. }
  218. //
  219. // CO_CREATE_VC_HANDLER and CO_DELETE_VC_HANDLER are synchronous calls
  220. //
  221. NDIS_STATUS
  222. EpvcClientCreateVc(
  223. IN NDIS_HANDLE ProtocolAfContext,
  224. IN NDIS_HANDLE NdisVcHandle,
  225. OUT PNDIS_HANDLE ProtocolVcContext
  226. )
  227. {
  228. TRACE (TL_T, TM_Cl, (" == EpvcClientCreateVc") );
  229. return NDIS_STATUS_FAILURE;
  230. }
  231. NDIS_STATUS
  232. EpvcClientDeleteVc(
  233. IN NDIS_HANDLE ProtocolVcContext
  234. )
  235. {
  236. TRACE (TL_T, TM_Cl, (" == EpvcClientDeleteVc") );
  237. return NDIS_STATUS_FAILURE;
  238. }
  239. NDIS_STATUS
  240. EpvcCoRequest(
  241. IN NDIS_HANDLE ProtocolAfContext,
  242. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  243. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  244. IN OUT PNDIS_REQUEST pNdisRequest
  245. )
  246. /*++
  247. Routine Description:
  248. This routine is called by NDIS when our Call Manager sends us an
  249. NDIS Request. NDIS Requests that are of significance to us are:
  250. - OID_CO_ADDRESS_CHANGE
  251. The set of addresses registered with the switch has changed,
  252. i.e. address registration is complete. We issue an NDIS Request
  253. ourselves to get the list of addresses registered.
  254. - OID_CO_SIGNALING_ENABLED
  255. We ignore this as of now.
  256. TODO: Add code that uses this and the SIGNALING_DISABLED
  257. OIDs to optimize on making calls.
  258. - OID_CO_SIGNALING_DISABLED
  259. We ignore this for now.
  260. - OID_CO_AF_CLOSE
  261. The Call manager wants us to shut down this AF open .
  262. We ignore all other OIDs.
  263. Arguments:
  264. ProtocolAfContext - Our context for the Address Family binding,
  265. which is a pointer to the ATMEPVC Interface.
  266. ProtocolVcContext - Our context for a VC, which is a pointer to
  267. an ATMEPVC VC structure.
  268. ProtocolPartyContext - Our context for a Party. Since we don't do
  269. PMP, this is ignored (must be NULL).
  270. pNdisRequest - Pointer to the NDIS Request.
  271. Return Value:
  272. NDIS_STATUS_SUCCESS if we recognized the OID
  273. NDIS_STATUS_NOT_RECOGNIZED if we didn't.
  274. --*/
  275. {
  276. ENTER("EpvcCoRequest",0xcc5aff85)
  277. PEPVC_I_MINIPORT pMiniport;
  278. NDIS_STATUS Status;
  279. RM_DECLARE_STACK_RECORD (SR)
  280. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  281. pMiniport = (PEPVC_I_MINIPORT)ProtocolAfContext;
  282. TRACE (TL_T, TM_Cl, (" ==> EpvcCoRequest") );
  283. //
  284. // Initialize
  285. //
  286. Status = NDIS_STATUS_NOT_RECOGNIZED;
  287. if (pNdisRequest->RequestType == NdisRequestSetInformation)
  288. {
  289. switch (pNdisRequest->DATA.SET_INFORMATION.Oid)
  290. {
  291. case OID_CO_ADDRESS_CHANGE:
  292. TRACE (TL_I, TM_Cl, ("CoRequestHandler: CO_ADDRESS_CHANGE\n"));
  293. //
  294. // The Call Manager says that the list of addresses
  295. // registered on this interface has changed. Get the
  296. // (potentially) new ATM address for this interface.
  297. Status = NDIS_STATUS_SUCCESS;
  298. break;
  299. case OID_CO_SIGNALING_ENABLED:
  300. TRACE (TL_I, TM_Cl, ("CoRequestHandler: CoRequestHandler: CO_SIGNALING_ENABLED\n"));
  301. // ignored for now
  302. Status = NDIS_STATUS_FAILURE;
  303. break;
  304. case OID_CO_SIGNALING_DISABLED:
  305. TRACE (TL_I, TM_Cl, ("CoRequestHandler: CO_SIGNALING_DISABLEDn"));
  306. // Ignored for now
  307. Status = NDIS_STATUS_FAILURE;
  308. break;
  309. case OID_CO_AF_CLOSE:
  310. TRACE (TL_I, TM_Cl, ("CoRequestHandler: CO_AF_CLOSE on MINIPORT %x\n", pMiniport));
  311. Status = epvcProcessOidCloseAf(pMiniport, &SR);
  312. break;
  313. default:
  314. break;
  315. }
  316. }
  317. TRACE (TL_T, TM_Cl, (" <== EpvcCoRequest") );
  318. RM_ASSERT_CLEAR(&SR)
  319. EXIT()
  320. return (Status);
  321. }
  322. VOID
  323. EpvcCoRequestComplete(
  324. IN NDIS_STATUS Status,
  325. IN NDIS_HANDLE ProtocolAfContext OPTIONAL,
  326. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  327. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  328. IN PNDIS_REQUEST pRequest
  329. )
  330. {
  331. TRACE (TL_T, TM_Cl, (" == EpvcCoRequest pRequest %x", pRequest) );
  332. }
  333. NDIS_STATUS
  334. epvcPrepareAndSendNdisRequest(
  335. IN PEPVC_ADAPTER pAdapter,
  336. IN PEPVC_NDIS_REQUEST pEpvcNdisRequest,
  337. IN REQUEST_COMPLETION pFunc, // OPTIONAL
  338. IN NDIS_OID Oid,
  339. IN PVOID pBuffer,
  340. IN ULONG BufferLength,
  341. IN NDIS_REQUEST_TYPE RequestType,
  342. IN PEPVC_I_MINIPORT pMiniport, // OPTIONAL
  343. IN BOOLEAN fPendedRequest, // OPTIONAL
  344. IN BOOLEAN fPendedSet, // OPTIONAL
  345. IN PRM_STACK_RECORD pSR
  346. )
  347. /*++
  348. Routine Description:
  349. Send an NDIS Request to query an adapter for information.
  350. If the request pends, block on the EPVC Adapter structure
  351. till it completes.
  352. Arguments:
  353. pAdapter - Points to EPVCAdapter structure
  354. pNdisRequest - Pointer to UNITIALIZED NDIS request structure
  355. pTask - OPTIONAL Task. If NULL, we block until the operation
  356. completes.
  357. PendCode - PendCode to suspend pTask
  358. Oid - OID to be passed in the request
  359. pBuffer - place for value(s)
  360. BufferLength - length of above
  361. pMiniport - Minport associated withe this request - OPTIONAL
  362. fPendedRequest - A request was pended at the miniport - OPTIONAL
  363. fPendedSet - Pended a Set Request - OPTIONAL
  364. Return Value:
  365. The NDIS status of the request.
  366. --*/
  367. {
  368. ENTER("epvcPrepareAndSendNdisRequest",0x1cc515d5)
  369. NDIS_STATUS Status;
  370. PNDIS_REQUEST pNdisRequest = &pEpvcNdisRequest->Request;
  371. TRACE (TL_T, TM_Cl, ("==>epvcSendAdapterNdisRequest pAdapter %x, pRequest %x",
  372. pAdapter, pNdisRequest));
  373. //ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  374. TRACE (TL_V, TM_Rq, ("Cl Requesting Adapter %x, Oid %x, Buffer %x, Length %x, pFunc %x",
  375. pAdapter,
  376. Oid,
  377. pBuffer,
  378. BufferLength,
  379. pFunc) );
  380. ASSERT (pNdisRequest != NULL);
  381. EPVC_ZEROSTRUCT(pEpvcNdisRequest);
  382. //
  383. // Fill in the NDIS Request structure
  384. //
  385. if (RequestType == NdisRequestQueryInformation)
  386. {
  387. pNdisRequest->RequestType = NdisRequestQueryInformation;
  388. pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  389. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  390. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
  391. pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
  392. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
  393. }
  394. else
  395. {
  396. ASSERT(RequestType == NdisRequestSetInformation);
  397. pNdisRequest->RequestType = NdisRequestSetInformation;
  398. pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
  399. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = pBuffer;
  400. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
  401. pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
  402. pNdisRequest->DATA.SET_INFORMATION.BytesNeeded = BufferLength;
  403. }
  404. ASSERT (pAdapter->bind.BindingHandle != NULL);
  405. //
  406. // If the completion routine is not defined then wait for this request
  407. // to complete.
  408. //
  409. if (pFunc == NULL)
  410. {
  411. // We might potentially wait.
  412. //
  413. ASSERT_PASSIVE();
  414. //
  415. //Insure that we aren't blocking a request that reached our miniport edge
  416. //
  417. ASSERT (pMiniport == NULL);
  418. NdisInitializeEvent(&pEpvcNdisRequest->Event);
  419. NdisRequest(
  420. &Status,
  421. pAdapter->bind.BindingHandle,
  422. pNdisRequest
  423. );
  424. if (PEND(Status))
  425. {
  426. NdisWaitEvent(&pEpvcNdisRequest->Event, 0);
  427. Status = pEpvcNdisRequest->Status;
  428. }
  429. }
  430. else
  431. {
  432. pEpvcNdisRequest->pFunc = pFunc;
  433. pEpvcNdisRequest->pMiniport = pMiniport;
  434. pEpvcNdisRequest->fPendedRequest = fPendedRequest ;
  435. pEpvcNdisRequest->fSet = fPendedSet;
  436. //
  437. // Set up an assoc between the miniport and this request
  438. //
  439. epvcLinkToExternal (&pMiniport->Hdr, // pHdr
  440. 0x46591e2d, // LUID
  441. (UINT_PTR)pEpvcNdisRequest, // External entity
  442. EPVC_ASSOC_MINIPORT_REQUEST, // AssocID
  443. "NetWorKAddressRequest %p\n",
  444. pSR
  445. ) ;
  446. NdisRequest(
  447. &Status,
  448. pAdapter->bind.BindingHandle,
  449. pNdisRequest
  450. );
  451. if (!PEND(Status))
  452. {
  453. (pFunc) (pEpvcNdisRequest, Status);
  454. // Let this thread complete with a status of pending
  455. Status = NDIS_STATUS_PENDING;
  456. }
  457. }
  458. if (Status == NDIS_STATUS_SUCCESS)
  459. {
  460. TRACE(TL_V, TM_Rq,("Adapter Query - Oid %x", Oid));
  461. DUMPDW (TL_V, TM_Rq, pBuffer, BufferLength);
  462. }
  463. return Status;
  464. }
  465. VOID
  466. epvcCoGenericWorkItem (
  467. IN PNDIS_WORK_ITEM pNdisWorkItem,
  468. IN PVOID Context
  469. )
  470. /*++
  471. Routine Description:
  472. Deref the miniport and invoke the function associated with
  473. the workitem
  474. Arguments:
  475. --*/
  476. {
  477. ENTER ("epvcCoGenericWorkItem ", 0x45b597e8)
  478. PEPVC_WORK_ITEM pEpvcWorkItem = (PEPVC_WORK_ITEM )pNdisWorkItem;
  479. RM_DECLARE_STACK_RECORD (SR);
  480. //
  481. // Deref the miniport or adapter
  482. //
  483. epvcUnlinkFromExternal(
  484. pEpvcWorkItem->pParentObj, // pObject
  485. 0x3a70de02,
  486. (UINT_PTR)pNdisWorkItem, // Instance1
  487. EPVC_ASSOC_WORKITEM, // AssociationID
  488. &SR
  489. );
  490. //
  491. // Call the function so that the work is completed
  492. //
  493. (pEpvcWorkItem->pFn) (pEpvcWorkItem->pParentObj, pEpvcWorkItem->ReturnStatus, &SR);
  494. EXIT();
  495. }
  496. VOID
  497. epvcMiniportQueueWorkItem (
  498. IN PEPVC_WORK_ITEM pEpvcWorkItem,
  499. IN PEPVC_I_MINIPORT pMiniport,
  500. IN PEVPC_WORK_ITEM_FUNC pFn,
  501. IN NDIS_STATUS Status,
  502. IN PRM_STACK_RECORD pSR
  503. )
  504. /*++
  505. Routine Description:
  506. Set up the Epvc Work Item with the pfn, Status and , ref the miniport
  507. and then queue the workitem
  508. Arguments:
  509. --*/
  510. {
  511. ENTER("epvcMiniportQueueWorkItem ", 0xc041af99);
  512. //
  513. // Store the contexts
  514. //
  515. pEpvcWorkItem->ReturnStatus = Status;
  516. pEpvcWorkItem->pParentObj = &pMiniport->Hdr;
  517. pEpvcWorkItem->pFn = pFn;
  518. //
  519. // Ref the RM Obj (its a miniport or an adapter)
  520. //
  521. epvcLinkToExternal( &pMiniport->Hdr,
  522. 0x62efba09,
  523. (UINT_PTR)&pEpvcWorkItem->WorkItem,
  524. EPVC_ASSOC_WORKITEM,
  525. " WorkItem %p\n",
  526. pSR);
  527. //
  528. // Queue the WorkItem
  529. //
  530. epvcInitializeWorkItem (&pMiniport->Hdr,
  531. &pEpvcWorkItem->WorkItem,
  532. epvcCoGenericWorkItem,
  533. NULL,
  534. pSR);
  535. EXIT()
  536. }