* 20 Aug 2003 vizzini - DMA support
* 3 Oct 2003 vizzini - SendPackets support
*/
-#include <miniport.h>
-#include <protocol.h>
+
+#include "ndissys.h"
+#include "efilter.h"
#ifdef DBG
#include <buffer.h>
#endif /* DBG */
+#undef NdisMSendComplete
+VOID
+EXPORT
+NdisMSendComplete(
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN PNDIS_PACKET Packet,
+ IN NDIS_STATUS Status);
+
/* Root of the scm database */
#define SERVICES_ROOT L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
-/* prefix for device object registration */
-#define DEVICE_ROOT L"\\Device\\"
-
/*
* Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
* for each new miniport starting up
*/
#define BREAK_ON_MINIPORT_INIT 0
-/*
+/*
* This has to be big enough to hold the results of querying the Route value
* from the Linkage key. Please re-code me to determine this dynamically.
*/
/* Number of media we know */
#define MEDIA_ARRAY_SIZE 15
-static NDIS_MEDIUM MediaArray[MEDIA_ARRAY_SIZE] =
+static NDIS_MEDIUM MediaArray[MEDIA_ARRAY_SIZE] =
{
NdisMedium802_3,
NdisMedium802_5,
LIST_ENTRY AdapterListHead;
KSPIN_LOCK AdapterListLock;
-/* global list and lock of orphan adapters waiting to be claimed by a miniport */
-LIST_ENTRY OrphanAdapterListHead;
-KSPIN_LOCK OrphanAdapterListLock;
-
-
VOID
MiniDisplayPacket(
PNDIS_PACKET Packet)
{
-//#ifdef DBG
-#if 0
+#ifdef DBG
ULONG i, Length;
UCHAR Buffer[64];
- if ((DebugTraceLevel | DEBUG_PACKET) > 0) {
+ if ((DebugTraceLevel & DEBUG_PACKET) > 0) {
Length = CopyPacketToBuffer(
(PUCHAR)&Buffer,
Packet,
PVOID LookaheadBuffer,
UINT LookaheadBufferSize)
{
-//#ifdef DBG
-#if 0
- if ((DebugTraceLevel | DEBUG_PACKET) > 0) {
+#ifdef DBG
+ if ((DebugTraceLevel & DEBUG_PACKET) > 0) {
ULONG i, Length;
PUCHAR p;
for (i = 0; i < HeaderBufferSize; i++) {
if (i % 16 == 0)
DbgPrint("\n%04X ", i);
- DbgPrint("%02X ", *p);
- (ULONG_PTR)p += 1;
+ DbgPrint("%02X ", *p++);
}
DbgPrint("\nFRAME:");
for (i = 0; i < Length; i++) {
if (i % 16 == 0)
DbgPrint("\n%04X ", i);
- DbgPrint("%02X ", *p);
- (ULONG_PTR)p += 1;
+ DbgPrint("%02X ", *p++);
}
DbgPrint("\n*** RECEIVE PACKET STOP ***\n");
* subsequently re-acquire the lock.
*
* I don't see how this does any good, as it would seem he's just
- * trying to protect the packet list. If someobdy else dequeues
+ * trying to protect the packet list. If somebody else dequeues
* a packet, we are in fact in bad shape, but we don't want to
* necessarily call the receive handler at elevated irql either.
*
//KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
{
CurrentEntry = Adapter->ProtocolListHead.Flink;
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("CurrentEntry = %x\n", CurrentEntry));
- if (CurrentEntry == &Adapter->ProtocolListHead)
+ if (CurrentEntry == &Adapter->ProtocolListHead)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("WARNING: No upper protocol layer.\n"));
}
- while (CurrentEntry->Flink != &Adapter->ProtocolListHead)
+ while (CurrentEntry != &Adapter->ProtocolListHead)
{
AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry);
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("AdapterBinding = %x\n", AdapterBinding));
/* see above */
/* KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */
-#if DBG
+#ifdef DBG
if(!AdapterBinding)
{
NDIS_DbgPrint(MIN_TRACE, ("AdapterBinding was null\n"));
break;
}
- if(!AdapterBinding->ProtocolBinding->Chars.u4.ReceiveHandler)
+ if(!AdapterBinding->ProtocolBinding->Chars.ReceiveHandler)
{
- NDIS_DbgPrint(MIN_TRACE, ("AdapterBinding->ProtocolBinding->Chars.u4.ReceiveHandler was null\n"));
+ 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",
+ *AdapterBinding->ProtocolBinding->Chars.ReceiveHandler,
+ AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
+ MacReceiveContext,
+ HeaderBuffer,
+ HeaderBufferSize,
+ LookaheadBuffer,
+ LookaheadBufferSize,
+ PacketSize));
+
/* call the receive handler */
- (*AdapterBinding->ProtocolBinding->Chars.u4.ReceiveHandler)(
+ (*AdapterBinding->ProtocolBinding->Chars.ReceiveHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
MacReceiveContext,
HeaderBuffer,
}
\f
-VOID STDCALL
+VOID NTAPI
MiniIndicateReceivePacket(
IN NDIS_HANDLE Miniport,
IN PPNDIS_PACKET PacketArray,
NDIS_DbgPrint(MID_TRACE, ("indicating a %d-byte packet\n", PacketLength));
- MiniIndicateData(Miniport, 0, PacketBuffer, 14, PacketBuffer+14, PacketLength-14, PacketLength-14);
+ MiniIndicateData(Miniport, NULL, PacketBuffer, 14, PacketBuffer+14, PacketLength-14, PacketLength-14);
NdisFreeMemory(PacketBuffer, 0, 0);
}
}
\f
-VOID STDCALL
-MiniEthReceiveComplete(
- IN PETH_FILTER Filter)
-/*
- * FUNCTION: Receive indication complete function for Ethernet devices
- * ARGUMENTS:
- * Filter = Pointer to Ethernet filter
- */
-{
- KIRQL OldIrql;
- PLIST_ENTRY CurrentEntry;
- PLOGICAL_ADAPTER Adapter;
- PADAPTER_BINDING AdapterBinding;
-
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
-
- if( !Filter ) return;
-
- Adapter = (PLOGICAL_ADAPTER)Filter->Miniport;
-
- NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n"));
- KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
- {
- CurrentEntry = Adapter->ProtocolListHead.Flink;
-
- while (CurrentEntry != &Adapter->ProtocolListHead)
- {
- AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry);
-
- /* see comment in MiniIndicateData */
- /* KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */
-
- (*AdapterBinding->ProtocolBinding->Chars.ReceiveCompleteHandler)(
- AdapterBinding->NdisOpenBlock.ProtocolBindingContext);
-
- /* see above */
- /* KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); */
-
- CurrentEntry = CurrentEntry->Flink;
- }
- }
- KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
-}
-
-\f
-VOID STDCALL
-MiniEthReceiveIndication(
- IN PETH_FILTER Filter, /* shouldn't be NDIS_HANDLE? */
- IN NDIS_HANDLE MacReceiveContext,
- IN PCHAR Address,
- IN PVOID HeaderBuffer,
- IN UINT HeaderBufferSize,
- IN PVOID LookaheadBuffer,
- IN UINT LookaheadBufferSize,
- IN UINT PacketSize)
-/*
- * FUNCTION: Receive indication function for Ethernet devices
- * ARGUMENTS:
- * Filter = Pointer to Ethernet filter
- * MacReceiveContext = MAC receive context handle
- * Address = Pointer to destination Ethernet address
- * HeaderBuffer = Pointer to Ethernet header buffer
- * HeaderBufferSize = Size of Ethernet header buffer
- * LookaheadBuffer = Pointer to lookahead buffer
- * LookaheadBufferSize = Size of lookahead buffer
- * PacketSize = Total size of received packet
- */
-{
- if( Filter ) {
- MiniIndicateData((PLOGICAL_ADAPTER)Filter->Miniport,
- MacReceiveContext,
- HeaderBuffer,
- HeaderBufferSize,
- LookaheadBuffer,
- LookaheadBufferSize,
- PacketSize);
- }
-}
-
-\f
-VOID STDCALL
+VOID NTAPI
MiniResetComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_STATUS Status,
}
-VOID STDCALL
+\f
+VOID NTAPI
+MiniRequestComplete(
+ IN PADAPTER_BINDING AdapterBinding,
+ IN PNDIS_REQUEST Request,
+ IN NDIS_STATUS Status)
+{
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
+
+ if( AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler ) {
+ (*AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler)(
+ AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
+ Request,
+ Status);
+ }
+}
+
+VOID NTAPI
MiniSendComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN PNDIS_PACKET Packet,
AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[0];
- (*AdapterBinding->ProtocolBinding->Chars.u2.SendCompleteHandler)(
+ (*AdapterBinding->ProtocolBinding->Chars.SendCompleteHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
Packet,
Status);
}
-VOID STDCALL
+VOID NTAPI
MiniSendResourcesAvailable(
IN NDIS_HANDLE MiniportAdapterHandle)
{
}
-VOID STDCALL
+VOID NTAPI
MiniTransferDataComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred)
{
- PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle;
- PADAPTER_BINDING AdapterBinding = Adapter->MiniportAdapterBinding;
+ PADAPTER_BINDING AdapterBinding;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
- (*AdapterBinding->ProtocolBinding->Chars.u3.TransferDataCompleteHandler)(
+ AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[0];
+
+ (*AdapterBinding->ProtocolBinding->Chars.SendCompleteHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
Packet,
- Status,
- BytesTransferred);
+ Status);
}
\f
PLOGICAL_ADAPTER Adapter,
PNDIS_PACKET Packet)
/*
- * FUNCTION: Determines wether a packet has the same destination address as an adapter
+ * FUNCTION: Determines whether a packet has the same destination address as an adapter
* ARGUMENTS:
* Adapter = Pointer to logical adapter object
* Packet = Pointer to NDIS packet
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
-#if DBG
+#ifdef DBG
if(!Adapter)
{
NDIS_DbgPrint(MID_TRACE, ("Adapter object was null\n"));
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
- if (!NdisBuffer)
+ if (!NdisBuffer)
{
NDIS_DbgPrint(MID_TRACE, ("Packet contains no buffers.\n"));
return FALSE;
/* FIXME: Should handle fragmented packets */
- switch (Adapter->NdisMiniportBlock.MediaType)
+ switch (Adapter->NdisMiniportBlock.MediaType)
{
case NdisMedium802_3:
Length = ETH_LENGTH_OF_ADDRESS;
return FALSE;
}
- if (BufferLength < Length)
+ if (BufferLength < Length)
{
NDIS_DbgPrint(MID_TRACE, ("Buffer is too small.\n"));
return FALSE;
{
CurrentEntry = AdapterListHead.Flink;
- while (CurrentEntry != &AdapterListHead)
+ while (CurrentEntry != &AdapterListHead)
{
Adapter = CONTAINING_RECORD(CurrentEntry, LOGICAL_ADAPTER, ListEntry);
ASSERT(Adapter);
- NDIS_DbgPrint(DEBUG_MINIPORT, ("AdapterName = %wZ\n", &AdapterName));
- NDIS_DbgPrint(DEBUG_MINIPORT, ("DeviceName = %wZ\n", &Adapter->DeviceName));
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("AdapterName = %wZ\n", AdapterName));
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("DeviceName = %wZ\n", &Adapter->NdisMiniportBlock.MiniportName));
- if (RtlCompareUnicodeString(AdapterName, &Adapter->DeviceName, TRUE) == 0)
+ if (RtlCompareUnicodeString(AdapterName, &Adapter->NdisMiniportBlock.MiniportName, TRUE) == 0)
{
ReferenceObject(Adapter);
break;
}
+ Adapter = NULL;
CurrentEntry = CurrentEntry->Flink;
}
} while (0);
if(Adapter)
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Leaving. Adapter found at 0x%x\n", Adapter));
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Leaving. Adapter found at 0x%x\n", Adapter));
}
else
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
- if (Adapter->QueryBufferLength == 0)
+ if (Adapter->QueryBufferLength == 0)
{
/* XXX is 32 the right number? */
Adapter->QueryBuffer = ExAllocatePool(NonPagedPool, (Size == 0)? 32 : Size);
- if (!Adapter->QueryBuffer)
+ if (!Adapter->QueryBuffer)
{
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES;
&BytesNeeded);
/* XXX is status_pending part of success macro? */
- if ((NT_SUCCESS(NdisStatus)) || (NdisStatus == NDIS_STATUS_PENDING))
+ if ((NT_SUCCESS(NdisStatus)) || (NdisStatus == NDIS_STATUS_PENDING))
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Miniport returned status (0x%X).\n", NdisStatus));
return NdisStatus;
}
- if (NdisStatus == NDIS_STATUS_INVALID_LENGTH)
+ if (NdisStatus == NDIS_STATUS_INVALID_LENGTH)
{
ExFreePool(Adapter->QueryBuffer);
Adapter->QueryBufferLength += BytesNeeded;
Adapter->QueryBuffer = ExAllocatePool(NonPagedPool, Adapter->QueryBufferLength);
- if (!Adapter->QueryBuffer)
+ if (!Adapter->QueryBuffer)
{
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES;
Adapter->NdisMiniportBlock.MiniportAdapterContext,
Oid,
Adapter->QueryBuffer,
- Size,
+ Adapter->QueryBufferLength,
BytesWritten,
&BytesNeeded);
}
NDIS_STATUS
FASTCALL
MiniQueueWorkItem(
- PLOGICAL_ADAPTER Adapter,
+ PADAPTER_BINDING AdapterBinding,
NDIS_WORK_ITEM_TYPE WorkItemType,
- PVOID WorkItemContext,
- NDIS_HANDLE Initiator)
+ PVOID WorkItemContext)
/*
* FUNCTION: Queues a work item for execution at a later time
* ARGUMENTS:
* Adapter = Pointer to the logical adapter object to queue work item on
* WorkItemType = Type of work item to queue
* WorkItemContext = Pointer to context information for work item
- * Initiator = Pointer to ADAPTER_BINDING structure of initiating protocol
* NOTES:
* Adapter lock must be held when called
* RETURNS:
* Status of operation
*/
{
- PNDIS_MINIPORT_WORK_ITEM Item;
-
- NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- ASSERT(Adapter);
-
- if (Adapter->WorkQueueLevel < NDIS_MINIPORT_WORK_QUEUE_SIZE - 1)
+ PINTERNAL_NDIS_MINIPORT_WORK_ITEM Item;
+ PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
+
+ NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ ASSERT(Adapter);
+ ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
+
+#if 0
+ if (Adapter->WorkQueueLevel < NDIS_MINIPORT_WORK_QUEUE_SIZE - 1)
{
- Item = &Adapter->WorkQueue[Adapter->WorkQueueLevel];
- Adapter->WorkQueueLevel++;
- }
- else
+ Item = &Adapter->WorkQueue[Adapter->WorkQueueLevel];
+ Adapter->WorkQueueLevel++;
+ }
+ else
+#endif
{
- Item = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM));
- if (Item)
- {
- /* Set flag so we know that the buffer should be freed when work item is dequeued */
- Item->Allocated = TRUE;
- }
- else
+ Item = ExAllocatePool(NonPagedPool, sizeof(INTERNAL_NDIS_MINIPORT_WORK_ITEM));
+ if (Item == NULL)
{
- NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return NDIS_STATUS_RESOURCES;
+ NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ return NDIS_STATUS_RESOURCES;
}
}
-
- Item->WorkItemType = WorkItemType;
- Item->WorkItemContext = WorkItemContext;
- Item->Initiator = Initiator;
-
- /* safe due to adapter lock held */
- Item->Link.Next = NULL;
- if (!Adapter->WorkQueueHead)
+
+ Item->AdapterBinding = AdapterBinding;
+ Item->RealWorkItem.WorkItemType = WorkItemType;
+ Item->RealWorkItem.WorkItemContext = WorkItemContext;
+
+ /* safe due to adapter lock held */
+ Item->Link.Next = NULL;
+ if (!Adapter->WorkQueueHead)
{
- Adapter->WorkQueueHead = Item;
- Adapter->WorkQueueTail = Item;
- }
- else
+ Adapter->WorkQueueHead = Item;
+ Adapter->WorkQueueTail = Item;
+ }
+ else
{
- Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)Item;
- Adapter->WorkQueueTail = Item;
+ Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)Item;
+ Adapter->WorkQueueTail = Item;
}
-
- KeInsertQueueDpc(&Adapter->MiniportDpc, NULL, NULL);
-
- return NDIS_STATUS_SUCCESS;
+
+ KeInsertQueueDpc(&Adapter->MiniportDpc, NULL, NULL);
+
+ return NDIS_STATUS_SUCCESS;
}
\f
FASTCALL
MiniDequeueWorkItem(
PLOGICAL_ADAPTER Adapter,
+ PADAPTER_BINDING *AdapterBinding,
NDIS_WORK_ITEM_TYPE *WorkItemType,
- PVOID *WorkItemContext,
- NDIS_HANDLE *Initiator)
+ PVOID *WorkItemContext)
/*
* FUNCTION: Dequeues a work item from the work queue of a logical adapter
* ARGUMENTS:
* Adapter = Pointer to the logical adapter object to dequeue work item from
+ * AdapterBinding = Address of buffer for adapter binding for this request
* WorkItemType = Address of buffer for work item type
* WorkItemContext = Address of buffer for pointer to context information
- * Initiator = Address of buffer for initiator of the work (ADAPTER_BINDING)
* NOTES:
* Adapter lock must be held when called
* RETURNS:
* Status of operation
*/
{
- PNDIS_MINIPORT_WORK_ITEM Item;
-
- NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- Item = Adapter->WorkQueueHead;
-
- if (Item)
+ PINTERNAL_NDIS_MINIPORT_WORK_ITEM Item;
+
+ NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ Item = Adapter->WorkQueueHead;
+
+ if (Item)
{
- /* safe due to adapter lock held */
- Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)Item->Link.Next;
-
- if (Item == Adapter->WorkQueueTail)
- Adapter->WorkQueueTail = NULL;
-
- *WorkItemType = Item->WorkItemType;
- *WorkItemContext = Item->WorkItemContext;
- *Initiator = Item->Initiator;
-
- if (Item->Allocated)
- {
- ExFreePool(Item);
- }
- else
- {
- Adapter->WorkQueueLevel--;
-#ifdef DBG
- if (Adapter->WorkQueueLevel < 0)
- {
- NDIS_DbgPrint(MIN_TRACE, ("Adapter->WorkQueueLevel is < 0 (should be >= 0).\n"));
- }
-#endif
- }
-
- return NDIS_STATUS_SUCCESS;
+ /* safe due to adapter lock held */
+ Adapter->WorkQueueHead = (PINTERNAL_NDIS_MINIPORT_WORK_ITEM)Item->Link.Next;
+
+ if (Item == Adapter->WorkQueueTail)
+ Adapter->WorkQueueTail = NULL;
+
+ *AdapterBinding = Item->AdapterBinding;
+ *WorkItemType = Item->RealWorkItem.WorkItemType;
+ *WorkItemContext = Item->RealWorkItem.WorkItemContext;
+
+ ExFreePool(Item);
+
+ return NDIS_STATUS_SUCCESS;
}
-
- return NDIS_STATUS_FAILURE;
+
+ return NDIS_STATUS_FAILURE;
}
\f
NDIS_STATUS
MiniDoRequest(
- PLOGICAL_ADAPTER Adapter,
+ PADAPTER_BINDING AdapterBinding,
PNDIS_REQUEST NdisRequest)
/*
* FUNCTION: Sends a request to a miniport
* ARGUMENTS:
- * Adapter = Pointer to logical adapter object
- * NdisRequest = Pointer to NDIS request structure describing request
+ * AdapterBinding = Pointer to binding used in the request
+ * NdisRequest = Pointer to NDIS request structure describing request
* RETURNS:
* Status of operation
*/
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
-
- Adapter->NdisMiniportBlock.MediaRequest = NdisRequest;
+ PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
- switch (NdisRequest->RequestType)
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
+
+ Adapter->NdisMiniportBlock.MediaRequest = NdisRequest;
+
+ switch (NdisRequest->RequestType)
{
- case NdisRequestQueryInformation:
+ case NdisRequestQueryInformation:
return (*Adapter->Miniport->Chars.QueryInformationHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext,
NdisRequest->DATA.QUERY_INFORMATION.Oid,
(PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesWritten,
(PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded);
break;
-
- case NdisRequestSetInformation:
+
+ case NdisRequestSetInformation:
return (*Adapter->Miniport->Chars.SetInformationHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext,
NdisRequest->DATA.SET_INFORMATION.Oid,
(PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesRead,
(PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesNeeded);
break;
-
- default:
+
+ default:
return NDIS_STATUS_FAILURE;
}
}
\f
-VOID STDCALL MiniportDpc(
+/*
+ * @implemented
+ */
+#undef NdisMQueryInformationComplete
+VOID
+EXPORT
+NdisMQueryInformationComplete(
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_STATUS Status)
+{
+ PNDIS_MINIPORT_BLOCK MiniportBlock =
+ (PNDIS_MINIPORT_BLOCK)MiniportAdapterHandle;
+ ASSERT(MiniportBlock);
+ if( MiniportBlock->QueryCompleteHandler )
+ (MiniportBlock->QueryCompleteHandler)(MiniportAdapterHandle, Status);
+}
+
+\f
+VOID NTAPI MiniportDpc(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
- /* XXX is adapter lock held here? should be... */
- NdisStatus = MiniDequeueWorkItem(Adapter, &WorkItemType, &WorkItemContext, (PNDIS_HANDLE)&AdapterBinding);
+ NdisStatus =
+ MiniDequeueWorkItem
+ (Adapter, &AdapterBinding, &WorkItemType, &WorkItemContext);
- if (NdisStatus == NDIS_STATUS_SUCCESS)
+ if (NdisStatus == NDIS_STATUS_SUCCESS)
{
- Adapter->MiniportAdapterBinding = AdapterBinding;
-
- switch (WorkItemType)
+ switch (WorkItemType)
{
case NdisWorkItemSend:
/*
*/
(*Adapter->Miniport->Chars.SendPacketsHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext, (PPNDIS_PACKET)&WorkItemContext, 1);
+ NdisStatus =
+ NDIS_GET_PACKET_STATUS((PNDIS_PACKET)WorkItemContext);
NDIS_DbgPrint(MAX_TRACE, ("back from miniport's SendPackets handler\n"));
}
{
NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n"));
- NdisStatus = (*Adapter->Miniport->Chars.u1.SendHandler)(
+ NdisStatus = (*Adapter->Miniport->Chars.SendHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext, (PNDIS_PACKET)WorkItemContext, 0);
NDIS_DbgPrint(MAX_TRACE, ("back from miniport's Send handler\n"));
-
- if (NdisStatus != NDIS_STATUS_PENDING)
- MiniSendComplete((NDIS_HANDLE)Adapter, (PNDIS_PACKET)WorkItemContext, NdisStatus);
}
-
+ if( NdisStatus != NDIS_STATUS_PENDING ) {
+ NdisMSendComplete
+ ( Adapter, (PNDIS_PACKET)WorkItemContext, NdisStatus );
+ Adapter->MiniportBusy = FALSE;
+ }
break;
case NdisWorkItemSendLoopback:
case NdisWorkItemResetInProgress:
break;
- case NdisWorkItemHalt:
- break;
-
case NdisWorkItemMiniportCallback:
break;
case NdisWorkItemRequest:
- NdisStatus = MiniDoRequest(Adapter, (PNDIS_REQUEST)WorkItemContext);
+ NdisStatus = MiniDoRequest(AdapterBinding, (PNDIS_REQUEST)WorkItemContext);
if (NdisStatus == NDIS_STATUS_PENDING)
break;
- switch (((PNDIS_REQUEST)WorkItemContext)->RequestType)
+ switch (((PNDIS_REQUEST)WorkItemContext)->RequestType)
{
case NdisRequestQueryInformation:
- NdisMQueryInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
+ NdisMQueryInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
+ MiniRequestComplete( AdapterBinding, (PNDIS_REQUEST)WorkItemContext, NdisStatus );
break;
case NdisRequestSetInformation:
NdisMSetInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
+ MiniRequestComplete( AdapterBinding, (PNDIS_REQUEST)WorkItemContext, NdisStatus );
break;
default:
* ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
*/
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportHandle;
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
+
if(Adapter->BugcheckContext->ShutdownHandler)
KeDeregisterBugCheckCallback(Adapter->BugcheckContext->CallbackRecord);
}
UNIMPLEMENTED
}
-
/*
* @unimplemented
*/
+#undef NdisMIndicateStatus
VOID
EXPORT
NdisMIndicateStatus(
UNIMPLEMENTED
}
-
/*
* @unimplemented
*/
+#undef NdisMIndicateStatusComplete
VOID
EXPORT
NdisMIndicateStatusComplete(
Miniport = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_DRIVER));
- if (!Miniport)
+ if (!Miniport)
{
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return;
}
\f
-/*
- * @implemented
- */
-VOID
-EXPORT
-NdisMQueryInformationComplete(
- IN NDIS_HANDLE MiniportAdapterHandle,
- IN NDIS_STATUS Status)
-{
- PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
- PADAPTER_BINDING AdapterBinding = (PADAPTER_BINDING)Adapter->MiniportAdapterBinding;
-
- NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- (*AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler)(
- AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
- Adapter->NdisMiniportBlock.MediaRequest,
- Status);
-}
-
-\f
-VOID STDCALL NdisIBugcheckCallback(
+VOID NTAPI NdisIBugcheckCallback(
IN PVOID Buffer,
IN ULONG Length)
/*
if(sh)
sh(Context->DriverContext);
-}
+}
\f
/*
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
- if(BugcheckContext)
+ if(BugcheckContext)
return;
BugcheckContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_BUGCHECK_CONTEXT));
/* not sure if this needs to be initialized or not... oh well, it's a leak. */
BugcheckContext->CallbackRecord = ExAllocatePool(NonPagedPool, sizeof(KBUGCHECK_CALLBACK_RECORD));
- KeRegisterBugCheckCallback(BugcheckContext->CallbackRecord, NdisIBugcheckCallback,
- BugcheckContext, sizeof(BugcheckContext), "Ndis Miniport");
+ KeRegisterBugCheckCallback(BugcheckContext->CallbackRecord, NdisIBugcheckCallback,
+ BugcheckContext, sizeof(BugcheckContext), (PUCHAR)"Ndis Miniport");
}
\f
/* Get MAC options for adapter */
NdisStatus = MiniQueryInformation(Adapter, OID_GEN_MAC_OPTIONS, 0, &BytesWritten);
- if (NdisStatus != NDIS_STATUS_SUCCESS)
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
{
NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus));
return NdisStatus;
/* Get current hardware address of adapter */
NdisStatus = MiniQueryInformation(Adapter, AddressOID, 0, &BytesWritten);
- if (NdisStatus != NDIS_STATUS_SUCCESS)
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
{
NDIS_DbgPrint(MIN_TRACE, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID, NdisStatus));
return NdisStatus;
/* Get maximum lookahead buffer size of adapter */
NdisStatus = MiniQueryInformation(Adapter, OID_GEN_MAXIMUM_LOOKAHEAD, 0, &BytesWritten);
- if (NdisStatus != NDIS_STATUS_SUCCESS)
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
{
NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus));
return NdisStatus;
}
- Adapter->MaxLookaheadLength = *((PULONG)Adapter->QueryBuffer);
+ Adapter->NdisMiniportBlock.MaximumLookahead = *((PULONG)Adapter->QueryBuffer);
- NDIS_DbgPrint(DEBUG_MINIPORT, ("MaxLookaheadLength (0x%X).\n", Adapter->MaxLookaheadLength));
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("MaxLookaheadLength (0x%X).\n", Adapter->NdisMiniportBlock.MaximumLookahead));
/* Get current lookahead buffer size of adapter */
NdisStatus = MiniQueryInformation(Adapter, OID_GEN_CURRENT_LOOKAHEAD, 0, &BytesWritten);
- if (NdisStatus != NDIS_STATUS_SUCCESS)
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
{
NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus));
return NdisStatus;
}
- Adapter->CurLookaheadLength = *((PULONG)Adapter->QueryBuffer);
+ Adapter->NdisMiniportBlock.CurrentLookahead = *((PULONG)Adapter->QueryBuffer);
- NDIS_DbgPrint(DEBUG_MINIPORT, ("CurLookaheadLength (0x%X).\n", Adapter->CurLookaheadLength));
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("CurLookaheadLength (0x%X).\n", Adapter->NdisMiniportBlock.CurrentLookahead));
- if (Adapter->MaxLookaheadLength != 0)
+ if (Adapter->NdisMiniportBlock.MaximumLookahead != 0)
{
- Adapter->LookaheadLength = Adapter->MaxLookaheadLength + Adapter->MediumHeaderSize;
+ Adapter->LookaheadLength = Adapter->NdisMiniportBlock.MaximumLookahead + Adapter->MediumHeaderSize;
Adapter->LookaheadBuffer = ExAllocatePool(NonPagedPool, Adapter->LookaheadLength);
if (!Adapter->LookaheadBuffer)
}
\f
-VOID
-NdisIStartAdapter(
- WCHAR *DeviceNameStr,
- UINT DeviceNameStrLength,
- PMINIPORT_DRIVER Miniport
-)
+NTSTATUS
+NTAPI
+NdisIForwardIrpAndWaitCompletionRoutine(
+ PDEVICE_OBJECT Fdo,
+ PIRP Irp,
+ PVOID Context)
+{
+ PKEVENT Event = Context;
+
+ if (Irp->PendingReturned)
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+\f
+NTSTATUS
+NTAPI
+NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter, PIRP Irp)
+{
+ KEVENT Event;
+ NTSTATUS Status;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp, NdisIForwardIrpAndWaitCompletionRoutine, &Event,
+ TRUE, TRUE, TRUE);
+ Status = IoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = Irp->IoStatus.Status;
+ }
+ return Status;
+}
+
+\f
+NTSTATUS
+NTAPI
+NdisIPnPStartDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
/*
- * FUNCTION: Start an adapter
+ * FUNCTION: Handle the PnP start device event
* ARGUMENTS:
- * DeviceNameStr: 0-terminated wide char string of name of device to start
- * DeviceNameStrLength: length of DeviceNameStr *IN WCHARs*
- * NOTES:
- * TODO:
- * - verify that all resources are properly freed on success & failure
- * - break up this 250-line function
+ * DeviceObejct = Functional Device Object
+ * Irp = IRP_MN_START_DEVICE I/O request packet
+ * RETURNS:
+ * Status of operation
*/
{
- WCHAR *DeviceName;
- HANDLE RegKeyHandle;
- WCHAR *RegKeyPath;
- UNICODE_STRING RegKeyPathU;
- OBJECT_ATTRIBUTES RegKeyAttributes;
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
+ NDIS_WRAPPER_CONTEXT WrapperContext;
NDIS_STATUS NdisStatus;
NDIS_STATUS OpenErrorStatus;
NTSTATUS Status;
UINT SelectedMediumIndex = 0;
- PLOGICAL_ADAPTER Adapter = 0;
NDIS_OID AddressOID;
- BOOLEAN MemError = FALSE;
- KIRQL OldIrql;
- PORPHAN_ADAPTER OrphanAdapter = 0;
+ BOOLEAN Success = FALSE;
+ ULONG ResourceCount;
+ ULONG ResourceListSize;
+ UNICODE_STRING ParamName;
+ PNDIS_CONFIGURATION_PARAMETER ConfigParam;
+ NDIS_HANDLE ConfigHandle;
+ ULONG Size;
+/* FIXME - KIRQL OldIrql; */
- NDIS_DbgPrint(MAX_TRACE, ("Called with %ws\n", DeviceNameStr));
- Adapter = ExAllocatePool(NonPagedPool, sizeof(LOGICAL_ADAPTER));
- if (!Adapter)
+ /*
+ * Prepare wrapper context used by HW and configuration routines.
+ */
+
+ Status = IoOpenDeviceRegistryKey(
+ Adapter->NdisMiniportBlock.PhysicalDeviceObject, PLUGPLAY_REGKEY_DRIVER,
+ KEY_ALL_ACCESS, &WrapperContext.RegistryHandle);
+ if (!NT_SUCCESS(Status))
{
- NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return;
+ NDIS_DbgPrint(MIN_TRACE,("failed to open adapter-specific reg key\n"));
+ return Status;
}
- /* This is very important */
- RtlZeroMemory(Adapter, sizeof(LOGICAL_ADAPTER));
+ NDIS_DbgPrint(MAX_TRACE, ("opened device reg key\n"));
- DeviceName = ExAllocatePool(NonPagedPool, sizeof(DEVICE_ROOT) + DeviceNameStrLength * sizeof(WCHAR));
- if(!DeviceName)
+ WrapperContext.DeviceObject = Adapter->NdisMiniportBlock.DeviceObject;
+
+ /*
+ * Store the adapter resources used by HW routines such as
+ * NdisMQueryAdapterResources.
+ */
+
+ if (Stack->Parameters.StartDevice.AllocatedResources != NULL &&
+ Stack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL)
{
- NDIS_DbgPrint(MIN_TRACE,("Insufficient memory\n"));
- ExFreePool(Adapter);
- return;
+ ResourceCount = Stack->Parameters.StartDevice.AllocatedResources->List[0].
+ PartialResourceList.Count;
+ ResourceListSize =
+ FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
+ PartialDescriptors[ResourceCount]);
+
+ Adapter->NdisMiniportBlock.AllocatedResources =
+ ExAllocatePool(PagedPool, ResourceListSize);
+ if (Adapter->NdisMiniportBlock.AllocatedResources == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Adapter->NdisMiniportBlock.AllocatedResourcesTranslated =
+ ExAllocatePool(PagedPool, ResourceListSize);
+ if (Adapter->NdisMiniportBlock.AllocatedResourcesTranslated == NULL)
+ {
+ ExFreePool(Adapter->NdisMiniportBlock.AllocatedResources);
+ Adapter->NdisMiniportBlock.AllocatedResources = NULL;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlCopyMemory(Adapter->NdisMiniportBlock.AllocatedResources,
+ Stack->Parameters.StartDevice.AllocatedResources,
+ ResourceListSize);
+
+ RtlCopyMemory(Adapter->NdisMiniportBlock.AllocatedResourcesTranslated,
+ Stack->Parameters.StartDevice.AllocatedResourcesTranslated,
+ ResourceListSize);
}
- /* DEVICE_ROOT is a constant string defined above, incl. 0-term */
- wcscpy(DeviceName, DEVICE_ROOT);
+ /*
+ * Store the Bus Type, Bus Number and Slot information. It's used by
+ * the hardware routines then.
+ */
- /* reg_sz is 0-term by def */
- wcsncat(DeviceName, DeviceNameStr, DeviceNameStrLength);
- RtlInitUnicodeString(&Adapter->DeviceName, DeviceName);
+ NdisOpenConfiguration(&NdisStatus, &ConfigHandle, (NDIS_HANDLE)&WrapperContext);
- NDIS_DbgPrint(MAX_TRACE, ("creating device %ws\n", DeviceName));
+ Size = sizeof(ULONG);
+ Status = IoGetDeviceProperty(Adapter->NdisMiniportBlock.PhysicalDeviceObject,
+ DevicePropertyLegacyBusType, Size,
+ &Adapter->NdisMiniportBlock.BusType, &Size);
+ if (!NT_SUCCESS(Status) || Adapter->NdisMiniportBlock.BusType == (NDIS_INTERFACE_TYPE)-1)
+ {
+ NdisInitUnicodeString(&ParamName, L"BusType");
+ NdisReadConfiguration(&NdisStatus, &ConfigParam, ConfigHandle,
+ &ParamName, NdisParameterInteger);
+ if (NdisStatus == NDIS_STATUS_SUCCESS)
+ Adapter->NdisMiniportBlock.BusType = ConfigParam->ParameterData.IntegerData;
+ else
+ Adapter->NdisMiniportBlock.BusType = Isa;
+ }
- Status = IoCreateDevice(Miniport->DriverObject, 0, &Adapter->DeviceName, FILE_DEVICE_PHYSICAL_NETCARD,
- 0, FALSE, &Adapter->NdisMiniportBlock.DeviceObject);
- if (!NT_SUCCESS(Status))
+ Status = IoGetDeviceProperty(Adapter->NdisMiniportBlock.PhysicalDeviceObject,
+ DevicePropertyBusNumber, Size,
+ &Adapter->NdisMiniportBlock.BusNumber, &Size);
+ if (!NT_SUCCESS(Status) || Adapter->NdisMiniportBlock.BusNumber == (NDIS_INTERFACE_TYPE)-1)
{
- NDIS_DbgPrint(MIN_TRACE, ("Could not create device object.\n"));
- ExFreePool(Adapter);
- return;
+ NdisInitUnicodeString(&ParamName, L"BusNumber");
+ NdisReadConfiguration(&NdisStatus, &ConfigParam, ConfigHandle,
+ &ParamName, NdisParameterInteger);
+ if (NdisStatus == NDIS_STATUS_SUCCESS)
+ Adapter->NdisMiniportBlock.BusNumber = ConfigParam->ParameterData.IntegerData;
+ else
+ Adapter->NdisMiniportBlock.BusNumber = 0;
}
+ WrapperContext.BusNumber = Adapter->NdisMiniportBlock.BusNumber;
- /* find out if there are any adapters in the orphans list and reserve resources */
- KeAcquireSpinLock(&OrphanAdapterListLock, &OldIrql);
- OrphanAdapter = (PORPHAN_ADAPTER)OrphanAdapterListHead.Flink;
- while(&OrphanAdapter->ListEntry != &OrphanAdapterListHead)
+ Status = IoGetDeviceProperty(Adapter->NdisMiniportBlock.PhysicalDeviceObject,
+ DevicePropertyAddress, Size,
+ &Adapter->NdisMiniportBlock.SlotNumber, &Size);
+ if (!NT_SUCCESS(Status) || Adapter->NdisMiniportBlock.SlotNumber == (NDIS_INTERFACE_TYPE)-1)
{
- PORPHAN_ADAPTER TempAdapter;
- PCM_RESOURCE_LIST ResourceList;
- UINT i;
+ NdisInitUnicodeString(&ParamName, L"SlotNumber");
+ NdisReadConfiguration(&NdisStatus, &ConfigParam, ConfigHandle,
+ &ParamName, NdisParameterInteger);
+ if (NdisStatus == NDIS_STATUS_SUCCESS)
+ Adapter->NdisMiniportBlock.SlotNumber = ConfigParam->ParameterData.IntegerData;
+ else
+ Adapter->NdisMiniportBlock.SlotNumber = 0;
+ }
- if(!RtlCompareUnicodeString(&OrphanAdapter->RegistryPath, Miniport->RegistryPath, TRUE))
- {
- OrphanAdapter = (PORPHAN_ADAPTER)OrphanAdapter->ListEntry.Flink;
- continue;
- }
+ NdisCloseConfiguration(ConfigHandle);
- NDIS_DbgPrint(MAX_TRACE, ("Found an orphan adapter for RegistryPath %wZ\n", Miniport->RegistryPath));
+ /*
+ * Call MiniportInitialize.
+ */
- /* there is an orphan adapter for us */
- Adapter->SlotNumber = OrphanAdapter->SlotNumber;
- Adapter->BusNumber = OrphanAdapter->BusNumber;
- Adapter->BusType = OrphanAdapter->BusType;
+ NDIS_DbgPrint(MID_TRACE, ("calling MiniportInitialize\n"));
+ NdisStatus = (*Adapter->Miniport->Chars.InitializeHandler)(
+ &OpenErrorStatus, &SelectedMediumIndex, &MediaArray[0],
+ MEDIA_ARRAY_SIZE, Adapter, (NDIS_HANDLE)&WrapperContext);
- Status = HalAssignSlotResources(Miniport->RegistryPath, 0, Miniport->DriverObject,
- Adapter->NdisMiniportBlock.DeviceObject, Adapter->BusType, Adapter->BusNumber,
- Adapter->SlotNumber, &ResourceList);
+ ZwClose(WrapperContext.RegistryHandle);
- if(!NT_SUCCESS(Status))
- {
- NDIS_DbgPrint(MIN_TRACE, ("HalAssignSlotResources broke: 0x%x\n", Status));
- ASSERT(0);
+ if (NdisStatus != NDIS_STATUS_SUCCESS ||
+ SelectedMediumIndex >= MEDIA_ARRAY_SIZE)
+ {
+ NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n"));
+ return (NTSTATUS)NdisStatus;
+ }
- /* i guess we should just give up on this adapter */
- break;
- }
+ /* Set handlers (some NDIS macros require these) */
+
+ Adapter->NdisMiniportBlock.EthRxCompleteHandler = EthFilterDprIndicateReceiveComplete;
+ Adapter->NdisMiniportBlock.EthRxIndicateHandler = EthFilterDprIndicateReceive;
+ Adapter->NdisMiniportBlock.SendCompleteHandler = MiniSendComplete;
+ Adapter->NdisMiniportBlock.SendResourcesHandler = MiniSendResourcesAvailable;
+ Adapter->NdisMiniportBlock.ResetCompleteHandler = MiniResetComplete;
+ Adapter->NdisMiniportBlock.TDCompleteHandler = MiniTransferDataComplete;
+ Adapter->NdisMiniportBlock.PacketIndicateHandler= MiniIndicateReceivePacket;
+
+ Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex];
- /* go through the returned resource list and populate the Adapter */
- for(i = 0; i<ResourceList->Count; i++)
+ switch (Adapter->NdisMiniportBlock.MediaType)
+ {
+ case NdisMedium802_3:
+ Adapter->MediumHeaderSize = 14; /* XXX figure out what to do about LLC */
+ AddressOID = OID_802_3_CURRENT_ADDRESS;
+ Adapter->AddressLength = ETH_LENGTH_OF_ADDRESS;
+ NdisStatus = DoQueries(Adapter, AddressOID);
+ if (NdisStatus == NDIS_STATUS_SUCCESS)
+ {
+ Success = EthCreateFilter(32, /* FIXME: Query this from miniport. */
+ Adapter->Address.Type.Medium802_3,
+ &Adapter->NdisMiniportBlock.EthDB);
+ if (Success)
+ ((PETHI_FILTER)Adapter->NdisMiniportBlock.EthDB)->Miniport = (PNDIS_MINIPORT_BLOCK)Adapter;
+ else
+ NdisStatus = NDIS_STATUS_RESOURCES;
+ }
+ break;
+
+ default:
+ /* FIXME: Support other types of media */
+ NDIS_DbgPrint(MIN_TRACE, ("error: unsupported media\n"));
+ ASSERT(FALSE);
+/* FIXME - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (!Success || NdisStatus != NDIS_STATUS_SUCCESS)
+ {
+ NDIS_DbgPrint(MAX_TRACE, ("couldn't create filter (%x)\n", NdisStatus));
+ if (Adapter->LookaheadBuffer)
{
- int j;
+ ExFreePool(Adapter->LookaheadBuffer);
+ Adapter->LookaheadBuffer = NULL;
+ }
+ return (NTSTATUS)NdisStatus;
+ }
- PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor = &ResourceList->List[i];
+ Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
+ Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStarted;
- for(j=0; j<ResourceDescriptor->PartialResourceList.Count; j++)
- {
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor =
- &ResourceDescriptor->PartialResourceList.PartialDescriptors[i];
+ /* Put adapter in adapter list for this miniport */
+ ExInterlockedInsertTailList(&Adapter->Miniport->AdapterListHead, &Adapter->MiniportListEntry, &Adapter->Miniport->Lock);
- switch(PartialResourceDescriptor->Type)
- {
- case CmResourceTypeInterrupt:
- Adapter->Irql = PartialResourceDescriptor->u.Interrupt.Level;
- Adapter->Vector = PartialResourceDescriptor->u.Interrupt.Vector;
- Adapter->Affinity = PartialResourceDescriptor->u.Interrupt.Affinity;
- break;
+ /* Put adapter in global adapter list */
+ ExInterlockedInsertTailList(&AdapterListHead, &Adapter->ListEntry, &AdapterListLock);
- case CmResourceTypePort:
- Adapter->BaseIoAddress = PartialResourceDescriptor->u.Port.Start;
- break;
+ return STATUS_SUCCESS;
+}
- case CmResourceTypeMemory:
- Adapter->BaseMemoryAddress = PartialResourceDescriptor->u.Memory.Start;
- break;
+\f
+NTSTATUS
+NTAPI
+NdisIPnPStopDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+/*
+ * FUNCTION: Handle the PnP stop device event
+ * ARGUMENTS:
+ * DeviceObejct = Functional Device Object
+ * Irp = IRP_MN_STOP_DEVICE I/O request packet
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
+ KIRQL OldIrql;
- case CmResourceTypeDma:
- Adapter->DmaPort = PartialResourceDescriptor->u.Dma.Port;
- Adapter->DmaChannel = PartialResourceDescriptor->u.Dma.Channel;
- break;
+ /* Remove adapter from adapter list for this miniport */
+ KeAcquireSpinLock(&Adapter->Miniport->Lock, &OldIrql);
+ RemoveEntryList(&Adapter->MiniportListEntry);
+ KeReleaseSpinLock(&Adapter->Miniport->Lock, OldIrql);
- case CmResourceTypeDeviceSpecific:
- default:
- break;
- }
- }
- }
+ /* Remove adapter from global adapter list */
+ KeAcquireSpinLock(&AdapterListLock, &OldIrql);
+ RemoveEntryList(&Adapter->ListEntry);
+ KeReleaseSpinLock(&AdapterListLock, OldIrql);
- /* remove the adapter from the list */
- TempAdapter = (PORPHAN_ADAPTER)OrphanAdapter->ListEntry.Flink;
- RemoveEntryList(&OrphanAdapter->ListEntry);
- OrphanAdapter = TempAdapter;
- }
- KeReleaseSpinLock(&OrphanAdapterListLock, OldIrql);
+ (*Adapter->Miniport->Chars.HaltHandler)(Adapter);
- /* includes room for a 0-term */
- RegKeyPath = ExAllocatePool(PagedPool, (wcslen(SERVICES_ROOT) + wcslen(DeviceNameStr) + 1) * sizeof(WCHAR));
- if(!RegKeyPath)
+ if (Adapter->LookaheadBuffer)
+ {
+ ExFreePool(Adapter->LookaheadBuffer);
+ Adapter->LookaheadBuffer = NULL;
+ }
+ if (Adapter->NdisMiniportBlock.AllocatedResources)
+ {
+ ExFreePool(Adapter->NdisMiniportBlock.AllocatedResources);
+ Adapter->NdisMiniportBlock.AllocatedResources = NULL;
+ }
+ if (Adapter->NdisMiniportBlock.AllocatedResourcesTranslated)
{
- NDIS_DbgPrint(MIN_TRACE,("Insufficient resources\n"));
- ExFreePool(Adapter);
- return;
+ ExFreePool(Adapter->NdisMiniportBlock.AllocatedResourcesTranslated);
+ Adapter->NdisMiniportBlock.AllocatedResourcesTranslated = NULL;
}
- wcscpy(RegKeyPath, SERVICES_ROOT);
- wcscat(RegKeyPath, DeviceNameStr);
- RegKeyPath[wcslen(SERVICES_ROOT) + wcslen(DeviceNameStr)] = 0;
+ Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
+ Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStopped;
+
+ return STATUS_SUCCESS;
+}
- RtlInitUnicodeString(&RegKeyPathU, RegKeyPath);
- InitializeObjectAttributes(&RegKeyAttributes, &RegKeyPathU, OBJ_CASE_INSENSITIVE, NULL, NULL);
+\f
+NTSTATUS
+NTAPI
+NdisIDispatchPnp(
+ IN PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
+ NTSTATUS Status;
- Status = ZwOpenKey(&RegKeyHandle, KEY_ALL_ACCESS, &RegKeyAttributes);
- if(Status != STATUS_SUCCESS)
+ switch (Stack->MinorFunction)
{
- NDIS_DbgPrint(MIN_TRACE,("failed to open adapter-specific reg key %wZ\n", &RegKeyPathU));
- ExFreePool(Adapter);
- return;
- }
+ case IRP_MN_START_DEVICE:
+ Status = NdisIForwardIrpAndWait(Adapter, Irp);
+ if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+ {
+ Status = NdisIPnPStartDevice(DeviceObject, Irp);
+ }
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ break;
- NDIS_DbgPrint(MAX_TRACE, ("opened device reg key: %wZ\n", &RegKeyPathU));
+ case IRP_MN_STOP_DEVICE:
+ /* FIXME */
+ Status = STATUS_UNSUCCESSFUL;
+ break;
+ Status = NdisIForwardIrpAndWait(Adapter, Irp);
+ if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+ {
+ Status = NdisIPnPStopDevice(DeviceObject, Irp);
+ }
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ break;
- NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n"));
- KeInitializeSpinLock(&Adapter->NdisMiniportBlock.Lock);
- InitializeListHead(&Adapter->ProtocolListHead);
- Adapter->RefCount = 1;
- Adapter->Miniport = Miniport;
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp);
+ break;
+ }
- /* Set handlers (some NDIS macros require these) */
+ return Status;
+}
- Adapter->NdisMiniportBlock.EthRxCompleteHandler = MiniEthReceiveComplete;
- Adapter->NdisMiniportBlock.EthRxIndicateHandler = MiniEthReceiveIndication;
- Adapter->NdisMiniportBlock.SendCompleteHandler = MiniSendComplete;
- Adapter->NdisMiniportBlock.SendResourcesHandler = MiniSendResourcesAvailable;
- Adapter->NdisMiniportBlock.ResetCompleteHandler = MiniResetComplete;
- Adapter->NdisMiniportBlock.TDCompleteHandler = MiniTransferDataComplete;
- Adapter->NdisMiniportBlock.PacketIndicateHandler= MiniIndicateReceivePacket;
+\f
+NTSTATUS
+NTAPI
+NdisIAddDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT PhysicalDeviceObject)
+/*
+ * FUNCTION: Create a device for an adapter found using PnP
+ * ARGUMENTS:
+ * DriverObject = Pointer to the miniport driver object
+ * PhysicalDeviceObject = Pointer to the PDO for our adapter
+ */
+{
+ static const WCHAR ClassKeyName[] = {'C','l','a','s','s','\\'};
+ static const WCHAR LinkageKeyName[] = {'\\','L','i','n','k','a','g','e',0};
+ PMINIPORT_DRIVER Miniport;
+ PMINIPORT_DRIVER *MiniportPtr;
+ WCHAR *LinkageKeyBuffer;
+ ULONG DriverKeyLength;
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ UNICODE_STRING ExportName;
+ PDEVICE_OBJECT DeviceObject;
+ PLOGICAL_ADAPTER Adapter;
+ NTSTATUS Status;
- KeInitializeDpc(&Adapter->MiniportDpc, MiniportDpc, (PVOID)Adapter);
+ /*
+ * Gain the access to the miniport data structure first.
+ */
- /* Put adapter in adapter list for this miniport */
- ExInterlockedInsertTailList(&Miniport->AdapterListHead, &Adapter->MiniportListEntry, &Miniport->Lock);
+ MiniportPtr = IoGetDriverObjectExtension(DriverObject, (PVOID)TAG('D','I','M','N'));
+ if (MiniportPtr == NULL)
+ {
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get driver object extension.\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+ Miniport = *MiniportPtr;
- /* Put adapter in global adapter list */
- ExInterlockedInsertTailList(&AdapterListHead, &Adapter->ListEntry, &AdapterListLock);
+ /*
+ * Get name of the Linkage registry key for our adapter. It's located under
+ * the driver key for our driver and so we have basicly two ways to do it.
+ * Either we can use IoOpenDriverRegistryKey or compose it using information
+ * gathered by IoGetDeviceProperty. I choosed the second because
+ * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
+ */
- /* Call MiniportInitialize */
- NDIS_DbgPrint(MID_TRACE, ("calling MiniportInitialize\n"));
- NdisStatus = (*Miniport->Chars.InitializeHandler)( &OpenErrorStatus, &SelectedMediumIndex, &MediaArray[0],
- MEDIA_ARRAY_SIZE, Adapter, RegKeyHandle);
+ Status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyDriverKeyName,
+ 0, NULL, &DriverKeyLength);
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport driver key length.\n"));
+ return Status;
+ }
- ZwClose(RegKeyHandle);
+ LinkageKeyBuffer = ExAllocatePool(PagedPool, DriverKeyLength +
+ sizeof(ClassKeyName) + sizeof(LinkageKeyName));
+ if (LinkageKeyBuffer == NULL)
+ {
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't allocate memory for driver key name.\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- if ((NdisStatus == NDIS_STATUS_SUCCESS) && (SelectedMediumIndex < MEDIA_ARRAY_SIZE))
+ Status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyDriverKeyName,
+ DriverKeyLength, LinkageKeyBuffer +
+ (sizeof(ClassKeyName) / sizeof(WCHAR)),
+ &DriverKeyLength);
+ if (!NT_SUCCESS(Status))
{
- NDIS_DbgPrint(MID_TRACE,("successful return from MiniportInitialize\n"));
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport driver key.\n"));
+ ExFreePool(LinkageKeyBuffer);
+ return Status;
+ }
- Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex];
+ /* Compose the linkage key name. */
+ RtlCopyMemory(LinkageKeyBuffer, ClassKeyName, sizeof(ClassKeyName));
+ RtlCopyMemory(LinkageKeyBuffer + ((sizeof(ClassKeyName) + DriverKeyLength) /
+ sizeof(WCHAR)) - 1, LinkageKeyName, sizeof(LinkageKeyName));
- switch (Adapter->NdisMiniportBlock.MediaType)
- {
- case NdisMedium802_3:
- Adapter->MediumHeaderSize = 14; /* XXX figure out what to do about LLC */
- AddressOID = OID_802_3_CURRENT_ADDRESS;
- Adapter->AddressLength = ETH_LENGTH_OF_ADDRESS;
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("LinkageKey: %S.\n", LinkageKeyBuffer));
- Adapter->NdisMiniportBlock.FilterDbs.u.EthDB = ExAllocatePool(NonPagedPool, sizeof(ETH_FILTER));
- if (Adapter->NdisMiniportBlock.FilterDbs.u.EthDB)
- {
- RtlZeroMemory(Adapter->NdisMiniportBlock.FilterDbs.u.EthDB, sizeof(ETH_FILTER));
- Adapter->NdisMiniportBlock.FilterDbs.u.EthDB->Miniport = (PNDIS_MINIPORT_BLOCK)Adapter;
- }
- else
- MemError = TRUE;
-
- break;
-
- default:
- /* FIXME: Support other types of media */
- NDIS_DbgPrint(MIN_TRACE, ("error: unsupported media\n"));
- ExFreePool(Adapter);
- ASSERT(FALSE);
- KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
- return;
- }
+ /*
+ * Now open the linkage key and read the "Export" and "RootDevice" values
+ * which contains device name and root service respectively.
+ */
- NdisStatus = DoQueries(Adapter, AddressOID);
+ RtlZeroMemory(QueryTable, sizeof(QueryTable));
+ RtlInitUnicodeString(&ExportName, NULL);
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[0].Name = L"Export";
+ QueryTable[0].EntryContext = &ExportName;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, LinkageKeyBuffer,
+ QueryTable, NULL, NULL);
+ ExFreePool(LinkageKeyBuffer);
+ if (!NT_SUCCESS(Status))
+ {
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport device name. (%x)\n", Status));
+ return Status;
}
- if ((MemError) || (NdisStatus != NDIS_STATUS_SUCCESS) || (SelectedMediumIndex >= MEDIA_ARRAY_SIZE))
+ /*
+ * Create the device object.
+ */
+
+ NDIS_DbgPrint(MAX_TRACE, ("creating device %wZ\n", &ExportName));
+
+ Status = IoCreateDevice(Miniport->DriverObject, sizeof(LOGICAL_ADAPTER),
+ &ExportName, FILE_DEVICE_PHYSICAL_NETCARD,
+ 0, FALSE, &DeviceObject);
+ if (!NT_SUCCESS(Status))
{
- NDIS_DbgPrint(MAX_TRACE, ("return from MiniportInitialize: NdisStatus 0x%x, SelectedMediumIndex 0x%x\n",
- NdisStatus, SelectedMediumIndex));
+ NDIS_DbgPrint(MIN_TRACE, ("Could not create device object.\n"));
+ RtlFreeUnicodeString(&ExportName);
+ return Status;
+ }
+
+ /*
+ * Initialize the adapter structure.
+ */
- /* Remove adapter from adapter list for this miniport */
- KeAcquireSpinLock(&Miniport->Lock, &OldIrql);
- RemoveEntryList(&Adapter->MiniportListEntry);
- KeReleaseSpinLock(&Miniport->Lock, OldIrql);
+ Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
+ KeInitializeSpinLock(&Adapter->NdisMiniportBlock.Lock);
+ InitializeListHead(&Adapter->ProtocolListHead);
+ Adapter->RefCount = 1;
+ Adapter->Miniport = Miniport;
- /* Remove adapter from global adapter list */
- KeAcquireSpinLock(&AdapterListLock, &OldIrql);
- RemoveEntryList(&Adapter->ListEntry);
- KeReleaseSpinLock(&AdapterListLock, OldIrql);
+ Adapter->NdisMiniportBlock.MiniportName = ExportName;
- if (Adapter->LookaheadBuffer)
- ExFreePool(Adapter->LookaheadBuffer);
+ Adapter->NdisMiniportBlock.DeviceObject = DeviceObject;
+ Adapter->NdisMiniportBlock.PhysicalDeviceObject = PhysicalDeviceObject;
+ Adapter->NdisMiniportBlock.NextDeviceObject =
+ IoAttachDeviceToDeviceStack(Adapter->NdisMiniportBlock.DeviceObject,
+ PhysicalDeviceObject);
- IoDeleteDevice(Adapter->NdisMiniportBlock.DeviceObject);
- ExFreePool(Adapter);
- NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n"));
- }
+ Adapter->NdisMiniportBlock.OldPnPDeviceState = 0;
+ Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceAdded;
+
+ KeInitializeDpc(&Adapter->MiniportDpc, MiniportDpc, (PVOID)Adapter);
+
+ DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ return STATUS_SUCCESS;
}
\f
* MiniportCharacteristics = Pointer to a buffer with miniport characteristics
* CharacteristicsLength = Number of bytes in characteristics buffer
* RETURNS:
- * Status of operation
- * NOTES:
- * - To create device objects for the miniport, the Route value under Linkage is
- * parsed. I don't know if this is the way Microsoft does it or not.
- * TODO:
- * verify this algorithm by playing with nt
+ * Status of operation
*/
{
UINT MinSize;
- NTSTATUS Status;
PMINIPORT_DRIVER Miniport = GET_MINIPORT_DRIVER(NdisWrapperHandle);
- OBJECT_ATTRIBUTES DeviceKeyAttributes;
- OBJECT_ATTRIBUTES LinkageKeyAttributes;
- HANDLE DeviceKeyHandle;
- HANDLE LinkageKeyHandle;
- UNICODE_STRING RouteVal;
- UNICODE_STRING LinkageKeyName;
- KEY_VALUE_PARTIAL_INFORMATION *RouteData;
- ULONG RouteDataLength;
- UINT NextRouteOffset = 0;
+ PMINIPORT_DRIVER *MiniportPtr;
+ NTSTATUS Status;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
- switch (MiniportCharacteristics->MajorNdisVersion)
+ switch (MiniportCharacteristics->MajorNdisVersion)
{
case 0x03:
- MinSize = sizeof(NDIS30_MINIPORT_CHARACTERISTICS_S);
+ MinSize = sizeof(NDIS30_MINIPORT_CHARACTERISTICS);
break;
case 0x04:
- MinSize = sizeof(NDIS40_MINIPORT_CHARACTERISTICS_S);
+ MinSize = sizeof(NDIS40_MINIPORT_CHARACTERISTICS);
break;
case 0x05:
- MinSize = sizeof(NDIS50_MINIPORT_CHARACTERISTICS_S);
+ MinSize = sizeof(NDIS50_MINIPORT_CHARACTERISTICS);
break;
default:
return NDIS_STATUS_BAD_VERSION;
}
- if (CharacteristicsLength < MinSize)
+ if (CharacteristicsLength < MinSize)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
(!MiniportCharacteristics->InitializeHandler)||
(!MiniportCharacteristics->QueryInformationHandler) ||
(!MiniportCharacteristics->ResetHandler) ||
- (!MiniportCharacteristics->SetInformationHandler))
+ (!MiniportCharacteristics->SetInformationHandler))
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
- if (MiniportCharacteristics->MajorNdisVersion == 0x03)
+ if (MiniportCharacteristics->MajorNdisVersion == 0x03)
{
- if (!MiniportCharacteristics->u1.SendHandler)
+ if (!MiniportCharacteristics->SendHandler)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
- }
- else if (MiniportCharacteristics->MajorNdisVersion >= 0x04)
+ }
+ else if (MiniportCharacteristics->MajorNdisVersion >= 0x04)
{
/* NDIS 4.0+ */
- if ((!MiniportCharacteristics->u1.SendHandler) &&
- (!MiniportCharacteristics->SendPacketsHandler))
+ if ((!MiniportCharacteristics->SendHandler) &&
+ (!MiniportCharacteristics->SendPacketsHandler))
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
RtlCopyMemory(&Miniport->Chars, MiniportCharacteristics, MinSize);
/*
- * extract the list of bound adapters from the registry's Route value
- * for this adapter. It seems under WinNT that the Route value in the
- * Linkage subkey holds an entry for each miniport instance we know about.
- * This surely isn't how Windows does it, but it's better than nothing.
- *
- * FIXME: this is documented in the ddk, believe it or not - read & do
+ * NOTE: This is VERY unoptimal! Should we store the MINIPORT_DRIVER
+ * struture in the driver extension or what?
*/
- /* Read the miniport config from the registry */
- InitializeObjectAttributes(&DeviceKeyAttributes, Miniport->RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- Status = ZwOpenKey(&DeviceKeyHandle, KEY_READ, &DeviceKeyAttributes);
- if(!NT_SUCCESS(Status))
- {
- NDIS_DbgPrint(MIN_TRACE,("Failed to open driver key: 0x%x\n", Status));
- return NDIS_STATUS_FAILURE;
- }
-
- RtlInitUnicodeString(&LinkageKeyName, L"Linkage");
- InitializeObjectAttributes(&LinkageKeyAttributes, &LinkageKeyName, OBJ_CASE_INSENSITIVE, DeviceKeyHandle, NULL);
-
- Status = ZwOpenKey(&LinkageKeyHandle, KEY_READ, &LinkageKeyAttributes);
- if(!NT_SUCCESS(Status))
+ Status = IoAllocateDriverObjectExtension(Miniport->DriverObject, (PVOID)TAG('D','I','M','N'),
+ sizeof(PMINIPORT_DRIVER), (PVOID*)&MiniportPtr);
+ if (!NT_SUCCESS(Status))
{
- NDIS_DbgPrint(MIN_TRACE,("Failed to open Linkage key: 0x%x\n", Status));
- ZwClose(DeviceKeyHandle);
- return NDIS_STATUS_FAILURE;
- }
-
- RouteData = ExAllocatePool(PagedPool, ROUTE_DATA_SIZE);
- if(!RouteData)
- {
- NDIS_DbgPrint(MIN_TRACE,("Insufficient resources\n"));
- ZwClose(LinkageKeyHandle);
- ZwClose(DeviceKeyHandle);
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't allocate driver object extension.\n"));
return NDIS_STATUS_RESOURCES;
}
- RtlInitUnicodeString(&RouteVal, L"Route");
-
- Status = ZwQueryValueKey(LinkageKeyHandle, &RouteVal, KeyValuePartialInformation, RouteData, ROUTE_DATA_SIZE, &RouteDataLength);
- if(!NT_SUCCESS(Status))
- {
- NDIS_DbgPrint(MIN_TRACE,("Failed to query Route value\n"));
- ZwClose(LinkageKeyHandle);
- ZwClose(DeviceKeyHandle);
- ExFreePool(RouteData);
- return NDIS_STATUS_FAILURE;
- }
-
- ZwClose(LinkageKeyHandle);
- ZwClose(DeviceKeyHandle);
-
- /* route is a REG_MULTI_SZ with each nic object created by NDI - create an adapter for each */
- while(*(RouteData->Data + NextRouteOffset))
- {
- NDIS_DbgPrint(MID_TRACE, ("Starting adapter %ws\n", (WCHAR *)(RouteData->Data + NextRouteOffset)));
-
- NdisIStartAdapter((WCHAR *)(RouteData->Data + NextRouteOffset),
- wcslen((WCHAR *)(RouteData->Data + NextRouteOffset)), Miniport);
+ *MiniportPtr = Miniport;
- /* NextRouteOffset is in bytes, not WCHARs */
- NextRouteOffset += wcslen((WCHAR *)(RouteData->Data + NextRouteOffset)) * sizeof(WCHAR);
- }
+ Miniport->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
+ Miniport->DriverObject->DriverExtension->AddDevice = NdisIAddDevice;
- ExFreePool(RouteData);
return NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
+#undef NdisMResetComplete
VOID
EXPORT
NdisMResetComplete(
/*
* @implemented
*/
+#undef NdisMSendComplete
VOID
EXPORT
NdisMSendComplete(
/*
* @implemented
*/
+#undef NdisMSendResourcesAvailable
VOID
EXPORT
NdisMSendResourcesAvailable(
/*
* @implemented
*/
+#undef NdisMTransferDataComplete
VOID
EXPORT
NdisMTransferDataComplete(
/*
* @implemented
*/
+#undef NdisMSetInformationComplete
VOID
EXPORT
NdisMSetInformationComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_STATUS Status)
{
- PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
- PADAPTER_BINDING AdapterBinding = (PADAPTER_BINDING)Adapter->MiniportAdapterBinding;
-
- NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- (*AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler)(
- AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
- Adapter->NdisMiniportBlock.MediaRequest,
- Status);
+ (*((PNDIS_MINIPORT_BLOCK)(MiniportAdapterHandle))->SetCompleteHandler)(MiniportAdapterHandle, Status);
}
\f
/*
* @implemented
*/
+#undef NdisMSetAttributes
VOID
EXPORT
NdisMSetAttributes(
* AdapterType = Specifies the I/O bus interface of the caller's NIC
*/
{
- PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
-
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- Adapter->NdisMiniportBlock.MiniportAdapterContext = MiniportAdapterContext;
-
- if(BusMaster)
- Adapter->NdisMiniportBlock.Flags |= NDIS_ATTRIBUTE_BUS_MASTER;
-
- Adapter->NdisMiniportBlock.AdapterType = AdapterType;
- Adapter->AttributesSet = TRUE;
+ NdisMSetAttributesEx(MiniportAdapterHandle, MiniportAdapterContext, 0,
+ BusMaster ? NDIS_ATTRIBUTE_BUS_MASTER : 0,
+ AdapterType);
}
\f
PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
- NDIS_DbgPrint(MAX_TRACE, ("Called - NdisMSetAttributesEx() is partly-implemented.\n"));
+ NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
Adapter->NdisMiniportBlock.MiniportAdapterContext = MiniportAdapterContext;
-
- /* don't know why this is here - anybody? */
- Adapter->NdisMiniportBlock.Flags = AttributeFlags;
-
+ Adapter->NdisMiniportBlock.Flags = AttributeFlags;
Adapter->NdisMiniportBlock.AdapterType = AdapterType;
Adapter->AttributesSet = TRUE;
+ if (AttributeFlags & NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER)
+ NDIS_DbgPrint(MAX_TRACE, ("Intermediate drivers not supported yet.\n"));
}
\f
IN PVOID SynchronizeFunction,
IN PVOID SynchronizeContext)
{
- return(KeSynchronizeExecution((PKINTERRUPT)Interrupt,
+ return(KeSynchronizeExecution(Interrupt->InterruptObject,
(PKSYNCHRONIZE_ROUTINE)SynchronizeFunction,
SynchronizeContext));
}