📄 driver.c
字号:
/*******************************************************************************
* Copyright (c) 2006 PLX Technology, Inc.
*
* PLX Technology Inc. licenses this software under specific terms and
* conditions. Use of any of the software or derviatives thereof in any
* product without a PLX Technology chip is strictly prohibited.
*
* PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
* EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. PLX makes no guarantee
* or representations regarding the use of, or the results of the use of,
* the software and documentation in terms of correctness, accuracy,
* reliability, currentness, or otherwise; and you rely on the software,
* documentation and results solely at your own risk.
*
* IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
* LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
* OF ANY KIND. IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
* PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
*
******************************************************************************/
/******************************************************************************
*
* File Name:
*
* Driver.c
*
* Description:
*
* Contains driver entry and cleanup routines as well as device
* resource initialization.
*
* Revision History:
*
* 03-01-06 : PCI SDK v4.40
*
*****************************************************************************/
#include <stdio.h>
#include "CommonApi.h"
#include "Dispatch.h"
#include "Driver.h"
#include "GlobalVars.h"
#include "PciSupport.h"
#include "PlugPlay.h"
#include "PlxInterrupt.h"
#include "Power.h"
#include "SupportFunc.h"
#if defined(ALLOC_PRAGMA) && !defined(PLX_DEBUG)
#pragma alloc_text(INIT, DriverEntry)
#endif
/******************************************************************************
*
* Function : DriverEntry
*
* Description: Entry point for the driver
*
******************************************************************************/
NTSTATUS
DriverEntry(
PDRIVER_OBJECT pDriverObject,
PUNICODE_STRING pRegistryPath
)
{
S8 MinorVersion;
WCHAR Win9x_RegistryPath[100];
BOOLEAN bVersionFound;
NTSTATUS status;
UNICODE_STRING Win9x_RegistryPath_Unicode;
REGISTRY_INFORMATION RegistryInfo;
DebugPrintf_NoInfo(("\n"));
DebugPrintf(("<========================================================>\n"));
DebugPrintf((
"PLX Driver v%d.%d%d - built on %s %s\n",
PLX_SDK_VERSION_MAJOR, PLX_SDK_VERSION_MINOR,
PLX_SDK_VERSION_REVISION, __DATE__, __TIME__
));
DebugPrintf((
"Supports WDM v%x.%x\n",
WDM_MAJORVERSION, WDM_MINORVERSION
));
// Set starting version
MinorVersion = 0x41;
// Determine the highest WDM version supported
do
{
// Decrement to lower version
MinorVersion--;
bVersionFound =
IoIsWdmVersionAvailable(
0x01, // Just check for version 1.x for now
MinorVersion
);
}
while ((bVersionFound == FALSE) && (MinorVersion >= 0));
// Display possible OS version
DebugPrintf(("OS supports WDM 1.%02x ", MinorVersion));
if (MinorVersion >= 0x30)
{
DebugPrintf_NoInfo(("(Windows 2003 Server or higher)\n"));
}
else if (MinorVersion >= 0x20)
{
DebugPrintf_NoInfo(("(Windows XP or higher)\n"));
}
else if (MinorVersion >= 0x10)
{
DebugPrintf_NoInfo(("(Windows 2000 or higher)\n"));
}
else
{
DebugPrintf_NoInfo(("(Windows 98 or higher)\n"));
// Use the centralized PLX registry path for driver options
swprintf(
Win9x_RegistryPath,
WIN9X_REGISTRY_PATH_UNICODE L"\\" PLX_DRIVER_NAME_UNICODE
);
RtlInitUnicodeString(
&Win9x_RegistryPath_Unicode,
Win9x_RegistryPath
);
// Override assigned path
pRegistryPath = &Win9x_RegistryPath_Unicode;
}
DebugPrintf((
"Driver Registry path = \"%ws\"\n",
pRegistryPath->Buffer
));
// Get configuration information from registry
PlxRegistryInformationGet(
pRegistryPath,
&RegistryInfo
);
// Fill in the appropriate dispatch handlers
pDriverObject->DriverUnload = DriverUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch_Create;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch_Close;
pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = Dispatch_Cleanup;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch_IoControl;
pDriverObject->MajorFunction[IRP_MJ_PNP] = Dispatch_Pnp;
pDriverObject->MajorFunction[IRP_MJ_POWER] = Dispatch_Power;
pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Dispatch_SystemControl;
pDriverObject->DriverExtension->AddDevice = AddDevice;
// Initialize device count
Gbl_DeviceCount = 0;
// Initialize Common buffer pointer
pGbl_CommonBuffer = NULL;
// Set common buffer requested size
Gbl_CommonBufferSize = RegistryInfo.CommonBufferSize;
// Set cacheability of physical buffers
Gbl_PhysicalMemoryCacheable = RegistryInfo.PhysicalMemoryCacheable;
return STATUS_SUCCESS;
}
/******************************************************************************
*
* Function : DriverUnload
*
* Description: Unload the driver
*
******************************************************************************/
VOID
DriverUnload(
PDRIVER_OBJECT pDriverObject
)
{
DebugPrintf_NoInfo(("\n"));
DebugPrintf(("Unloading Driver...\n"));
DebugPrintf(("...Driver unloaded\n"));
}
/******************************************************************************
*
* Function : AddDevice
*
* Description: Add a new device object to the driver
*
******************************************************************************/
NTSTATUS
AddDevice(
PDRIVER_OBJECT pDriverObject,
PDEVICE_OBJECT pdo
)
{
U8 i;
WCHAR DeviceName[PLX_MAX_NAME_LENGTH];
WCHAR DeviceLinkName[PLX_MAX_NAME_LENGTH];
NTSTATUS status;
POWER_STATE PowerState;
UNICODE_STRING DeviceName_Unicode;
UNICODE_STRING DeviceLinkName_Unicode;
PDEVICE_OBJECT fdo;
DEVICE_EXTENSION *pdx;
// Build a device name and attempt to create it
for (i=0; i < 64; i++)
{
swprintf(
DeviceName,
L"\\Device\\" PLX_DRIVER_NAME_UNICODE L"-%d",
i
);
RtlInitUnicodeString(
&DeviceName_Unicode,
DeviceName
);
// Create the device object
status =
IoCreateDevice(
pDriverObject,
sizeof(DEVICE_EXTENSION),
&DeviceName_Unicode,
FILE_DEVICE_UNKNOWN,
0,
FALSE, // Shared by applications
&fdo
);
// IoCreateDevice() will fail if the same object already exists
if (NT_SUCCESS(status))
{
break;
}
}
// Check if the creation succeeded
if ( !NT_SUCCESS(status) )
{
DebugPrintf(("ERROR - Unable to create Device\n"));
return status;
}
DebugPrintf_NoInfo(("\n"));
DebugPrintf((
"Created Device (%ws)...\n",
DeviceName
));
// Link a Win32 name for user applications
swprintf(
DeviceLinkName,
L"\\DosDevices\\" PLX_DRIVER_NAME_UNICODE L"-%d",
i
);
RtlInitUnicodeString(
&DeviceLinkName_Unicode,
DeviceLinkName
);
DebugPrintf((
"Creating Win32 symbolic link (%ws)...\n",
DeviceLinkName
));
status =
IoCreateSymbolicLink(
&DeviceLinkName_Unicode,
&DeviceName_Unicode
);
if ( !NT_SUCCESS(status) )
{
DebugPrintf(("WARNING - Unable to create symbolic link for Win32 Apps\n"));
swprintf(DeviceLinkName, L"");
}
//
// Initialize the device extension
//
pdx = fdo->DeviceExtension;
// Clear device extension
RtlZeroMemory(
pdx,
sizeof(DEVICE_EXTENSION)
);
// Save the parent device object
pdx->pDeviceObject = fdo;
pdx->pPhysicalDeviceObject = pdo;
pdx->usage = 1; // Locked until RemoveDevice
sprintf(
pdx->Device.SerialNumber,
PLX_DRIVER_NAME "-%d",
i
);
wcscpy(
pdx->LinkName,
DeviceLinkName
);
// Initialize PCI BAR variables
for (i = 0 ; i < PCI_NUM_BARS_TYPE_00; i++)
{
pdx->PciBar[i].pVa = NULL;
pdx->PciBar[i].Physical.QuadPart = 0;
pdx->PciBar[i].Size = 0;
pdx->PciBar[i].bIsIoSpace = FALSE;
pdx->PciBar[i].pMdl = NULL;
InitializeListHead(
&(pdx->PciBar[i].List_Mappings)
);
KeInitializeSpinLock(
&(pdx->PciBar[i].Lock_MappingsList)
);
}
KeInitializeSpinLock(
&(pdx->Lock_HwAccess)
);
InitializeListHead(
&(pdx->List_WaitObjects)
);
KeInitializeSpinLock(
&(pdx->Lock_WaitObjectsList)
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -