From c7198d46d8797402a26ca3cbc438eb60bb907cba Mon Sep 17 00:00:00 2001 From: Vizzini Date: Mon, 15 Sep 2003 03:47:22 +0000 Subject: [PATCH] implemented MiniportHalt, MiniportQueryInformation, and MiniportSetInformation svn path=/trunk/; revision=6085 --- reactos/drivers/net/dd/pcnet/Makefile | 2 +- reactos/drivers/net/dd/pcnet/pcnet.c | 141 +++----- reactos/drivers/net/dd/pcnet/pcnet.h | 23 ++ reactos/drivers/net/dd/pcnet/requests.c | 445 ++++++++++++++++++++++++ 4 files changed, 521 insertions(+), 90 deletions(-) create mode 100644 reactos/drivers/net/dd/pcnet/requests.c diff --git a/reactos/drivers/net/dd/pcnet/Makefile b/reactos/drivers/net/dd/pcnet/Makefile index c9f5f3ad671..39416239968 100644 --- a/reactos/drivers/net/dd/pcnet/Makefile +++ b/reactos/drivers/net/dd/pcnet/Makefile @@ -8,7 +8,7 @@ TARGET_NAME = pcnet # TARGET_CFLAGS = -I. -DDBG=1 -Wall -Werror -DNDIS40 -DANONYMOUSUNIONS -TARGET_OBJECTS = pcnet.o +TARGET_OBJECTS = pcnet.o requests.o TARGET_DDKLIBS = ndis.a include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk diff --git a/reactos/drivers/net/dd/pcnet/pcnet.c b/reactos/drivers/net/dd/pcnet/pcnet.c index a45d4143fea..d7affa8636f 100644 --- a/reactos/drivers/net/dd/pcnet/pcnet.c +++ b/reactos/drivers/net/dd/pcnet/pcnet.c @@ -35,23 +35,6 @@ #include "pcnethw.h" #include "pcnet.h" - -VOID -STDCALL -MiniportHalt( - IN NDIS_HANDLE MiniportAdapterContext) -/* - * FUNCTION: Stop the miniport and prepare for unload - * ARGUMENTS: - * MiniportAdapterContext: context specified to NdisMSetAttributes - * NOTES: - * - Called by NDIS at PASSIVE_LEVEL - */ -{ - /* XXX Implement me */ - PCNET_DbgPrint(("Called\n")); -} - VOID STDCALL @@ -83,13 +66,15 @@ MiniportHandleInterrupt( { if(Data & CSR0_ERR) { +#if DBG if(ErrorHandled) { PCNET_DbgPrint(("ERROR HANDLED TWO TIMES\n")); - __asm__("int $3\n"); + ASSERT(0); } ErrorHandled = TRUE; +#endif PCNET_DbgPrint(("clearing an error\n")); NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_MERR|CSR0_BABL|CSR0_CERR|CSR0_MISS); @@ -98,13 +83,15 @@ MiniportHandleInterrupt( } else if(Data & CSR0_IDON) { +#if DBG if(IdonHandled) { PCNET_DbgPrint(("IDON HANDLED TWO TIMES\n")); - __asm__("int $3\n"); + ASSERT(0); } IdonHandled = TRUE; +#endif PCNET_DbgPrint(("clearing IDON\n")); NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_IDON); @@ -113,13 +100,15 @@ MiniportHandleInterrupt( } else if(Data & CSR0_RINT) { +#if DBG if(ReceiveHandled) { PCNET_DbgPrint(("RECEIVE HANDLED TWO TIMES\n")); - __asm__("int $3\n"); + ASSERT(0); } ReceiveHandled = TRUE; +#endif PCNET_DbgPrint(("receive interrupt - clearing\n")); NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_RINT); @@ -172,7 +161,7 @@ MiniportHandleInterrupt( else { PCNET_DbgPrint(("UNHANDLED INTERRUPT\n")); - __asm__("int $3\n"); + ASSERT(FALSE); } NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data); @@ -549,6 +538,44 @@ MiFreeSharedMemory( } } + +VOID +STDCALL +MiniportHalt( + IN NDIS_HANDLE MiniportAdapterContext) +/* + * FUNCTION: Stop the adapter and release any per-adapter resources + * ARGUMENTS: + * MiniportAdapterContext: context specified to NdisMSetAttributes + * NOTES: + * - Called by NDIS at PASSIVE_LEVEL + */ +{ + PADAPTER Adapter = (PADAPTER)Adapter; + + PCNET_DbgPrint(("Called\n")); + ASSERT(Adapter); + + /* stop the chip */ + NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0); + NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STOP); + + /* deregister the interrupt */ + NdisMDeregisterInterrupt(&Adapter->InterruptObject); + + /* deregister i/o port range */ + NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress, NUMBER_OF_PORTS, Adapter->PortOffset); + + /* free shared memory */ + MiFreeSharedMemory(Adapter); + + /* free map registers */ + NdisMFreeMapRegisters(Adapter->MiniportAdapterHandle); + + /* free the adapter */ + NdisFreeMemory(Adapter, 0, 0); +} + VOID MiInitChip( @@ -682,13 +709,6 @@ MiTestCard( NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data); PCNET_DbgPrint(("CSR6: 0x%x\n", Data)); - /* finally, fire a test interrupt to test the ISR */ - NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR4); - NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data); - Data |= CSR4_UINTCMD; - NdisRawWritePortUshort(Adapter->PortOffset + RDP, Data); - PCNET_DbgPrint(("just wrote 0x%x to CSR4 for test interrupt\n", Data)); - return TRUE; } @@ -858,7 +878,7 @@ MiniportInitialize( #if DBG if(!MiTestCard(Adapter)) - __asm__("int $3\n"); + ASSERT(0); #endif PCNET_DbgPrint(("returning 0x%x\n", Status)); @@ -920,37 +940,6 @@ MiniportISR( NdisRawWritePortUshort(Adapter->PortOffset + RAP, Rap); } - -NDIS_STATUS -STDCALL -MiniportQueryInformation( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesWritten, - OUT PULONG BytesNeeded) -/* - * FUNCTION: Query an OID from the driver - * ARGUMENTS: - * MiniportAdapterContext: context originally passed to NdisMSetAttributes - * Oid: OID NDIS is querying - * InformationBuffer: pointer to buffer into which to write the results of the query - * InformationBufferLength: size in bytes of InformationBuffer - * BytesWritten: number of bytes written into InformationBuffer in response to the query - * BytesNeeded: number of bytes needed to answer the query - * RETURNS: - * NDIS_STATUS_SUCCESS on all queries - * NOTES: - * - Called by NDIS at PASSIVE_LEVEL - * - If InformationBufferLength is insufficient to store the results, return the amount - * needed in BytesNeeded and return NDIS_STATUS_INVALID_LENGTH - */ -{ - PCNET_DbgPrint(("Called\n")); - return NDIS_STATUS_SUCCESS; -} - NDIS_STATUS STDCALL @@ -970,36 +959,10 @@ MiniportReset( */ { PCNET_DbgPrint(("Called\n")); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -STDCALL -MiniportSetInformation( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesRead, - OUT PULONG BytesNeeded) -/* - * FUNCTION: Set a miniport variable (OID) - * ARGUMENTS: - * MiniportAdapterContext: context originally passed into NdisMSetAttributes - * Oid: the variable being set - * InformationBuffer: the data to set the variable to - * InformationBufferLength: number of bytes in InformationBuffer - * BytesRead: number of bytes read by us out of the buffer - * BytesNeeded: number of bytes required to satisfy the request if InformationBufferLength - * is insufficient - * RETURNS: - * NDIS_STATUS_SUCCESS on all requests - * NOTES: - * - Called by NDIS at PASSIVE_LEVEL - */ -{ - PCNET_DbgPrint(("Called\n")); + /* MiniportReset doesn't do anything at the moment... perhaps this should be fixed. */ + + *AddressingReset = FALSE; return NDIS_STATUS_SUCCESS; } diff --git a/reactos/drivers/net/dd/pcnet/pcnet.h b/reactos/drivers/net/dd/pcnet/pcnet.h index 004279df697..e364a690c00 100644 --- a/reactos/drivers/net/dd/pcnet/pcnet.h +++ b/reactos/drivers/net/dd/pcnet/pcnet.h @@ -44,6 +44,8 @@ typedef struct _ADAPTER PVOID PortOffset; NDIS_MINIPORT_INTERRUPT InterruptObject; ULONG CurrentReceiveDescriptorIndex; + ULONG CurrentPacketFilter; + ULONG CurrentLookaheadSize; /* initialization block */ ULONG InitializationBlockLength; @@ -72,6 +74,27 @@ typedef struct _ADAPTER } ADAPTER, *PADAPTER; +/* forward declarations */ +NDIS_STATUS +STDCALL +MiniportQueryInformation( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded); + +NDIS_STATUS +STDCALL +MiniportSetInformation( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded); + /* operational constants */ #define NUMBER_OF_BUFFERS 0x20 #define LOG_NUMBER_OF_BUFFERS 5 /* log2(NUMBER_OF_BUFFERS) */ diff --git a/reactos/drivers/net/dd/pcnet/requests.c b/reactos/drivers/net/dd/pcnet/requests.c new file mode 100644 index 00000000000..c107406162f --- /dev/null +++ b/reactos/drivers/net/dd/pcnet/requests.c @@ -0,0 +1,445 @@ +/* + * ReactOS AMD PCNet Driver + * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * PROJECT: ReactOS AMD PCNet Driver + * FILE: drivers/net/dd/pcnet/pcnet.c + * PURPOSE: PCNet Device Driver + * PROGRAMMERS: Vizzini (vizzini@plasmic.com), + * borrowed very heavily from the ReactOS ne2000 driver by + * Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISIONS: + * 14-Sept-2003 vizzini - Created + * NOTES: + */ +#include +#include "pcnethw.h" +#include "pcnet.h" + +/* List of supported OIDs */ +static ULONG MiniportOIDList[] = +{ + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_LOOKAHEAD, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BUFFER_SPACE, + OID_GEN_RECEIVE_BUFFER_SPACE, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_CURRENT_PACKET_FILTER, + OID_GEN_CURRENT_LOOKAHEAD, + OID_GEN_DRIVER_VERSION, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_PROTOCOL_OPTIONS, + OID_GEN_MAC_OPTIONS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAXIMUM_LIST_SIZE, + OID_802_3_MAC_OPTIONS +}; + + +NDIS_STATUS +STDCALL +MiniportQueryInformation( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded) +/* + * FUNCTION: Query an OID from the driver + * ARGUMENTS: + * MiniportAdapterContext: context originally passed to NdisMSetAttributes + * Oid: OID NDIS is querying + * InformationBuffer: pointer to buffer into which to write the results of the query + * InformationBufferLength: size in bytes of InformationBuffer + * BytesWritten: number of bytes written into InformationBuffer in response to the query + * BytesNeeded: number of bytes needed to answer the query + * RETURNS: + * NDIS_STATUS_SUCCESS on all queries + * NOTES: + * - Called by NDIS at PASSIVE_LEVEL + * - If InformationBufferLength is insufficient to store the results, return the amount + * needed in BytesNeeded and return NDIS_STATUS_INVALID_LENGTH + * TODO: + * - Update to verify input buffer & size and return insufficient buffer codes + */ +{ + NDIS_STATUS Status; + PVOID CopyFrom; + UINT CopySize; + ULONG GenericULONG; + PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; + + PCNET_DbgPrint(("Called. OID 0x%x\n", Oid)); + + ASSERT(Adapter); + + Status = NDIS_STATUS_SUCCESS; + CopyFrom = (PVOID)&GenericULONG; + CopySize = sizeof(ULONG); + + switch (Oid) + { + case OID_GEN_SUPPORTED_LIST: + { + CopyFrom = (PVOID)&MiniportOIDList; + CopySize = sizeof(MiniportOIDList); + break; + } + + case OID_GEN_HARDWARE_STATUS: + { + /* TODO: implement this... */ + GenericULONG = (ULONG)NdisHardwareStatusReady; + break; + } + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + { + NDIS_MEDIUM Medium = NdisMedium802_3; + CopyFrom = (PVOID)&Medium; + CopySize = sizeof(NDIS_MEDIUM); + break; + } + + case OID_GEN_MAXIMUM_LOOKAHEAD: + { + GenericULONG = 1500; + break; + } + + case OID_GEN_MAXIMUM_FRAME_SIZE: + { + /* XXX I'm not sure this is correct */ + GenericULONG = 1514; + break; + } + + case OID_GEN_LINK_SPEED: + { + GenericULONG = 100000; /* 10Mbps */ + break; + } + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + { + /* XXX fix me */ + GenericULONG = BUFFER_SIZE; + break; + } + + case OID_GEN_RECEIVE_BUFFER_SPACE: + { + /* XXX fix me */ + GenericULONG = BUFFER_SIZE; + break; + } + + case OID_GEN_TRANSMIT_BLOCK_SIZE: + { + GenericULONG = BUFFER_SIZE; + break; + } + + case OID_GEN_RECEIVE_BLOCK_SIZE: + { + GenericULONG = BUFFER_SIZE; + break; + } + + case OID_GEN_VENDOR_ID: + { + GenericULONG = 0x1022; + break; + } + + case OID_GEN_VENDOR_DESCRIPTION: + { + /* XXX implement me */ + CopyFrom = 0; + CopySize = 0; + break; + } + + case OID_GEN_VENDOR_DRIVER_VERSION: + { + /* XXX implement me */ + GenericULONG = 1; + break; + } + + case OID_GEN_CURRENT_PACKET_FILTER: + { + GenericULONG = Adapter->CurrentPacketFilter; + break; + } + + case OID_GEN_CURRENT_LOOKAHEAD: + { + /* XXX make me a constant */ + GenericULONG = 1500; + break; + } + + case OID_GEN_DRIVER_VERSION: + { + GenericULONG = 1; + break; + } + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + { + GenericULONG = 1514; + break; + } + + case OID_GEN_PROTOCOL_OPTIONS: + { + PCNET_DbgPrint(("OID_GEN_PROTOCOL_OPTIONS.\n")); + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + case OID_GEN_MAC_OPTIONS: + { + GenericULONG = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | + NDIS_MAC_OPTION_RECEIVE_SERIALIZED | + NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | + NDIS_MAC_OPTION_NO_LOOPBACK; + break; + } + + case OID_GEN_MEDIA_CONNECT_STATUS: + { + GenericULONG = (ULONG)NdisMediaStateConnected; + break; + } + + case OID_GEN_MAXIMUM_SEND_PACKETS: + { + GenericULONG = 1; + break; + } + + case OID_802_3_CURRENT_ADDRESS: + case OID_802_3_PERMANENT_ADDRESS: + { + CopyFrom = (PVOID)&Adapter->InitializationBlockVirt->PADR; + CopySize = 6; + break; + } + + case OID_802_3_MULTICAST_LIST: + { + /* XXX Implement me */ + PCNET_DbgPrint(("OID_802_3_MULTICAST_LIST.\n")); + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + case OID_802_3_MAXIMUM_LIST_SIZE: + { + /* XXX Implement me */ + GenericULONG = 0; + break; + } + + case OID_802_3_MAC_OPTIONS: + { + /* XXX Implement me */ + PCNET_DbgPrint(("OID_802_3_MAC_OPTIONS.\n")); + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + default: + { + PCNET_DbgPrint(("Unknown OID\n")); + Status = NDIS_STATUS_INVALID_OID; + break; + } + } + + if (Status == NDIS_STATUS_SUCCESS) + { + if (CopySize > InformationBufferLength) + { + *BytesNeeded = (CopySize - InformationBufferLength); + *BytesWritten = 0; + Status = NDIS_STATUS_INVALID_LENGTH; + } + else + { + NdisMoveMemory(InformationBuffer, CopyFrom, CopySize); + *BytesWritten = CopySize; + *BytesNeeded = 0; + } + } + + PCNET_DbgPrint(("Leaving. Status is 0x%x\n", Status)); + + return Status; +} + + +NDIS_STATUS +STDCALL +MiniportSetInformation( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded) +/* + * FUNCTION: Set a miniport variable (OID) + * ARGUMENTS: + * MiniportAdapterContext: context originally passed into NdisMSetAttributes + * Oid: the variable being set + * InformationBuffer: the data to set the variable to + * InformationBufferLength: number of bytes in InformationBuffer + * BytesRead: number of bytes read by us out of the buffer + * BytesNeeded: number of bytes required to satisfy the request if InformationBufferLength + * is insufficient + * RETURNS: + * NDIS_STATUS_SUCCESS on all requests + * NOTES: + * - Called by NDIS at PASSIVE_LEVEL + * - verify buffer space as mentioned in previous function notes + */ +{ + ULONG GenericULONG; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; + + ASSERT(Adapter); + + PCNET_DbgPrint(("Called, OID 0x%x\n", Oid)); + + switch (Oid) + { + case OID_GEN_CURRENT_PACKET_FILTER: + { + /* Verify length */ + if (InformationBufferLength < sizeof(ULONG)) + { + *BytesRead = 0; + *BytesNeeded = sizeof(ULONG) - InformationBufferLength; + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG)); + + /* Check for properties the driver don't support */ + if (GenericULONG & + (NDIS_PACKET_TYPE_ALL_FUNCTIONAL | + NDIS_PACKET_TYPE_FUNCTIONAL | + NDIS_PACKET_TYPE_GROUP | + NDIS_PACKET_TYPE_MAC_FRAME | + NDIS_PACKET_TYPE_SMT | + NDIS_PACKET_TYPE_SOURCE_ROUTING) + ) + { + *BytesRead = 4; + *BytesNeeded = 0; + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + Adapter->CurrentPacketFilter = GenericULONG; + + /* FIXME: Set filter on hardware */ + + break; + } + + case OID_GEN_CURRENT_LOOKAHEAD: + { + /* Verify length */ + if (InformationBufferLength < sizeof(ULONG)) + { + *BytesRead = 0; + *BytesNeeded = sizeof(ULONG) - InformationBufferLength; + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG)); + + if (GenericULONG > 1500) + Status = NDIS_STATUS_INVALID_LENGTH; + else + Adapter->CurrentLookaheadSize = GenericULONG; + + break; + } + + case OID_802_3_MULTICAST_LIST: + { + /* Verify length. Must be multiple of hardware address length */ + if ((InformationBufferLength % 6) != 0) + { + *BytesRead = 0; + *BytesNeeded = 0; + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + /* Set new multicast address list */ + //NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength); + + /* FIXME: Update hardware */ + + break; + } + + default: + { + PCNET_DbgPrint(("Invalid object ID (0x%X).\n", Oid)); + *BytesRead = 0; + *BytesNeeded = 0; + Status = NDIS_STATUS_INVALID_OID; + break; + } + } + + if (Status == NDIS_STATUS_SUCCESS) + { + *BytesRead = InformationBufferLength; + *BytesNeeded = 0; + } + + PCNET_DbgPrint(("Leaving. Status (0x%X).\n", Status)); + + return Status; +} +