📄 init.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 1995 - 1998 OSR Open Systems Resources, Inc.
// All Rights Reserved
// Based on a previous work by Microsoft Corporation
// Copyright (c) 1991, 1992, 1993 Microsoft Corporation
//
// This sofware is supplied for instructional purposes only.
//
// OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
// for this software. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
// THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
// PURPOSE. THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
// WITH YOU. OSR's entire liability and your exclusive remedy shall not
// exceed the price paid for this material. In no event shall OSR or its
// suppliers be liable for any damages whatsoever (including, without
// limitation, damages for loss of business profit, business interruption,
// loss of business information, or any other pecuniary loss) arising out
// of the use or inability to use this software, even if OSR has been
// advised of the possibility of such damages. Because some states/
// jurisdictions do not allow the exclusion or limitation of liability for
// consequential or incidental damages, the above limitation may not apply
// to you.
//
// This driver is the example Programmed I/O device driver that
// accompanies the book Windows NT Device Driver Development, by
// Peter Viscarola and W. Anthony Mason, (c) 1998 OSR Open Systems
// Resources, Inc. and published by MacMillan Technical Publishing
// ISBN 1578700582.
//
// MODULE:
//
// $Workfile: init.c $
//
// ABSTRACT:
//
// This module handles the initialization of the IDE driver, specifically
// the DriverEntry entry point
//
// AUTHOR:
//
// Open Systems Resources, Inc.
//
// REVISION:
//
//
///////////////////////////////////////////////////////////////////////////////
#include "ntddk.h" // main NT include
#include "ntdddisk.h" // disk driver IOCTL definitions
#include "hw.h" // the access macro/definitions
#include "ide.h" // general declarations/structures
#include "utils.h" // IdeWaitController utilities
#include "config.h" // IdeGetConfigData declarations
//
// static forward declarations
//
static NTSTATUS
InitializeController(
IN PDRIVER_OBJECT DriverObject,
IN PCONFIG_DATA ConfigData
);
static NTSTATUS
InitializeDisk(IN PDRIVER_OBJECT DriverObject,
IN PCONFIG_DATA ConfigData,
IN OUT PCONTROLLER_DATA ControllerData);
static BOOLEAN
ReportUsage(IN PDRIVER_OBJECT DriverObject,
IN PCONFIG_DATA ConfigData);
///////////////////////////////////////////////////////////////////////////////
//
// DriverEntry
//
// This is the mail entry point for the IDE driver
//
// INPUTS:
//
// DriverObject - pointer to our device driver object
// Registrypath - this driver's service registry path
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS if initialization is successful, otherwise
// the appropriate failure status
//
// IRQL:
//
// IRQL_PASSIVE_LEVEL
//
// NOTES:
//
// While this routine is normally physically very large, many of the
// functions have been partitioned off to other files. DriverEntry calls:
//
// IdeGetConfigData - gets the bus/drive (configuration) data
// InitializeController - initialization of the controller and disk
// This calls InitializeDisk to init the disk
// The DeviceObject->DeviceExtension will
// contain the IDE_DEV_EXT structure
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
PCONFIG_DATA configData; // pointer to config mgr's returned data
NTSTATUS ntStatus;
//
// let folks know who we are
//
DbgPrint("DriverEntry: Osr Ide Sample Disk Driver\n");
//
// Allocate and zero the data structure used during initialization.
//
configData = ExAllocatePool(PagedPool, sizeof (CONFIG_DATA));
//
// If we can't get the memory for the CONFIG_DATA structure, we fail
//
if (configData == NULL) {
DbgPrint(
"DriverEntry: Can't allocate memory for config data\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
//
// Insure that the structure is clean
//
RtlZeroMemory(configData, sizeof(CONFIG_DATA));
//
// Get the bus and disk configuration and data
//
ntStatus = IdeGetConfigData(DriverObject, RegistryPath, configData);
//
// If IdeGetConfigInfo() failed, just exit returning the error to the
// I/O Manager
//
if(!NT_SUCCESS(ntStatus)) {
//
// Cleanup and return the error to the I/O Manger
//
ExFreePool(configData);
return ntStatus;
}
//
// Initialize the driver object with this driver's entry points.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = IdeDispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IdeDispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = IdeDispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = IdeDispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IdeDispatchDeviceControl;
DriverObject->DriverStartIo = IdeStartIo;
//
// Call ReportUsage() (which calls IoReportResourceUsage()) to
// determine if there are any resource conflicts
//
if (ReportUsage(DriverObject, configData)) {
//
// There are no resource conflicts, so now initialize the
// controller
//
ntStatus = InitializeController(DriverObject, configData);
} else {
//
// There were resource conflicts, so set the return status
// to an error
//
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
//
// Cleanup and return the error to the I/O Manger
//
// Tell Emmy, Katy and Bethy it's time to start working.
//
ExFreePool(configData);
return(ntStatus);
}
///////////////////////////////////////////////////////////////////////////////
//
// InitializeController
//
// This routine initializes the disk controller
//
// INPUTS:
//
// ConfigData - pointer to the configuration data
// DriverObject - pointer to our driver object
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS if controller and disk are initialized
//
// IRQL:
//
// IRQL_PASSIVE_LEVEL
//
// NOTES:
//
// If the controller is properly initialized, the disk is then
// initialized via InitializeDisk.
//
///////////////////////////////////////////////////////////////////////////////
static NTSTATUS
InitializeController(IN PDRIVER_OBJECT DriverObject,
IN PCONFIG_DATA ConfigData)
{
PCONTROLLER_DATA controllerData;
NTSTATUS ntStatus;
//
// Allocate the controller data structure out of NonPagedPool so
// that this structure is always available
//
controllerData = ExAllocatePool(NonPagedPool, sizeof (CONTROLLER_DATA));
//
// Fail if we can't get the memory
//
if (controllerData == NULL) {
DbgPrint("InitializeController: Couldn't create the controllerData structure.\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
//
// Make sure that the data area is clean.
//
RtlZeroMemory(controllerData, sizeof(CONTROLLER_DATA));
//
// save away some addresses and flags
//
controllerData->ControllerAddress = ConfigData->ControllerBaseAddress;
controllerData->ControlPortAddress = ConfigData->ControlPortAddress;
controllerData->ControlFlags = ConfigData->ControlFlags;
//
// Connect to the interrupt here, but delay the enable of the
// interrupt until the disk device object is complete.
//
// Note that there is some code in IdeISR() which checks to make sure
// that the controllerData->DeviceObject is filled in. If true, then
// we know that the interrupt belongs to us and not some other device
// which may be sharing this interrupt.
//
// Note that for this Isa device, we assume the interrupt mode is latched
//
ntStatus = IoConnectInterrupt(&controllerData->InterruptObject,
IdeISR, // our ISR routine
controllerData, // the ISR context
NULL, // no optional spinlock
ConfigData->ControllerVector, // from HalGetInterruptVector
ConfigData->ControllerIrql, // from HalGetInterruptVector
ConfigData->ControllerIrql, // from HalGetInterruptVector
Latched, // we're Latched and not LevelSensitive
FALSE, // we're not sharing this interrupt
ConfigData->ProcessorNumber, // from HalGetInterruptVector
FALSE); // don't save the FP state
//
// If we can't get the Interrupt vector, then notify the user and
// exit this routine
//
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("InitializeController: Couldn't connect to the interrupt - status %x\n",ntStatus);
return ntStatus;
}
//
// It doesn't matter whether we have any devices yet. The interrupt
// service routine will simply dismiss any iterrupts until it's ready.
//
// Well wait up to 2 seconds for the controller to accept the reset.
//
WRITE_PORT_UCHAR(controllerData->ControlPortAddress,RESET_CONTROLLER);
IdeWaitControllerBusy(controllerData->ControllerAddress + STATUS_REGISTER,
20,
75000);
WRITE_PORT_UCHAR(controllerData->ControlPortAddress,
(UCHAR)(ENABLE_INTERRUPTS | controllerData->ControlFlags));
//
// Initialize the disk and hook the controllerData to the disk
//
ASSERT((ConfigData->Disk.DriveType != 0));
ntStatus = InitializeDisk(DriverObject, ConfigData, controllerData);
//
// If we succeed, then we can continue along
//
if (NT_SUCCESS(ntStatus))
{
//
// increment the global disk count. This pointer was obtained
// from IoGetConfigurationInformation in IdeGetConfigData()
//
(*(ConfigData->HardDiskCount))++;
}
else {
//
// InitilaizeDisk() failed for some reason, so we need to
// cleanup. First, disconnnect the interrupt
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -