📄 adapter.cpp
字号:
/********************************************************************************
** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved.
**
** Portions Copyright (c) 1998-1999 Intel Corporation
**
********************************************************************************/
//
// The name that is printed in debug output messages
//
static char STR_MODULENAME[] = "ICH Adapter: ";
//
// All the GUIDs from portcls and your own defined GUIDs end up in this object.
//
#define PUT_GUIDS_HERE
//
// We want the global debug variables here.
//
#define DEFINE_DEBUG_VARS
#include "adapter.h"
#pragma code_seg("PAGE")
/*****************************************************************************
* InstallSubdevice
*****************************************************************************
* This function creates and registers a subdevice consisting of a port
* driver, a minport driver and a set of resources bound together. It will
* also optionally place a pointer to an interface on the port driver in a
* specified location before initializing the port driver. This is done so
* that a common ISR can have access to the port driver during initialization,
* when the ISR might fire.
* This function is internally used and validates no parameters.
*/
NTSTATUS InstallSubdevice
(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PWCHAR Name,
IN REFGUID PortClassId,
IN REFGUID MiniportClassId,
IN PFNCREATEINSTANCE MiniportCreate OPTIONAL,
IN PUNKNOWN UnknownAdapter OPTIONAL,
IN PRESOURCELIST ResourceList,
IN REFGUID PortInterfaceId,
OUT PMINIPORT * OutMiniport OPTIONAL,
OUT PUNKNOWN * OutPortUnknown OPTIONAL
)
{
PAGED_CODE ();
NTSTATUS ntStatus;
PPORT port;
PMINIPORT miniport;
DOUT (DBG_PRINT, ("[InstallSubdevice]"));
//
// Create the port driver object
//
ntStatus = PcNewPort (&port,PortClassId);
//
// return immediately in case of an error
//
if (!NT_SUCCESS (ntStatus))
return ntStatus;
//
// Create the miniport object
//
if (MiniportCreate)
{
ntStatus = MiniportCreate ((PUNKNOWN*)&miniport, MiniportClassId,
NULL, NonPagedPool);
}
else
{
ntStatus = PcNewMiniport (&miniport,MiniportClassId);
}
//
// return immediately in case of an error
//
if (!NT_SUCCESS (ntStatus))
{
port->Release ();
return ntStatus;
}
//
// Init the port driver and miniport in one go.
//
ntStatus = port->Init (DeviceObject, Irp, miniport, UnknownAdapter,
ResourceList);
if (NT_SUCCESS (ntStatus))
{
//
// Register the subdevice (port/miniport combination).
//
ntStatus = PcRegisterSubdevice (DeviceObject, Name, port);
//
// Deposit the port as an unknown if it's needed.
//
if (OutPortUnknown && NT_SUCCESS (ntStatus))
{
ntStatus = port->QueryInterface (IID_IUnknown,
(PVOID *)OutPortUnknown);
}
//
// Deposit the miniport as an IMiniport if it's needed.
//
if ( OutMiniport && NT_SUCCESS (ntStatus) )
{
ntStatus = miniport->QueryInterface (IID_IMiniport,
(PVOID *)OutMiniport);
}
}
//
// Release the reference for the port and miniport. This is the right
// thing to do, regardless of the outcome.
//
miniport->Release ();
port->Release ();
return ntStatus;
}
/*****************************************************************************
* ValidateResources
*****************************************************************************
* This function validates the list of resources for the various functions on
* the card. This code is specific to the adapter.
* This function doesn't check the ResourceList parameter and returns
* STATUS_SUCCESS when the resources are valid.
*/
NTSTATUS ValidateResources
(
IN PRESOURCELIST ResourceList // All resources.
)
{
PAGED_CODE ();
DOUT (DBG_PRINT, ("[ValidateResources]"));
//
// Get counts for the types of resources.
//
ULONG countIO = ResourceList->NumberOfPorts ();
ULONG countIRQ = ResourceList->NumberOfInterrupts ();
ULONG countDMA = ResourceList->NumberOfDmas ();
// validate resources
if ((countIO != 2) || (countIRQ != 1) || (countDMA != 0))
{
DOUT (DBG_ERROR, ("Unknown configuration:\n"
" IO count: %d\n"
" IRQ count: %d\n"
" DMA count: %d",
countIO, countIRQ, countDMA));
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
return STATUS_SUCCESS;
}
/*****************************************************************************
* StartDevice
*****************************************************************************
* This function is called by the operating system when the device is started.
* It is responsible for starting the miniports. This code is specific to
* the adapter because it calls out miniports for functions that are specific
* to the adapter.
*/
NTSTATUS StartDevice
(
IN PDEVICE_OBJECT DeviceObject, // Device object.
IN PIRP Irp, // IO request packet.
IN PRESOURCELIST ResourceList // List of hardware resources.
)
{
PAGED_CODE ();
ASSERT (DeviceObject);
ASSERT (Irp);
ASSERT (ResourceList);
NTSTATUS ntStatus;
DOUT (DBG_PRINT, ("[StartDevice]"));
//
// Determine which version of the OS we are running under. We don't want
// to run under Win98G.
//
// create a wave cyclic port
PPORT pPort = 0;
ntStatus = PcNewPort (&pPort,CLSID_PortWaveCyclic);
// check error code
if (NT_SUCCESS (ntStatus))
{
// query for the event interface which is not supported in Win98 gold.
PPORTEVENTS pPortEvents = 0;
ntStatus = pPort->QueryInterface (IID_IPortEvents,
(PVOID *)&pPortEvents);
if (!NT_SUCCESS (ntStatus))
{
DOUT (DBG_ERROR, ("This driver is not for Win98 Gold!"));
ntStatus = STATUS_UNSUCCESSFUL; // change error code.
}
else
{
pPortEvents->Release ();
}
pPort->Release ();
}
// now return in case it was Win98 Gold.
if (!NT_SUCCESS (ntStatus))
return ntStatus;
//
// Validate the resources.
// We don't have to split the resources into several resource lists cause
// the topology miniport doesn't need a resource list, the wave pci miniport
// needs all resources like the adapter common object.
//
ntStatus = ValidateResources (ResourceList);
//
// return immediately in case of an error
//
if (!NT_SUCCESS (ntStatus))
return ntStatus;
//
// If the adapter has the right resources...
//
PADAPTERCOMMON pAdapterCommon = NULL;
PUNKNOWN pUnknownCommon;
// create a new adapter common object
ntStatus = NewAdapterCommon (&pUnknownCommon, IID_IAdapterCommon,
NULL, NonPagedPool);
if (NT_SUCCESS (ntStatus))
{
// query for the IAdapterCommon interface
ntStatus = pUnknownCommon->QueryInterface (IID_IAdapterCommon,
(PVOID *)&pAdapterCommon);
if (NT_SUCCESS (ntStatus))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -