|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: send.c ! 8: ! 9: Abstract: ! 10: ! 11: This file contains the code for putting a packet through the ! 12: staged allocation for transmission. ! 13: ! 14: This is a process of ! 15: ! 16: 1) Calculating the what would need to be done to the ! 17: packet so that the packet can be transmitted on the hardware. ! 18: ! 19: 2) Potentially allocating adapter buffers and copying user data ! 20: to those buffers so that the packet data is transmitted under ! 21: the hardware constraints. ! 22: ! 23: 3) Allocating enough hardware ring entries so that the packet ! 24: can be transmitted. ! 25: ! 26: 4) Relinquish thos ring entries to the hardware. ! 27: ! 28: The overall structure and most of the code is taken from ! 29: the Lance driver by Tony Ercolano. ! 30: ! 31: Author: ! 32: ! 33: Anthony V. Ercolano (Tonye) 12-Sept-1990 ! 34: Adam Barr (adamba) 16-Nov-1990 ! 35: ! 36: Environment: ! 37: ! 38: Kernel Mode - Or whatever is the equivalent. ! 39: ! 40: Revision History: ! 41: ! 42: ! 43: --*/ ! 44: ! 45: #pragma optimize("",off) ! 46: ! 47: #include <ndis.h> ! 48: ! 49: #include <tfilter.h> ! 50: #include <tokhrd.h> ! 51: #include <toksft.h> ! 52: ! 53: ! 54: #if DEVL ! 55: #define STATIC ! 56: #else ! 57: #define STATIC static ! 58: #endif ! 59: ! 60: #if DBG ! 61: extern INT IbmtokDbg; ! 62: ! 63: extern UCHAR Packets[5][64]; ! 64: extern UCHAR NextPacket; ! 65: #endif ! 66: ! 67: ! 68: ! 69: #ifdef CHECK_DUP_SENDS ! 70: ! 71: // ! 72: // CHECK_DUP_SENDS enables checking ownership of packets, to ! 73: // make sure we are not given the same packet twice, or ! 74: // complete the same packet twice. ! 75: // ! 76: ! 77: #define PACKET_LIST_SIZE 50 ! 78: ! 79: PNDIS_PACKET IbmtokPacketList[PACKET_LIST_SIZE]; ! 80: IbmtokPacketListSize = 0; ! 81: IbmtokPacketsAdded = 0; ! 82: IbmtokPacketsRemoved = 0; ! 83: ! 84: VOID ! 85: IbmtokAddPacketToList( ! 86: PIBMTOK_ADAPTER Adapter, ! 87: PNDIS_PACKET NewPacket ! 88: ) ! 89: { ! 90: INT i; ! 91: ! 92: ++IbmtokPacketsAdded; ! 93: ! 94: for (i=0; i<IbmtokPacketListSize; i++) { ! 95: ! 96: if (IbmtokPacketList[i] == NewPacket) { ! 97: ! 98: DbgPrint("IBMTOK: dup send of %lx\n", NewPacket); ! 99: ! 100: } ! 101: ! 102: } ! 103: ! 104: IbmtokPacketList[IbmtokPacketListSize] = NewPacket; ! 105: ++IbmtokPacketListSize; ! 106: ! 107: } ! 108: ! 109: VOID ! 110: IbmtokRemovePacketFromList( ! 111: PIBMTOK_ADAPTER Adapter, ! 112: PNDIS_PACKET OldPacket ! 113: ) ! 114: { ! 115: INT i; ! 116: ! 117: ++IbmtokPacketsRemoved; ! 118: ! 119: for (i=0; i<IbmtokPacketListSize; i++) { ! 120: ! 121: if (IbmtokPacketList[i] == OldPacket) { ! 122: ! 123: break; ! 124: ! 125: } ! 126: ! 127: } ! 128: ! 129: if (i == IbmtokPacketListSize) { ! 130: ! 131: DbgPrint("IBMTOK: bad remove of %lx\n", OldPacket); ! 132: ! 133: } else { ! 134: ! 135: --IbmtokPacketListSize; ! 136: IbmtokPacketList[i] = IbmtokPacketList[IbmtokPacketListSize]; ! 137: ! 138: } ! 139: ! 140: } ! 141: #endif // CHECK_DUP_SENDS ! 142: ! 143: ! 144: extern ! 145: NDIS_STATUS ! 146: IbmtokSend( ! 147: IN NDIS_HANDLE MacBindingHandle, ! 148: IN PNDIS_PACKET Packet ! 149: ) ! 150: ! 151: /*++ ! 152: ! 153: Routine Description: ! 154: ! 155: The IbmtokSend request instructs a MAC to transmit a packet through ! 156: the adapter onto the medium. ! 157: ! 158: Arguments: ! 159: ! 160: MacBindingHandle - The context value returned by the MAC when the ! 161: adapter was opened. In reality, it is a pointer to IBMTOK_OPEN. ! 162: ! 163: Packet - A pointer to a descriptor for the packet that is to be ! 164: transmitted. ! 165: ! 166: Return Value: ! 167: ! 168: The function value is the status of the operation. ! 169: ! 170: ! 171: --*/ ! 172: ! 173: { ! 174: ! 175: // ! 176: // Holds the status that should be returned to the caller. ! 177: // ! 178: NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING; ! 179: ! 180: // ! 181: // Pointer to the adapter. ! 182: // ! 183: PIBMTOK_ADAPTER Adapter; ! 184: ! 185: ULONG PacketLength; ! 186: ! 187: Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 188: ! 189: NdisQueryPacket( ! 190: Packet, ! 191: NULL, ! 192: NULL, ! 193: NULL, ! 194: &PacketLength ! 195: ); ! 196: ! 197: // ! 198: // Check that the packet will go on the wire. Note: I do not ! 199: // check that we have enough receive space to receive a packet ! 200: // of this size -- it is up to a protocol to work this out. ! 201: // ! 202: ! 203: if ((PacketLength < 14) || ! 204: (PacketLength > Adapter->MaxTransmittablePacket)) { ! 205: ! 206: return(NDIS_STATUS_INVALID_PACKET); ! 207: ! 208: } ! 209: ! 210: NdisAcquireSpinLock(&Adapter->Lock); ! 211: ! 212: Adapter->References++; ! 213: ! 214: if (Adapter->Unplugged) { ! 215: ! 216: StatusToReturn = NDIS_STATUS_DEVICE_FAILED; ! 217: ! 218: } else if (!Adapter->NotAcceptingRequests) { ! 219: ! 220: PIBMTOK_OPEN Open; ! 221: PIBMTOK_RESERVED Reserved = PIBMTOK_RESERVED_FROM_PACKET(Packet); ! 222: ! 223: Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 224: ! 225: if (!Open->BindingShuttingDown) { ! 226: ! 227: // ! 228: // We do not have to increment the open count. Since we hold ! 229: // the lock for the entire function we cannot have the open ! 230: // removed out from under us. ! 231: // ! 232: ! 233: // ! 234: // NOTE NOTE NOTE !!!!!! ! 235: // ! 236: // There is an assumption in the code that no pointer ! 237: // (which are really handles) to an ndis packet will have ! 238: // its low bit set. (Always have even byte alignment.) ! 239: // ! 240: ! 241: ASSERT(!((UINT)Packet & 1)); ! 242: ! 243: // ! 244: // ALL packets go on the wire (loopback is done ! 245: // by the card). ! 246: // ! 247: #ifdef CHECK_DUP_SENDS ! 248: IbmtokAddPacketToList(Adapter, Packet); ! 249: #endif ! 250: ! 251: Reserved->MacBindingHandle = MacBindingHandle; ! 252: Reserved->Packet = Packet; ! 253: ! 254: if (Adapter->FirstTransmit == NULL) { ! 255: ! 256: Adapter->FirstTransmit = Packet; ! 257: ! 258: } else { ! 259: ! 260: PIBMTOK_RESERVED_FROM_PACKET(Adapter->LastTransmit)->Next = Packet; ! 261: ! 262: } ! 263: ! 264: Adapter->LastTransmit = Packet; ! 265: ! 266: Reserved->Next = NULL; ! 267: ! 268: // ! 269: // Increment the reference on the open since it ! 270: // will be leaving this packet around on the transmit ! 271: // queues. ! 272: // ! 273: ! 274: Open->References++; ! 275: ! 276: // ! 277: // This will send the transmit SRB command ! 278: // if the SRB is available. ! 279: // ! 280: ! 281: IbmtokProcessSrbRequests( ! 282: Adapter ! 283: ); ! 284: ! 285: } else { ! 286: ! 287: StatusToReturn = NDIS_STATUS_CLOSING; ! 288: ! 289: } ! 290: ! 291: } else { ! 292: ! 293: if (Adapter->ResetInProgress) { ! 294: ! 295: StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS; ! 296: ! 297: } else if (Adapter->AdapterNotOpen) { ! 298: ! 299: StatusToReturn = NDIS_STATUS_FAILURE; ! 300: ! 301: } else { ! 302: ! 303: NdisWriteErrorLogEntry( ! 304: Adapter->NdisAdapterHandle, ! 305: NDIS_ERROR_CODE_DRIVER_FAILURE, ! 306: 2, ! 307: IBMTOK_ERRMSG_INVALID_STATE, ! 308: 2 ! 309: ); ! 310: ! 311: } ! 312: ! 313: } ! 314: ! 315: ! 316: // ! 317: // This macro assumes it is called with the lock held, ! 318: // and releases it. ! 319: // ! 320: ! 321: IBMTOK_DO_DEFERRED(Adapter); ! 322: return StatusToReturn; ! 323: } ! 324:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.