Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

857 lines
22 KiB

/*++
Copyright (c) 2002 Microsoft Corporation
Module Name:
sdbus.h
Abstract:
Author:
Neil Sandlin (neilsa) 1-Jan-2002
Revision History
--*/
#ifndef _SDBUS_H_
#define _SDBUS_H_
typedef enum _DEVICE_OBJECT_TYPE {
FDO = 0,
PDO
} DEVICE_OBJECT_TYPE;
//
// Type of the controller
//
typedef ULONG SDBUS_CONTROLLER_TYPE, *PSDBUS_CONTROLLER_TYPE;
struct _FDO_EXTENSION;
struct _PDO_EXTENSION;
struct _SD_WORK_PACKET;
//
// Io Worker States
//
typedef enum {
WORKER_IDLE = 0,
PACKET_PENDING,
IN_PROCESS,
WAITING_FOR_TIMER
} WORKER_STATE;
//
// socket enumeration states
//
typedef enum {
SOCKET_EMPTY = 0,
CARD_DETECTED,
CARD_NEEDS_ENUMERATION,
CARD_ACTIVE,
CARD_LOGICALLY_REMOVED
} SOCKET_STATE;
//
// Define SynchronizeExecution routine.
//
typedef
BOOLEAN
(*PSYNCHRONIZATION_ROUTINE) (
IN PKINTERRUPT Interrupt,
IN PKSYNCHRONIZE_ROUTINE Routine,
IN PVOID SynchronizeContext
);
//
// Completion routine called by various timed routines
//
typedef
VOID
(*PSDBUS_COMPLETION_ROUTINE) (
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context
);
typedef
VOID
(*PSDBUS_ACTIVATE_COMPLETION_ROUTINE) (
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context,
IN NTSTATUS Status
);
//
// SD_FUNCTION_BLOCK allows for a level of indirection, thereby allowing
// the top-level SDBUS code to do it's work without worrying about who's
// particular brand of SD controller it's addressing.
//
typedef struct _SD_FUNCTION_BLOCK {
//
// Function to initialize controller. This is done once after
// the host controller is started, or powered on.
//
VOID
(*InitController)(
IN struct _FDO_EXTENSION *FdoExtension
);
//
// Function to initialize SD function. This is done once after
// the function is started.
//
VOID
(*InitFunction)(
IN struct _FDO_EXTENSION *FdoExtension,
IN struct _PDO_EXTENSION *PdoExtension
);
//
// function to set power for a socket
//
NTSTATUS
(*SetPower)(
IN struct _FDO_EXTENSION *FdoExtension,
IN BOOLEAN Enable,
OUT PULONG pDelayTime
);
//
// function to set reset an SD card
//
NTSTATUS
(*ResetHost)(
IN struct _FDO_EXTENSION *FdoExtension,
IN UCHAR Phase,
OUT PULONG pDelayTime
);
//
// function to control the external LED
//
VOID
(*SetLED)(
IN struct _FDO_EXTENSION *FdoExtension,
IN BOOLEAN Enable
);
//
// Switch focus between IO function or memory function
//
VOID
(*SetFunctionType)(
IN struct _FDO_EXTENSION *FdoExtension,
UCHAR FunctionType
);
//
// Function to determine if a card is in the socket
//
BOOLEAN
(*DetectCardInSocket)(
IN struct _FDO_EXTENSION *FdoExtension
);
BOOLEAN
(*IsWriteProtected)(
IN struct _FDO_EXTENSION *FdoExtension
);
NTSTATUS
(*CheckStatus)(
IN struct _FDO_EXTENSION *FdoExtension
);
NTSTATUS
(*SendSDCommand)(
IN struct _FDO_EXTENSION *FdoExtension,
IN struct _SD_WORK_PACKET *WorkPacket
);
NTSTATUS
(*GetSDResponse)(
IN struct _FDO_EXTENSION *FdoExtension,
IN struct _SD_WORK_PACKET *WorkPacket
);
//
// Interfaces for block memory operations
//
VOID
(*StartBlockOperation)(
IN struct _FDO_EXTENSION *FdoExtension
);
VOID
(*SetBlockParameters)(
IN struct _FDO_EXTENSION *FdoExtension,
IN USHORT SectorCount
);
VOID
(*EndBlockOperation)(
IN struct _FDO_EXTENSION *FdoExtension
);
//
// Copy a sector from the data port to a buffer
//
VOID
(*ReadDataPort)(
IN struct _FDO_EXTENSION *FdoExtension,
IN PUCHAR Buffer,
IN ULONG Length
);
//
// Copy a sector from a buffer to the data port
//
VOID
(*WriteDataPort)(
IN struct _FDO_EXTENSION *FdoExtension,
IN PUCHAR Buffer,
IN ULONG Length
);
//
// Function to enable/disable status change interrupts
//
VOID
(*EnableEvent)(
IN struct _FDO_EXTENSION *FdoExtension,
IN ULONG EventMask
);
VOID
(*DisableEvent)(
IN struct _FDO_EXTENSION *FdoExtension,
IN ULONG EventMask
);
//
// vendor-specific function to handle interrupts
//
ULONG
(*GetPendingEvents)(
IN struct _FDO_EXTENSION *FdoExtension
);
VOID
(*AcknowledgeEvent)(
IN struct _FDO_EXTENSION *FdoExtension,
IN ULONG EventMask
);
} SD_FUNCTION_BLOCK, *PSD_FUNCTION_BLOCK;
//
// Enumeration structures
//
#define MAX_MANFID_LENGTH 64
#define MAX_IDENT_LENGTH 64
typedef struct _SD_FUNCTION_DATA {
struct _SD_FUNCTION_DATA *Next;
//
// Function Number
//
UCHAR Function;
ULONG CardPsn;
ULONG CsaSize;
ULONG Ocr;
UCHAR IoDeviceInterface;
} SD_FUNCTION_DATA, *PSD_FUNCTION_DATA;
typedef struct _SD_CARD_DATA {
UCHAR MfgText[MAX_MANFID_LENGTH];
UCHAR ProductText[MAX_IDENT_LENGTH];
USHORT MfgId;
USHORT MfgInfo;
//
// SD Io card parameters
//
UCHAR CardCapabilities;
//
// SD Memory Card parameters
//
SD_CID SdCid;
SD_CSD SdCsd;
UCHAR ProductName[6];
//
// array of per-function data
//
PSD_FUNCTION_DATA FunctionData;
} SD_CARD_DATA, *PSD_CARD_DATA;
//
// Synchronization primitives
//
#define SDBUS_TEST_AND_SET(X) (InterlockedCompareExchange(X, 1, 0) == 0)
#define SDBUS_TEST_AND_RESET(X) (InterlockedCompareExchange(X, 0, 1) == 1)
//
// Power
//
typedef struct _SD_POWER_CONTEXT {
PSDBUS_COMPLETION_ROUTINE CompletionRoutine;
PVOID Context;
} SD_POWER_CONTEXT, *PSD_POWER_CONTEXT;
typedef struct _SD_ACTIVATE_CONTEXT {
PSDBUS_ACTIVATE_COMPLETION_ROUTINE CompletionRoutine;
PVOID Context;
} SD_ACTIVATE_CONTEXT, *PSD_ACTIVATE_CONTEXT;
//
// Functional Device Object's device extension information
//
// There is one device object for each SDBUS socket controller
// located in the system. This contains the root pointers for
// each of the lists of information on this controller.
//
//
// Flags common to both fdoExtension and pdoExtension
//
#define SDBUS_DEVICE_STARTED 0x00000001
#define SDBUS_DEVICE_LOGICALLY_REMOVED 0x00000002
#define SDBUS_DEVICE_PHYSICALLY_REMOVED 0x00000004
#define SDBUS_DEVICE_WAKE_PENDING 0x00000010
#define SDBUS_DEVICE_DELETED 0x00000040
//
// Flags indicating controller state (fdoExtension)
//
#define SDBUS_HOST_REGISTER_BASE_MAPPED 0x00010000
#define SDBUS_FDO_CONTEXT_SAVED 0x00020000
#define SDBUS_FDO_OFFLINE 0x00040000
#define SDBUS_FDO_WAKE_BY_CD 0x00080000
#define SDBUS_FDO_WORK_ITEM_ACTIVE 0x00100000
//
// Flags indicating interrupt status
//
#define SDBUS_EVENT_INSERTION 0x00000001
#define SDBUS_EVENT_REMOVAL 0x00000002
#define SDBUS_EVENT_CARD_RESPONSE 0x00000004
#define SDBUS_EVENT_CARD_RW_END 0x00000008
#define SDBUS_EVENT_BUFFER_EMPTY 0x00000010
#define SDBUS_EVENT_BUFFER_FULL 0x00000020
#define SDBUS_EVENT_CARD_INTERRUPT 0x00000040
#define SDBUS_EVENT_ALL 0xFFFFFFFF
//
// Flags indicating what type of function is currently being addressed
//
#define SDBUS_FUNCTION_TYPE_MEMORY 1
#define SDBUS_FUNCTION_TYPE_IO 2
//
// FDO Flags
//
#define SDBUS_FDO_EXTENSION_SIGNATURE 'FmcP'
//
// Device extension for the functional device object for sd controllers
//
typedef struct _FDO_EXTENSION {
ULONG Signature;
//
// Pointer to the next sd controller's FDO in the central list
// of all sd controller managed by this driver.
// The head of the list is pointed to by the global variable FdoList
//
PDEVICE_OBJECT NextFdo;
//
// The PDO ejected by the parent bus driver for this sd controller
//
//
PDEVICE_OBJECT Pdo;
//
// The immediately lower device attached beneath the sd controller's FDO.
// This would be the same as the Pdo above, excepting in cases when there are
// lower filter drivers for the sd controller - like the ACPI driver
//
PDEVICE_OBJECT LowerDevice;
//
// Pointer to the miniport-like
//
PSD_FUNCTION_BLOCK FunctionBlock;
//
// Various flags used to track the state of this
// (flags prefixed by SDBUS_ above)
//
ULONG Flags;
//
// Type of the controller. We need to know this since this is
// a monolithic driver. We can do controller specific stuff
// based on the type if needed.
//
SDBUS_CONTROLLER_TYPE ControllerType;
//
// Index into the device dispatch table for vendor-specific
// controller functions
//
ULONG DeviceDispatchIndex;
PDEVICE_OBJECT DeviceObject;
PDRIVER_OBJECT DriverObject;
PUNICODE_STRING RegistryPath;
//
// Kernel objects to handle Io processing
//
KTIMER WorkerTimer;
KDPC WorkerTimeoutDpc;
//
// This field holds the "current work packet" so that the timeout
// dpc can pass it back to the worker routine
//
struct _SD_WORK_PACKET *TimeoutPacket;
KDPC WorkerDpc;
WORKER_STATE WorkerState;
KSPIN_LOCK WorkerSpinLock;
LIST_ENTRY SystemWorkPacketQueue;
LIST_ENTRY IoWorkPacketQueue;
//
// Io workitem to execute card functions at passive level
//
PIO_WORKITEM IoWorkItem;
KEVENT CardInterruptEvent;
KEVENT WorkItemExitEvent;
//
// Sequence number for event logging
//
ULONG SequenceNumber;
//
// Pointer to the interrupt object - if we use interrupt based
// card status change detection
//
PKINTERRUPT SdbusInterruptObject;
//
// IsrEventStatus is the hardware state. It is accessed only at DIRQL
//
ULONG IsrEventStatus;
//
// LatchedIsrEventStatus is pulled from IsrEventStatus synchronously. It is
// used by the ISR's DPC to reflect new hardware events.
//
ULONG LatchedIsrEventStatus;
//
// WorkerEventEventStatus is the set of events pending to be reflected to
// the io worker engine
//
ULONG WorkerEventStatus;
//
// Keeps track of currently enabled events
//
ULONG CurrentlyEnabledEvents;
//
// These are the card events we would like to see
//
ULONG CardEvents;
//
// Power management related stuff.
//
//
// Current power states
//
SYSTEM_POWER_STATE SystemPowerState;
DEVICE_POWER_STATE DevicePowerState;
//
// Indicates device busy
//
ULONG PowerStateInTransition;
//
// Indicates how many children (pc-cards) are pending on an
// IRP_MN_WAIT_WAKE
//
ULONG ChildWaitWakeCount;
//
// Device capabilities as reported by our bus driver
//
DEVICE_CAPABILITIES DeviceCapabilities;
//
// Pending wait wake Irp
//
PIRP WaitWakeIrp;
LONG WaitWakeState;
//
// PCI Bus interface standard
// This contains interfaces to read/write from PCI config space
// of the cardbus controller, among other stuff..
//
BUS_INTERFACE_STANDARD PciBusInterface;
//
// Configuration resources for the sd controller
//
CM_PARTIAL_RESOURCE_DESCRIPTOR Interrupt;
CM_PARTIAL_RESOURCE_DESCRIPTOR TranslatedInterrupt;
//
// Type of bus we are on
//
INTERFACE_TYPE InterfaceType;
//
// SD Host register base
//
PVOID HostRegisterBase;
//
// Size of the register base that has been mapped
//
ULONG HostRegisterSize;
// Memory = 1, IO = 2
UCHAR FunctionType;
USHORT ArgumentReg;
USHORT CmdReg;
USHORT CardStatusReg;
USHORT ResponseReg;
USHORT InterruptMaskReg;
//
// These are used for debugging
//
USHORT cardStatus;
USHORT errorStatus;
//
// card data which describes current card in the socket
//
PSD_CARD_DATA CardData;
//
// State of the current card in the slot
//
UCHAR numFunctions;
BOOLEAN memFunction;
ULONG RelativeAddr;
SD_CID SdCid;
SD_CSD SdCsd;
//
// Status of socket
//
SOCKET_STATE SocketState;
//
// Head of the list of child pc-card PDO's hanging off this controller.
// This is a linked list running through "NextPdoInFdoChain" in the pdo
// extension. This list represents the devices that were enumerated by
// the fdo.
//
PDEVICE_OBJECT PdoList;
//
// Keeps track of the number of PDOs which are actually
// valid (not removed). This is primarily used in
// enumeration of the sd controller upon an IRP_MN_QUERY_DEVICE_RELATIONS
//
ULONG LivePdoCount;
//
// Remove lock for PnP synchronization
//
IO_REMOVE_LOCK RemoveLock;
} FDO_EXTENSION, *PFDO_EXTENSION;
//
// Physical Device Object's device extension information
//
// There is one device object for each function of an SD device
//
//
// Flags indicating card state
//
#define SDBUS_PDO_GENERATES_IRQ 0x00010000
#define SDBUS_PDO_DPC_CALLBACK 0x00020000
#define SDBUS_PDO_CALLBACK_REQUESTED 0x00040000
#define SDBUS_PDO_CALLBACK_IN_SERVICE 0x00080000
#define SDBUS_PDO_EXTENSION_SIGNATURE 'PmcP'
//
// The PDO extension represents an instance of a single SD function on an SD card
//
typedef struct _PDO_EXTENSION {
ULONG Signature;
PDEVICE_OBJECT DeviceObject;
//
// Link to next pdo in the Fdo's pdo chain
//
PDEVICE_OBJECT NextPdoInFdoChain;
//
// Parent extension
//
PFDO_EXTENSION FdoExtension;
//
// Flags
//
ULONG Flags;
//
// Device ISR
//
PSDBUS_CALLBACK_ROUTINE CallbackRoutine;
PVOID CallbackRoutineContext;
//
// Power declarations
//
DEVICE_POWER_STATE DevicePowerState;
SYSTEM_POWER_STATE SystemPowerState;
//
// Device Capabilities
//
DEVICE_CAPABILITIES DeviceCapabilities;
//
// Pending wait wake irp
//
PIRP WaitWakeIrp;
//
// Deletion Mutex
//
ULONG DeletionLock;
//
// SD Function number
//
UCHAR Function;
UCHAR FunctionType;
} PDO_EXTENSION, *PPDO_EXTENSION;
//
// Struct for Database of card bus controller information
// which maps the vendor id/device id to a CONTROLLER_TYPE
//
typedef struct _PCI_CONTROLLER_INFORMATION {
USHORT VendorID;
USHORT DeviceID;
SDBUS_CONTROLLER_TYPE ControllerType;
} PCI_CONTROLLER_INFORMATION, *PPCI_CONTROLLER_INFORMATION;
//
// Struct for database of generic vendor class based on vendor ID
//
typedef struct _PCI_VENDOR_INFORMATION {
USHORT VendorID;
PSD_FUNCTION_BLOCK FunctionBlock;
} PCI_VENDOR_INFORMATION, *PPCI_VENDOR_INFORMATION;
// The pccard device id prefix
#define SDBUS_ID_STRING "SDBUS"
// String to be substituted if manufacturer name is not known
#define SDBUS_UNKNOWN_MANUFACTURER_STRING "UNKNOWN_MANUFACTURER"
// Max length of device id
#define SDBUS_MAXIMUM_DEVICE_ID_LENGTH 128
// Sdbus controller device name
#define SDBUS_DEVICE_NAME "\\Device\\Sdbus"
// Sdbus controller device symbolic link name
#define SDBUS_LINK_NAME "\\DosDevices\\Sdbus"
#define SDBUS_ENABLE_DELAY 10000
//
// problems observed on tecra 750 and satellite 300, with dec-chipset cb nic
//
#define SDBUS_DEFAULT_CONTROLLER_POWERUP_DELAY 250000 // 250 msec
//
// Amount of time to wait after an event interrupt was asserted on the controller
//
#define SDBUS_DEFAULT_EVENT_DPC_DELAY 400000 // 400 msec
//
// Macros for manipulating PDO's flags
//
#define IsDeviceFlagSet(deviceExtension, Flag) (((deviceExtension)->Flags & (Flag))?TRUE:FALSE)
#define SetDeviceFlag(deviceExtension, Flag) ((deviceExtension)->Flags |= (Flag))
#define ResetDeviceFlag(deviceExtension,Flag) ((deviceExtension)->Flags &= ~(Flag))
#define IsFdoExtension(fdoExtension) (fdoExtension->Signature == SDBUS_FDO_EXTENSION_SIGNATURE)
#define IsPdoExtension(pdoExtension) (pdoExtension->Signature == SDBUS_PDO_EXTENSION_SIGNATURE)
#define MarkDeviceStarted(deviceExtension) ((deviceExtension)->Flags |= SDBUS_DEVICE_STARTED)
#define MarkDeviceNotStarted(deviceExtension) ((deviceExtension)->Flags &= ~SDBUS_DEVICE_STARTED)
#define MarkDeviceDeleted(deviceExtension) ((deviceExtension)->Flags |= SDBUS_DEVICE_DELETED);
#define MarkDevicePhysicallyRemoved(deviceExtension) \
((deviceExtension)->Flags |= SDBUS_DEVICE_PHYSICALLY_REMOVED)
#define MarkDevicePhysicallyInserted(deviceExtension) \
((deviceExtension)->Flags &= ~SDBUS_DEVICE_PHYSICALLY_REMOVED)
#define MarkDeviceLogicallyRemoved(deviceExtension) \
((deviceExtension)->Flags |= SDBUS_DEVICE_LOGICALLY_REMOVED)
#define MarkDeviceLogicallyInserted(deviceExtension) \
((deviceExtension)->Flags &= ~SDBUS_DEVICE_LOGICALLY_REMOVED)
#define MarkDeviceMultifunction(deviceExtension) \
((deviceExtension)->Flags |= SDBUS_DEVICE_MULTIFUNCTION)
#define IsDeviceStarted(deviceExtension) (((deviceExtension)->Flags & SDBUS_DEVICE_STARTED)?TRUE:FALSE)
#define IsDevicePhysicallyRemoved(deviceExtension) \
(((deviceExtension)->Flags & SDBUS_DEVICE_PHYSICALLY_REMOVED)?TRUE:FALSE)
#define IsDeviceLogicallyRemoved(deviceExtension) \
(((deviceExtension)->Flags & SDBUS_DEVICE_LOGICALLY_REMOVED)?TRUE:FALSE)
#define IsDeviceDeleted(deviceExtension) (((deviceExtension)->Flags & SDBUS_DEVICE_DELETED)?TRUE:FALSE)
#define IsDeviceMultifunction(deviceExtension) (((deviceExtension)->Flags & SDBUS_DEVICE_MULTIFUNCTION)?TRUE:FALSE)
//
// NT definitions
//
#ifdef POOL_TAGGING
#undef ExAllocatePool
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'ubdS')
#endif
#define IO_RESOURCE_LIST_VERSION 0x1
#define IO_RESOURCE_LIST_REVISION 0x1
#define IRP_MN_PNP_MAXIMUM_FUNCTION IRP_MN_QUERY_LEGACY_BUS_INFORMATION
//
// Some useful macros
//
#define MIN(x,y) ((x) > (y) ? (y) : (x)) // return minimum among x & y
#define MAX(x,y) ((x) > (y) ? (x) : (y)) // return maximum among x & y
//
// BOOLEAN
// IS_PDO (IN PDEVICE_OBJECT DeviceObject);
//
#define IS_PDO(DeviceObject) (((DeviceObject)->Flags & DO_BUS_ENUMERATED_DEVICE)?TRUE:FALSE)
//
// Io extension macro to just pass on the Irp to a lower driver
//
//
// VOID
// SdbusSkipCallLowerDriver(OUT NTSTATUS Status,
// IN PDEVICE_OBJECT DeviceObject,
// IN PIRP Irp);
//
#define SdbusSkipCallLowerDriver(Status, DeviceObject, Irp) { \
IoSkipCurrentIrpStackLocation(Irp); \
Status = IoCallDriver(DeviceObject,Irp);}
//
// VOID
// SdbusCopyCallLowerDriver(OUT NTSTATUS Status,
// IN PDEVICE_OBJECT DeviceObject,
// IN PIRP Irp);
//
#define SdbusCopyCallLowerDriver(Status, DeviceObject, Irp) { \
IoCopyCurrentIrpStackLocationToNext(Irp); \
Status = IoCallDriver(DeviceObject,Irp); }
// BOOLEAN
// CompareGuid(
// IN LPGUID guid1,
// IN LPGUID guid2
// );
#define CompareGuid(g1, g2) ((g1) == (g2) ?TRUE: \
RtlCompareMemory((g1), \
(g2), \
sizeof(GUID)) \
== sizeof(GUID) \
)
//
// BOOLEAN
// ValidateController(IN FDO_EXTENSION fdoExtension)
//
// Bit of paranoia code. Make sure that the cardbus controller's registers
// are still visible.
//
#define ValidateController(fdoExtension) TRUE
//
// Structure which defines what global parameters are read from the registry
//
typedef struct _GLOBAL_REGISTRY_INFORMATION {
PWSTR Name;
PULONG pValue;
ULONG Default;
} GLOBAL_REGISTRY_INFORMATION, *PGLOBAL_REGISTRY_INFORMATION;
#endif //_SDBUS_H_