📄 hpna_2k.c
字号:
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
Abstract:
Main Module
Environment:
kernel mode only
Notes:
Revision History:
hawkfly - 03/18/02: this source code for HomePNA USB to fast Ethernet adapter driver
show how an NDIS miniport driver can interface with an USB device.
This is just a example and shouldn't be used in a production environment
as is. This driver will work as is for ADMtek8511 chip.
--*/
#define BINARY_COMPATIBLE 1 // for win9x compatibility with ndis.h
#define DOBREAKS // enable debug breaks
#include <ndis.h>
#include <ntddndis.h> // defines OID's
#include "debug.h"
#include "common.h"
#include "USBNDIS.h"
//
// Mark the DriverEntry function to run once during initialization.
//
NDIS_STATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
#pragma NDIS_INIT_FUNCTION(DriverEntry)
// Begin, Code....
NDIS_STATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
NDIS_MINIPORT_CHARACTERISTICS characteristics;
NDIS_HANDLE hWrapper;
NdisMInitializeWrapper(
&hWrapper,
DriverObject,
RegistryPath,
NULL
);
NdisZeroMemory(
&characteristics,
sizeof(NDIS_MINIPORT_CHARACTERISTICS)
);
characteristics.MajorNdisVersion = (UCHAR)NDIS_MAJOR_VERSION;
characteristics.MinorNdisVersion = (UCHAR)NDIS_MINOR_VERSION;
characteristics.Reserved = 0;
characteristics.InitializeHandler = MiniportInitialize;
characteristics.QueryInformationHandler = MiniportQueryInformation;
characteristics.SetInformationHandler = MiniportSetInformation;
characteristics.ResetHandler = MiniportReset;
//
// For now we will allow NDIS to send only one packet at a time.
characteristics.SendHandler = MiniportSend;
characteristics.SendPacketsHandler = NULL;
//
// We don't use NdisMIndicateXxxReceive function, so we will
// need a ReturnPacketHandler to retrieve our packet resources.
//
characteristics.ReturnPacketHandler = MiniportReturnPacket;
characteristics.HaltHandler = MiniportHalt;
characteristics.TransferDataHandler = NULL;
//
// NDIS never calls the ReconfigureHandler.
//
characteristics.ReconfigureHandler = NULL;
//
// This miniport driver does not handle interrupts.
//
characteristics.HandleInterruptHandler = NULL;
characteristics.ISRHandler = NULL;
characteristics.DisableInterruptHandler = NULL;
characteristics.EnableInterruptHandler = NULL;
//
// This miniport does not control a busmaster DMA with
// NdisMAllocateShareMemoryAsysnc, AllocateCompleteHandler won't be
// called from NDIS.
//
characteristics.AllocateCompleteHandler = NULL;
status = NdisMRegisterMiniport(
hWrapper,
&characteristics,
sizeof(NDIS_MINIPORT_CHARACTERISTICS)
);
return status;
}
//运行PASSIVE_LEVEL在系统线程上下文
NDIS_STATUS
MiniportInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE NdisAdapterHandle,
IN NDIS_HANDLE WrapperConfigurationContext
)
{
UINT i;
PUSB_DEVICE device = NULL;
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
NTSTATUS ntStatus = STATUS_SUCCESS;
NTSTATUS tstat = STATUS_SUCCESS;
PDEVICE_OBJECT PhysicalDeviceObject = NULL;
PDEVICE_OBJECT NextDeviceObject = NULL;
BOOLEAN fRes;
//
// Search for the Ethernet medium in the medium array.
//
for (i = 0; i < MediumArraySize; i++)
{
if (MediumArray[i] == NdisMedium802_3)
{
break;
}
}
if (i < MediumArraySize)
{
*SelectedMediumIndex = i;
}
else
{
//
// medium not found.
//
status = NDIS_STATUS_UNSUPPORTED_MEDIA;
goto done;
}
NdisMGetDeviceProperty(NdisAdapterHandle,
&PhysicalDeviceObject,//物理
NULL,
&NextDeviceObject,//总线
NULL,
NULL);
//
// Allocate memory to store device information.
//为保存USB设备信息分配
device = MemAlloc(sizeof(USB_DEVICE));
if (device == NULL)
{
status = NDIS_STATUS_RESOURCES;
goto done;
}
NdisZeroMemory((PVOID)device, sizeof(USB_DEVICE));
//给device->pUsbinfo分配内存和清零
fRes = AllocUsbInfo( device );
if ( !fRes )
{
status = NDIS_STATUS_RESOURCES;
goto done;
}
device->pUsbDevObj = NextDeviceObject;//总线设备对象
device->pPhysDevObj = PhysicalDeviceObject;
//
// Initialize device object and resources.
// All the queues and buffer/packets etc. are allocated here.
//
//给device结构附初值
status = InitializeDevice(device);
if (status != NDIS_STATUS_SUCCESS)
{
goto done;
}
//
// Record the NdisAdapterHandle.
//from NdisMGetDeviceProperty
device->hNdisAdapter = NdisAdapterHandle;
//
// NdisMSetAttributes will associate our adapter handle with the wrapper's
// adapter handle. The wrapper will then always use our handle
// when calling us. We use a pointer to the device as the context.
//
NdisMSetAttributesEx(NdisAdapterHandle,
(NDIS_HANDLE)device,
0,
NDIS_ATTRIBUTE_DESERIALIZE,
NdisInterfaceInternal);
// Now we're ready to do our own startup processing.
// USB client drivers such as us set up URBs (USB Request Packets) to send requests
// to the host controller driver (HCD). The URB structure defines a format for all
// possible commands that can be sent to a USB device.
// Here, we request the device descriptor and store it,
// and configure the device.
// In USB, no special HW processing is required to 'open' or 'close' the pipes
ntStatus = StartDevice(device);//开始设备
if ( ntStatus != STATUS_SUCCESS)
{
status = NDIS_STATUS_ADAPTER_NOT_FOUND;
goto done;
}
//
// Create an irp and begin our receives.
// NOTE: All other receive processing will be done in the read completion
// routine and PollingThread started therein.
//
//创建了PassiveLevelThread,PollingThread两个内核线程用以接收
status = InitializeReceive(device);
if (status != NDIS_STATUS_SUCCESS)
{
goto done;
}
done:
if (status != NDIS_STATUS_SUCCESS)
{
if (device != NULL)
{
DeinitializeDevice(device);
MemFree( device, sizeof(USB_DEVICE));
FreeUsbInfo( device );
}
}
return status;
}
NDIS_STATUS
InitializeDevice(
IN OUT PUSB_DEVICE Device)
{
int i;
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
DEBUGMSG(DBG_FUNC|DBG_PNP, ("+InitializeDevice\n"));
ASSERT(Device != NULL);
//
// Init statistical info.
// We need to do this cause reset wont free and realloc Device!
//
Device->packetsReceived = 0;
Device->packetsReceivedDropped = 0;
Device->packetsReceivedOverflow = 0;
Device->packetsSent = 0;
Device->packetsSentDropped = 0;
Device->SendContextsInUse = 0;
Device->RcvBuffersInUse = 0;
Device->fDeviceStarted = FALSE;
Device->fGotFilterIndication = FALSE;
Device->fPendingHalt = FALSE;
Device->fPendingReset = FALSE;
Device->fPendingReadClearStall = FALSE;
Device->fPendingWriteClearStall = FALSE;
Device->fKillPollingThread = FALSE;
Device->fKillPassiveLevelThread = FALSE;
Device->LastQueryTime.QuadPart = 0;
Device->LastSetTime.QuadPart = 0;
Device->PendingIrpCount = 0;
Device->IntInternalTime = 0;
Device->fQuerypending = FALSE;
Device->fSetpending = FALSE;
// InterlockedExchange( &Device->fMediaBusy, FALSE );
// InterlockedExchange( &Device->fIndicatedMediaBusy, FALSE );
Device->pCurrentRcvBuf = NULL;
Device->fReceiving = FALSE;
//
// Initialize the queues.
//
if ( TRUE != InitWdmStuff(Device) )
{
goto done;
}
//
// Allocate the NDIS packet and NDIS buffer pools
// for this device's RECEIVE buffer queue.
// Our receive packets must only contain one buffer a piece,
// so #buffers == #packets.
//
NdisAllocatePacketPool(
&status, // return status
&Device->hPacketPool, // handle to the packet pool
NUM_RCV_BUFS, // number of packet descriptors
16 // number of bytes reserved for
); // ProtocolReserved field
if (status != NDIS_STATUS_SUCCESS)
{
goto done;
}
NdisAllocateBufferPool(
&status, // return status
&Device->hBufferPool,// handle to the buffer pool
NUM_RCV_BUFS // number of buffer descriptors
);
if (status != NDIS_STATUS_SUCCESS)
{
goto done;
}
for (i = 0; i < NUM_WORK_ITEMS; i++)//NUM_WORK_ITEMS 19
{
PUSB_WORK_ITEM pWorkItem;
pWorkItem = &(Device->WorkItems[i]);
pWorkItem->pDevice = Device;//本层设备对象
pWorkItem->InfoBuf = NULL;
pWorkItem->InfoBufLen = 0;
pWorkItem->fInUse = FALSE;
pWorkItem->Callback = NULL;
}
//
// Initialize each of the RECEIVE objects for this device.
//
//创建了16个接收缓冲
for (i = 0; i < NUM_RCV_BUFS; i++)
{
PNDIS_BUFFER pBuffer = NULL;
PRCV_BUFFER pReceivBuffer = &Device->rcvBufs[i];
//
// Allocate a data buffer
//
//包缓冲大小1514字节
pReceivBuffer->dataBuf = MemAlloc(MAX_PACKET_SIZE);
//分配一个Bulk或Interrupt传输的Urb内存块
pReceivBuffer->Urb = AllocXferUrb();
if (pReceivBuffer->dataBuf == NULL)
{
status = NDIS_STATUS_RESOURCES;
goto done;
}
NdisZeroMemory(
pReceivBuffer->dataBuf,
MAX_PACKET_SIZE
);
pReceivBuffer->device = Device;
pReceivBuffer->dataLen = 0;
pReceivBuffer->state = STATE_FREE;
//为同步创建内核对象
KeInitializeEvent(
&pReceivBuffer->Event, NotificationEvent,
FALSE // event initially non-signalled
);
//
// Allocate the NDIS_PACKET.
//
//从PacketPool给Rev_Buffer结构分配一个包描述符
NdisAllocatePacket(
&status, // return status
&((PNDIS_PACKET)pReceivBuffer->packet),// return pointer to allocated descriptor
Device->hPacketPool // handle to packet pool
);
if (status != NDIS_STATUS_SUCCESS)
{
goto done;
}
}//for
done:
//
// If we didn't complete the init successfully, then we should clean
// up what we did allocate.
//
if (status != NDIS_STATUS_SUCCESS)
{
DeinitializeDevice(Device);
}
else
{
}
return status;
}
/*****************************************************************************
*
* Function: DeinitializeDevice
*
* Synopsis: deallocate the resources of the ir device object
*
* Arguments: Device - the ir device object to close
*
* Returns: none
*
*
* Notes:
*
* Called for shutdown and reset.
* Don't clear hNdisAdapter, since we might just be resetting.
* This function should be called with device lock held.
*
*****************************************************************************/
NDIS_STATUS
DeinitializeDevice(
IN OUT PUSB_DEVICE Device
)
{
UINT i;
NDIS_STATUS status;
NTSTATUS ntstatus;
status = NDIS_STATUS_SUCCESS;
//
// Free all resources for the RECEIVE buffer queue.
//
for (i = 0; i < NUM_RCV_BUFS; i++)
{
PNDIS_BUFFER pBuffer = NULL;
PRCV_BUFFER pRcvBuf = &Device->rcvBufs[i];
if (pRcvBuf->packet != NULL)
{
NdisFreePacket((PNDIS_PACKET) pRcvBuf->packet);
pRcvBuf->packet = NULL;
}
if (pRcvBuf->dataBuf != NULL)
{
MemFree(pRcvBuf->dataBuf, MAX_PACKET_SIZE);
pRcvBuf->dataBuf = NULL;
}
if (pRcvBuf->Urb != NULL)
{
FreeXferUrb( pRcvBuf->Urb );
pRcvBuf->Urb = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -