Windows NT 4.0 source code leak
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.

280 lines
6.6 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. lttimer.c
  5. Abstract:
  6. This module contains the polling timer processing routines.
  7. Author:
  8. Stephen Hou (stephh@microsoft.com)
  9. Nikhil Kamkolkar (nikhilk@microsoft.com)
  10. Revision History:
  11. 19 Jun 1992 Initial Version (dch@pacvax.pacersoft.com)
  12. Notes: Tab stop: 4
  13. --*/
  14. #define LTTIMER_H_LOCALS
  15. #include "ltmain.h"
  16. #include "lttimer.h"
  17. #include "ltreset.h"
  18. // Define file id for errorlogging
  19. #define FILENUM LTTIMER
  20. VOID
  21. LtTimerPoll(
  22. IN PVOID SystemSpecific1,
  23. IN PVOID Context,
  24. IN PVOID SystemSpecific2,
  25. IN PVOID SystemSpecific3
  26. )
  27. /*++
  28. Routine Description:
  29. This is the polling timer routine. It will receive data from the card
  30. and process all the queues that are there- send/receive/loopback. NOTE:
  31. Priority must be given to sends.
  32. Arguments:
  33. Context : Pointer to the Adapter structure.
  34. All other parameters as described in NDIS 3.0
  35. Return Value:
  36. None.
  37. --*/
  38. {
  39. USHORT ResponseLength;
  40. UCHAR Data, ResponseType;
  41. LT_INIT_RESPONSE InitPacket;
  42. PRECV_DESC RecvDesc;
  43. PUCHAR RecvPkt;
  44. NDIS_STATUS Status;
  45. BOOLEAN ProcessReset = FALSE;
  46. BOOLEAN ClearCardData = FALSE;
  47. PLT_ADAPTER Adapter = (PLT_ADAPTER)Context;
  48. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_LOW,
  49. ("LtTimerPoll: Entering...\n"));
  50. LtReferenceAdapter(Adapter, &Status);
  51. if (Status != NDIS_STATUS_SUCCESS)
  52. {
  53. // We are probably shutting down.
  54. ASSERTMSG("LtTimerPoll: Adapter not closing!\n",
  55. ((Adapter->Flags & ADAPTER_CLOSING) == 0));
  56. // Remove the reference we added at timer set.
  57. LtDeReferenceAdapter(Adapter);
  58. return;
  59. }
  60. // BUGBUG: Verify reset handling.
  61. // !!! Send's get very high priority. In total, the queue is processed
  62. // !!! three times, twice in the timer and once in LtSend
  63. LtSendProcessQueue(Adapter);
  64. // Check for receive data
  65. NdisRawReadPortUchar(SC_PORT, &Data);
  66. if (Data & RX_READY)
  67. {
  68. // Get the length of the response on the card
  69. NdisRawReadPortUchar(XFER_PORT, &Data);
  70. ResponseLength = (USHORT)(Data & 0xFF);
  71. NdisRawReadPortUchar(XFER_PORT, &Data);
  72. ResponseLength |= (Data << 8);
  73. // Now get the IO code.
  74. NdisRawReadPortUchar(XFER_PORT, &ResponseType);
  75. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_INFO,
  76. ("LtPoll: RespType = %x, RespLength = %d\n",
  77. ResponseType, ResponseLength));
  78. switch (ResponseType)
  79. {
  80. case LT_RSP_LAP_INIT:
  81. if (ResponseLength != sizeof(LT_INIT_RESPONSE))
  82. {
  83. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_ERR,
  84. ("LtTimerPoll: Bad response length %lx! \n", ResponseLength));
  85. ClearCardData = TRUE;
  86. }
  87. break;
  88. case LT_RSP_LAP_FRAME:
  89. // Verify the frame is of the maximum packet size possible.
  90. if (ResponseLength > LT_MAX_PACKET_SIZE)
  91. {
  92. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_ERR,
  93. ("LtTimerPoll: Bad packet length %lx! \n", ResponseLength));
  94. // Keep track of number of bad receives
  95. NdisDprAcquireSpinLock(&Adapter->Lock);
  96. ++Adapter->GeneralMandatory[GM_RECEIVE_BAD];
  97. NdisDprReleaseSpinLock(&Adapter->Lock);
  98. ClearCardData = TRUE;
  99. break;
  100. }
  101. // Allocate a receive buffer descriptor for the packet.
  102. NdisAllocateMemory(
  103. &RecvDesc,
  104. (UINT)(sizeof(RECV_DESC)+ResponseLength),
  105. 0,
  106. LtNdisPhyAddr);
  107. if (RecvDesc == NULL)
  108. {
  109. // Keep track of the number of times we couldnt get a buffer.
  110. NdisDprAcquireSpinLock(&Adapter->Lock);
  111. ++Adapter->GeneralMandatory[GM_RECEIVE_NO_BUFFER];
  112. NdisDprReleaseSpinLock(&Adapter->Lock);
  113. ClearCardData = TRUE;
  114. break;
  115. }
  116. // Get a pointer to the receive packet storage.
  117. RecvPkt = (PUCHAR)((PUCHAR)RecvDesc + sizeof(RECV_DESC));
  118. NdisRawReadPortBufferUchar(XFER_PORT,
  119. RecvPkt,
  120. ResponseLength);
  121. RecvDesc->Broadcast = IS_PACKET_BROADCAST(RecvPkt);
  122. RecvDesc->BufferLength = ResponseLength;
  123. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_INFO,
  124. ("LtTimerPoll: Recd Pkt Desc %lx Pkt %lx! \n",
  125. RecvDesc, RecvPkt));
  126. NdisDprAcquireSpinLock(&Adapter->Lock);
  127. ++Adapter->GeneralMandatory[GM_RECEIVE_GOOD];
  128. if (RecvDesc->Broadcast)
  129. {
  130. ++Adapter->GeneralOptionalFrameCount[GO_BROADCAST_RECEIVES];
  131. LtAddLongToLargeInteger(
  132. Adapter->GeneralOptionalByteCount[GO_BROADCAST_RECEIVES],
  133. RecvDesc->BufferLength);
  134. Adapter->MediaMandatory[MM_IN_BROADCASTS]++;
  135. }
  136. else
  137. {
  138. ++Adapter->GeneralOptionalFrameCount[GO_DIRECTED_RECEIVES];
  139. LtAddLongToLargeInteger(
  140. Adapter->GeneralOptionalByteCount[GO_DIRECTED_RECEIVES],
  141. RecvDesc->BufferLength);
  142. }
  143. InsertTailList(
  144. &Adapter->Receive,
  145. &RecvDesc->Linkage);
  146. NdisDprReleaseSpinLock(&Adapter->Lock);
  147. break;
  148. case LT_RSP_STATUS:
  149. if (ResponseLength != sizeof(LT_STATUS_RESPONSE))
  150. {
  151. ClearCardData = TRUE;
  152. break;
  153. }
  154. NdisRawReadPortBufferUchar(XFER_PORT,
  155. (PUCHAR)&Adapter->LastCardStatusResponse,
  156. ResponseLength);
  157. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_INFO,
  158. ("Node ID = %lx, Rom Ver = %lx, FirmWare Ver %lx\n",
  159. Adapter->LastCardStatusResponse.NodeId,
  160. Adapter->LastCardStatusResponse.RomVer,
  161. Adapter->LastCardStatusResponse.SwVer));
  162. break;
  163. default:
  164. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_ERR,
  165. ("LtTimerPoll: Unknown response type %lx\n", ResponseType));
  166. ClearCardData = TRUE;
  167. break;
  168. }
  169. }
  170. if (ClearCardData)
  171. {
  172. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_WARN,
  173. ("LtTimerPoll: Clearing Card of response %d\n", ResponseLength));
  174. while (ResponseLength-- > 0 )
  175. {
  176. NdisRawReadPortUchar(XFER_PORT, &Data);
  177. }
  178. }
  179. // Call all the processing routines if their respective queues are
  180. // not empty!
  181. NdisDprAcquireSpinLock(&Adapter->Lock);
  182. ASSERT (Adapter->Flags & ADAPTER_NODE_ID_VALID);
  183. if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS)
  184. {
  185. ProcessReset = TRUE;
  186. }
  187. NdisDprReleaseSpinLock(&Adapter->Lock);
  188. if (ProcessReset)
  189. {
  190. LtResetComplete(Adapter);
  191. }
  192. // Process our receive queue.
  193. LtRecvProcessQueue(Adapter);
  194. // Process send queue as processing receives would have entailed
  195. // some sends.
  196. // NOTE: Process LoopQueue after SendQueue as the Send Packet
  197. // goes into the loop queue if it is a broadcast, after
  198. // being sent out on the net.
  199. LtSendProcessQueue(Adapter);
  200. LtLoopProcessQueue(Adapter);
  201. DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_LOW,
  202. ("LtTimerPoll: Setting timer and Leaving...\n"));
  203. // Re-arm the timer
  204. NdisSetTimer(&Adapter->PollingTimer, LT_POLLING_TIME);
  205. // Remove the reference we added at the beginning of this routine.
  206. LtDeReferenceAdapter(Adapter);
  207. }