- Finish our NDIS S/G DMA implementation

- Totally untested due to lack of HAL S/G support

svn path=/trunk/; revision=41246
This commit is contained in:
Cameron Gutman 2009-06-02 00:37:23 +00:00
parent 5e49d1b3cc
commit 2d20153f5f
4 changed files with 107 additions and 6 deletions

View file

@ -67,6 +67,9 @@ NdisIPnPCancelStopDevice(
IN PDEVICE_OBJECT DeviceObject,
PIRP Irp);
NDIS_STATUS
proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet);
#endif /* __PROTOCOL_H */
/* EOF */

View file

@ -944,12 +944,6 @@ NdisMInitializeScatterGatherDma(
if (!(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_BUS_MASTER))
return NDIS_STATUS_NOT_SUPPORTED;
if (Adapter->NdisMiniportBlock.SystemAdapterObject)
{
NDIS_DbgPrint(MIN_TRACE,("Using existing DMA adapter\n"));
return NDIS_STATUS_SUCCESS;
}
RtlZeroMemory(&DeviceDesc, sizeof(DEVICE_DESCRIPTION));
DeviceDesc.Version = DEVICE_DESCRIPTION_VERSION;
@ -967,6 +961,9 @@ NdisMInitializeScatterGatherDma(
if (!Adapter->NdisMiniportBlock.SystemAdapterObject)
return NDIS_STATUS_RESOURCES;
/* FIXME: Right now we just use this as a place holder */
Adapter->NdisMiniportBlock.ScatterGatherListSize = 1;
return NDIS_STATUS_SUCCESS;
}

View file

@ -430,18 +430,40 @@ MiniSendComplete(
* Status = Status of send operation
*/
{
PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle;
PADAPTER_BINDING AdapterBinding;
KIRQL OldIrql;
PSCATTER_GATHER_LIST SGList;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[1];
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
/* Should we free this before or after calling SendComplete? */
if (Adapter->NdisMiniportBlock.ScatterGatherListSize != 0)
{
NDIS_DbgPrint(MAX_TRACE, ("Freeing Scatter/Gather list\n"));
SGList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet,
ScatterGatherListPacketInfo);
Adapter->NdisMiniportBlock.SystemAdapterObject->
DmaOperations->PutScatterGatherList(
Adapter->NdisMiniportBlock.SystemAdapterObject,
SGList,
TRUE);
NDIS_PER_PACKET_INFO_FROM_PACKET(Packet,
ScatterGatherListPacketInfo) = NULL;
}
(*AdapterBinding->ProtocolBinding->Chars.SendCompleteHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
Packet,
Status);
KeLowerIrql(OldIrql);
}

View file

@ -22,6 +22,11 @@ KSPIN_LOCK ProtocolListLock;
#define WORKER_TEST 0
typedef struct _DMA_CONTEXT {
PLOGICAL_ADAPTER Adapter;
PNDIS_PACKET Packet;
} DMA_CONTEXT, *PDMA_CONTEXT;
PNET_PNP_EVENT
ProSetupPnPEvent(
NET_PNP_EVENT_CODE EventCode,
@ -327,6 +332,33 @@ ProReset(
return NDIS_STATUS_FAILURE;
}
VOID NTAPI
ScatterGatherSendPacket(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PSCATTER_GATHER_LIST ScatterGather,
IN PVOID Context)
{
PDMA_CONTEXT DmaContext = Context;
PLOGICAL_ADAPTER Adapter = DmaContext->Adapter;
PNDIS_PACKET Packet = DmaContext->Packet;
NDIS_STATUS Status;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
NDIS_PER_PACKET_INFO_FROM_PACKET(Packet,
ScatterGatherListPacketInfo) = ScatterGather;
Status = proSendPacketToMiniport(Adapter, Packet);
if (Status != NDIS_STATUS_PENDING) {
NDIS_DbgPrint(MAX_TRACE, ("Completing packet.\n"));
MiniSendComplete(Adapter,
Packet,
Status);
}
}
NDIS_STATUS
proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet)
{
@ -412,6 +444,11 @@ ProSend(
{
PADAPTER_BINDING AdapterBinding;
PLOGICAL_ADAPTER Adapter;
PNDIS_BUFFER NdisBuffer;
PDMA_CONTEXT Context;
NDIS_STATUS NdisStatus;
UINT PacketLength;
KIRQL OldIrql;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
@ -447,6 +484,48 @@ ProSend(
return ProIndicatePacket(Adapter, Packet);
#endif
} else {
if (Adapter->NdisMiniportBlock.ScatterGatherListSize != 0)
{
NDIS_DbgPrint(MAX_TRACE, ("Using Scatter/Gather DMA\n"));
NdisQueryPacket(Packet,
NULL,
NULL,
&NdisBuffer,
&PacketLength);
Context = ExAllocatePool(NonPagedPool, sizeof(DMA_CONTEXT));
if (!Context)
return NDIS_STATUS_RESOURCES;
Context->Adapter = Adapter;
Context->Packet = Packet;
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeFlushIoBuffers(NdisBuffer, FALSE, TRUE);
NdisStatus = Adapter->NdisMiniportBlock.SystemAdapterObject->DmaOperations->GetScatterGatherList(
Adapter->NdisMiniportBlock.SystemAdapterObject,
Adapter->NdisMiniportBlock.PhysicalDeviceObject,
NdisBuffer,
MmGetMdlVirtualAddress(NdisBuffer),
PacketLength,
ScatterGatherSendPacket,
Context,
TRUE);
KeLowerIrql(OldIrql);
if (!NT_SUCCESS(NdisStatus)) {
NDIS_DbgPrint(MIN_TRACE, ("GetScatterGatherList failed!\n"));
return NdisStatus;
}
return NDIS_STATUS_PENDING;
}
return proSendPacketToMiniport(Adapter, Packet);
}
}