diff --git a/reactos/drivers/network/dd/ne2000/include/ne2000.h b/reactos/drivers/network/dd/ne2000/include/ne2000.h index 64fc8fb944c..eb14bcdb9ac 100644 --- a/reactos/drivers/network/dd/ne2000/include/ne2000.h +++ b/reactos/drivers/network/dd/ne2000/include/ne2000.h @@ -175,6 +175,7 @@ typedef struct _NIC_ADAPTER /* Flags used for driver cleanup */ BOOLEAN IOPortRangeRegistered; BOOLEAN InterruptRegistered; + BOOLEAN ShutdownHandlerRegistered; } NIC_ADAPTER, *PNIC_ADAPTER; /* Global driver information */ diff --git a/reactos/drivers/network/dd/ne2000/ne2000/main.c b/reactos/drivers/network/dd/ne2000/ne2000/main.c index 0def256dea9..0959b00020d 100644 --- a/reactos/drivers/network/dd/ne2000/ne2000/main.c +++ b/reactos/drivers/network/dd/ne2000/ne2000/main.c @@ -140,10 +140,13 @@ static VOID STDCALL MiniportHalt( 0x20, Adapter->IOBase); + if (Adapter->ShutdownHandlerRegistered) + NdisMDeregisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle); + /* Remove adapter from global adapter list */ if ((&Adapter->ListEntry)->Blink != NULL) { RemoveEntryList(&Adapter->ListEntry); - } + } /* Free adapter context area */ 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( OUT PNDIS_STATUS OpenErrorStatus, @@ -411,6 +422,12 @@ static NDIS_STATUS STDCALL MiniportInitialize( /* Start the NIC */ NICStart(Adapter); #endif + + /* Register the shutdown handler */ + NdisMRegisterAdapterShutdownHandler(MiniportAdapterHandle, Adapter, MiniportShutdown); + + Adapter->ShutdownHandlerRegistered = TRUE; + /* Add adapter to the global adapter list */ InsertTailList(&DriverInfo.AdapterListHead, &Adapter->ListEntry); diff --git a/reactos/drivers/network/dd/pcnet/pcnet.c b/reactos/drivers/network/dd/pcnet/pcnet.c index 31c9c77cf4b..f1fbf06e681 100644 --- a/reactos/drivers/network/dd/pcnet/pcnet.c +++ b/reactos/drivers/network/dd/pcnet/pcnet.c @@ -573,6 +573,9 @@ MiniportHalt( /* deregister i/o port range */ NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress, NUMBER_OF_PORTS, (PVOID)Adapter->PortOffset); + /* deregister the shutdown routine */ + NdisMDeregisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle); + /* free shared memory */ MiFreeSharedMemory(Adapter); @@ -781,6 +784,18 @@ MiTestCard( } #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 STDCALL MiniportInitialize( @@ -952,6 +967,8 @@ MiniportInitialize( ASSERT(0); #endif + NdisMRegisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle, Adapter, MiniportShutdown); + DPRINT("returning 0x%x\n", Status); *OpenErrorStatus = Status; return Status; diff --git a/reactos/drivers/network/ndis/ndis/miniport.c b/reactos/drivers/network/ndis/ndis/miniport.c index 392390433e1..ae7231c7d25 100644 --- a/reactos/drivers/network/ndis/ndis/miniport.c +++ b/reactos/drivers/network/ndis/ndis/miniport.c @@ -182,26 +182,6 @@ MiniIndicateData( AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry); 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 (MID_TRACE, ("XXX (%x) %x %x %x %x %x %x %x XXX\n", @@ -235,60 +215,46 @@ MiniIndicateData( VOID NTAPI MiniIndicateReceivePacket( - IN NDIS_HANDLE Miniport, + IN NDIS_HANDLE MiniportAdapterHandle, IN PPNDIS_PACKET PacketArray, IN UINT NumberOfPackets) /* * FUNCTION: receives miniport packet array indications * ARGUMENTS: - * Miniport: Miniport handle for the adapter + * MiniportAdapterHandle: Miniport handle for the adapter * PacketArray: pointer to a list of packet pointers 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; - for(i = 0; i < NumberOfPackets; i++) - { - PCHAR PacketBuffer = 0; - UINT PacketLength = 0; - PNDIS_BUFFER NdisBuffer = 0; + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); -#define PACKET_TAG (('k' << 24) + ('P' << 16) + ('D' << 8) + 'N') + CurrentEntry = Adapter->ProtocolListHead.Flink; - NdisAllocateMemoryWithTag((PVOID)&PacketBuffer, 1518, PACKET_TAG); - if(!PacketBuffer) - { - NDIS_DbgPrint(MIN_TRACE, ("insufficient resources\n")); - return; - } + while (CurrentEntry != &Adapter->ProtocolListHead) + { + AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry); - 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) - { - PNDIS_BUFFER CurrentBuffer; - PVOID BufferVa; - UINT BufferLen; + CurrentEntry = CurrentEntry->Flink; + } - NdisQueryBuffer(NdisBuffer, &BufferVa, &BufferLen); - 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); - } + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); } @@ -298,7 +264,13 @@ MiniResetComplete( IN NDIS_STATUS Status, 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; } + NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_START, NULL, 0); + NdisMIndicateStatusComplete(Adapter); + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)( Adapter->NdisMiniportBlock.MiniportAdapterContext, AddressingReset); 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; } @@ -678,37 +662,52 @@ MiniQueueWorkItem( * 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")); ASSERT(Adapter); ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); - Item = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM)); - if (Item == NULL) + MiniportWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM)); + if (!MiniportWorkItem) { NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NDIS_STATUS_RESOURCES; } - Item->WorkItemType = WorkItemType; - Item->WorkItemContext = WorkItemContext; + NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM)); + if (!NdisWorkItem) + { + ExFreePool(MiniportWorkItem); + return NDIS_STATUS_RESOURCES; + } + + MiniportWorkItem->WorkItemType = WorkItemType; + MiniportWorkItem->WorkItemContext = WorkItemContext; /* safe due to adapter lock held */ - Item->Link.Next = NULL; + MiniportWorkItem->Link.Next = NULL; if (!Adapter->WorkQueueHead) { - Adapter->WorkQueueHead = Item; - Adapter->WorkQueueTail = Item; + Adapter->WorkQueueHead = MiniportWorkItem; + Adapter->WorkQueueTail = MiniportWorkItem; } else { - Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)Item; - Adapter->WorkQueueTail = Item; + Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)MiniportWorkItem; + 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; } @@ -733,30 +732,38 @@ MiniDequeueWorkItem( * 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")); if (Adapter->MiniportBusy) { 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; } - Item = Adapter->WorkQueueHead; + MiniportWorkItem = Adapter->WorkQueueHead; - if (Item) + if (MiniportWorkItem) { /* 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; - *WorkItemType = Item->WorkItemType; - *WorkItemContext = Item->WorkItemContext; + *WorkItemType = MiniportWorkItem->WorkItemType; + *WorkItemContext = MiniportWorkItem->WorkItemContext; - ExFreePool(Item); + ExFreePool(MiniportWorkItem); Adapter->MiniportBusy = TRUE; @@ -953,6 +960,9 @@ VOID NTAPI MiniportWorker(IN PVOID WorkItem) break; case NdisWorkItemResetRequested: + NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_START, NULL, 0); + NdisMIndicateStatusComplete(Adapter); + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)( 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 NTAPI @@ -1150,8 +1128,10 @@ NdisMDeregisterAdapterShutdownHandler( NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); - if(Adapter->BugcheckContext->ShutdownHandler) + if(Adapter->BugcheckContext->ShutdownHandler) { KeDeregisterBugCheckCallback(Adapter->BugcheckContext->CallbackRecord); + IoUnregisterShutdownNotification(Adapter->NdisMiniportBlock.DeviceObject); + } } @@ -1319,13 +1299,10 @@ NdisMRegisterAdapterShutdownHandler( */ { PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportHandle; - PMINIPORT_BUGCHECK_CONTEXT BugcheckContext = Adapter->BugcheckContext; + PMINIPORT_BUGCHECK_CONTEXT BugcheckContext; NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); - if(BugcheckContext) - return; - BugcheckContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_BUGCHECK_CONTEXT)); if(!BugcheckContext) { @@ -1337,11 +1314,19 @@ NdisMRegisterAdapterShutdownHandler( BugcheckContext->DriverContext = ShutdownContext; BugcheckContext->CallbackRecord = ExAllocatePool(NonPagedPool, sizeof(KBUGCHECK_CALLBACK_RECORD)); + if (!BugcheckContext->CallbackRecord) { + ExFreePool(BugcheckContext); + return; + } + + Adapter->BugcheckContext = BugcheckContext; KeInitializeCallbackRecord(BugcheckContext->CallbackRecord); KeRegisterBugCheckCallback(BugcheckContext->CallbackRecord, NdisIBugcheckCallback, BugcheckContext, sizeof(BugcheckContext), (PUCHAR)"Ndis Miniport"); + + IoRegisterShutdownNotification(Adapter->NdisMiniportBlock.DeviceObject); } @@ -1671,15 +1656,20 @@ NdisIPnPStartDevice( ZwClose(WrapperContext.RegistryHandle); - if (NdisStatus != NDIS_STATUS_SUCCESS || - SelectedMediumIndex >= MEDIA_ARRAY_SIZE) + if (NdisStatus != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n")); ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); - if (NdisStatus == NDIS_STATUS_SUCCESS) NdisStatus = NDIS_STATUS_FAILURE; 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]; switch (Adapter->NdisMiniportBlock.MediaType) @@ -1768,6 +1758,8 @@ NdisIPnPStopDevice( RemoveEntryList(&Adapter->ListEntry); KeReleaseSpinLock(&AdapterListLock, OldIrql); + KeCancelTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer); + (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter); if (Adapter->LookaheadBuffer) @@ -1789,7 +1781,27 @@ NdisIPnPStopDevice( Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState; 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; } @@ -1979,7 +1991,6 @@ NdisIAddDevice( KeInitializeTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer); KeInitializeDpc(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Dpc, MiniportHangDpc, Adapter); - KeInitializeDpc(&Adapter->NdisMiniportBlock.DeferredDpc, MiniportDpc, Adapter); DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; @@ -2088,6 +2099,7 @@ NdisMRegisterMiniport( *MiniportPtr = Miniport; Miniport->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp; + Miniport->DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = NdisIShutdown; Miniport->DriverObject->DriverExtension->AddDevice = NdisIAddDevice; return NDIS_STATUS_SUCCESS; diff --git a/reactos/drivers/network/ndis/ndis/object.c b/reactos/drivers/network/ndis/ndis/object.c new file mode 100644 index 00000000000..47d95617476 --- /dev/null +++ b/reactos/drivers/network/ndis/ndis/object.c @@ -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); +} + diff --git a/reactos/drivers/network/ndis/ndis/protocol.c b/reactos/drivers/network/ndis/ndis/protocol.c index d974545c775..f487402dcf0 100644 --- a/reactos/drivers/network/ndis/ndis/protocol.c +++ b/reactos/drivers/network/ndis/ndis/protocol.c @@ -215,14 +215,18 @@ ProSend( if ((Adapter->NdisMiniportBlock.MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK) && 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); - return NDIS_STATUS_PENDING; + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); + + return ProIndicatePacket(Adapter, Packet); } else { if(Adapter->MiniportBusy) { - MiniQueueWorkItem(Adapter, NdisWorkItemSend, (PVOID)Packet); + MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet); KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); return NDIS_STATUS_PENDING; } @@ -794,13 +798,13 @@ NdisRegisterProtocol( /* Put protocol binding struct on global list */ ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock); } - - /* else if(*Status != NDIS_STATUS_PENDING) { - // what to do here? + ExFreePool(Protocol); + ExFreePool(KeyInformation); + *NdisProtocolHandle = NULL; + return; } - */ } ExFreePool(KeyInformation); diff --git a/reactos/drivers/network/ndis/ndis/workitem.c b/reactos/drivers/network/ndis/ndis/workitem.c new file mode 100644 index 00000000000..1be554c5c3c --- /dev/null +++ b/reactos/drivers/network/ndis/ndis/workitem.c @@ -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); +} diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index 930b6ba3dd5..35a57977db3 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -201,6 +201,8 @@ VOID STDCALL ProtocolOpenAdapterComplete( TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); + Adapter->NdisStatus = Status; + KeSetEvent(&Adapter->Event, 0, FALSE); } @@ -235,7 +237,13 @@ VOID STDCALL ProtocolResetComplete( * 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( NDIS_HANDLE BindingContext, - NDIS_STATUS GenerelStatus, + NDIS_STATUS GeneralStatus, PVOID StatusBuffer, UINT StatusBufferSize) /* * FUNCTION: Called by NDIS when the underlying driver has changed state * ARGUMENTS: * 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 * StatusBufferSize = Number of bytes in StatusBuffer */ { + PLAN_ADAPTER Adapter = BindingContext; + 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; + } } diff --git a/reactos/include/ddk/ndis.h b/reactos/include/ddk/ndis.h index 41239f502f9..089369ac4f8 100644 --- a/reactos/include/ddk/ndis.h +++ b/reactos/include/ddk/ndis.h @@ -842,6 +842,19 @@ typedef struct _NDIS_PACKET_EXTENSION { PVOID NdisPacketInfo[MaxPerPacketInfo]; } 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 * NDIS_GET_ORIGINAL_PACKET( diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index 0e56c4ce3de..f777d9145fd 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -412,11 +412,13 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor( TI_DbgPrint(MID_TRACE,("Packet targeted at broadcast addr\n")); NCE = NBAddNeighbor(Interface, Address, NULL, Interface->AddressLength, NUD_CONNECTED); + if (!NCE) return NULL; NCE->EventTimer = 0; NCE->EventCount = 0; } else { NCE = NBAddNeighbor(Interface, Address, NULL, Interface->AddressLength, NUD_INCOMPLETE); + if (!NCE) return NULL; NCE->EventTimer = 1; NCE->EventCount = 0; } diff --git a/reactos/lib/drivers/ip/network/transmit.c b/reactos/lib/drivers/ip/network/transmit.c index 3fdc7ff9e0b..810c4854337 100644 --- a/reactos/lib/drivers/ip/network/transmit.c +++ b/reactos/lib/drivers/ip/network/transmit.c @@ -204,9 +204,7 @@ NTSTATUS SendFragments( /* Prepare next fragment for transmission and send it */ PrepareNextFragment(IFC); - IPSendFragment(IFC->NdisPacket, NCE, IFC); - - return STATUS_SUCCESS; + return IPSendFragment(IFC->NdisPacket, NCE, IFC); } NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE,