- Merge aicom-network-fixes up to r36740

svn path=/trunk/; revision=36741
This commit is contained in:
Cameron Gutman 2008-10-13 01:07:37 +00:00
commit 7beefc5606
11 changed files with 317 additions and 137 deletions

View file

@ -175,6 +175,7 @@ typedef struct _NIC_ADAPTER
/* Flags used for driver cleanup */ /* Flags used for driver cleanup */
BOOLEAN IOPortRangeRegistered; BOOLEAN IOPortRangeRegistered;
BOOLEAN InterruptRegistered; BOOLEAN InterruptRegistered;
BOOLEAN ShutdownHandlerRegistered;
} NIC_ADAPTER, *PNIC_ADAPTER; } NIC_ADAPTER, *PNIC_ADAPTER;
/* Global driver information */ /* Global driver information */

View file

@ -140,10 +140,13 @@ static VOID STDCALL MiniportHalt(
0x20, 0x20,
Adapter->IOBase); Adapter->IOBase);
if (Adapter->ShutdownHandlerRegistered)
NdisMDeregisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle);
/* Remove adapter from global adapter list */ /* Remove adapter from global adapter list */
if ((&Adapter->ListEntry)->Blink != NULL) { if ((&Adapter->ListEntry)->Blink != NULL) {
RemoveEntryList(&Adapter->ListEntry); RemoveEntryList(&Adapter->ListEntry);
} }
/* Free adapter context area */ /* Free adapter context area */
NdisFreeMemory(Adapter, sizeof(NIC_ADAPTER), 0); NdisFreeMemory(Adapter, sizeof(NIC_ADAPTER), 0);
@ -200,6 +203,14 @@ static VOID STDCALL MiQueryResources(
} }
} }
VOID
STDCALL
MiniportShutdown(PVOID Context)
{
#ifndef NOCARD
NICStop((PNIC_ADAPTER)Context);
#endif
}
static NDIS_STATUS STDCALL MiniportInitialize( static NDIS_STATUS STDCALL MiniportInitialize(
OUT PNDIS_STATUS OpenErrorStatus, OUT PNDIS_STATUS OpenErrorStatus,
@ -411,6 +422,12 @@ static NDIS_STATUS STDCALL MiniportInitialize(
/* Start the NIC */ /* Start the NIC */
NICStart(Adapter); NICStart(Adapter);
#endif #endif
/* Register the shutdown handler */
NdisMRegisterAdapterShutdownHandler(MiniportAdapterHandle, Adapter, MiniportShutdown);
Adapter->ShutdownHandlerRegistered = TRUE;
/* Add adapter to the global adapter list */ /* Add adapter to the global adapter list */
InsertTailList(&DriverInfo.AdapterListHead, &Adapter->ListEntry); InsertTailList(&DriverInfo.AdapterListHead, &Adapter->ListEntry);

View file

@ -573,6 +573,9 @@ MiniportHalt(
/* deregister i/o port range */ /* deregister i/o port range */
NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress, NUMBER_OF_PORTS, (PVOID)Adapter->PortOffset); NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress, NUMBER_OF_PORTS, (PVOID)Adapter->PortOffset);
/* deregister the shutdown routine */
NdisMDeregisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle);
/* free shared memory */ /* free shared memory */
MiFreeSharedMemory(Adapter); MiFreeSharedMemory(Adapter);
@ -781,6 +784,18 @@ MiTestCard(
} }
#endif #endif
VOID
STDCALL
MiniportShutdown( PVOID Context )
{
PADAPTER Adapter = Context;
DPRINT("Stopping the chip\n");
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STOP);
}
static NDIS_STATUS static NDIS_STATUS
STDCALL STDCALL
MiniportInitialize( MiniportInitialize(
@ -952,6 +967,8 @@ MiniportInitialize(
ASSERT(0); ASSERT(0);
#endif #endif
NdisMRegisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle, Adapter, MiniportShutdown);
DPRINT("returning 0x%x\n", Status); DPRINT("returning 0x%x\n", Status);
*OpenErrorStatus = Status; *OpenErrorStatus = Status;
return Status; return Status;

View file

@ -182,26 +182,6 @@ MiniIndicateData(
AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry); AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry);
NDIS_DbgPrint(DEBUG_MINIPORT, ("AdapterBinding = %x\n", AdapterBinding)); NDIS_DbgPrint(DEBUG_MINIPORT, ("AdapterBinding = %x\n", AdapterBinding));
#ifdef DBG
if(!AdapterBinding)
{
NDIS_DbgPrint(MIN_TRACE, ("AdapterBinding was null\n"));
break;
}
if(!AdapterBinding->ProtocolBinding)
{
NDIS_DbgPrint(MIN_TRACE, ("AdapterBinding->ProtocolBinding was null\n"));
break;
}
if(!AdapterBinding->ProtocolBinding->Chars.ReceiveHandler)
{
NDIS_DbgPrint(MIN_TRACE, ("AdapterBinding->ProtocolBinding->Chars.ReceiveHandler was null\n"));
break;
}
#endif
NDIS_DbgPrint NDIS_DbgPrint
(MID_TRACE, (MID_TRACE,
("XXX (%x) %x %x %x %x %x %x %x XXX\n", ("XXX (%x) %x %x %x %x %x %x %x XXX\n",
@ -235,60 +215,46 @@ MiniIndicateData(
VOID NTAPI VOID NTAPI
MiniIndicateReceivePacket( MiniIndicateReceivePacket(
IN NDIS_HANDLE Miniport, IN NDIS_HANDLE MiniportAdapterHandle,
IN PPNDIS_PACKET PacketArray, IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets) IN UINT NumberOfPackets)
/* /*
* FUNCTION: receives miniport packet array indications * FUNCTION: receives miniport packet array indications
* ARGUMENTS: * ARGUMENTS:
* Miniport: Miniport handle for the adapter * MiniportAdapterHandle: Miniport handle for the adapter
* PacketArray: pointer to a list of packet pointers to indicate * PacketArray: pointer to a list of packet pointers to indicate
* NumberOfPackets: number of packets to indicate * NumberOfPackets: number of packets to indicate
* NOTES: *
* - This currently is a big temporary hack. In the future this should
* call ProtocolReceivePacket() on each bound protocol if it exists.
* For now it just mimics NdisMEthIndicateReceive.
*/ */
{ {
PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle;
PLIST_ENTRY CurrentEntry;
PADAPTER_BINDING AdapterBinding;
KIRQL OldIrql;
UINT i; UINT i;
for(i = 0; i < NumberOfPackets; i++) KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
{
PCHAR PacketBuffer = 0;
UINT PacketLength = 0;
PNDIS_BUFFER NdisBuffer = 0;
#define PACKET_TAG (('k' << 24) + ('P' << 16) + ('D' << 8) + 'N') CurrentEntry = Adapter->ProtocolListHead.Flink;
NdisAllocateMemoryWithTag((PVOID)&PacketBuffer, 1518, PACKET_TAG); while (CurrentEntry != &Adapter->ProtocolListHead)
if(!PacketBuffer) {
{ AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry);
NDIS_DbgPrint(MIN_TRACE, ("insufficient resources\n"));
return;
}
NdisQueryPacket(PacketArray[i], NULL, NULL, &NdisBuffer, NULL); if (AdapterBinding->ProtocolBinding->Chars.ReceivePacketHandler)
{
for (i = 0; i < NumberOfPackets; i++)
{
(*AdapterBinding->ProtocolBinding->Chars.ReceivePacketHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
PacketArray[i]);
}
}
while(NdisBuffer) CurrentEntry = CurrentEntry->Flink;
{ }
PNDIS_BUFFER CurrentBuffer;
PVOID BufferVa;
UINT BufferLen;
NdisQueryBuffer(NdisBuffer, &BufferVa, &BufferLen); KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
memcpy(PacketBuffer + PacketLength, BufferVa, BufferLen);
PacketLength += BufferLen;
CurrentBuffer = NdisBuffer;
NdisGetNextBuffer(CurrentBuffer, &NdisBuffer);
}
NDIS_DbgPrint(MID_TRACE, ("indicating a %d-byte packet\n", PacketLength));
MiniIndicateData(Miniport, NULL, PacketBuffer, 14, PacketBuffer+14, PacketLength-14, PacketLength-14);
NdisFreeMemory(PacketBuffer, 0, 0);
}
} }
@ -298,7 +264,13 @@ MiniResetComplete(
IN NDIS_STATUS Status, IN NDIS_STATUS Status,
IN BOOLEAN AddressingReset) IN BOOLEAN AddressingReset)
{ {
UNIMPLEMENTED PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle;
KIRQL OldIrql;
NDIS_DbgPrint(MIN_TRACE, ("FIXME: MiniResetComplete is partially implemented\n"));
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0);
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
Adapter->MiniportBusy = FALSE;
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
} }
@ -631,12 +603,24 @@ MiniReset(
return NDIS_STATUS_PENDING; return NDIS_STATUS_PENDING;
} }
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_START, NULL, 0);
NdisMIndicateStatusComplete(Adapter);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)( Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext, Adapter->NdisMiniportBlock.MiniportAdapterContext,
AddressingReset); AddressingReset);
KeLowerIrql(OldIrql); KeLowerIrql(OldIrql);
if (Status != NDIS_STATUS_PENDING) {
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0);
NdisMIndicateStatusComplete(Adapter);
} else {
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
Adapter->MiniportBusy = TRUE;
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
}
return Status; return Status;
} }
@ -678,37 +662,52 @@ MiniQueueWorkItem(
* Status of operation * Status of operation
*/ */
{ {
PNDIS_MINIPORT_WORK_ITEM Item; PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem;
PNDIS_WORK_ITEM NdisWorkItem;
PWORK_QUEUE_ITEM WorkQueueItem;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
ASSERT(Adapter); ASSERT(Adapter);
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
Item = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM)); MiniportWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM));
if (Item == NULL) if (!MiniportWorkItem)
{ {
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES; return NDIS_STATUS_RESOURCES;
} }
Item->WorkItemType = WorkItemType; NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM));
Item->WorkItemContext = WorkItemContext; if (!NdisWorkItem)
{
ExFreePool(MiniportWorkItem);
return NDIS_STATUS_RESOURCES;
}
MiniportWorkItem->WorkItemType = WorkItemType;
MiniportWorkItem->WorkItemContext = WorkItemContext;
/* safe due to adapter lock held */ /* safe due to adapter lock held */
Item->Link.Next = NULL; MiniportWorkItem->Link.Next = NULL;
if (!Adapter->WorkQueueHead) if (!Adapter->WorkQueueHead)
{ {
Adapter->WorkQueueHead = Item; Adapter->WorkQueueHead = MiniportWorkItem;
Adapter->WorkQueueTail = Item; Adapter->WorkQueueTail = MiniportWorkItem;
} }
else else
{ {
Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)Item; Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)MiniportWorkItem;
Adapter->WorkQueueTail = Item; Adapter->WorkQueueTail = MiniportWorkItem;
} }
KeInsertQueueDpc(&Adapter->NdisMiniportBlock.DeferredDpc, NULL, NULL); WorkQueueItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved;
NdisWorkItem->Context = Adapter;
ExInitializeWorkItem(WorkQueueItem, MiniportWorker, NdisWorkItem);
ExQueueWorkItem(WorkQueueItem, CriticalWorkQueue);
return NDIS_STATUS_SUCCESS; return NDIS_STATUS_SUCCESS;
} }
@ -733,30 +732,38 @@ MiniDequeueWorkItem(
* Status of operation * Status of operation
*/ */
{ {
PNDIS_MINIPORT_WORK_ITEM Item; PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem;
PNDIS_WORK_ITEM NdisWorkItem;
PWORK_QUEUE_ITEM WorkQueueItem;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
if (Adapter->MiniportBusy) { if (Adapter->MiniportBusy) {
NDIS_DbgPrint(MID_TRACE, ("Waiting for miniport to become free.\n")); NDIS_DbgPrint(MID_TRACE, ("Waiting for miniport to become free.\n"));
KeInsertQueueDpc(&Adapter->NdisMiniportBlock.DeferredDpc, NULL, NULL); NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM));
if (!NdisWorkItem) return NDIS_STATUS_RESOURCES;
WorkQueueItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved;
NdisWorkItem->Context = Adapter;
ExInitializeWorkItem(WorkQueueItem, MiniportWorker, NdisWorkItem);
ExQueueWorkItem(WorkQueueItem, CriticalWorkQueue);
return NDIS_STATUS_FAILURE; return NDIS_STATUS_FAILURE;
} }
Item = Adapter->WorkQueueHead; MiniportWorkItem = Adapter->WorkQueueHead;
if (Item) if (MiniportWorkItem)
{ {
/* safe due to adapter lock held */ /* safe due to adapter lock held */
Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)Item->Link.Next; Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)MiniportWorkItem->Link.Next;
if (Item == Adapter->WorkQueueTail) if (MiniportWorkItem == Adapter->WorkQueueTail)
Adapter->WorkQueueTail = NULL; Adapter->WorkQueueTail = NULL;
*WorkItemType = Item->WorkItemType; *WorkItemType = MiniportWorkItem->WorkItemType;
*WorkItemContext = Item->WorkItemContext; *WorkItemContext = MiniportWorkItem->WorkItemContext;
ExFreePool(Item); ExFreePool(MiniportWorkItem);
Adapter->MiniportBusy = TRUE; Adapter->MiniportBusy = TRUE;
@ -953,6 +960,9 @@ VOID NTAPI MiniportWorker(IN PVOID WorkItem)
break; break;
case NdisWorkItemResetRequested: case NdisWorkItemResetRequested:
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_START, NULL, 0);
NdisMIndicateStatusComplete(Adapter);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)( NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext, Adapter->NdisMiniportBlock.MiniportAdapterContext,
@ -1011,38 +1021,6 @@ VOID NTAPI MiniportWorker(IN PVOID WorkItem)
} }
VOID NTAPI MiniportDpc(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
/*
* FUNCTION: Deferred routine to handle serialization
* ARGUMENTS:
* Dpc = Pointer to DPC object
* DeferredContext = Pointer to context information (LOGICAL_ADAPTER)
* SystemArgument1 = Unused
* SystemArgument2 = Unused
*/
{
PNDIS_WORK_ITEM NdisWorkItem;
PWORK_QUEUE_ITEM WorkItem;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM));
if (!NdisWorkItem) return;
WorkItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved;
NdisWorkItem->Context = DeferredContext;
ExInitializeWorkItem(WorkItem, MiniportWorker, NdisWorkItem);
ExQueueWorkItem(WorkItem, CriticalWorkQueue);
}
VOID VOID
NTAPI NTAPI
@ -1150,8 +1128,10 @@ NdisMDeregisterAdapterShutdownHandler(
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
if(Adapter->BugcheckContext->ShutdownHandler) if(Adapter->BugcheckContext->ShutdownHandler) {
KeDeregisterBugCheckCallback(Adapter->BugcheckContext->CallbackRecord); KeDeregisterBugCheckCallback(Adapter->BugcheckContext->CallbackRecord);
IoUnregisterShutdownNotification(Adapter->NdisMiniportBlock.DeviceObject);
}
} }
@ -1319,13 +1299,10 @@ NdisMRegisterAdapterShutdownHandler(
*/ */
{ {
PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportHandle; PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportHandle;
PMINIPORT_BUGCHECK_CONTEXT BugcheckContext = Adapter->BugcheckContext; PMINIPORT_BUGCHECK_CONTEXT BugcheckContext;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
if(BugcheckContext)
return;
BugcheckContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_BUGCHECK_CONTEXT)); BugcheckContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_BUGCHECK_CONTEXT));
if(!BugcheckContext) if(!BugcheckContext)
{ {
@ -1337,11 +1314,19 @@ NdisMRegisterAdapterShutdownHandler(
BugcheckContext->DriverContext = ShutdownContext; BugcheckContext->DriverContext = ShutdownContext;
BugcheckContext->CallbackRecord = ExAllocatePool(NonPagedPool, sizeof(KBUGCHECK_CALLBACK_RECORD)); BugcheckContext->CallbackRecord = ExAllocatePool(NonPagedPool, sizeof(KBUGCHECK_CALLBACK_RECORD));
if (!BugcheckContext->CallbackRecord) {
ExFreePool(BugcheckContext);
return;
}
Adapter->BugcheckContext = BugcheckContext;
KeInitializeCallbackRecord(BugcheckContext->CallbackRecord); KeInitializeCallbackRecord(BugcheckContext->CallbackRecord);
KeRegisterBugCheckCallback(BugcheckContext->CallbackRecord, NdisIBugcheckCallback, KeRegisterBugCheckCallback(BugcheckContext->CallbackRecord, NdisIBugcheckCallback,
BugcheckContext, sizeof(BugcheckContext), (PUCHAR)"Ndis Miniport"); BugcheckContext, sizeof(BugcheckContext), (PUCHAR)"Ndis Miniport");
IoRegisterShutdownNotification(Adapter->NdisMiniportBlock.DeviceObject);
} }
@ -1671,15 +1656,20 @@ NdisIPnPStartDevice(
ZwClose(WrapperContext.RegistryHandle); ZwClose(WrapperContext.RegistryHandle);
if (NdisStatus != NDIS_STATUS_SUCCESS || if (NdisStatus != NDIS_STATUS_SUCCESS)
SelectedMediumIndex >= MEDIA_ARRAY_SIZE)
{ {
NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n")); NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
if (NdisStatus == NDIS_STATUS_SUCCESS) NdisStatus = NDIS_STATUS_FAILURE;
return NdisStatus; return NdisStatus;
} }
if (SelectedMediumIndex >= MEDIA_ARRAY_SIZE)
{
NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return NDIS_STATUS_UNSUPPORTED_MEDIA;
}
Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex]; Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex];
switch (Adapter->NdisMiniportBlock.MediaType) switch (Adapter->NdisMiniportBlock.MediaType)
@ -1768,6 +1758,8 @@ NdisIPnPStopDevice(
RemoveEntryList(&Adapter->ListEntry); RemoveEntryList(&Adapter->ListEntry);
KeReleaseSpinLock(&AdapterListLock, OldIrql); KeReleaseSpinLock(&AdapterListLock, OldIrql);
KeCancelTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer);
(*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter); (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter);
if (Adapter->LookaheadBuffer) if (Adapter->LookaheadBuffer)
@ -1789,7 +1781,27 @@ NdisIPnPStopDevice(
Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState; Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStopped; Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStopped;
KeCancelTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer); return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
NdisIShutdown(
IN PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PLOGICAL_ADAPTER Adapter = DeviceObject->DeviceExtension;
PMINIPORT_BUGCHECK_CONTEXT Context = Adapter->BugcheckContext;
ADAPTER_SHUTDOWN_HANDLER ShutdownHandler = Context->ShutdownHandler;
ASSERT(ShutdownHandler);
ShutdownHandler(Context->DriverContext);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1979,7 +1991,6 @@ NdisIAddDevice(
KeInitializeTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer); KeInitializeTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer);
KeInitializeDpc(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Dpc, MiniportHangDpc, Adapter); KeInitializeDpc(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Dpc, MiniportHangDpc, Adapter);
KeInitializeDpc(&Adapter->NdisMiniportBlock.DeferredDpc, MiniportDpc, Adapter);
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
@ -2088,6 +2099,7 @@ NdisMRegisterMiniport(
*MiniportPtr = Miniport; *MiniportPtr = Miniport;
Miniport->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp; Miniport->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
Miniport->DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = NdisIShutdown;
Miniport->DriverObject->DriverExtension->AddDevice = NdisIAddDevice; Miniport->DriverObject->DriverExtension->AddDevice = NdisIAddDevice;
return NDIS_STATUS_SUCCESS; return NDIS_STATUS_SUCCESS;

View file

@ -0,0 +1,40 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS library
* FILE: object.c
* PURPOSE: Implements the NDIS 6.0 object interface
* PROGRAMMERS: Cameron Gutman (aicommander@gmail.com)
*/
#include "ndissys.h"
PNDIS_GENERIC_OBJECT
EXPORT
NdisAllocateGenericObject(
IN PDRIVER_OBJECT DriverObject OPTIONAL,
IN ULONG Tag,
IN USHORT Size)
{
PNDIS_GENERIC_OBJECT Object;
Object = ExAllocatePoolWithTag(NonPagedPool, sizeof(NDIS_GENERIC_OBJECT) + Size, Tag);
if (!Object) return NULL;
RtlZeroMemory(Object, sizeof(NDIS_GENERIC_OBJECT) + Size);
Object->DriverObject = DriverObject;
Object->Header.Type = NDIS_OBJECT_TYPE_GENERIC_OBJECT;
Object->Header.Revision = NDIS_GENERIC_OBJECT_REVISION_1;
Object->Header.Size = sizeof(NDIS_GENERIC_OBJECT);
return Object;
}
VOID
EXPORT
NdisFreeGenericObject(
IN PNDIS_GENERIC_OBJECT NdisGenericObject)
{
ExFreePool(NdisGenericObject);
}

View file

@ -215,14 +215,18 @@ ProSend(
if ((Adapter->NdisMiniportBlock.MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK) && if ((Adapter->NdisMiniportBlock.MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK) &&
MiniAdapterHasAddress(Adapter, Packet)) MiniAdapterHasAddress(Adapter, Packet))
{ {
NDIS_DbgPrint(MID_TRACE, ("Queuing packet.\n")); if(Adapter->MiniportBusy) {
MiniQueueWorkItem(Adapter, NdisWorkItemSendLoopback, Packet);
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql);
return NDIS_STATUS_PENDING;
}
MiniQueueWorkItem(Adapter, NdisWorkItemSendLoopback, (PVOID)Packet); KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql);
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql);
return NDIS_STATUS_PENDING; return ProIndicatePacket(Adapter, Packet);
} else { } else {
if(Adapter->MiniportBusy) { if(Adapter->MiniportBusy) {
MiniQueueWorkItem(Adapter, NdisWorkItemSend, (PVOID)Packet); MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet);
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql);
return NDIS_STATUS_PENDING; return NDIS_STATUS_PENDING;
} }
@ -794,13 +798,13 @@ NdisRegisterProtocol(
/* Put protocol binding struct on global list */ /* Put protocol binding struct on global list */
ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock); ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock);
} }
/*
else if(*Status != NDIS_STATUS_PENDING) else if(*Status != NDIS_STATUS_PENDING)
{ {
// what to do here? ExFreePool(Protocol);
ExFreePool(KeyInformation);
*NdisProtocolHandle = NULL;
return;
} }
*/
} }
ExFreePool(KeyInformation); ExFreePool(KeyInformation);

View file

@ -0,0 +1,43 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS library
* FILE: workitem.c
* PURPOSE: Implements the NDIS 6.0 work item interface
* PROGRAMMERS: Cameron Gutman (aicommander@gmail.com)
*/
#include "ndissys.h"
NDIS_HANDLE
EXPORT
NdisAllocateIoWorkItem(
IN NDIS_HANDLE NdisObjectHandle)
{
PLOGICAL_ADAPTER Adapter = NdisObjectHandle;
return IoAllocateWorkItem(Adapter->NdisMiniportBlock.PhysicalDeviceObject);
}
VOID
EXPORT
NdisQueueIoWorkItem(
IN NDIS_HANDLE NdisIoWorkItemHandle,
IN NDIS_IO_WORKITEM_ROUTINE Routine,
IN PVOID WorkItemContext)
{
PNDIS_IO_WORKITEM WorkItem = NdisIoWorkItemHandle;
IoQueueWorkItem(WorkItem,
Routine,
CriticalWorkQueue,
WorkItemContext);
}
VOID
EXPORT
NdisFreeIoWorkItem(
IN NDIS_HANDLE NdisIoWorkItemHandle)
{
PNDIS_IO_WORKITEM WorkItem = NdisIoWorkItemHandle;
IoFreeWorkItem(WorkItem);
}

View file

@ -201,6 +201,8 @@ VOID STDCALL ProtocolOpenAdapterComplete(
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
Adapter->NdisStatus = Status;
KeSetEvent(&Adapter->Event, 0, FALSE); KeSetEvent(&Adapter->Event, 0, FALSE);
} }
@ -235,7 +237,13 @@ VOID STDCALL ProtocolResetComplete(
* Status = Status of the operation * Status = Status of the operation
*/ */
{ {
TI_DbgPrint(MID_TRACE, ("Called.\n")); PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
Adapter->NdisStatus = Status;
KeSetEvent(&Adapter->Event, 0, FALSE);
} }
@ -517,19 +525,44 @@ VOID STDCALL ProtocolReceiveComplete(
VOID STDCALL ProtocolStatus( VOID STDCALL ProtocolStatus(
NDIS_HANDLE BindingContext, NDIS_HANDLE BindingContext,
NDIS_STATUS GenerelStatus, NDIS_STATUS GeneralStatus,
PVOID StatusBuffer, PVOID StatusBuffer,
UINT StatusBufferSize) UINT StatusBufferSize)
/* /*
* FUNCTION: Called by NDIS when the underlying driver has changed state * FUNCTION: Called by NDIS when the underlying driver has changed state
* ARGUMENTS: * ARGUMENTS:
* BindingContext = Pointer to a device context (LAN_ADAPTER) * BindingContext = Pointer to a device context (LAN_ADAPTER)
* GenerelStatus = A generel status code * GeneralStatus = A general status code
* StatusBuffer = Pointer to a buffer with medium-specific data * StatusBuffer = Pointer to a buffer with medium-specific data
* StatusBufferSize = Number of bytes in StatusBuffer * StatusBufferSize = Number of bytes in StatusBuffer
*/ */
{ {
PLAN_ADAPTER Adapter = BindingContext;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
switch(GeneralStatus)
{
case NDIS_STATUS_MEDIA_CONNECT:
DbgPrint("NDIS_STATUS_MEDIA_CONNECT\n");
break;
case NDIS_STATUS_MEDIA_DISCONNECT:
DbgPrint("NDIS_STATUS_MEDIA_DISCONNECT\n");
break;
case NDIS_STATUS_RESET_START:
Adapter->State = LAN_STATE_RESETTING;
break;
case NDIS_STATUS_RESET_END:
Adapter->State = LAN_STATE_STARTED;
break;
default:
DbgPrint("Unhandled status: %x", GeneralStatus);
break;
}
} }

View file

@ -842,6 +842,19 @@ typedef struct _NDIS_PACKET_EXTENSION {
PVOID NdisPacketInfo[MaxPerPacketInfo]; PVOID NdisPacketInfo[MaxPerPacketInfo];
} NDIS_PACKET_EXTENSION, *PNDIS_PACKET_EXTENSION; } NDIS_PACKET_EXTENSION, *PNDIS_PACKET_EXTENSION;
typedef struct _NDIS_OBJECT_HEADER {
UCHAR Type;
UCHAR Revision;
USHORT Size;
} NDIS_OBJECT_HEADER, *PNDIS_OBJECT_HEADER;
typedef struct _NDIS_GENERIC_OBJECT {
NDIS_OBJECT_HEADER Header;
PVOID Caller;
PVOID CallersCaller;
PDRIVER_OBJECT DriverObject;
} NDIS_GENERIC_OBJECT, *PNDIS_GENERIC_OBJECT;
/* /*
* PNDIS_PACKET * PNDIS_PACKET
* NDIS_GET_ORIGINAL_PACKET( * NDIS_GET_ORIGINAL_PACKET(

View file

@ -412,11 +412,13 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
TI_DbgPrint(MID_TRACE,("Packet targeted at broadcast addr\n")); TI_DbgPrint(MID_TRACE,("Packet targeted at broadcast addr\n"));
NCE = NBAddNeighbor(Interface, Address, NULL, NCE = NBAddNeighbor(Interface, Address, NULL,
Interface->AddressLength, NUD_CONNECTED); Interface->AddressLength, NUD_CONNECTED);
if (!NCE) return NULL;
NCE->EventTimer = 0; NCE->EventTimer = 0;
NCE->EventCount = 0; NCE->EventCount = 0;
} else { } else {
NCE = NBAddNeighbor(Interface, Address, NULL, NCE = NBAddNeighbor(Interface, Address, NULL,
Interface->AddressLength, NUD_INCOMPLETE); Interface->AddressLength, NUD_INCOMPLETE);
if (!NCE) return NULL;
NCE->EventTimer = 1; NCE->EventTimer = 1;
NCE->EventCount = 0; NCE->EventCount = 0;
} }

View file

@ -204,9 +204,7 @@ NTSTATUS SendFragments(
/* Prepare next fragment for transmission and send it */ /* Prepare next fragment for transmission and send it */
PrepareNextFragment(IFC); PrepareNextFragment(IFC);
IPSendFragment(IFC->NdisPacket, NCE, IFC); return IPSendFragment(IFC->NdisPacket, NCE, IFC);
return STATUS_SUCCESS;
} }
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE, NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE,