205 lines
4.3 KiB
C
205 lines
4.3 KiB
C
|
#define SMBCLASS 1
|
||
|
|
||
|
#include <wdm.h>
|
||
|
#include <smbus.h>
|
||
|
#include <devioctl.h>
|
||
|
#include <acpiioct.h>
|
||
|
#include <acpimsft.h>
|
||
|
|
||
|
#define _INC_NSOBJ_ONLY
|
||
|
#include <amli.h>
|
||
|
#include <aml.h>
|
||
|
|
||
|
#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); \
|
||
|
}
|
||
|
|
||
|
|