|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
smbpoll.c
Abstract:
Device polling for SMB Host Controller Driver for ALI chipset
Author:
Michael Hills
Environment:
Notes:
Revision History:
--*/
#include "smbalip.h"
VOID SmbAliPollDpc ( IN struct _KDPC *Dpc, IN struct _SMB_CLASS* SmbClass, IN PVOID SystemArgument1, IN PVOID SystemArgument2 );
VOID SmbAliPollWorker ( IN PDEVICE_OBJECT DeviceObject, IN struct _SMB_CLASS* SmbClass );
//LARGE_INTEGER SmbAlertPollRate = {-1*SECONDS, -1}; // 1 second poll rate
LARGE_INTEGER SmbDevicePollRate = {-5*SECONDS, -1}; // 5 second poll rate
LONG SmbDevicePollPeriod = 5000; // 5000 ms = 5 sec
// address, command, protocol, valid_data, last_data
SMB_ALI_POLL_ENTRY SmbDevicePollList [2] = { {0x0b, 0x16, SMB_READ_WORD, FALSE, 0}, // battery, BatteryStatus()
{0x09, 0x13, SMB_READ_WORD, FALSE, 0} // charger, ChargerStatus()
};
VOID SmbAliStartDevicePolling ( IN struct _SMB_CLASS* SmbClass ) { PSMB_ALI_DATA AliData = (PSMB_ALI_DATA)(SmbClass->Miniport);
AliData->PollList = SmbDevicePollList; AliData->PollListCount = sizeof (SmbDevicePollList)/sizeof(SMB_ALI_POLL_ENTRY); AliData->PollWorker = IoAllocateWorkItem (SmbClass->DeviceObject);
KeInitializeTimer (&AliData->PollTimer); KeInitializeDpc (&AliData->PollDpc, SmbAliPollDpc, SmbClass); KeInitializeEvent (&AliData->PollWorkerActive, NotificationEvent, TRUE); KeSetTimerEx (&AliData->PollTimer, SmbDevicePollRate, SmbDevicePollPeriod, &AliData->PollDpc); }
VOID SmbAliStopDevicePolling ( IN struct _SMB_CLASS* SmbClass ) { PSMB_ALI_DATA AliData = (PSMB_ALI_DATA)(SmbClass->Miniport); KeCancelTimer (&AliData->PollTimer); if (KeResetEvent(&AliData->PollWorkerActive) == 0) { KeWaitForSingleObject (&AliData->PollWorkerActive, Executive, KernelMode, FALSE, NULL); } }
VOID SmbAliPollDpc ( IN struct _KDPC *Dpc, IN struct _SMB_CLASS* SmbClass, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ) { PSMB_ALI_DATA AliData = (PSMB_ALI_DATA)(SmbClass->Miniport);
if (KeResetEvent(&AliData->PollWorkerActive) != 0) { IoQueueWorkItem (AliData->PollWorker, SmbAliPollWorker, DelayedWorkQueue, SmbClass); } }
VOID SmbAliPollWorker ( IN PDEVICE_OBJECT DeviceObject, IN struct _SMB_CLASS* SmbClass ) { PSMB_ALI_DATA AliData = (PSMB_ALI_DATA)(SmbClass->Miniport); PIRP irp; SMB_REQUEST smbRequest; IO_STATUS_BLOCK ioStatus; KEVENT event; ULONG i;
KeInitializeEvent (&event, SynchronizationEvent, FALSE);
SmbPrint(SMB_TRACE, ("SmbAliPollWorker: Entered\n"));
for (i = 0; i < AliData->PollListCount; i++) { smbRequest.Protocol = AliData->PollList[i].Protocol; smbRequest.Address = AliData->PollList[i].Address; smbRequest.Command = AliData->PollList[i].Command; irp = IoBuildDeviceIoControlRequest ( SMB_BUS_REQUEST, SmbClass->DeviceObject, &smbRequest, sizeof (smbRequest), &smbRequest, sizeof (smbRequest), TRUE, &event, &ioStatus);
if (!irp) { continue; }
IoCallDriver (SmbClass->DeviceObject, irp);
KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
if (!NT_SUCCESS(ioStatus.Status)) { continue; } if (smbRequest.Status != SMB_STATUS_OK) { if (AliData->PollList[i].ValidData) { AliData->PollList[i].ValidData = FALSE; } } else { //BUGBUG: only supports word protocols
if ((!AliData->PollList[i].ValidData) || (AliData->PollList[i].LastData != *((PUSHORT)smbRequest.Data))) { AliData->PollList[i].ValidData = TRUE; AliData->PollList[i].LastData = *((PUSHORT)smbRequest.Data); SmbPrint(SMB_TRACE, ("SmbAliPollWorker: Alarm: Address 0x%02x Data 0x%04x\n", AliData->PollList[i].Address, AliData->PollList[i].LastData)); SmbClassLockDevice (SmbClass); SmbClassAlarm (SmbClass, AliData->PollList[i].Address, AliData->PollList[i].LastData); SmbClassUnlockDevice (SmbClass); } SmbPrint(SMB_TRACE, ("SmbAliPollWorker: AlarmData: Address 0x%02x Data 0x%04x\n", AliData->PollList[i].Address, AliData->PollList[i].LastData)); } }
KeSetEvent (&AliData->PollWorkerActive, 0, FALSE); }
|