|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: transfer.c ! 8: ! 9: Abstract: ! 10: ! 11: This file contains the code to implement the MacTransferData ! 12: API for the ndis 3.0 interface. ! 13: ! 14: Author: ! 15: ! 16: Anthony V. Ercolano (Tonye) 12-Sept-1990 ! 17: Adam Barr (adamba) 15-Mar-1991 ! 18: ! 19: Environment: ! 20: ! 21: Kernel Mode - Or whatever is the equivalent. ! 22: ! 23: Revision History: ! 24: ! 25: ! 26: --*/ ! 27: ! 28: #pragma optimize("",off) ! 29: ! 30: #include <ndis.h> ! 31: ! 32: #include <tfilter.h> ! 33: #include <tokhrd.h> ! 34: #include <toksft.h> ! 35: ! 36: ! 37: extern ! 38: NDIS_STATUS ! 39: IbmtokTransferData( ! 40: IN NDIS_HANDLE MacBindingHandle, ! 41: IN NDIS_HANDLE MacReceiveContext, ! 42: IN UINT ByteOffset, ! 43: IN UINT BytesToTransfer, ! 44: OUT PNDIS_PACKET Packet, ! 45: OUT PUINT BytesTransferred ! 46: ) ! 47: ! 48: /*++ ! 49: ! 50: Routine Description: ! 51: ! 52: A protocol calls the IbmtokTransferData request (indirectly via ! 53: NdisTransferData) from within its Receive event handler ! 54: to instruct the MAC to copy the contents of the received packet ! 55: a specified packet buffer. ! 56: ! 57: Arguments: ! 58: ! 59: MacBindingHandle - The context value returned by the MAC when the ! 60: adapter was opened. In reality this is a pointer to IBMTOK. ! 61: ! 62: MacReceiveContext - The context value passed by the MAC on its call ! 63: to NdisIndicateReceive. The MAC can use this value to determine ! 64: which packet, on which adapter, is being received. ! 65: ! 66: ByteOffset - An unsigned integer specifying the offset within the ! 67: received packet at which the copy is to begin. If the entire packet ! 68: is to be copied, ByteOffset must be zero. ! 69: ! 70: BytesToTransfer - An unsigned integer specifying the number of bytes ! 71: to copy. It is legal to transfer zero bytes; this has no effect. If ! 72: the sum of ByteOffset and BytesToTransfer is greater than the size ! 73: of the received packet, then the remainder of the packet (starting from ! 74: ByteOffset) is transferred, and the trailing portion of the receive ! 75: buffer is not modified. ! 76: ! 77: Packet - A pointer to a descriptor for the packet storage into which ! 78: the MAC is to copy the received packet. ! 79: ! 80: BytesTransfered - A pointer to an unsigned integer. The MAC writes ! 81: the actual number of bytes transferred into this location. This value ! 82: is not valid if the return status is STATUS_PENDING. ! 83: ! 84: Return Value: ! 85: ! 86: The function value is the status of the operation. ! 87: ! 88: ! 89: --*/ ! 90: ! 91: { ! 92: ! 93: PIBMTOK_ADAPTER Adapter; ! 94: ! 95: NDIS_STATUS StatusToReturn; ! 96: ! 97: Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 98: ! 99: NdisAcquireSpinLock(&Adapter->Lock); ! 100: Adapter->References++; ! 101: ! 102: if (!Adapter->NotAcceptingRequests) { ! 103: ! 104: PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 105: ! 106: if (!Open->BindingShuttingDown) { ! 107: ! 108: // ! 109: // The code in this section is quite similar to the ! 110: // code in CopyFromPacketToPacket. It could easily go ! 111: // into its own routine, except that it is not likely ! 112: // to be used in any other implementation. ! 113: // ! 114: SRAM_PTR SourceReceiveBuffer = ! 115: Adapter->IndicatedReceiveBuffer; ! 116: ! 117: // ! 118: // Holds the count of the number of ndis buffers comprising ! 119: // the destination packet. ! 120: // ! 121: UINT DestinationBufferCount; ! 122: ! 123: // ! 124: // Points to the buffer into which we are putting data. ! 125: // ! 126: PNDIS_BUFFER DestinationCurrentBuffer; ! 127: ! 128: // ! 129: // Holds the virtual address of the current destination ! 130: // buffer. ! 131: // ! 132: PVOID DestinationVirtualAddress; ! 133: ! 134: // ! 135: // Holds the virtual address of the current source buffer. ! 136: // ! 137: PRECEIVE_BUFFER SourceBufferAddress; ! 138: ! 139: // ! 140: // Holds the address of the data in the current source buffer. ! 141: // ! 142: PVOID SourceVirtualAddress; ! 143: ! 144: // ! 145: // Holds the length of the current destination buffer. ! 146: // ! 147: UINT DestinationCurrentLength; ! 148: ! 149: // ! 150: // Holds the length of the current source buffer. ! 151: // ! 152: UINT SourceCurrentLength; ! 153: ! 154: // ! 155: // Keep a local variable of BytesTransferred so we aren't ! 156: // referencing through a pointer. ! 157: // ! 158: UINT LocalBytesTransferred = 0; ! 159: ! 160: USHORT PortValue; ! 161: ! 162: Open->References++; ! 163: ! 164: NdisReleaseSpinLock(&Adapter->Lock); ! 165: ! 166: *BytesTransferred = 0; ! 167: ! 168: ASSERT(sizeof(UINT) >= 2); ! 169: ASSERT(sizeof(UINT) == sizeof(NDIS_HANDLE)); ! 170: ! 171: // ! 172: // Get the first buffer of the destination. ! 173: // ! 174: ! 175: NdisQueryPacket( ! 176: Packet, ! 177: NULL, ! 178: &DestinationBufferCount, ! 179: &DestinationCurrentBuffer, ! 180: NULL ! 181: ); ! 182: ! 183: // ! 184: // Could have a null packet. ! 185: // ! 186: ! 187: if (DestinationBufferCount != 0) { ! 188: ! 189: NdisQueryBuffer( ! 190: DestinationCurrentBuffer, ! 191: &DestinationVirtualAddress, ! 192: &DestinationCurrentLength ! 193: ); ! 194: ! 195: // ! 196: // Get the information for the first buffer of the source. ! 197: // ! 198: ! 199: SourceBufferAddress = (PRECEIVE_BUFFER) ! 200: ((PUCHAR)SRAM_PTR_TO_PVOID(Adapter, ! 201: SourceReceiveBuffer) + 2); ! 202: ! 203: // ! 204: // Adjust the address and length to account for the ! 205: // header for this frame. ! 206: // ! 207: ! 208: SourceVirtualAddress = ! 209: SourceBufferAddress->FrameData + ! 210: Adapter->IndicatedHeaderLength; ! 211: ! 212: NdisReadRegisterUshort(&SourceBufferAddress->BufferLength, ! 213: &PortValue ! 214: ); ! 215: ! 216: SourceCurrentLength = IBMSHORT_TO_USHORT(PortValue) - ! 217: Adapter->IndicatedHeaderLength; ! 218: ! 219: ! 220: ! 221: // ! 222: // Take care of boundary condition of zero length copy. ! 223: // ! 224: ! 225: while (LocalBytesTransferred < BytesToTransfer) { ! 226: ! 227: // ! 228: // Check to see whether we've exhausted the current ! 229: // destination buffer. If so, move onto the next one. ! 230: // ! 231: ! 232: if (!DestinationCurrentLength) { ! 233: ! 234: NdisGetNextBuffer( ! 235: DestinationCurrentBuffer, ! 236: &DestinationCurrentBuffer ! 237: ); ! 238: ! 239: if (!DestinationCurrentBuffer) { ! 240: ! 241: // ! 242: // We've reached the end of the packet. We ! 243: // return with what we've done so far. (Which ! 244: // must be shorter than requested.) ! 245: // ! 246: ! 247: break; ! 248: ! 249: } ! 250: ! 251: NdisQueryBuffer( ! 252: DestinationCurrentBuffer, ! 253: &DestinationVirtualAddress, ! 254: &DestinationCurrentLength ! 255: ); ! 256: continue; ! 257: ! 258: } ! 259: ! 260: ! 261: // ! 262: // Check to see whether we've exhausted the current ! 263: // source buffer. If so, move onto the next one. ! 264: // ! 265: ! 266: if (!SourceCurrentLength) { ! 267: ! 268: NdisReadRegisterUshort( ! 269: &SourceBufferAddress->NextBuffer, ! 270: &SourceReceiveBuffer ! 271: ); ! 272: ! 273: if (SourceReceiveBuffer == NULL_SRAM_PTR) { ! 274: ! 275: // ! 276: // We've reached the end of the frame. We ! 277: // return with what we've done so far. (Which ! 278: // must be shorter than requested.) ! 279: // ! 280: ! 281: break; ! 282: ! 283: } ! 284: ! 285: SourceBufferAddress = (PRECEIVE_BUFFER) ! 286: SRAM_PTR_TO_PVOID(Adapter, SourceReceiveBuffer); ! 287: ! 288: SourceVirtualAddress = ! 289: (PVOID)SourceBufferAddress->FrameData; ! 290: ! 291: NdisReadRegisterUshort( ! 292: &SourceBufferAddress->BufferLength, ! 293: &SourceCurrentLength ! 294: ); ! 295: ! 296: SourceCurrentLength = IBMSHORT_TO_USHORT( ! 297: SourceCurrentLength ! 298: ); ! 299: ! 300: continue; ! 301: ! 302: } ! 303: ! 304: // ! 305: // Try to get us up to the point to start the copy. ! 306: // ! 307: ! 308: if (ByteOffset) { ! 309: ! 310: if (ByteOffset > SourceCurrentLength) { ! 311: ! 312: // ! 313: // What we want isn't in this buffer. ! 314: // ! 315: ! 316: ByteOffset -= SourceCurrentLength; ! 317: SourceCurrentLength = 0; ! 318: continue; ! 319: ! 320: } else { ! 321: ! 322: SourceVirtualAddress = ! 323: (PCHAR)SourceVirtualAddress + ByteOffset; ! 324: SourceCurrentLength -= ByteOffset; ! 325: ByteOffset = 0; ! 326: ! 327: } ! 328: ! 329: } ! 330: ! 331: // ! 332: // Copy the data. ! 333: // ! 334: ! 335: { ! 336: ! 337: // ! 338: // Holds the amount of data to move. ! 339: // ! 340: UINT AmountToMove; ! 341: ! 342: // ! 343: // Holds the amount desired remaining. ! 344: // ! 345: UINT Remaining = BytesToTransfer ! 346: - LocalBytesTransferred; ! 347: ! 348: AmountToMove = ! 349: ((SourceCurrentLength <= DestinationCurrentLength)? ! 350: (SourceCurrentLength):(DestinationCurrentLength)); ! 351: ! 352: AmountToMove = ((Remaining < AmountToMove)? ! 353: (Remaining):(AmountToMove)); ! 354: ! 355: IBMTOK_MOVE_FROM_MAPPED_MEMORY( ! 356: DestinationVirtualAddress, ! 357: SourceVirtualAddress, ! 358: AmountToMove ! 359: ); ! 360: ! 361: DestinationVirtualAddress = ! 362: (PCHAR)DestinationVirtualAddress + AmountToMove; ! 363: SourceVirtualAddress = ! 364: (PCHAR)SourceVirtualAddress + AmountToMove; ! 365: ! 366: LocalBytesTransferred += AmountToMove; ! 367: SourceCurrentLength -= AmountToMove; ! 368: DestinationCurrentLength -= AmountToMove; ! 369: ! 370: } ! 371: ! 372: } ! 373: ! 374: *BytesTransferred = LocalBytesTransferred; ! 375: ! 376: } ! 377: ! 378: NdisAcquireSpinLock(&Adapter->Lock); ! 379: Open->References--; ! 380: StatusToReturn = NDIS_STATUS_SUCCESS; ! 381: ! 382: } else { ! 383: ! 384: StatusToReturn = NDIS_STATUS_REQUEST_ABORTED; ! 385: ! 386: } ! 387: ! 388: } else { ! 389: ! 390: if (Adapter->ResetInProgress) { ! 391: ! 392: StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS; ! 393: ! 394: } else if (Adapter->OpenInProgress) { ! 395: ! 396: StatusToReturn = NDIS_STATUS_FAILURE; ! 397: ! 398: } else { ! 399: ! 400: NdisWriteErrorLogEntry( ! 401: Adapter->NdisAdapterHandle, ! 402: NDIS_ERROR_CODE_DRIVER_FAILURE, ! 403: 2, ! 404: IBMTOK_ERRMSG_INVALID_STATE, ! 405: 1 ! 406: ); ! 407: ! 408: } ! 409: ! 410: } ! 411: ! 412: IBMTOK_DO_DEFERRED(Adapter); ! 413: return StatusToReturn; ! 414: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.