⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 硬盘驱动程序, 硬盘驱动程序,硬盘驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  (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 + -