- 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, IN PDEVICE_OBJECT DeviceObject,
PIRP Irp); PIRP Irp);
NDIS_STATUS
proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet);
#endif /* __PROTOCOL_H */ #endif /* __PROTOCOL_H */
/* EOF */ /* EOF */

View file

@ -944,12 +944,6 @@ NdisMInitializeScatterGatherDma(
if (!(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_BUS_MASTER)) if (!(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_BUS_MASTER))
return NDIS_STATUS_NOT_SUPPORTED; 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)); RtlZeroMemory(&DeviceDesc, sizeof(DEVICE_DESCRIPTION));
DeviceDesc.Version = DEVICE_DESCRIPTION_VERSION; DeviceDesc.Version = DEVICE_DESCRIPTION_VERSION;
@ -967,6 +961,9 @@ NdisMInitializeScatterGatherDma(
if (!Adapter->NdisMiniportBlock.SystemAdapterObject) if (!Adapter->NdisMiniportBlock.SystemAdapterObject)
return NDIS_STATUS_RESOURCES; return NDIS_STATUS_RESOURCES;
/* FIXME: Right now we just use this as a place holder */
Adapter->NdisMiniportBlock.ScatterGatherListSize = 1;
return NDIS_STATUS_SUCCESS; return NDIS_STATUS_SUCCESS;
} }

View file

@ -430,18 +430,40 @@ MiniSendComplete(
* Status = Status of send operation * Status = Status of send operation
*/ */
{ {
PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle;
PADAPTER_BINDING AdapterBinding; PADAPTER_BINDING AdapterBinding;
KIRQL OldIrql; KIRQL OldIrql;
PSCATTER_GATHER_LIST SGList;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[1]; AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[1];
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); 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->ProtocolBinding->Chars.SendCompleteHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext, AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
Packet, Packet,
Status); Status);
KeLowerIrql(OldIrql); KeLowerIrql(OldIrql);
} }

View file

@ -22,6 +22,11 @@ KSPIN_LOCK ProtocolListLock;
#define WORKER_TEST 0 #define WORKER_TEST 0
typedef struct _DMA_CONTEXT {
PLOGICAL_ADAPTER Adapter;
PNDIS_PACKET Packet;
} DMA_CONTEXT, *PDMA_CONTEXT;
PNET_PNP_EVENT PNET_PNP_EVENT
ProSetupPnPEvent( ProSetupPnPEvent(
NET_PNP_EVENT_CODE EventCode, NET_PNP_EVENT_CODE EventCode,
@ -327,6 +332,33 @@ ProReset(
return NDIS_STATUS_FAILURE; 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 NDIS_STATUS
proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet) proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet)
{ {
@ -412,6 +444,11 @@ ProSend(
{ {
PADAPTER_BINDING AdapterBinding; PADAPTER_BINDING AdapterBinding;
PLOGICAL_ADAPTER Adapter; PLOGICAL_ADAPTER Adapter;
PNDIS_BUFFER NdisBuffer;
PDMA_CONTEXT Context;
NDIS_STATUS NdisStatus;
UINT PacketLength;
KIRQL OldIrql;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
@ -447,6 +484,48 @@ ProSend(
return ProIndicatePacket(Adapter, Packet); return ProIndicatePacket(Adapter, Packet);
#endif #endif
} else { } 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); return proSendPacketToMiniport(Adapter, Packet);
} }
} }