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.

2046 lines
40 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. D:\nt\private\ntos\tdi\rawwan\core\receive.c
  5. Abstract:
  6. Routines for receiving data, including TDI and NDIS entry
  7. points and completions.
  8. Revision History:
  9. Who When What
  10. -------- -------- ----------------------------------------------
  11. arvindm 05-16-97 Created
  12. Notes:
  13. --*/
  14. #include <precomp.h>
  15. #define _FILENUMBER 'VCER'
  16. #if STATS
  17. ULONG RecvPktsOk = 0;
  18. ULONG RecvBytesOk = 0;
  19. ULONG RecvPktsFail = 0;
  20. ULONG RecvBytesFail = 0;
  21. #endif // STATS
  22. #if DBG
  23. BOOLEAN bVerifyData = FALSE;
  24. UCHAR CheckChar = 'X';
  25. VOID
  26. RWanCheckDataForChar(
  27. IN PCHAR pHelpString,
  28. IN PVOID Context,
  29. IN PUCHAR pBuffer,
  30. IN ULONG Length,
  31. IN UCHAR Char
  32. );
  33. #define RWAN_CHECK_DATA(_pHelp, _Ctxt, _pBuf, _Len) \
  34. { \
  35. if (bVerifyData) \
  36. { \
  37. RWanCheckDataForChar(_pHelp, _Ctxt, _pBuf, _Len, CheckChar); \
  38. } \
  39. }
  40. #else
  41. #define RWAN_CHECK_DATA(_pHelp, _Ctxt, _pBuf, _Len)
  42. #endif // DBG
  43. #if DBG
  44. VOID
  45. RWanCheckDataForChar(
  46. IN PCHAR pHelpString,
  47. IN PVOID Context,
  48. IN PUCHAR pBuffer,
  49. IN ULONG Length,
  50. IN UCHAR Char
  51. )
  52. {
  53. ULONG i;
  54. PUCHAR pBuf = pBuffer+1;
  55. for (i = 1; i < Length; i++)
  56. {
  57. if (*pBuf == Char)
  58. {
  59. DbgPrint("RAWWAN: %s: %p: Found char %c at offset %d, 0x%p, of buffer 0x%p\n",
  60. pHelpString,
  61. Context,
  62. Char,
  63. i,
  64. pBuf,
  65. pBuffer);
  66. DbgBreakPoint();
  67. }
  68. pBuf++;
  69. }
  70. }
  71. #endif // DBG
  72. RWAN_STATUS
  73. RWanInitReceive(
  74. VOID
  75. )
  76. /*++
  77. Routine Description:
  78. Initialize our receive structures. We allocate a buffer pool and
  79. a packet pool for keeping copies of received packets that we aren't
  80. allowed to keep by the miniport.
  81. Arguments:
  82. None
  83. Return Value:
  84. RWAN_STATUS_SUCCESS if initialized successfully, else RWAN_STATUS_RESOURCES.
  85. --*/
  86. {
  87. RWAN_STATUS RWanStatus;
  88. NDIS_STATUS Status;
  89. //
  90. // Initialize.
  91. //
  92. RWanCopyPacketPool = NULL;
  93. RWanCopyBufferPool = NULL;
  94. RWanStatus = RWAN_STATUS_SUCCESS;
  95. NdisAllocatePacketPoolEx(
  96. &Status,
  97. &RWanCopyPacketPool,
  98. RWAN_INITIAL_COPY_PACKET_COUNT,
  99. RWAN_OVERFLOW_COPY_PACKET_COUNT,
  100. 0
  101. );
  102. if (Status != NDIS_STATUS_SUCCESS)
  103. {
  104. RWanStatus = RWAN_STATUS_RESOURCES;
  105. }
  106. else
  107. {
  108. NdisAllocateBufferPool(
  109. &Status,
  110. &RWanCopyBufferPool,
  111. RWAN_INITIAL_COPY_PACKET_COUNT+RWAN_OVERFLOW_COPY_PACKET_COUNT
  112. );
  113. if (Status != NDIS_STATUS_SUCCESS)
  114. {
  115. NdisFreePacketPool(RWanCopyPacketPool);
  116. RWanCopyPacketPool = NULL;
  117. RWanStatus = RWAN_STATUS_RESOURCES;
  118. }
  119. }
  120. return (RWanStatus);
  121. }
  122. VOID
  123. RWanShutdownReceive(
  124. VOID
  125. )
  126. /*++
  127. Routine Description:
  128. This is shutdown code, to clean up our receive structures.
  129. We free the packet pool and buffer pool allocated when we
  130. init'ed.
  131. Arguments:
  132. None
  133. Return Value:
  134. None
  135. --*/
  136. {
  137. if (RWanCopyPacketPool != NULL)
  138. {
  139. NdisFreePacketPool(RWanCopyPacketPool);
  140. RWanCopyPacketPool = NULL;
  141. }
  142. if (RWanCopyBufferPool != NULL)
  143. {
  144. NdisFreeBufferPool(RWanCopyBufferPool);
  145. RWanCopyBufferPool = NULL;
  146. }
  147. return;
  148. }
  149. TDI_STATUS
  150. RWanTdiReceive(
  151. IN PTDI_REQUEST pTdiRequest,
  152. OUT PUSHORT pFlags,
  153. IN PUINT pReceiveLength,
  154. IN PNDIS_BUFFER pNdisBuffer
  155. )
  156. /*++
  157. Routine Description:
  158. This is the TDI Entry point for receiving data over a connection.
  159. Arguments:
  160. pTdiRequest - Pointer to the TDI Request
  161. pFlags - Place to return additional information about this
  162. receive
  163. pReceiveLength - Points to the total length of the receive buffer chain
  164. pNdisBuffer - Start of receive buffer chain
  165. Return Value:
  166. TDI_PENDING if we queued this receive request successfully
  167. TDI_INVALID_CONNECTION if the Connection context isn't valid
  168. TDI_NO_RESOURCES if we had a resource problem with this receive
  169. --*/
  170. {
  171. RWAN_CONN_ID ConnId;
  172. PRWAN_TDI_CONNECTION pConnObject;
  173. BOOLEAN bIsLockAcquired; // Do we hold the Conn Object lock
  174. PRWAN_NDIS_VC pVc;
  175. TDI_STATUS TdiStatus;
  176. PRWAN_RECEIVE_REQUEST pRcvReq;
  177. PRWAN_NDIS_ADAPTER pAdapter;
  178. //
  179. // Initialize.
  180. //
  181. TdiStatus = TDI_PENDING;
  182. bIsLockAcquired = FALSE;
  183. ConnId = (RWAN_CONN_ID) PtrToUlong(pTdiRequest->Handle.ConnectionContext);
  184. pRcvReq = NULL;
  185. do
  186. {
  187. //
  188. // Allocate space to hold context for this receive
  189. //
  190. pRcvReq = RWanAllocateReceiveReq();
  191. if (pRcvReq == NULL)
  192. {
  193. RWANDEBUGP(DL_INFO, DC_WILDCARD,
  194. ("Rcv: Failed to allocate receive req!\n"));
  195. TdiStatus = TDI_NO_RESOURCES;
  196. break;
  197. }
  198. //
  199. // Prepare the receive request.
  200. //
  201. pRcvReq->Request.pReqComplete = pTdiRequest->RequestNotifyObject;
  202. pRcvReq->Request.ReqContext = pTdiRequest->RequestContext;
  203. pRcvReq->TotalBufferLength = *pReceiveLength;
  204. pRcvReq->AvailableBufferLength = *pReceiveLength;
  205. pRcvReq->pUserFlags = pFlags;
  206. pRcvReq->pBuffer = pNdisBuffer;
  207. NdisQueryBufferSafe(
  208. pNdisBuffer,
  209. &(pRcvReq->pWriteData),
  210. &(pRcvReq->BytesLeftInBuffer),
  211. NormalPagePriority
  212. );
  213. if (pRcvReq->pWriteData == NULL)
  214. {
  215. RWANDEBUGP(DL_INFO, DC_WILDCARD,
  216. ("Rcv: Failed to query req buffer!\n"));
  217. TdiStatus = TDI_NO_RESOURCES;
  218. break;
  219. }
  220. pRcvReq->pNextRcvReq = NULL;
  221. if (pRcvReq->BytesLeftInBuffer > pRcvReq->AvailableBufferLength)
  222. {
  223. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  224. ("Rcv: pRcvReq %x, BytesLeft %d > Available %d, pTdiRequest %x\n",
  225. pRcvReq,
  226. pRcvReq->BytesLeftInBuffer,
  227. pRcvReq->AvailableBufferLength,
  228. pTdiRequest));
  229. pRcvReq->BytesLeftInBuffer = pRcvReq->AvailableBufferLength;
  230. }
  231. //
  232. // See if the given Connection is valid.
  233. //
  234. RWAN_ACQUIRE_CONN_TABLE_LOCK();
  235. pConnObject = RWanGetConnFromId(ConnId);
  236. RWAN_RELEASE_CONN_TABLE_LOCK();
  237. if (pConnObject == NULL_PRWAN_TDI_CONNECTION)
  238. {
  239. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  240. ("Rcv: Invalid connection!\n"));
  241. TdiStatus = TDI_INVALID_CONNECTION;
  242. break;
  243. }
  244. bIsLockAcquired = TRUE;
  245. RWAN_ACQUIRE_CONN_LOCK(pConnObject);
  246. //
  247. // Check the Connection state.
  248. //
  249. if ((pConnObject->State != RWANS_CO_CONNECTED) ||
  250. (RWAN_IS_BIT_SET(pConnObject->Flags, RWANF_CO_CLOSING)))
  251. {
  252. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  253. ("TdiReceive: Conn %x bad state %d/flags %x\n",
  254. pConnObject, pConnObject->State, pConnObject->Flags));
  255. TdiStatus = TDI_INVALID_STATE;
  256. break;
  257. }
  258. pVc = pConnObject->NdisConnection.pNdisVc;
  259. RWAN_ASSERT(pVc != NULL);
  260. RWAN_STRUCT_ASSERT(pVc, nvc);
  261. pAdapter = pVc->pNdisAf->pAdapter;
  262. //
  263. // Queue the receive request at the end of the queue on this VC.
  264. //
  265. if (pVc->pRcvReqHead == NULL)
  266. {
  267. pVc->pRcvReqHead = pVc->pRcvReqTail = pRcvReq;
  268. }
  269. else
  270. {
  271. RWAN_ASSERT(pVc->pRcvReqTail != NULL);
  272. pVc->pRcvReqTail->pNextRcvReq = pRcvReq;
  273. pVc->pRcvReqTail = pRcvReq;
  274. }
  275. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  276. ("Rcv: VC %x, queued RcvReq %x, space available %d bytes\n",
  277. pVc, pRcvReq, pRcvReq->AvailableBufferLength));
  278. //
  279. // Start the common indicate code (for receive requests as well
  280. // as for receive indications).
  281. //
  282. RWAN_RESET_BIT(pConnObject->Flags, RWANF_CO_PAUSE_RECEIVE);
  283. RWanIndicateData(pConnObject);
  284. bIsLockAcquired = FALSE;
  285. //
  286. // Force return of any received packets that we have completed
  287. // processing, to the miniport.
  288. //
  289. RWanNdisReceiveComplete((NDIS_HANDLE)pAdapter);
  290. break;
  291. }
  292. while (FALSE);
  293. if (bIsLockAcquired)
  294. {
  295. RWAN_RELEASE_CONN_LOCK(pConnObject);
  296. }
  297. if (TdiStatus != TDI_PENDING)
  298. {
  299. //
  300. // Error - clean up.
  301. //
  302. if (pRcvReq != NULL)
  303. {
  304. RWanFreeReceiveReq(pRcvReq);
  305. }
  306. }
  307. return (TdiStatus);
  308. }
  309. UINT
  310. RWanNdisCoReceivePacket(
  311. IN NDIS_HANDLE ProtocolBindingContext,
  312. IN NDIS_HANDLE ProtocolVcContext,
  313. IN PNDIS_PACKET pNdisPacket
  314. )
  315. /*++
  316. Routine Description:
  317. This is the NDIS entry point announcing arrival of a packet
  318. on a VC known to us.
  319. Arguments:
  320. ProtocolBindingContext - Pointer to our Adapter context
  321. ProtocolVcContext - Pointer to our VC context
  322. pNdisPacket - the received packet
  323. Return Value:
  324. UINT - this is the reference count we place on the packet.
  325. This is 0 if we either dropped the packet, or if the miniport
  326. had marked the packet with NDIS_STATUS_RESOURCES. Otherwise,
  327. this is 1 (we queue the packet and will call NdisReturnPackets
  328. later).
  329. --*/
  330. {
  331. PRWAN_NDIS_VC pVc;
  332. PRWAN_TDI_CONNECTION pConnObject;
  333. UINT PacketRefCount;
  334. NDIS_STATUS ReceiveStatus;
  335. PRWAN_RECEIVE_INDICATION pRcvInd;
  336. BOOLEAN bIsMiniportPacket; // Are we queueing the miniport's packet?
  337. BOOLEAN bIsLockAcquired;
  338. #if STATS
  339. PNDIS_BUFFER StpNdisBuffer;
  340. PVOID StFirstBufferVa;
  341. UINT StFirstBufferLength;
  342. UINT StTotalLength;
  343. #endif // STATS
  344. UNREFERENCED_PARAMETER(ProtocolBindingContext);
  345. pVc = (PRWAN_NDIS_VC)ProtocolVcContext;
  346. RWAN_STRUCT_ASSERT(pVc, nvc);
  347. RWAN_ASSERT(pNdisPacket);
  348. pConnObject = pVc->pConnObject;
  349. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  350. ("Rcv: VC %x, NdisVCHandle %x, Pkt %x\n",
  351. ProtocolVcContext,
  352. ((PRWAN_NDIS_VC)ProtocolVcContext)->NdisVcHandle,
  353. pNdisPacket));
  354. //
  355. // Initialize.
  356. //
  357. PacketRefCount = 1;
  358. ReceiveStatus = NDIS_STATUS_SUCCESS;
  359. bIsMiniportPacket = TRUE;
  360. bIsLockAcquired = TRUE;
  361. do
  362. {
  363. #if STATS
  364. NdisGetFirstBufferFromPacket(
  365. pNdisPacket,
  366. &StpNdisBuffer,
  367. &StFirstBufferVa,
  368. &StFirstBufferLength,
  369. &StTotalLength
  370. );
  371. #endif // STATS
  372. #if DBG
  373. //
  374. // Debugging miniports indicating up garbage packets.
  375. //
  376. {
  377. ULONG DbgTotalLength;
  378. PNDIS_BUFFER pDbgFirstBuffer;
  379. PVOID pFirstBufferVA;
  380. UINT DbgFirstBufferLength;
  381. UINT DbgTotalBufferLength;
  382. if ((pNdisPacket->Private.Head == NULL) || (pNdisPacket->Private.Tail == NULL))
  383. {
  384. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  385. ("Rcv: VC %x, Pkt %x, Head/Tail is NULL!\n",
  386. ProtocolVcContext, pNdisPacket));
  387. RWAN_ASSERT(FALSE);
  388. }
  389. NdisGetFirstBufferFromPacket(
  390. pNdisPacket,
  391. &pDbgFirstBuffer,
  392. &pFirstBufferVA,
  393. &DbgFirstBufferLength,
  394. &DbgTotalBufferLength
  395. );
  396. if (pDbgFirstBuffer == NULL)
  397. {
  398. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  399. ("Rcv: VC %x, Pkt %x, first buffer is NULL!\n",
  400. ProtocolVcContext, pNdisPacket));
  401. RWAN_ASSERT(FALSE);
  402. }
  403. if (DbgFirstBufferLength == 0)
  404. {
  405. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  406. ("Rcv: VC %x, Pkt %x, first buffer length is 0!\n",
  407. ProtocolVcContext, pNdisPacket));
  408. // RWAN_ASSERT(FALSE);
  409. }
  410. if (DbgTotalBufferLength == 0)
  411. {
  412. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  413. ("Rcv: VC %x, Pkt %x, Total buffer length is 0, FirstBufferLength %d!\n",
  414. ProtocolVcContext, pNdisPacket, DbgFirstBufferLength));
  415. // RWAN_ASSERT(FALSE);
  416. }
  417. if (pFirstBufferVA == NULL)
  418. {
  419. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  420. ("Rcv: VC %x, Pkt %x, FirstBufferVA is NULL, FirstLength %d, Total %d\n",
  421. ProtocolVcContext, pNdisPacket, DbgFirstBufferLength, DbgTotalBufferLength));
  422. RWAN_ASSERT(FALSE);
  423. }
  424. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  425. ("Recv: VC %x, Pkt %x, TotalLength %d bytes\n",
  426. ProtocolVcContext, pNdisPacket, DbgTotalBufferLength));
  427. if (DbgTotalBufferLength == 0)
  428. {
  429. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  430. ("Recv: VC %x, Pkt %x: discarding cuz zero length\n",
  431. ProtocolVcContext, pNdisPacket));
  432. bIsLockAcquired = FALSE;
  433. PacketRefCount = 0;
  434. ReceiveStatus = NDIS_STATUS_FAILURE;
  435. break;
  436. }
  437. }
  438. #endif
  439. //
  440. // See if we are aborting this connection. If so, drop this packet.
  441. //
  442. if (pConnObject == NULL)
  443. {
  444. bIsLockAcquired = FALSE;
  445. PacketRefCount = 0;
  446. ReceiveStatus = NDIS_STATUS_FAILURE;
  447. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  448. ("Rcv: dropping cuz ConnObj is NULL\n"));
  449. break;
  450. }
  451. RWAN_STRUCT_ASSERT(pConnObject, ntc);
  452. RWAN_ACQUIRE_CONN_LOCK(pConnObject);
  453. //
  454. // See if connection is closing. If so, drop this packet.
  455. //
  456. if (RWAN_IS_BIT_SET(pConnObject->Flags, RWANF_CO_CLOSING) ||
  457. ((pConnObject->State != RWANS_CO_CONNECTED) &&
  458. (pConnObject->State != RWANS_CO_IN_CALL_ACCEPTING)))
  459. {
  460. PacketRefCount = 0;
  461. ReceiveStatus = NDIS_STATUS_FAILURE;
  462. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  463. ("Rcv: dropping on Conn %p, Flags %x, State %d\n",
  464. pConnObject, pConnObject->Flags, pConnObject->State));
  465. break;
  466. }
  467. //
  468. // If the packet cannot be queued, attempt to make a copy.
  469. //
  470. if (NDIS_GET_PACKET_STATUS(pNdisPacket) == NDIS_STATUS_RESOURCES)
  471. {
  472. PacketRefCount = 0; // we cannot hang on to this packet
  473. pNdisPacket = RWanMakeReceiveCopy(pNdisPacket);
  474. if (pNdisPacket == NULL)
  475. {
  476. RWANDEBUGP(DL_WARN, DC_WILDCARD,
  477. ("Rcv: failed to allocate receive copy!\n"));
  478. ReceiveStatus = NDIS_STATUS_RESOURCES;
  479. PacketRefCount = 0;
  480. break;
  481. }
  482. bIsMiniportPacket = FALSE;
  483. }
  484. //
  485. // Prepare a receive indication element to keep track of this
  486. // receive.
  487. //
  488. pRcvInd = RWanAllocateReceiveInd();
  489. if (pRcvInd == NULL)
  490. {
  491. PacketRefCount = 0;
  492. ReceiveStatus = NDIS_STATUS_RESOURCES;
  493. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  494. ("Rcv: dropping cuz of failure allocating receive Ind!\n"));
  495. break;
  496. }
  497. pRcvInd->pPacket = pNdisPacket;
  498. pRcvInd->bIsMiniportPacket = bIsMiniportPacket;
  499. pRcvInd->pNextRcvInd = NULL;
  500. pRcvInd->pVc = pVc;
  501. NdisGetFirstBufferFromPacket(
  502. pNdisPacket,
  503. &(pRcvInd->pBuffer),
  504. (PVOID *)&(pRcvInd->pReadData),
  505. &(pRcvInd->BytesLeftInBuffer),
  506. &(pRcvInd->PacketLength)
  507. );
  508. pRcvInd->TotalBytesLeft = pRcvInd->PacketLength;
  509. //
  510. // Queue the receive indication at the end of the receive queue on
  511. // this VC.
  512. //
  513. if (pVc->pRcvIndHead == NULL)
  514. {
  515. pVc->pRcvIndHead = pVc->pRcvIndTail = pRcvInd;
  516. }
  517. else
  518. {
  519. RWAN_ASSERT(pVc->pRcvIndTail != NULL);
  520. pVc->pRcvIndTail->pNextRcvInd = pRcvInd;
  521. pVc->pRcvIndTail = pRcvInd;
  522. }
  523. RWANDEBUGP(DL_EXTRA_LOUD, DC_DATA_RX,
  524. ("CoRcvPacket: Pkt x%x, pVc x%x, pRcvInd x%x, BytesLeft %d, PktLen %d, Head x%x, Tail x%x\n",
  525. pNdisPacket,
  526. pVc,
  527. pRcvInd,
  528. pRcvInd->BytesLeftInBuffer,
  529. pRcvInd->PacketLength,
  530. pVc->pRcvIndHead,
  531. pVc->pRcvIndTail));
  532. pVc->PendingPacketCount++; // Receive Ind
  533. //
  534. // Start the common indicate code (for receive requests as well
  535. // as for receive indications).
  536. //
  537. if (pConnObject->State != RWANS_CO_IN_CALL_ACCEPTING)
  538. {
  539. RWanIndicateData(pConnObject);
  540. }
  541. else
  542. {
  543. RWAN_RELEASE_CONN_LOCK(pConnObject);
  544. RWANDEBUGP(DL_FATAL, DC_DATA_RX,
  545. ("Rcv: queued packet %d bytes on accepting VC %x, pConn %x\n",
  546. pRcvInd->PacketLength, pVc, pConnObject));
  547. }
  548. bIsLockAcquired = FALSE; // It's released within RWanIndicateData
  549. break;
  550. }
  551. while (FALSE);
  552. if (bIsLockAcquired)
  553. {
  554. RWAN_RELEASE_CONN_LOCK(pConnObject);
  555. }
  556. if (ReceiveStatus != NDIS_STATUS_SUCCESS)
  557. {
  558. #if STATS
  559. INCR_STAT(&RecvPktsFail);
  560. ADD_STAT(&RecvBytesFail, StTotalLength);
  561. #endif // STATS
  562. //
  563. // Clean up.
  564. //
  565. if (!bIsMiniportPacket &&
  566. (pNdisPacket != NULL))
  567. {
  568. RWanFreeReceiveCopy(pNdisPacket);
  569. }
  570. }
  571. #if STATS
  572. else
  573. {
  574. INCR_STAT(&RecvPktsOk);
  575. ADD_STAT(&RecvBytesOk, StTotalLength);
  576. }
  577. #endif // STATS
  578. return (PacketRefCount);
  579. }
  580. VOID
  581. RWanIndicateData(
  582. IN PRWAN_TDI_CONNECTION pConnObject
  583. )
  584. /*++
  585. Routine Description:
  586. Core internal receive processing routine. This tries to match up
  587. queued receive requests with queued receive indications and completes
  588. as many requests as it can. It calls the receive event handler, if any,
  589. for a receive indication that reaches the head of its queue without
  590. matching up with a receive request.
  591. Arguments:
  592. pConnObject - Points to our TDI Connection context.
  593. Locks on Entry:
  594. pConnObject
  595. Locks on Exit:
  596. None
  597. Return Value:
  598. None
  599. --*/
  600. {
  601. PRWAN_TDI_ADDRESS pAddrObject;
  602. PRWAN_NDIS_VC pVc;
  603. PRWAN_NDIS_ADAPTER pAdapter;
  604. PRcvEvent pRcvIndEvent;
  605. INT rc;
  606. PRWAN_RECEIVE_REQUEST pRcvReq;
  607. PRWAN_RECEIVE_INDICATION pRcvInd;
  608. PRWAN_RECEIVE_INDICATION pNextRcvInd;
  609. UINT BytesToCopy;
  610. //
  611. // List of receive indications that have been completed here.
  612. //
  613. PRWAN_RECEIVE_INDICATION pCompletedRcvIndHead;
  614. PRWAN_RECEIVE_INDICATION pCompletedRcvIndTail;
  615. BOOLEAN IsMessageMode = TRUE;
  616. //
  617. // TBD: Set IsMessageMode based on the connection type/protocol type.
  618. //
  619. PVOID TdiEventContext;
  620. BOOLEAN bConnectionInBadState = FALSE;
  621. BOOLEAN bContinue = TRUE;
  622. pVc = pConnObject->NdisConnection.pNdisVc;
  623. pAddrObject = pConnObject->pAddrObject;
  624. RWAN_ASSERT(pAddrObject != NULL);
  625. pRcvIndEvent = pAddrObject->pRcvInd;
  626. TdiEventContext = pAddrObject->RcvIndContext;
  627. pCompletedRcvIndHead = NULL;
  628. pCompletedRcvIndTail = NULL;
  629. pAdapter = pVc->pNdisAf->pAdapter;
  630. //
  631. // Check if the client has paused receiving.
  632. //
  633. if (RWAN_IS_BIT_SET(pConnObject->Flags, RWANF_CO_PAUSE_RECEIVE))
  634. {
  635. RWAN_RELEASE_CONN_LOCK(pConnObject);
  636. return;
  637. }
  638. //
  639. // Re-entrancy check.
  640. //
  641. if (RWAN_IS_BIT_SET(pConnObject->Flags, RWANF_CO_INDICATING_DATA))
  642. {
  643. RWAN_RELEASE_CONN_LOCK(pConnObject);
  644. return;
  645. }
  646. RWAN_SET_BIT(pConnObject->Flags, RWANF_CO_INDICATING_DATA);
  647. //
  648. // Make sure the Connection Object doesn't go away as long
  649. // as we are in this routine.
  650. //
  651. RWanReferenceConnObject(pConnObject); // temp ref: RWanIndicateData
  652. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  653. ("=> Ind-Rcv: VC %x/%x, ReqHead %x, IndHead %x\n",
  654. pVc, pVc->Flags, pVc->pRcvReqHead, pVc->pRcvIndHead));
  655. //
  656. // Loop till we run out of receive requests/indications.
  657. //
  658. for (/* Nothing */;
  659. /* Nothing */;
  660. /* Nothing */)
  661. {
  662. if (pVc->pRcvIndHead == NULL)
  663. {
  664. //
  665. // No data to pass up. Quit.
  666. //
  667. break;
  668. }
  669. //
  670. // See if we have data available in the current receive indication.
  671. //
  672. pRcvInd = pVc->pRcvIndHead;
  673. if (pRcvInd->TotalBytesLeft == 0)
  674. {
  675. //
  676. // Move to the next receive indication.
  677. //
  678. pNextRcvInd = pRcvInd->pNextRcvInd;
  679. //
  680. // Add the current receive indication to the list of receive
  681. // indications to be freed up.
  682. //
  683. pRcvInd->pNextRcvInd = NULL;
  684. if (pCompletedRcvIndTail != NULL)
  685. {
  686. pCompletedRcvIndTail->pNextRcvInd = pRcvInd;
  687. }
  688. else
  689. {
  690. pCompletedRcvIndHead = pRcvInd;
  691. }
  692. pCompletedRcvIndTail = pRcvInd;
  693. pVc->PendingPacketCount--; // Moved packet to completed list
  694. //
  695. // Move to the next receive indication.
  696. //
  697. pVc->pRcvIndHead = pNextRcvInd;
  698. pRcvInd = pNextRcvInd;
  699. //
  700. // See if there are no more receive indications.
  701. //
  702. if (pRcvInd == NULL)
  703. {
  704. pVc->pRcvIndTail = NULL;
  705. break;
  706. }
  707. }
  708. #if DBG
  709. if (pRcvInd)
  710. {
  711. RWAN_CHECK_DATA("IndicateData:", pRcvInd, pRcvInd->pReadData, pRcvInd->BytesLeftInBuffer);
  712. }
  713. #endif // DBG
  714. //
  715. // We have data available to pass up.
  716. //
  717. // If we don't have any pending receive requests, and there
  718. // is a Receive Indication event handler available, call the
  719. // handler. We may get back a receive request.
  720. //
  721. if ((pVc->pRcvReqHead == NULL) &&
  722. (pRcvIndEvent != NULL))
  723. {
  724. CONNECTION_CONTEXT ConnectionHandle;
  725. ULONG ReceiveFlags;
  726. ULONG BytesIndicated;
  727. ULONG BytesTaken;
  728. ULONG BytesAvailable;
  729. PVOID pTSDU;
  730. TDI_STATUS TdiStatus;
  731. #ifdef NT
  732. EventRcvBuffer * ERB;
  733. EventRcvBuffer ** pERB = &ERB;
  734. PTDI_REQUEST_KERNEL_RECEIVE pRequestInformation;
  735. PIO_STACK_LOCATION pIrpSp;
  736. #else
  737. EventRcvBuffer ERB;
  738. EventRcvBuffer * pERB = &ERB;
  739. #endif // !NT
  740. //
  741. // Pre-allocate a receive request.
  742. //
  743. pRcvReq = RWanAllocateReceiveReq();
  744. if (pRcvReq == NULL)
  745. {
  746. RWAN_ASSERT(FALSE);
  747. break;
  748. }
  749. pRcvInd = pVc->pRcvIndHead;
  750. ConnectionHandle = pConnObject->ConnectionHandle;
  751. BytesIndicated = pRcvInd->BytesLeftInBuffer;
  752. BytesAvailable = pRcvInd->TotalBytesLeft;
  753. pTSDU = (PVOID)pRcvInd->pReadData;
  754. RWAN_RELEASE_CONN_LOCK(pConnObject);
  755. ReceiveFlags = TDI_RECEIVE_NORMAL | TDI_RECEIVE_ENTIRE_MESSAGE;
  756. BytesTaken = 0;
  757. RWAN_ASSERT(BytesIndicated != 0);
  758. RWAN_ASSERT(BytesAvailable != 0);
  759. TdiStatus = (*pRcvIndEvent)(
  760. TdiEventContext,
  761. ConnectionHandle,
  762. ReceiveFlags,
  763. BytesIndicated,
  764. BytesAvailable,
  765. &BytesTaken,
  766. pTSDU,
  767. pERB
  768. );
  769. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  770. ("Ind-Rcv: VC %x, Head %x, Indicated %d, Available %d, Bytes taken %d, Status %x\n",
  771. pVc, pVc->pRcvReqHead, BytesIndicated, BytesAvailable, BytesTaken, TdiStatus));
  772. RWAN_ACQUIRE_CONN_LOCK(pConnObject);
  773. //
  774. // Check if anything bad happened to this connection
  775. // while we were indicating.
  776. //
  777. if ((pConnObject->State != RWANS_CO_CONNECTED) ||
  778. (RWAN_IS_BIT_SET(pConnObject->Flags, RWANF_CO_CLOSING)))
  779. {
  780. RWanFreeReceiveReq(pRcvReq);
  781. bConnectionInBadState = TRUE;
  782. break;
  783. }
  784. //
  785. // See if a receive request is given to us.
  786. //
  787. if (TdiStatus == TDI_MORE_PROCESSING)
  788. {
  789. //
  790. // We have a receive request. Get at it.
  791. //
  792. #ifdef NT
  793. NTSTATUS Status;
  794. RWAN_ASSERT(ERB != NULL);
  795. pIrpSp = IoGetCurrentIrpStackLocation(*pERB);
  796. Status = RWanPrepareIrpForCancel(
  797. (PRWAN_ENDPOINT) pIrpSp->FileObject->FsContext,
  798. ERB,
  799. RWanCancelRequest
  800. );
  801. if (NT_SUCCESS(Status))
  802. {
  803. pRequestInformation = (PTDI_REQUEST_KERNEL_RECEIVE)
  804. &(pIrpSp->Parameters);
  805. pRcvReq->Request.pReqComplete = RWanDataRequestComplete;
  806. pRcvReq->Request.ReqContext = ERB;
  807. pRcvReq->TotalBufferLength = pRequestInformation->ReceiveLength;
  808. pRcvReq->pBuffer = ERB->MdlAddress;
  809. pRcvReq->pUserFlags = (PUSHORT)
  810. &(pRequestInformation->ReceiveFlags);
  811. #else
  812. pRcvReq->Request.pReqComplete = ERB.erb_rtn;
  813. pRcvReq->Request.ReqContext = ERB.erb_context;
  814. pRcvReq->TotalBufferLength = ERB.erb_size;
  815. pRcvReq->pBuffer = ERB.erb_buffer;
  816. pRcvReq->pUserFlags = ERB.erb_flags;
  817. #endif // NT
  818. pRcvReq->AvailableBufferLength = pRcvReq->TotalBufferLength;
  819. NdisQueryBufferSafe(
  820. pRcvReq->pBuffer,
  821. &(pRcvReq->pWriteData),
  822. &(pRcvReq->BytesLeftInBuffer),
  823. NormalPagePriority
  824. );
  825. if (pRcvReq->pWriteData != NULL)
  826. {
  827. if (pRcvReq->BytesLeftInBuffer > pRcvReq->AvailableBufferLength)
  828. {
  829. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  830. ("Indicate: pRcvReq %x, BytesLeft %d > Available %d, pTdiRequest %x\n",
  831. pRcvReq,
  832. pRcvReq->BytesLeftInBuffer,
  833. pRcvReq->AvailableBufferLength,
  834. pRequestInformation));
  835. pRcvReq->BytesLeftInBuffer = pRcvReq->AvailableBufferLength;
  836. }
  837. pRcvReq->pNextRcvReq = NULL;
  838. //
  839. // Insert this receive request at the head of the pending
  840. // request queue.
  841. //
  842. if (pVc->pRcvReqHead == NULL)
  843. {
  844. pVc->pRcvReqHead = pVc->pRcvReqTail = pRcvReq;
  845. }
  846. else
  847. {
  848. RWAN_ASSERT(pVc->pRcvReqTail != NULL);
  849. pRcvReq->pNextRcvReq = pVc->pRcvReqHead;
  850. pVc->pRcvReqHead = pRcvReq;
  851. }
  852. }
  853. else
  854. {
  855. //
  856. // Couldn't get virtual address of MDL passed in.
  857. //
  858. TdiStatus = TDI_SUCCESS;
  859. RWanFreeReceiveReq(pRcvReq);
  860. pRcvReq = NULL;
  861. }
  862. #ifdef NT
  863. }
  864. else
  865. {
  866. //
  867. // The IRP was cancelled before it got to us.
  868. // Continue as if the user returned SUCCESS.
  869. //
  870. TdiStatus = TDI_SUCCESS;
  871. RWanFreeReceiveReq(pRcvReq);
  872. pRcvReq = NULL;
  873. }
  874. #endif // NT
  875. //
  876. // Update based on what was consumed during the Indicate.
  877. //
  878. pRcvInd->BytesLeftInBuffer -= BytesTaken;
  879. pRcvInd->TotalBytesLeft -= BytesTaken;
  880. //
  881. // If we still don't have any pending receive requests, quit.
  882. //
  883. if (pVc->pRcvReqHead == NULL)
  884. {
  885. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  886. ("Ind: VC %x/%x, ConnObj %x/%x, RcvInd %x, no pending Req\n",
  887. pVc, pVc->Flags,
  888. pConnObject, pConnObject->Flags,
  889. pRcvInd));
  890. break;
  891. }
  892. //
  893. // We have receive requests, so continue from the top.
  894. //
  895. continue;
  896. }
  897. else
  898. {
  899. //
  900. // We didn't get a receive request.
  901. //
  902. if (TdiStatus == TDI_NOT_ACCEPTED)
  903. {
  904. BytesTaken = 0;
  905. //
  906. // By returning this status, the TDI client is telling
  907. // us to stop indicating data on this connection until
  908. // it sends us a TDI receive.
  909. //
  910. RWAN_SET_BIT(pConnObject->Flags, RWANF_CO_PAUSE_RECEIVE);
  911. }
  912. //
  913. // Update based on what was consumed during the Indicate.
  914. //
  915. pRcvInd->BytesLeftInBuffer -= BytesTaken;
  916. pRcvInd->TotalBytesLeft -= BytesTaken;
  917. RWanFreeReceiveReq(pRcvReq);
  918. if (TdiStatus == TDI_SUCCESS)
  919. {
  920. continue;
  921. }
  922. }
  923. } // if Receive Event handler exists
  924. //
  925. // If we still don't have any pending receive requests, quit.
  926. //
  927. if (pVc->pRcvReqHead == NULL)
  928. {
  929. #if DBG1
  930. if (pVc->pRcvIndHead && (pVc->pRcvIndHead->TotalBytesLeft == 0))
  931. {
  932. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  933. ("Ind: VC %x/%x, No pending recv reqs, RcvInd empty!\n", pVc, pVc->Flags));
  934. RWAN_ASSERT(FALSE);
  935. }
  936. #endif
  937. break;
  938. }
  939. //
  940. // Fill in the receive request at the head of the queue
  941. // as much as we can.
  942. //
  943. pRcvReq = pVc->pRcvReqHead;
  944. pRcvInd = pVc->pRcvIndHead;
  945. RWAN_ASSERT(pRcvReq != NULL);
  946. RWAN_ASSERT(pRcvInd != NULL);
  947. while (pRcvReq->AvailableBufferLength != 0)
  948. {
  949. if (pRcvReq->BytesLeftInBuffer == 0)
  950. {
  951. //
  952. // Move to the next buffer in the chain.
  953. //
  954. RWAN_ADVANCE_RCV_REQ_BUFFER(pRcvReq);
  955. RWAN_ASSERT(pRcvReq->BytesLeftInBuffer != 0);
  956. }
  957. RWAN_ASSERT(pRcvInd != NULL);
  958. if (pRcvInd->BytesLeftInBuffer == 0)
  959. {
  960. RWAN_ADVANCE_RCV_IND_BUFFER(pRcvInd);
  961. RWAN_ASSERT(pRcvInd->BytesLeftInBuffer != 0);
  962. }
  963. BytesToCopy = MIN(pRcvReq->BytesLeftInBuffer, pRcvInd->BytesLeftInBuffer);
  964. RWANDEBUGP(DL_EXTRA_LOUD, DC_DATA_RX,
  965. ("IndicateData: pVc x%x, pRcvInd x%x, pRcvReq x%x, copying %d bytes, %x to %x\n",
  966. pVc,
  967. pRcvInd,
  968. pRcvReq,
  969. BytesToCopy,
  970. pRcvInd->pReadData,
  971. pRcvReq->pWriteData));
  972. #if DBG
  973. if (pRcvInd)
  974. {
  975. RWAN_CHECK_DATA("IndicateData - copy:", pRcvInd, pRcvInd->pReadData, BytesToCopy);
  976. }
  977. #endif // DBG
  978. RWAN_COPY_MEM(pRcvReq->pWriteData,
  979. pRcvInd->pReadData,
  980. BytesToCopy);
  981. pRcvReq->pWriteData += BytesToCopy;
  982. pRcvReq->BytesLeftInBuffer -= BytesToCopy;
  983. pRcvReq->AvailableBufferLength -= BytesToCopy;
  984. #if DBG
  985. if (pRcvReq->AvailableBufferLength > pRcvReq->TotalBufferLength)
  986. {
  987. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  988. ("Indicate: VC %x, RcvRq %x, Avail %d > Total %d, BytesToCopy %d, RcvInd %x\n",
  989. pVc, pRcvReq,
  990. pRcvReq->AvailableBufferLength,
  991. pRcvReq->TotalBufferLength,
  992. BytesToCopy,
  993. pRcvInd));
  994. RWAN_ASSERT(FALSE);
  995. }
  996. #endif
  997. pRcvInd->pReadData += BytesToCopy;
  998. pRcvInd->BytesLeftInBuffer -= BytesToCopy;
  999. pRcvInd->TotalBytesLeft -= BytesToCopy;
  1000. //
  1001. // See if we have data available in the current receive indication.
  1002. //
  1003. if (pRcvInd->TotalBytesLeft == 0)
  1004. {
  1005. //
  1006. // Move to the next receive indication.
  1007. //
  1008. pNextRcvInd = pRcvInd->pNextRcvInd;
  1009. //
  1010. // Add the current receive indication to the list of receive
  1011. // indications to be freed up.
  1012. //
  1013. pRcvInd->pNextRcvInd = NULL;
  1014. if (pCompletedRcvIndTail != NULL)
  1015. {
  1016. pCompletedRcvIndTail->pNextRcvInd = pRcvInd;
  1017. }
  1018. else
  1019. {
  1020. pCompletedRcvIndHead = pRcvInd;
  1021. }
  1022. pCompletedRcvIndTail = pRcvInd;
  1023. pVc->PendingPacketCount--; // Moved packet to completed list
  1024. //
  1025. // Move to the next receive indication.
  1026. //
  1027. pVc->pRcvIndHead = pNextRcvInd;
  1028. pRcvInd = pNextRcvInd;
  1029. //
  1030. // See if there are no more receive indications.
  1031. //
  1032. if (pRcvInd == NULL)
  1033. {
  1034. pVc->pRcvIndTail = NULL;
  1035. break;
  1036. }
  1037. //
  1038. // If this connection uses message mode delivery,
  1039. // we don't allow a receive request to span multiple
  1040. // received packets.
  1041. //
  1042. if (IsMessageMode)
  1043. {
  1044. break;
  1045. }
  1046. }
  1047. }
  1048. //
  1049. // A receive request has been filled in either completely
  1050. // or partially. If we are in message mode, complete the
  1051. // receive now, otherwise we will wait for more data.
  1052. //
  1053. if ((pRcvReq->AvailableBufferLength == 0) ||
  1054. IsMessageMode)
  1055. {
  1056. TDI_STATUS ReceiveStatus;
  1057. UINT BytesCopied;
  1058. //
  1059. // A receive request has been fully/partially satisfied. Take it
  1060. // out of the pending list and complete it.
  1061. //
  1062. pVc->pRcvReqHead = pRcvReq->pNextRcvReq;
  1063. if (pVc->pRcvReqHead == NULL)
  1064. {
  1065. pVc->pRcvReqTail = NULL;
  1066. }
  1067. BytesCopied = pRcvReq->TotalBufferLength - pRcvReq->AvailableBufferLength;
  1068. //
  1069. // Check if we copied in only part of a received packet into
  1070. // this receive request. If so, indicate an overflow.
  1071. //
  1072. if ((pRcvReq->AvailableBufferLength == 0) &&
  1073. (pVc->pRcvIndHead != NULL) &&
  1074. (pVc->pRcvIndHead->TotalBytesLeft != pVc->pRcvIndHead->PacketLength))
  1075. {
  1076. RWANDEBUGP(DL_LOUD, DC_WILDCARD,
  1077. ("Ind-Rcv: Overflow: VC %x/%x, Head %x, BytesCopied %d, Left %d\n",
  1078. pVc, pVc->Flags, pVc->pRcvIndHead, BytesCopied, pVc->pRcvIndHead->TotalBytesLeft));
  1079. ReceiveStatus = TDI_BUFFER_OVERFLOW;
  1080. *(pRcvReq->pUserFlags) = 0;
  1081. }
  1082. else
  1083. {
  1084. ReceiveStatus = TDI_SUCCESS;
  1085. *(pRcvReq->pUserFlags) = TDI_RECEIVE_ENTIRE_MESSAGE;
  1086. }
  1087. RWAN_RELEASE_CONN_LOCK(pConnObject);
  1088. *(pRcvReq->pUserFlags) |= TDI_RECEIVE_NORMAL;
  1089. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  1090. ("Ind-Rcv: VC %x/%x, Head %x, completing TDI Rcv %x, %d bytes, Status %x\n",
  1091. pVc, pVc->Flags, pVc->pRcvReqHead, pRcvReq, BytesCopied, ReceiveStatus));
  1092. //
  1093. // Complete the Receive Req
  1094. //
  1095. (*pRcvReq->Request.pReqComplete)(
  1096. pRcvReq->Request.ReqContext,
  1097. ReceiveStatus,
  1098. BytesCopied
  1099. );
  1100. RWanFreeReceiveReq(pRcvReq);
  1101. RWAN_ACQUIRE_CONN_LOCK(pConnObject);
  1102. //
  1103. // Check if anything bad happened to this connection
  1104. // while we were completing the receive request.
  1105. //
  1106. if ((pConnObject->State != RWANS_CO_CONNECTED) ||
  1107. (RWAN_IS_BIT_SET(pConnObject->Flags, RWANF_CO_CLOSING)))
  1108. {
  1109. bConnectionInBadState = TRUE;
  1110. break;
  1111. }
  1112. }
  1113. } // forever
  1114. RWAN_RESET_BIT(pConnObject->Flags, RWANF_CO_INDICATING_DATA);
  1115. rc = RWanDereferenceConnObject(pConnObject); // end temp ref: RWanIndicateData
  1116. if (rc > 0)
  1117. {
  1118. //
  1119. // Update receive indication queue on the VC. Only if the VC
  1120. // is still around...
  1121. //
  1122. if (pVc == pConnObject->NdisConnection.pNdisVc)
  1123. {
  1124. if (bConnectionInBadState)
  1125. {
  1126. ULONG AbortCount = 0;
  1127. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  1128. ("Ind: start abort VC %x/%x state %d, pComplRcvHead %p, tail %p\n",
  1129. pVc, pVc->Flags, pVc->State, pCompletedRcvIndHead, pCompletedRcvIndTail));
  1130. //
  1131. // Take out all pending receives.
  1132. //
  1133. for (pRcvInd = pVc->pRcvIndHead;
  1134. pRcvInd != NULL;
  1135. pRcvInd = pNextRcvInd)
  1136. {
  1137. pNextRcvInd = pRcvInd->pNextRcvInd;
  1138. pRcvInd->pNextRcvInd = NULL;
  1139. if (pCompletedRcvIndTail != NULL)
  1140. {
  1141. pCompletedRcvIndTail->pNextRcvInd = pRcvInd;
  1142. }
  1143. else
  1144. {
  1145. pCompletedRcvIndHead = pRcvInd;
  1146. }
  1147. pCompletedRcvIndTail = pRcvInd;
  1148. pVc->PendingPacketCount--; // Abort: Moved packet to completed list
  1149. AbortCount++;
  1150. }
  1151. pVc->pRcvIndHead = pVc->pRcvIndTail = NULL;
  1152. RWANDEBUGP(DL_INFO, DC_DATA_RX,
  1153. ("Ind: end abort VC %x/%x state %d, pComplRcvHead %p, tail %p, Count %d\n",
  1154. pVc, pVc->Flags, pVc->State, pCompletedRcvIndHead, pCompletedRcvIndTail, AbortCount));
  1155. }
  1156. else
  1157. {
  1158. //
  1159. // Update the first Receive Indication if necessary.
  1160. //
  1161. if (pVc->pRcvIndHead &&
  1162. (pVc->pRcvIndHead->TotalBytesLeft == 0))
  1163. {
  1164. RWANDEBUGP(DL_LOUD, DC_WILDCARD,
  1165. ("Ind: VC %x/%x, empty pRcvInd at head %x\n", pVc, pVc->Flags,
  1166. pVc->pRcvIndHead));
  1167. pRcvInd = pVc->pRcvIndHead;
  1168. pNextRcvInd = pRcvInd->pNextRcvInd;
  1169. pRcvInd->pNextRcvInd = NULL;
  1170. if (pCompletedRcvIndTail != NULL)
  1171. {
  1172. pCompletedRcvIndTail->pNextRcvInd = pRcvInd;
  1173. }
  1174. else
  1175. {
  1176. pCompletedRcvIndHead = pRcvInd;
  1177. }
  1178. pCompletedRcvIndTail = pRcvInd;
  1179. pVc->PendingPacketCount--; // IndComplete: Moved packet to completed list
  1180. pVc->pRcvIndHead = pNextRcvInd;
  1181. if (pVc->pRcvIndHead == NULL)
  1182. {
  1183. pVc->pRcvIndTail = NULL;
  1184. }
  1185. }
  1186. }
  1187. }
  1188. #if DBG
  1189. else
  1190. {
  1191. RWANDEBUGP(DL_FATAL, DC_DATA_RX, ("Ind: ConnObj %p, VC %p blown away!\n",
  1192. pConnObject, pVc));
  1193. }
  1194. #endif // DBG
  1195. //
  1196. // Check if we had queued up an IncomingClose while indicating data:
  1197. //
  1198. if (RWAN_IS_FLAG_SET(pConnObject->Flags, RWANF_CO_PENDED_DISCON, RWANF_CO_PENDED_DISCON))
  1199. {
  1200. RWAN_RESET_BIT(pConnObject->Flags, RWANF_CO_PENDED_DISCON);
  1201. RWANDEBUGP(DL_FATAL, DC_DATA_RX, ("Ind: Conn %x, State %d, Addr %x, handling pended discon\n",
  1202. pConnObject, pConnObject->State, pConnObject->pAddrObject));
  1203. if (pConnObject->pAddrObject != NULL_PRWAN_TDI_ADDRESS)
  1204. {
  1205. PDisconnectEvent pDisconInd;
  1206. PVOID IndContext;
  1207. PVOID ConnectionHandle;
  1208. pDisconInd = pConnObject->pAddrObject->pDisconInd;
  1209. IndContext = pConnObject->pAddrObject->DisconIndContext;
  1210. if (pDisconInd != NULL)
  1211. {
  1212. RWANDEBUGP(DL_FATAL, DC_DATA_RX,
  1213. ("IndicateData: pConnObj %x/%x, st %x, will discon ind\n",
  1214. pConnObject, pConnObject->Flags, pConnObject->State));
  1215. pConnObject->State = RWANS_CO_DISCON_INDICATED;
  1216. ConnectionHandle = pConnObject->ConnectionHandle;
  1217. RWanScheduleDisconnect(pConnObject);
  1218. bContinue = FALSE;
  1219. (*pDisconInd)(
  1220. IndContext,
  1221. ConnectionHandle,
  1222. 0, // Disconnect Data Length
  1223. NULL, // Disconnect Data
  1224. 0, // Disconnect Info Length
  1225. NULL, // Disconnect Info
  1226. TDI_DISCONNECT_RELEASE
  1227. );
  1228. }
  1229. else
  1230. {
  1231. RWAN_ASSERT(FALSE);
  1232. }
  1233. }
  1234. else
  1235. {
  1236. RWAN_ASSERT(FALSE);
  1237. }
  1238. }
  1239. //
  1240. // Check if we need to close this connection.
  1241. //
  1242. if (bContinue)
  1243. {
  1244. if (RWAN_IS_BIT_SET(pVc->Flags, RWANF_VC_NEEDS_CLOSE))
  1245. {
  1246. RWanStartCloseCall(pConnObject, pVc);
  1247. }
  1248. else
  1249. {
  1250. RWAN_RELEASE_CONN_LOCK(pConnObject);
  1251. }
  1252. }
  1253. }
  1254. //
  1255. // Link all completed receive indications to the list on this adapter.
  1256. // They will be returned to the miniport in the ReceiveComplete
  1257. // handler.
  1258. //
  1259. RWAN_ACQUIRE_GLOBAL_LOCK();
  1260. {
  1261. PRWAN_RECEIVE_INDICATION * ppRcvIndTail;
  1262. ppRcvIndTail = &(pAdapter->pCompletedReceives);
  1263. while (*ppRcvIndTail != NULL)
  1264. {
  1265. ppRcvIndTail = &((*ppRcvIndTail)->pNextRcvInd);
  1266. }
  1267. #if DBG
  1268. if (bConnectionInBadState)
  1269. {
  1270. RWANDEBUGP(DL_INFO, DC_WILDCARD,
  1271. ("Ind: Adapter %p &ComplRcvs %p ComplRcvs %p, will tack on %p\n",
  1272. pAdapter,
  1273. &pAdapter->pCompletedReceives,
  1274. pAdapter->pCompletedReceives,
  1275. pCompletedRcvIndHead));
  1276. }
  1277. #endif // DBG
  1278. *ppRcvIndTail = pCompletedRcvIndHead;
  1279. }
  1280. RWAN_RELEASE_GLOBAL_LOCK();
  1281. }
  1282. VOID
  1283. RWanNdisReceiveComplete(
  1284. IN NDIS_HANDLE ProtocolBindingContext
  1285. )
  1286. /*++
  1287. Routine Description:
  1288. This is the entry point called by NDIS when the miniport
  1289. informs it that it has completed indicating a bunch of
  1290. received packets.
  1291. We use this event to free up any completed receives
  1292. on this adapter binding.
  1293. Arguments:
  1294. ProtocolBindingContext - Pointer to our Adapter structure
  1295. Return Value:
  1296. None
  1297. --*/
  1298. {
  1299. PRWAN_NDIS_ADAPTER pAdapter;
  1300. PRWAN_RECEIVE_INDICATION pRcvInd;
  1301. pAdapter = (PRWAN_NDIS_ADAPTER)ProtocolBindingContext;
  1302. RWAN_STRUCT_ASSERT(pAdapter, nad);
  1303. //
  1304. // Detach the list of completed receives from the adapter.
  1305. //
  1306. RWAN_ACQUIRE_GLOBAL_LOCK();
  1307. pRcvInd = pAdapter->pCompletedReceives;
  1308. pAdapter->pCompletedReceives = NULL;
  1309. RWAN_RELEASE_GLOBAL_LOCK();
  1310. RWanFreeReceiveIndList(pRcvInd);
  1311. return;
  1312. }
  1313. VOID
  1314. RWanNdisTransferDataComplete(
  1315. IN NDIS_HANDLE ProtocolBindingContext,
  1316. IN PNDIS_PACKET pNdisPacket,
  1317. IN NDIS_STATUS Status,
  1318. IN UINT BytesTransferred
  1319. )
  1320. /*++
  1321. Routine Description:
  1322. Arguments:
  1323. Return Value:
  1324. None
  1325. --*/
  1326. {
  1327. // Not expected.
  1328. RWAN_ASSERT(FALSE);
  1329. }
  1330. NDIS_STATUS
  1331. RWanNdisReceive(
  1332. IN NDIS_HANDLE ProtocolBindingContext,
  1333. IN NDIS_HANDLE MacReceiveContext,
  1334. IN PVOID HeaderBuffer,
  1335. IN UINT HeaderBufferSize,
  1336. IN PVOID pLookAheadBuffer,
  1337. IN UINT LookAheadBufferSize,
  1338. IN UINT PacketSize
  1339. )
  1340. /*++
  1341. Routine Description:
  1342. Arguments:
  1343. Return Value:
  1344. None
  1345. --*/
  1346. {
  1347. // Not expected.
  1348. RWAN_ASSERT(FALSE);
  1349. return (NDIS_STATUS_FAILURE);
  1350. }
  1351. INT
  1352. RWanNdisReceivePacket(
  1353. IN NDIS_HANDLE ProtocolBindingContext,
  1354. IN PNDIS_PACKET pNdisPacket
  1355. )
  1356. /*++
  1357. Routine Description:
  1358. Arguments:
  1359. Return Value:
  1360. None
  1361. --*/
  1362. {
  1363. // Not expected.
  1364. RWAN_ASSERT(FALSE);
  1365. return (0);
  1366. }
  1367. PRWAN_RECEIVE_REQUEST
  1368. RWanAllocateReceiveReq(
  1369. VOID
  1370. )
  1371. /*++
  1372. Routine Description:
  1373. Allocate a structure to keep context of a TDI Receive request.
  1374. Arguments:
  1375. None
  1376. Return Value:
  1377. Pointer to the allocated receive request structure, or NULL.
  1378. --*/
  1379. {
  1380. PRWAN_RECEIVE_REQUEST pRcvReq;
  1381. RWAN_ALLOC_MEM(pRcvReq, RWAN_RECEIVE_REQUEST, sizeof(RWAN_RECEIVE_REQUEST));
  1382. if (pRcvReq != NULL)
  1383. {
  1384. RWAN_SET_SIGNATURE(pRcvReq, nrr);
  1385. }
  1386. return (pRcvReq);
  1387. }
  1388. VOID
  1389. RWanFreeReceiveReq(
  1390. IN PRWAN_RECEIVE_REQUEST pRcvReq
  1391. )
  1392. /*++
  1393. Routine Description:
  1394. Free a receive request structure.
  1395. Arguments:
  1396. pRcvReq - Points to structure to be freed
  1397. Return Value:
  1398. None
  1399. --*/
  1400. {
  1401. RWAN_STRUCT_ASSERT(pRcvReq, nrr);
  1402. RWAN_FREE_MEM(pRcvReq);
  1403. }
  1404. PRWAN_RECEIVE_INDICATION
  1405. RWanAllocateReceiveInd(
  1406. VOID
  1407. )
  1408. /*++
  1409. Routine Description:
  1410. Allocate a structure to keep context about an NDIS receive indication.
  1411. Arguments:
  1412. None
  1413. Return Value:
  1414. Pointer to the allocated structure, or NULL.
  1415. --*/
  1416. {
  1417. PRWAN_RECEIVE_INDICATION pRcvInd;
  1418. RWAN_ALLOC_MEM(pRcvInd, RWAN_RECEIVE_INDICATION, sizeof(RWAN_RECEIVE_INDICATION));
  1419. if (pRcvInd != NULL)
  1420. {
  1421. RWAN_SET_SIGNATURE(pRcvInd, nri);
  1422. }
  1423. return (pRcvInd);
  1424. }
  1425. VOID
  1426. RWanFreeReceiveInd(
  1427. IN PRWAN_RECEIVE_INDICATION pRcvInd
  1428. )
  1429. /*++
  1430. Routine Description:
  1431. Free a receive indication structure.
  1432. Arguments:
  1433. pRcvInd - Points to structure to be freed.
  1434. Return Value:
  1435. None
  1436. --*/
  1437. {
  1438. RWAN_STRUCT_ASSERT(pRcvInd, nri);
  1439. RWAN_FREE_MEM(pRcvInd);
  1440. }
  1441. PNDIS_PACKET
  1442. RWanMakeReceiveCopy(
  1443. IN PNDIS_PACKET pNdisPacket
  1444. )
  1445. /*++
  1446. Routine Description:
  1447. Make a copy of a received packet to a private packet.
  1448. Arguments:
  1449. pNdisPacket - Points to original packet
  1450. Return Value:
  1451. Pointer to private packet if successful, NULL otherwise.
  1452. --*/
  1453. {
  1454. PNDIS_PACKET pNewPacket;
  1455. PNDIS_BUFFER pNewBuffer;
  1456. PUCHAR pData;
  1457. UINT TotalLength;
  1458. UINT BytesCopied;
  1459. NDIS_STATUS Status;
  1460. //
  1461. // Initialize.
  1462. //
  1463. pNewPacket = NULL;
  1464. pNewBuffer = NULL;
  1465. pData = NULL;
  1466. do
  1467. {
  1468. NdisQueryPacket(
  1469. pNdisPacket,
  1470. NULL,
  1471. NULL,
  1472. NULL,
  1473. &TotalLength
  1474. );
  1475. //
  1476. // Allocate space for the data.
  1477. //
  1478. RWAN_ALLOC_MEM(pData, UCHAR, TotalLength);
  1479. if (pData == NULL)
  1480. {
  1481. break;
  1482. }
  1483. //
  1484. // Make this an NDIS Buffer (MDL).
  1485. //
  1486. NdisAllocateBuffer(
  1487. &Status,
  1488. &pNewBuffer,
  1489. RWanCopyBufferPool,
  1490. pData,
  1491. TotalLength
  1492. );
  1493. if (Status != NDIS_STATUS_SUCCESS)
  1494. {
  1495. break;
  1496. }
  1497. //
  1498. // Allocate a new packet.
  1499. //
  1500. NdisAllocatePacket(
  1501. &Status,
  1502. &pNewPacket,
  1503. RWanCopyPacketPool
  1504. );
  1505. if (Status != NDIS_STATUS_SUCCESS)
  1506. {
  1507. break;
  1508. }
  1509. NDIS_SET_PACKET_STATUS(pNewPacket, 0);
  1510. //
  1511. // Link the buffer to the packet.
  1512. //
  1513. NdisChainBufferAtFront(pNewPacket, pNewBuffer);
  1514. //
  1515. // Copy in the received packet.
  1516. //
  1517. NdisCopyFromPacketToPacket(
  1518. pNewPacket,
  1519. 0, // Destn offset
  1520. TotalLength,
  1521. pNdisPacket,
  1522. 0, // Source offset
  1523. &BytesCopied
  1524. );
  1525. RWAN_ASSERT(BytesCopied == TotalLength);
  1526. break;
  1527. }
  1528. while (FALSE);
  1529. if (pNewPacket == NULL)
  1530. {
  1531. //
  1532. // Clean up.
  1533. //
  1534. if (pData != NULL)
  1535. {
  1536. RWAN_FREE_MEM(pData);
  1537. }
  1538. if (pNewBuffer != NULL)
  1539. {
  1540. NdisFreeBuffer(pNewBuffer);
  1541. }
  1542. }
  1543. return (pNewPacket);
  1544. }
  1545. VOID
  1546. RWanFreeReceiveCopy(
  1547. IN PNDIS_PACKET pCopyPacket
  1548. )
  1549. /*++
  1550. Routine Description:
  1551. Free a packet that was used to keep a copy of a received packet,
  1552. and its components (buffer etc).
  1553. Arguments:
  1554. pCopyPacket - Points to packet to be freed.
  1555. Return Value:
  1556. None
  1557. --*/
  1558. {
  1559. PNDIS_BUFFER pCopyBuffer;
  1560. PUCHAR pCopyData;
  1561. UINT TotalLength;
  1562. UINT BufferLength;
  1563. NdisGetFirstBufferFromPacket(
  1564. pCopyPacket,
  1565. &pCopyBuffer,
  1566. (PVOID *)&pCopyData,
  1567. &BufferLength,
  1568. &TotalLength
  1569. );
  1570. RWAN_ASSERT(BufferLength == TotalLength);
  1571. RWAN_ASSERT(pCopyBuffer != NULL);
  1572. NdisFreePacket(pCopyPacket);
  1573. NdisFreeBuffer(pCopyBuffer);
  1574. RWAN_FREE_MEM(pCopyData);
  1575. return;
  1576. }
  1577. VOID
  1578. RWanFreeReceiveIndList(
  1579. IN PRWAN_RECEIVE_INDICATION pRcvInd
  1580. )
  1581. /*++
  1582. Routine Description:
  1583. Free a list of receive indications, and return any packets in there
  1584. that belong to the miniport.
  1585. Arguments:
  1586. pRcvInd - Head of list of receives.
  1587. Return Value:
  1588. None
  1589. --*/
  1590. {
  1591. PRWAN_RECEIVE_INDICATION pNextRcvInd;
  1592. PNDIS_PACKET pNdisPacket;
  1593. #if DBG
  1594. RWAN_IRQL EntryIrq, ExitIrq;
  1595. #endif // DBG
  1596. RWAN_GET_ENTRY_IRQL(EntryIrq);
  1597. while (pRcvInd != NULL)
  1598. {
  1599. pNextRcvInd = pRcvInd->pNextRcvInd;
  1600. pNdisPacket = pRcvInd->pPacket;
  1601. RWANDEBUGP(DL_EXTRA_LOUD, DC_DATA_RX,
  1602. ("FreeRcvIndList: freeing Pkt x%x, RcvInd x%x\n",
  1603. pNdisPacket, pRcvInd));
  1604. if (pRcvInd->bIsMiniportPacket)
  1605. {
  1606. NdisReturnPackets(&pNdisPacket, 1);
  1607. }
  1608. else
  1609. {
  1610. RWanFreeReceiveCopy(pNdisPacket);
  1611. }
  1612. RWanFreeReceiveInd(pRcvInd);
  1613. pRcvInd = pNextRcvInd;
  1614. }
  1615. RWAN_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  1616. }