/*++ Copyright (c) 1997 Microsoft Corporation Module Name: ecp.h Abstract: Header file for ACPI EC Driver Author: Environment: NT Kernel Model Driver only --*/ #include #include #include #include #include #include "errlog.h" // // Debugging // #define DEBUG DBG #if DEBUG extern ULONG ECDebug; #define EcPrint(l,m) if(l & ECDebug) DbgPrint m #else #define EcPrint(l,m) #endif #define EC_LOW 0x00000010 #define EC_NOTE 0x00000001 #define EC_WARN 0x00000002 #define EC_ERROR 0x00000004 #define EC_ERRORS (EC_ERROR | EC_WARN) #define EC_HANDLER 0x00000020 #define EC_IO 0x00000040 #define EC_OPREGION 0x00000080 #define EC_QUERY 0x00000200 #define EC_TRACE 0x00000400 #define EC_TRANSACTION 0x00000800 // // Control methods used by EC // #define CM_GPE_METHOD (ULONG) ('EPG_') // control method "_GPE" // // Misc // extern ACPI_INTERFACE_STANDARD AcpiInterfaces; #define MAX_QUERY 255 #define BITS_PER_ULONG (sizeof(ULONG)*8) #define EVTBITS ((MAX_QUERY+1)/BITS_PER_ULONG) extern LARGE_INTEGER AcpiEcWatchdogTimeout; // // Query vector // typedef struct { UCHAR Next; UCHAR Vector; PVECTOR_HANDLER Handler; PVOID Context; } VECTOR_TABLE, *PVECTOR_TABLE; // // EC configuration information structure contains information // about the embedded controller attached and its configuration. // typedef struct _ACPIEC_CONFIGURATION_INFORMATION { INTERFACE_TYPE InterfaceType; ULONG BusNumber; ULONG SlotNumber; PHYSICAL_ADDRESS PortAddress; USHORT PortSize; USHORT UntranslatedPortAddress; CM_PARTIAL_RESOURCE_DESCRIPTOR Interrupt; // // For PCI-based controllers, indicates the pin number which we need // for programming the controller interrupt // UCHAR InterruptPin; BOOLEAN FloatingSave; } ACPIEC_CONFIGURATION_INFORMATION, *PACPIEC_CONFIGURATION_INFORMATION; // // Definitions for keeping track of the last x actions taken by the EC driver. // #define ACPIEC_ACTION_COUNT 0x20 #define ACPIEC_ACTION_COUNT_MASK 0x1f typedef struct { UCHAR IoStateAction; // EcData->IoState | EC_ACTION_???? (see definitions below) UCHAR Data; // Depends on event USHORT Time; // Delta time of first event of identical events } ACPIEC_ACTION, *PACPIEC_ACTION; #define EC_ACTION_MASK 0xf0 #define EC_ACTION_READ_STATUS 0x10 #define EC_ACTION_READ_DATA 0x20 #define EC_ACTION_WRITE_CMD 0x30 #define EC_ACTION_WRITE_DATA 0x40 #define EC_ACTION_INTERRUPT 0x50 #define EC_ACTION_DISABLE_GPE 0x60 #define EC_ACTION_ENABLE_GPE 0x70 #define EC_ACTION_CLEAR_GPE 0x80 #define EC_ACTION_QUEUED_IO 0x90 #define EC_ACTION_REPEATED 0xa0 #define EC_ACTION_MAX 0xb0 // // ACPI Embedded Control Device object extenstion // typedef struct { PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT NextFdo; PDEVICE_OBJECT Pdo; //Pdo corresponding to this fdo PDEVICE_OBJECT LowerDeviceObject; // // Static device information // PUCHAR DataPort; // EC Data port PUCHAR StatusPort; // EC Status port PUCHAR CommandPort; // EC Command port ULONG MaxBurstStall; // Max delay for EC reponse in burst mode ULONG MaxNonBurstStall; // Max delay for EC otherwise BOOLEAN IsStarted; // // Gpe and Operation Region info // PVOID EnableGpe; PVOID DisableGpe; PVOID ClearGpeStatus; PVOID GpeVectorObject; // Object representing attachment to the EC GPE vector ULONG GpeVector; // GPE vector assigned to the EC device PVOID OperationRegionObject; // Attachment to the EC operation region ACPIEC_CONFIGURATION_INFORMATION Configuration; // // Lock for device data // KSPIN_LOCK Lock; // Lock device data // // Device maintenance // KEVENT Unload; // Event to wait of for unload UCHAR DeviceState; // // Query/vector operations // UCHAR QueryState; UCHAR VectorState; ULONG QuerySet[EVTBITS]; // If pending or not ULONG QueryType[EVTBITS]; // Type of Query or Vector PIRP QueryRequest; // IRP to execute query methods UCHAR QueryMap[MAX_QUERY+1]; // Query pending list and vector table map UCHAR QueryHead; // List of pending queries UCHAR VectorHead; // List of pending vectors UCHAR VectorFree; // List of free vectors entries UCHAR VectorTableSize; // Sizeof vector table PVECTOR_TABLE VectorTable; // // Device's work queue (owned by Lock owner) // BOOLEAN InService; // Serialize in service BOOLEAN InServiceLoop; // Flag when in service needs to loop BOOLEAN InterruptEnabled; // Masked or not LIST_ENTRY WorkQueue; // Queued IO IRPs to the device PIRP MiscRequest; // IRP for start/stop device // // Data IO (owned by InService owner) // UCHAR IoState; // Io state UCHAR IoBurstState; // Pushed state for burst enable UCHAR IoTransferMode; // read or write transfer UCHAR IoAddress; // Address in EC for transfer UCHAR IoLength; // Length of transfer UCHAR IoRemain; // Length remaining of transfer PUCHAR IoBuffer; // RAM location for transfer // // Watchdog Timer to catch hung and/or malfunctioning ECs // UCHAR ConsecutiveFailures;// Count how many times watdog fired without making progress. UCHAR LastAction; // Index into RecentActions array. LARGE_INTEGER PerformanceFrequency; KTIMER WatchdogTimer; KDPC WatchdogDpc; ACPIEC_ACTION RecentActions [ACPIEC_ACTION_COUNT]; // // Stats // ULONG NonBurstTimeout; ULONG BurstTimeout; ULONG BurstComplete; ULONG BurstAborted; ULONG TotalBursts; ULONG Errors; ULONG MaxServiceLoop; } ECDATA, *PECDATA; // // DeviceState // #define EC_DEVICE_WORKING 0 #define EC_DEVICE_UNLOAD_PENDING 1 #define EC_DEVICE_UNLOAD_CANCEL_TIMER 2 #define EC_DEVICE_UNLOAD_COMPLETE 3 // // QueryState // #define EC_QUERY_IDLE 0 #define EC_QUERY_DISPATCH 1 #define EC_QUERY_DISPATCH_WAITING 2 #define EC_QUERY_DISPATCH_COMPLETE 3 // // Embedded Control read state // #define EC_IO_NONE 0 // Idle #define EC_IO_READ_BYTE 1 // Read byte on OBF #define EC_IO_READ_QUERY 2 // Query response on OBF #define EC_IO_BURST_ACK 3 // Brust ACK on OBF #define EC_IO_WRITE_BYTE 4 // Write byte on IBE #define EC_IO_NEXT_BYTE 5 // Issue read/write on IBE #define EC_IO_SEND_ADDRESS 6 // Send transfer address on IBE #define EC_IO_UNKNOWN 7 // // Status port definitions // #define EC_OUTPUT_FULL 0x01 // Output buffer full (data from EC to Host) #define EC_INPUT_FULL 0x02 // Input buffer full (data from Host to EC) #define EC_BURST 0x10 // In burst transfer #define EC_QEVT_PENDING 0x20 // Query event is pending #define EC_BUSY 0x80 // Device is busy // // Embedded controller commands // #define EC_READ_BYTE 0x80 #define EC_WRITE_BYTE 0x81 #define EC_BURST_TRANSFER 0x82 #define EC_CANCEL_BURST 0x83 #define EC_QUERY_EVENT 0x84 // // Prototypes // NTSTATUS AcpiEcSynchronousRequest ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS AcpiEcNewEc ( IN PDEVICE_OBJECT Fdo ); NTSTATUS AcpiEcOpenClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS AcpiEcReadWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS AcpiEcInternalControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS AcpiEcForwardRequest( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID AcpiEcUnload( IN PDRIVER_OBJECT DriverObject ); BOOLEAN AcpiEcGpeServiceRoutine ( IN PVOID GpeVectorObject, IN PVOID ServiceContext ); VOID AcpiEcServiceDevice ( IN PECDATA EcData ); VOID AcpiEcDispatchQueries ( IN PECDATA EcData ); VOID AcpiEcUnloadPending ( IN PECDATA EcData ); NTSTATUS AcpiEcConnectHandler ( IN PECDATA EcData, IN PIRP Irp ); NTSTATUS AcpiEcDisconnectHandler ( IN PECDATA EcData, IN PIRP Irp ); NTSTATUS AcpiEcGetPdo ( IN PECDATA EcData, IN PIRP Irp ); NTSTATUS EXPORT AcpiEcOpRegionHandler ( ULONG AccessType, PVOID OpRegion, ULONG Address, ULONG Size, PULONG Data, ULONG_PTR Context, PACPI_OPREGION_CALLBACK CompletionHandler, PVOID CompletionContext ); NTSTATUS AcpiEcGetAcpiInterfaces ( IN PECDATA EcData ); NTSTATUS AcpiEcGetGpeVector ( IN PECDATA EcData ); NTSTATUS AcpiEcConnectGpeVector ( IN PECDATA EcData ); NTSTATUS AcpiEcDisconnectGpeVector ( IN PECDATA EcData ); NTSTATUS AcpiEcInstallOpRegionHandler ( IN PECDATA EcData ); NTSTATUS AcpiEcRemoveOpRegionHandler ( IN PECDATA EcData ); NTSTATUS AcpiEcForwardIrpAndWait ( IN PECDATA EcData, IN PIRP Irp ); NTSTATUS AcpiEcIoCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PKEVENT pdoIoCompletedEvent ); NTSTATUS AcpiEcAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo ); NTSTATUS AcpiEcStartDevice( IN PDEVICE_OBJECT Fdo, IN PIRP Irp ); NTSTATUS AcpiEcStopDevice( IN PDEVICE_OBJECT Fdo, IN PIRP Irp ); NTSTATUS AcpiEcCreateFdo( IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *NewDeviceObject ); VOID AcpiEcServiceIoLoop ( IN PECDATA EcData ); VOID AcpiEcDispatchQueries ( IN PECDATA EcData ); VOID AcpiEcWatchdogDpc( IN PKDPC Dpc, IN PECDATA EcData, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); VOID AcpiEcLogAction ( PECDATA EcData, UCHAR Action, UCHAR Data ); VOID AcpiEcLogError ( PECDATA EcData, NTSTATUS ErrCode ); // // Io extension macro to just pass on the Irp to a lower driver // #define AcpiEcCallLowerDriver(Status, DeviceObject, Irp) { \ IoSkipCurrentIrpStackLocation(Irp); \ Status = IoCallDriver(DeviceObject,Irp); \ }