/*++
Copyright (C) Microsoft Corporation, 2005
Module Name:
entrypts.c
Abstract:
This header file contains function of entry points to the AHCI ATA miniport.
This includes ATA miniport interface functions for both channel and controller interfaces.
Notes:
Revision History:
Nathan Obr (natobr), February 2005 - September 2006 rev 1 (NCQ, LPM, Hotplug, persistant state)
December 2006 - August 2007 rev 2 (async)
--*/
#include "geninc.h"
//#pragma alloc_text(INIT, DriverEntry)
ULONG //REMOVE: 1PCIIDEX to driver entry
DriverEntry ( // DriverEntry(
PVOID Argument1,// IN PDRIVER_OBJECT DriverObject,
PVOID Argument2 // IN PUNICODE_STRING RegistryPath
) // )
/*++
The only goal of DriverEntry is to create an IDE_CONTROLLER_INTERFACE, populate and
send it to AtaPortInitializeEx.
It assumes:
DriverEntry is the first function called in msahci.sys
The OS-specific port driver allocates a controller extension initializes it and sends it to AtaPortInitializeEx.
AtaPortInitializeEx initializes the miniport driver�s dispatch tables and allocates an extension for the driver object.
It stores the pointer to the AtaControllerInitialize entry point and the ControllerExtensionSize in the driver object extension for later use.
Called by:
external
It performs:
(overview)
1. Initialization of the Ide Controller Interface
2. Calling into PCIIDEX through AtaPortInitializeEx.
(details)
1.1 Initialize IDE_CONTROLLER_INTERFACE to 0s
1.2 The miniport driver indicates the support for the channel interface by setting the ChannelExtensionSize and the AtaChannelInitRoutine entry point in the controller interface structure.
1.3 Add mini driver entry points
1.4 add pointers to data structures and IO alignment
2.1 The miniport must call AtaPortInitializeEx from its DriverEntry routine.
Affected Variables/Registers:
none
Return Values:
The miniport driver must return TRUE if the initialization succeeded. If the miniport driver fails to initialize it must return FALSE.
Initialization success is dependant on AtaPortInitializeEx's Return Value
--*/
{ //used to initialize the IDE Controller Interface
IDE_CONTROLLER_INTERFACE IdeControllerInterface;
PUCHAR pIdeControllerInterface = (PUCHAR) &IdeControllerInterface;
int i=0;
//1.1 initialize IDE_CONTROLLER_INTERFACE to 0s
for (i= 0; i<sizeof(IDE_CONTROLLER_INTERFACE); i++) {
(*(pIdeControllerInterface))=0;
pIdeControllerInterface++;
}
//1.2 The miniport driver indicates the support
IdeControllerInterface.ChannelExtensionSize= sizeof(AHCI_CHANNEL_EXTENSION);
IdeControllerInterface.AtaChannelInitRoutine= AhciChannelInitRoutine;
//1.3 Add mini driver entry points
IdeControllerInterface.AtaControllerChannelEnabled = AhciChannelEnabled;
IdeControllerInterface.AtaControllerTransferModeSelect = NULL;
IdeControllerInterface.AtaAdapterControl= AhciAdapterControl;
//1.4 add pointers to data structures and IO alignment
IdeControllerInterface.Version= sizeof(IDE_CONTROLLER_INTERFACE);
IdeControllerInterface.ControllerExtensionSize= sizeof(AHCI_CONTROLLER_EXTENSION);
IdeControllerInterface.AlignmentMask = 1; // The PRDT DBA must be word aligned.
//2.1 call into PCIIDEX where it will handle creating the controller's FDO
return AtaPortInitializeEx( Argument1, //DriverObject,
Argument2, //RegistryPath,
&IdeControllerInterface);
}
BOOLEAN
AhciAdapterControl(
PVOID ControllerExtension,
IN IDE_CONTROL_ACTION ControlAction,
IN PVOID Parameters //when ControlAction is IdeStart, this is a pointer to a IDE_CONTROLLER_CONFIGURATION
)
/*++
This is a CONTROLLER dispatch routine for for notifications the miniport driver receives about the various PNP and power events in the system.
This function is a function dispatcher for the IDE_CONTROL_ACTIONS: Start, Stop, PowerUp, and PowerDown
It assumes:
The port driver ensures that there is no outstanding I/O on the adapter before invoking this routine.
Called by:
external
It performs:
Dispatch based on the IDE_CONTROL_ACTIONS for the Controller
Affected Variables/Registers:
none
Return Values:
The miniport driver must return TRUE to acknowledge the completion of the requested action.
A return value of FALSE indicates that the miniport was not able to complete the action successfully.
A return value of FALSE for certain actions might cause the device installation to fail.
FALSE is only valid if the IDE_CONTROLLER_CONFIGURATION structure is not the right version.
This causes the PCIIDEX driver to return from IRP_MJ_PnP with a STATUS_REVISION_MISMATCH
--*/
{ //Used to perform dispatch
BOOLEAN retVal;
PIDE_CONTROLLER_CONFIGURATION controllerConfiguration;
switch (ControlAction) {
case IdeStart:
controllerConfiguration = Parameters;
retVal = AhciAdapterControlIdeStart(ControllerExtension, controllerConfiguration);
break;
case IdeStop:
retVal = AhciAdapterControlIdeStop(ControllerExtension);
break;
case IdePowerUp:
retVal = AhciAdapterControlIdePowerUp(ControllerExtension);
break;
case IdePowerDown:
retVal = AhciAdapterControlIdePowerDown(ControllerExtension);
break;
default:
retVal = FALSE;
break;
}
return retVal;
}
ATA_CHANNEL_STATE
AhciChannelEnabled(
IN PVOID ControllerExtension,
IN ULONG Channel
)
/*++
AtaControllerChannelEnabled is an optional routine. This is an optional routine and should not have controller critical steps in it.
This function is not called in the case of a channel restart, only on QueryDeviceRelations
If the miniport driver does not implement this routine a default handler will be loaded, and all channels are assumed to be enabled.
PCIIDEX uses this function to help it build PDOs for each channel.
Once the PDOs are created, it is time to load ATAport who will start the channels and do enumeration for the device(s) on the channel(s).
It assumes:
This function will be called with 'ULONG Channel' valuse from 0 to (ControllerConfiguration->NumberOfChannels - 1) which was given to PCIIDEX in AhciAdapterControl (IdeStart).
Called by:
external
It performs:
(overview)
1. Verification of channel's existance
(details)
1.1 Initialize variables
1.2 Verify the channel's existance
Ataport doesn't support sparse channels explicitly. It is possible this channel doesn't exist.
Affected Variables/Registers:
Return Values:
ChannelStateEnabled = Channel is ready to be used by time this function finishes
ChannelStateDisabled= If previously enabled, this state causes the port driver to mark the channel dead
ChannelStateUnKnown = use only if you want the port driver to assert.
--*/
{
ATA_CHANNEL_STATE state;
PAHCI_CONTROLLER_EXTENSION controllerExtension;
//structures to get information from the Controller
PAHCI_MEMORY_REGISTERS abar;
ULONG pi;
//this is an optional routine and should not have controller critical steps in it.
//this is not called in the case of a channel restart, only on QueryDeviceRelations
//1.1 Initialize variables
state = ChannelStateUnKnown;
controllerExtension = (PAHCI_CONTROLLER_EXTENSION) ControllerExtension;
abar = (PAHCI_MEMORY_REGISTERS) controllerExtension->ABAR_Address;
pi = AtaPortReadRegisterUlong(&abar->PI);
评论3