- Implement NdisMSetupDmaTransfer, NdisMCompleteDmaTransfer, NdisSetupDmaTransfer, NdisCompleteDmaTransfer, and NdisAllocateDmaChannel

svn path=/trunk/; revision=54251
This commit is contained in:
Cameron Gutman 2011-10-24 20:38:36 +00:00
parent da83a8919e
commit 84409cef86
3 changed files with 175 additions and 70 deletions

View file

@ -11,23 +11,6 @@
#include "ndissys.h"
/*
* @unimplemented
*/
VOID
EXPORT
NdisCompleteDmaTransfer(
OUT PNDIS_STATUS Status,
IN PNDIS_HANDLE NdisDmaHandle,
IN PNDIS_BUFFER Buffer,
IN ULONG Offset,
IN ULONG Length,
IN BOOLEAN WriteToDevice)
{
UNIMPLEMENTED
}
/*
* @unimplemented
*/
@ -87,21 +70,6 @@ FddiFilterDprIndicateReceiveComplete(
}
/*
* @unimplemented
*/
VOID
EXPORT
NdisAllocateDmaChannel(
OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE NdisDmaHandle,
IN NDIS_HANDLE NdisAdapterHandle,
IN PNDIS_DMA_DESCRIPTION DmaDescription,
IN ULONG MaximumLength)
{
UNIMPLEMENTED
}
/*
* @unimplemented
*/

View file

@ -241,29 +241,6 @@ NdisReleaseAdapterResources(
}
/*
* @unimplemented
*/
VOID
EXPORT
NdisSetupDmaTransfer(
OUT PNDIS_STATUS Status,
IN PNDIS_HANDLE NdisDmaHandle,
IN PNDIS_BUFFER Buffer,
IN ULONG Offset,
IN ULONG Length,
IN BOOLEAN WriteToDevice)
/*
* FUNCTION:
* ARGUMENTS:
* NOTES:
* NDIS 4.0
*/
{
UNIMPLEMENTED
}
/*
* @implemented
*/

View file

@ -184,8 +184,36 @@ NdisImmediateWritePortUshort(
WRITE_PORT_USHORT(UlongToPtr(Port), Data); // FIXME: What to do with WrapperConfigurationContext?
}
IO_ALLOCATION_ACTION NTAPI NdisMapRegisterCallback (
IO_ALLOCATION_ACTION NTAPI NdisSubordinateMapRegisterCallback (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID MapRegisterBase,
IN PVOID Context)
/*
* FUNCTION: Called back during reservation of map registers
* ARGUMENTS:
* DeviceObject: Device object of the deivce setting up DMA
* Irp: Reserved; must be ignored
* MapRegisterBase: Map registers assigned for transfer
* Context: LOGICAL_ADAPTER object of the requesting miniport
* NOTES:
* - Called at IRQL = DISPATCH_LEVEL
*/
{
PNDIS_DMA_BLOCK DmaBlock = Context;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
DmaBlock->MapRegisterBase = MapRegisterBase;
NDIS_DbgPrint(MAX_TRACE, ("setting event and leaving.\n"));
KeSetEvent(&DmaBlock->AllocationEvent, 0, FALSE);
/* We have to hold the object open to keep our lock on the system DMA controller */
return KeepObject;
}
IO_ALLOCATION_ACTION NTAPI NdisBusMasterMapRegisterCallback (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID MapRegisterBase,
@ -212,11 +240,9 @@ IO_ALLOCATION_ACTION NTAPI NdisMapRegisterCallback (
KeSetEvent(Adapter->NdisMiniportBlock.AllocationEvent, 0, FALSE);
/* this is only the thing to do for busmaster NICs */
/* We're a bus master so we can go ahead and deallocate the object now */
return DeallocateObjectKeepRegisters;
}
}
/*
* @implemented
*/
@ -359,7 +385,7 @@ NdisMAllocateMapRegisters(
{
NtStatus = AdapterObject->DmaOperations->AllocateAdapterChannel(
AdapterObject, DeviceObject, MapRegistersPerBaseRegister,
NdisMapRegisterCallback, Adapter);
NdisBusMasterMapRegisterCallback, Adapter);
}
KeLowerIrql(OldIrql);
@ -398,7 +424,7 @@ NdisMAllocateMapRegisters(
/*
* @unimplemented
* @implemented
*/
VOID
EXPORT
@ -409,12 +435,87 @@ NdisMSetupDmaTransfer(OUT PNDIS_STATUS Status,
IN ULONG Length,
IN BOOLEAN WriteToDevice)
{
UNIMPLEMENTED
*Status = NDIS_STATUS_FAILURE;
PNDIS_DMA_BLOCK DmaBlock = MiniportDmaHandle;
NTSTATUS NtStatus;
PLOGICAL_ADAPTER Adapter;
KIRQL OldIrql;
PDMA_ADAPTER AdapterObject;
ULONG MapRegistersNeeded;
NDIS_DbgPrint(MAX_TRACE, ("called: Handle 0x%x, Buffer 0x%x, Offset 0x%x, Length 0x%x, WriteToDevice 0x%x\n",
MiniportDmaHandle, Buffer, Offset, Length, WriteToDevice));
Adapter = (PLOGICAL_ADAPTER)DmaBlock->Miniport;
AdapterObject = (PDMA_ADAPTER)DmaBlock->SystemAdapterObject;
MapRegistersNeeded = (Length + (PAGE_SIZE - 1)) / PAGE_SIZE;
KeFlushIoBuffers(Buffer, !WriteToDevice, TRUE);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
{
NtStatus = AdapterObject->DmaOperations->AllocateAdapterChannel(AdapterObject,
Adapter->NdisMiniportBlock.PhysicalDeviceObject,
MapRegistersNeeded,
NdisSubordinateMapRegisterCallback, Adapter);
}
KeLowerIrql(OldIrql);
if(!NT_SUCCESS(NtStatus))
{
NDIS_DbgPrint(MIN_TRACE, ("AllocateAdapterChannel failed: 0x%x\n", NtStatus));
AdapterObject->DmaOperations->FreeAdapterChannel(AdapterObject);
*Status = NDIS_STATUS_RESOURCES;
return;
}
NtStatus = KeWaitForSingleObject(&DmaBlock->AllocationEvent, Executive, KernelMode, FALSE, 0);
if(!NT_SUCCESS(NtStatus))
{
NDIS_DbgPrint(MIN_TRACE, ("KeWaitForSingleObject failed: 0x%x\n", NtStatus));
AdapterObject->DmaOperations->FreeAdapterChannel(AdapterObject);
*Status = NDIS_STATUS_RESOURCES;
return;
}
/* We must throw away the return value of MapTransfer for a system DMA device */
AdapterObject->DmaOperations->MapTransfer(AdapterObject, Buffer,
DmaBlock->MapRegisterBase,
(PUCHAR)MmGetMdlVirtualAddress(Buffer) + Offset, &Length, WriteToDevice);
NDIS_DbgPrint(MAX_TRACE, ("returning success\n"));
*Status = NDIS_STATUS_SUCCESS;
}
/*
* @unimplemented
* @implemented
*/
VOID
EXPORT
NdisSetupDmaTransfer(OUT PNDIS_STATUS Status,
IN PNDIS_HANDLE NdisDmaHandle,
IN PNDIS_BUFFER Buffer,
IN ULONG Offset,
IN ULONG Length,
IN BOOLEAN WriteToDevice)
/*
* FUNCTION:
* ARGUMENTS:
* NOTES:
* NDIS 4.0
*/
{
NdisMSetupDmaTransfer(Status,
NdisDmaHandle,
Buffer,
Offset,
Length,
WriteToDevice);
}
/*
* @implemented
*/
VOID
EXPORT
@ -425,10 +526,50 @@ NdisMCompleteDmaTransfer(OUT PNDIS_STATUS Status,
IN ULONG Length,
IN BOOLEAN WriteToDevice)
{
UNIMPLEMENTED
*Status = NDIS_STATUS_FAILURE;
PNDIS_DMA_BLOCK DmaBlock = MiniportDmaHandle;
PDMA_ADAPTER AdapterObject = (PDMA_ADAPTER)DmaBlock->SystemAdapterObject;
NDIS_DbgPrint(MAX_TRACE, ("called: Handle 0x%x, Buffer 0x%x, Offset 0x%x, Length 0x%x, WriteToDevice 0x%x\n",
MiniportDmaHandle, Buffer, Offset, Length, WriteToDevice));
if (!AdapterObject->DmaOperations->FlushAdapterBuffers(AdapterObject,
Buffer,
DmaBlock->MapRegisterBase,
(PUCHAR)MmGetMdlVirtualAddress(Buffer) + Offset,
Length,
WriteToDevice))
{
NDIS_DbgPrint(MIN_TRACE, ("FlushAdapterBuffers failed\n"));
*Status = NDIS_STATUS_FAILURE;
return;
}
AdapterObject->DmaOperations->FreeAdapterChannel(AdapterObject);
NDIS_DbgPrint(MAX_TRACE, ("returning success\n"));
*Status = NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
EXPORT
NdisCompleteDmaTransfer(OUT PNDIS_STATUS Status,
IN PNDIS_HANDLE NdisDmaHandle,
IN PNDIS_BUFFER Buffer,
IN ULONG Offset,
IN ULONG Length,
IN BOOLEAN WriteToDevice)
{
NdisMCompleteDmaTransfer(Status,
NdisDmaHandle,
Buffer,
Offset,
Length,
WriteToDevice);
}
/*
* @implemented
*/
@ -768,6 +909,8 @@ NdisMRegisterDmaChannel(
}
Adapter->NdisMiniportBlock.SystemAdapterObject = (PDMA_ADAPTER)DmaBlock->SystemAdapterObject;
KeInitializeEvent(&DmaBlock->AllocationEvent, NotificationEvent, FALSE);
DmaBlock->Miniport = Adapter;
@ -776,7 +919,24 @@ NdisMRegisterDmaChannel(
return NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
EXPORT
NdisAllocateDmaChannel(OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE NdisDmaHandle,
IN NDIS_HANDLE NdisAdapterHandle,
IN PNDIS_DMA_DESCRIPTION DmaDescription,
IN ULONG MaximumLength)
{
*Status = NdisMRegisterDmaChannel(NdisDmaHandle,
NdisAdapterHandle,
0,
FALSE,
DmaDescription,
MaximumLength);
}
/*
* @implemented
*/