Exemplo n.º 1
0
NDIS_STATUS NDIS_API PacketReceiveIndicate(IN NDIS_HANDLE ProtocolBindingContext,
                                           IN NDIS_HANDLE MacReceiveContext,
                                           IN PVOID       HeaderBuffer,
                                           IN UINT        HeaderBufferSize,
                                           IN PVOID       LookaheadBuffer,
                                           IN UINT        LookaheadBufferSize,
                                           IN UINT        PacketSize)
{
  // upcall on packet arrival

  POPEN_INSTANCE      Open;
  PLIST_ENTRY         PacketListEntry;
  PNDIS_PACKET        pPacket;
  NDIS_STATUS         Status;
  UINT                BytesTransfered = 0;
  PPACKET_RESERVED    pReserved;


  if (HeaderBufferSize != ETHERNET_HEADER_LENGTH)
    return NDIS_STATUS_NOT_ACCEPTED;
  
  Open = (POPEN_INSTANCE) ProtocolBindingContext;
  
  //  See if there are any pending reads that we can satisfy
  NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 5.11.97
  
  if (IsListEmpty(&Open->RcvList)) { 
    NdisReleaseSpinLock(&Open->RcvQSpinLock);
    return NDIS_STATUS_NOT_ACCEPTED;
  }

  PacketListEntry = RemoveHeadList(&Open->RcvList);
  NdisReleaseSpinLock(&Open->RcvQSpinLock);
  
  pReserved = CONTAINING_RECORD(PacketListEntry, PACKET_RESERVED, ListElement);
  pPacket = CONTAINING_RECORD(pReserved, NDIS_PACKET, ProtocolReserved);
  
  // Copy the MAC header
  NdisMoveMemory(RESERVED(pPacket)->lpBuffer, HeaderBuffer, HeaderBufferSize);

  //  Call the Mac to transfer the data portion of the packet
  NdisTransferData(&Status, Open->AdapterHandle, MacReceiveContext, 0, PacketSize, pPacket, &BytesTransfered);
  if (Status == NDIS_STATUS_PENDING)
    return NDIS_STATUS_PENDING;

  if (Status == NDIS_STATUS_SUCCESS) {
    PacketTransferDataComplete(Open, pPacket, Status, BytesTransfered);
    return NDIS_STATUS_SUCCESS;
  }

  PacketTransferDataComplete(Open, pPacket, Status, 0);
  return NDIS_STATUS_SUCCESS;
}
Exemplo n.º 2
0
VOID NDIS_API PacketUnbindAdapter(OUT PNDIS_STATUS   Status,
                                  IN  POPEN_INSTANCE Open,
                                  IN  POPEN_INSTANCE junk)
{
  // detach protocol from the NIC clean up any pending I/O requests

  PLIST_ENTRY  PacketListEntry;
  PNDIS_PACKET pPacket;


  //  The open instance of the device is about to close
  //  We need to complete all pending I/O requests
  //  First we complete any pending read requests
  NdisAcquireSpinLock(&Open->RcvQSpinLock);

  while (!IsListEmpty(&Open->RcvList)) {
    PacketListEntry = RemoveHeadList(&Open->RcvList);
    pPacket = CONTAINING_RECORD(PacketListEntry, NDIS_PACKET, ProtocolReserved);

    //  complete normally
    PacketTransferDataComplete(Open, pPacket, NDIS_STATUS_SUCCESS, 0);
  }

  NdisReleaseSpinLock(&Open->RcvQSpinLock);

  // close the adapter
  NdisCloseAdapter(Status, Open->AdapterHandle);

  // Save status returned from NdisCloseAdapter for completion routine
  Open->Status = *Status;

  if (*Status != NDIS_STATUS_PENDING)
    PacketUnbindAdapterComplete(Open, *Status);
}
Exemplo n.º 3
0
/************************************************************
Function that frees the pending requests
************************************************************/
VOID
PacketCleanUp(	PNDIS_STATUS	Status,
                POPEN_INSTANCE	Open )
{
    PLIST_ENTRY			PacketListEntry;
    PNDIS_PACKET   	pPacket;
    PPACKET_RESERVED  Reserved;

    TRACE_ENTER( "Cleanup" );
    /*clean all the pending requests*/
    NdisAcquireSpinLock( &(Open->RcvQSpinLock) );
    while( (PacketListEntry = PacketRemoveHeadList( &(Open->RcvList) )) != NULL )
    {
        IF_VERY_LOUD( "CleanUp - Completing read" );
        Reserved = CONTAINING_RECORD( PacketListEntry, PACKET_RESERVED, ListElement );
        pPacket  = CONTAINING_RECORD( Reserved, NDIS_PACKET, ProtocolReserved );
        /*emulate the end of a transfer to wake the processes that
        are waiting on a request */
        PacketTransferDataComplete( Open, pPacket, NDIS_STATUS_SUCCESS, 0 );
    }
    NdisReleaseSpinLock( &(Open->RcvQSpinLock) );
    TRACE_LEAVE( "Cleanup" );
    return;
}
Exemplo n.º 4
0
NDIS_STATUS
PacketReceiveIndicate (
    IN NDIS_HANDLE ProtocolBindingContext,
    IN NDIS_HANDLE MacReceiveContext,
    IN PVOID       HeaderBuffer,
    IN UINT        HeaderBufferSize,
    IN PVOID       LookAheadBuffer,
    IN UINT        LookaheadBufferSize,
    IN UINT        PacketSize
)
{
	POPEN_INSTANCE      open;
	PIO_STACK_LOCATION  irpSp;
	PIRP                irp;
	PLIST_ENTRY         packetListEntry;
	PNDIS_PACKET        pPacket;
	ULONG               sizeToTransfer;
	NDIS_STATUS         status;
	UINT                bytesTransfered = 0;
	ULONG               bufferLength;
	PPACKET_RESERVED    reserved;
	PMDL                pMdl;

	// DebugPrint(("ReceiveIndicate\n"));

	open= (POPEN_INSTANCE)ProtocolBindingContext;

	if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) {
			return NDIS_STATUS_SUCCESS;
	}

	//  See if there are any pending read that we can satisfy
	packetListEntry = ExInterlockedRemoveHeadList( &open->RcvList, &open->RcvQSpinLock );

	if (packetListEntry == NULL) {
		// DebugPrint(("No pending read, dropping packets\n"));
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	reserved = CONTAINING_RECORD(packetListEntry,PACKET_RESERVED,ListElement);
	pPacket = CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved);

	irp = RESERVED(pPacket)->Irp;
	irpSp = IoGetCurrentIrpStackLocation(irp);

	// We don't have to worry about the situation where the IRP is cancelled
	// after we remove it from the queue and before we reset the cancel
	// routine because the cancel routine has been coded to cancel an IRP
	// only if it's in the queue.

	IoSetCancelRoutine(irp, NULL);

	bufferLength = irpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH;

		sizeToTransfer = (PacketSize < bufferLength) ? PacketSize : bufferLength;

	NdisMoveMappedMemory(
			MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority),
			HeaderBuffer,
			HeaderBufferSize
			);

	pMdl=IoAllocateMdl(
						MmGetMdlVirtualAddress(irp->MdlAddress),
						MmGetMdlByteCount(irp->MdlAddress),
						FALSE,
						FALSE,
						NULL
						);

	if (pMdl == NULL) {
		// DebugPrint(("Packet: Read-Failed to allocate Mdl\n"));
		status = NDIS_STATUS_RESOURCES;
		goto ERROR;
	}

	IoBuildPartialMdl(
			irp->MdlAddress,
			pMdl,
			((PUCHAR)MmGetMdlVirtualAddress(irp->MdlAddress))+ETHERNET_HEADER_LENGTH,
			0
			);

	pMdl->Next = NULL;

	RESERVED(pPacket)->pMdl=pMdl;

	NdisChainBufferAtFront(pPacket,pMdl);

	NdisTransferData(
			&status,
			open->AdapterHandle,
			MacReceiveContext,
			0,
			sizeToTransfer,
			pPacket,
			&bytesTransfered
	);

	if (status == NDIS_STATUS_PENDING) {
		return NDIS_STATUS_SUCCESS;
	}

ERROR:
	PacketTransferDataComplete( open, pPacket, status, bytesTransfered );
	return NDIS_STATUS_SUCCESS;
}