#define SMBCLASS 1 #include #include #include #include #include #define _INC_NSOBJ_ONLY #include #include #if DBG #define DEBUG 1 #else #define DEBUG 0 #endif // // Debug // extern ULONG SMBCDebug; #if DEBUG #define SmbPrint(l,m) if(l & SMBCDebug) DbgPrint m #define ASSERT_DEVICE_LOCKED(a) ASSERT(a->SpinLockAcquired); #else #define SmbPrint(l,m) #define ASSERT_DEVICE_LOCKED(a) #endif #define SMB_LOW 0x00000010 #define SMB_STATE 0x00000020 #define SMB_HANDLER 0x00000040 #define SMB_ALARMS 0x00000080 #define SMB_NOTE 0x00000001 #define SMB_WARN 0x00000002 #define SMB_ERROR 0x00000004 #define SMB_ERRORS (SMB_ERROR | SMB_WARN) #define SMB_TRANSACTION 0x00000100 // // Internal SMB class data // #define MAX_RETRIES 5 #define RETRY_TIME -800000 // Delay 80ms //typedef //VOID //(*SMB_ALARM_NOTIFY)( // IN PVOID Context, // IN USHORT AlarmData // ); typedef struct { LIST_ENTRY Link; // List of all alarm notifies UCHAR Flag; UCHAR Reference; UCHAR MinAddress; // Min address on bus UCHAR MaxAddress; // Max address SMB_ALARM_NOTIFY NotifyFunction; PVOID NotifyContext; } SMB_ALARM, *PSMB_ALARM; #define SMBC_ALARM_DELETE_PENDING 0x01 typedef struct { SMB_CLASS Class; // Shared Class/Miniport data KSPIN_LOCK SpinLock; // Lock device data KIRQL SpinLockIrql; // Irql spinlock acquired at BOOLEAN SpinLockAcquired; // Debug only // // Alarm notifies // LIST_ENTRY Alarms; // List of all Alarm notifies KEVENT AlarmEvent; // Used to delete alarms // // IO // LIST_ENTRY WorkQueue; // Queued IO IRPs to the device BOOLEAN InService; // Irp UCHAR IoState; // // Current IO request // UCHAR RetryCount; KTIMER RetryTimer; KDPC RetryDpc; // // Operation Region // PVOID RawOperationRegionObject; } SMBDATA, *PSMBDATA; // // IoState // #define SMBC_IDLE 0 #define SMBC_START_REQUEST 1 #define SMBC_WAITING_FOR_REQUEST 2 #define SMBC_COMPLETE_REQUEST 3 #define SMBC_COMPLETING_REQUEST 4 #define SMBC_WAITING_FOR_RETRY 5 // // ACPI SMBus opregion details // typedef struct { UCHAR Status; UCHAR Length; UCHAR Data [32]; } BUFFERACC_BUFFER, *PBUFFERACC_BUFFER; #define SMB_QUICK 0x02 #define SMB_SEND_RECEIVE 0x04 #define SMB_BYTE 0x06 #define SMB_WORD 0x08 #define SMB_BLOCK 0x0a #define SMB_PROCESS 0x0c #define SMB_BLOCK_PROCESS 0x0d // // Prototypes // VOID SmbClassStartIo ( IN PSMBDATA Smb ); VOID SmbCRetry ( IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); NTSTATUS SmbCRegisterAlarm ( PSMBDATA Smb, PIRP Irp ); NTSTATUS SmbCDeregisterAlarm ( PSMBDATA Smb, PIRP Irp ); NTSTATUS EXPORT SmbCRawOpRegionHandler ( ULONG AccessType, PFIELDUNITOBJ FieldUnit, POBJDATA Data, ULONG_PTR Context, PACPI_OPREGION_CALLBACK CompletionHandler, PVOID CompletionContext ); NTSTATUS SmbCRawOpRegionCompletion ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS SmbCSynchronousRequest ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PKEVENT IoCompletionEvent ); // // Io extension macro to just pass on the Irp to a lower driver // #define SmbCallLowerDriver(Status, DeviceObject, Irp) { \ IoSkipCurrentIrpStackLocation(Irp); \ Status = IoCallDriver(DeviceObject,Irp); \ }