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.

322 lines
6.3 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. send.c
  5. Abstract:
  6. This file contains the code for putting a packet through the
  7. staged allocation for transmission.
  8. This is a process of
  9. 1) Calculating the what would need to be done to the
  10. packet so that the packet can be transmitted on the hardware.
  11. 2) Potentially allocating adapter buffers and copying user data
  12. to those buffers so that the packet data is transmitted under
  13. the hardware constraints.
  14. 3) Allocating enough hardware ring entries so that the packet
  15. can be transmitted.
  16. 4) Relinquish thos ring entries to the hardware.
  17. The overall structure and most of the code is taken from
  18. the Lance driver by Tony Ercolano.
  19. Author:
  20. Anthony V. Ercolano (Tonye) 12-Sept-1990
  21. Adam Barr (adamba) 16-Nov-1990
  22. Environment:
  23. Kernel Mode - Or whatever is the equivalent.
  24. Revision History:
  25. --*/
  26. #include <ndis.h>
  27. #include <tfilter.h>
  28. #include <tokhrd.h>
  29. #include <toksft.h>
  30. #if DEVL
  31. #define STATIC
  32. #else
  33. #define STATIC static
  34. #endif
  35. #if DBG
  36. extern INT IbmtokDbg;
  37. extern UCHAR Packets[5][64];
  38. extern UCHAR NextPacket;
  39. #endif
  40. #ifdef CHECK_DUP_SENDS
  41. //
  42. // CHECK_DUP_SENDS enables checking ownership of packets, to
  43. // make sure we are not given the same packet twice, or
  44. // complete the same packet twice.
  45. //
  46. #define PACKET_LIST_SIZE 50
  47. PNDIS_PACKET IbmtokPacketList[PACKET_LIST_SIZE];
  48. IbmtokPacketListSize = 0;
  49. IbmtokPacketsAdded = 0;
  50. IbmtokPacketsRemoved = 0;
  51. VOID
  52. IbmtokAddPacketToList(
  53. PIBMTOK_ADAPTER Adapter,
  54. PNDIS_PACKET NewPacket
  55. )
  56. {
  57. INT i;
  58. ++IbmtokPacketsAdded;
  59. for (i=0; i<IbmtokPacketListSize; i++) {
  60. if (IbmtokPacketList[i] == NewPacket) {
  61. DbgPrint("IBMTOK: dup send of %lx\n", NewPacket);
  62. }
  63. }
  64. IbmtokPacketList[IbmtokPacketListSize] = NewPacket;
  65. ++IbmtokPacketListSize;
  66. }
  67. VOID
  68. IbmtokRemovePacketFromList(
  69. PIBMTOK_ADAPTER Adapter,
  70. PNDIS_PACKET OldPacket
  71. )
  72. {
  73. INT i;
  74. ++IbmtokPacketsRemoved;
  75. for (i=0; i<IbmtokPacketListSize; i++) {
  76. if (IbmtokPacketList[i] == OldPacket) {
  77. break;
  78. }
  79. }
  80. if (i == IbmtokPacketListSize) {
  81. DbgPrint("IBMTOK: bad remove of %lx\n", OldPacket);
  82. } else {
  83. --IbmtokPacketListSize;
  84. IbmtokPacketList[i] = IbmtokPacketList[IbmtokPacketListSize];
  85. }
  86. }
  87. #endif // CHECK_DUP_SENDS
  88. extern
  89. NDIS_STATUS
  90. IbmtokSend(
  91. IN NDIS_HANDLE MacBindingHandle,
  92. IN PNDIS_PACKET Packet
  93. )
  94. /*++
  95. Routine Description:
  96. The IbmtokSend request instructs a MAC to transmit a packet through
  97. the adapter onto the medium.
  98. Arguments:
  99. MacBindingHandle - The context value returned by the MAC when the
  100. adapter was opened. In reality, it is a pointer to IBMTOK_OPEN.
  101. Packet - A pointer to a descriptor for the packet that is to be
  102. transmitted.
  103. Return Value:
  104. The function value is the status of the operation.
  105. --*/
  106. {
  107. //
  108. // Holds the status that should be returned to the caller.
  109. //
  110. NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING;
  111. //
  112. // Pointer to the adapter.
  113. //
  114. PIBMTOK_ADAPTER Adapter;
  115. ULONG PacketLength;
  116. Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
  117. NdisQueryPacket(
  118. Packet,
  119. NULL,
  120. NULL,
  121. NULL,
  122. &PacketLength
  123. );
  124. //
  125. // Check that the packet will go on the wire. Note: I do not
  126. // check that we have enough receive space to receive a packet
  127. // of this size -- it is up to a protocol to work this out.
  128. //
  129. if ((PacketLength < 14) ||
  130. (PacketLength > Adapter->MaxTransmittablePacket)) {
  131. return(NDIS_STATUS_INVALID_PACKET);
  132. }
  133. NdisAcquireSpinLock(&Adapter->Lock);
  134. Adapter->References++;
  135. if (Adapter->Unplugged) {
  136. StatusToReturn = NDIS_STATUS_DEVICE_FAILED;
  137. } else if (!Adapter->NotAcceptingRequests) {
  138. PIBMTOK_OPEN Open;
  139. PIBMTOK_RESERVED Reserved = PIBMTOK_RESERVED_FROM_PACKET(Packet);
  140. Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
  141. if (!Open->BindingShuttingDown) {
  142. //
  143. // We do not have to increment the open count. Since we hold
  144. // the lock for the entire function we cannot have the open
  145. // removed out from under us.
  146. //
  147. //
  148. // NOTE NOTE NOTE !!!!!!
  149. //
  150. // There is an assumption in the code that no pointer
  151. // (which are really handles) to an ndis packet will have
  152. // its low bit set. (Always have even byte alignment.)
  153. //
  154. ASSERT(!((UINT)Packet & 1));
  155. //
  156. // ALL packets go on the wire (loopback is done
  157. // by the card).
  158. //
  159. #ifdef CHECK_DUP_SENDS
  160. IbmtokAddPacketToList(Adapter, Packet);
  161. #endif
  162. Reserved->MacBindingHandle = MacBindingHandle;
  163. Reserved->Packet = Packet;
  164. if (Adapter->FirstTransmit == NULL) {
  165. Adapter->FirstTransmit = Packet;
  166. } else {
  167. PIBMTOK_RESERVED_FROM_PACKET(Adapter->LastTransmit)->Next = Packet;
  168. }
  169. Adapter->LastTransmit = Packet;
  170. Reserved->Next = NULL;
  171. //
  172. // Increment the reference on the open since it
  173. // will be leaving this packet around on the transmit
  174. // queues.
  175. //
  176. Open->References++;
  177. //
  178. // This will send the transmit SRB command
  179. // if the SRB is available.
  180. //
  181. IbmtokProcessSrbRequests(
  182. Adapter
  183. );
  184. } else {
  185. StatusToReturn = NDIS_STATUS_CLOSING;
  186. }
  187. } else {
  188. if (Adapter->ResetInProgress) {
  189. StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
  190. } else if (Adapter->AdapterNotOpen) {
  191. StatusToReturn = NDIS_STATUS_FAILURE;
  192. } else {
  193. NdisWriteErrorLogEntry(
  194. Adapter->NdisAdapterHandle,
  195. NDIS_ERROR_CODE_DRIVER_FAILURE,
  196. 2,
  197. IBMTOK_ERRMSG_INVALID_STATE,
  198. 2
  199. );
  200. }
  201. }
  202. //
  203. // This macro assumes it is called with the lock held,
  204. // and releases it.
  205. //
  206. IBMTOK_DO_DEFERRED(Adapter);
  207. return StatusToReturn;
  208. }