📄 smbmisc.c
字号:
IoBuffer->Command,
strBuffer,
&strLength
);
SmbBattRB (
SmbBatt,
IoBuffer->Command,
strBuffer2,
&strLength
);
} while (strcmp (strBuffer, strBuffer2));
RtlInitAnsiString (&ansiString, strBuffer);
RtlAnsiStringToUnicodeString (&unicodeString, &ansiString, FALSE);
ReturnBufferLength = unicodeString.Length;
} else {
status = STATUS_INVALID_BUFFER_SIZE;
}
} else {
// Unsupported Commands
status = STATUS_INVALID_PARAMETER;
}
}
}
SmbBattResetSelectorComm (SmbBatt, oldSelectorState);
SmbBattUnlockDevice (SmbBatt);
SmbBattUnlockSelector (SmbBatt->Selector);
} else if (DeviceExtension->SmbBattFdoType == SmbTypeSubsystem) {
// This is a battery subsystem
SubsystemExt = (PSMB_BATT_SUBSYSTEM) DeviceExtension;
SmbBattLockSelector (SubsystemExt->Selector);
if ((InputLen >= sizeof(SMBBATT_DATA_STRUCT)) && (OutputLen == 0)) {
// This is a write command
status = STATUS_NOT_IMPLEMENTED;
} else if ((InputLen == sizeof(SMBBATT_DATA_STRUCT)) && (OutputLen > 0)){
// This is a Read command
switch (IoBuffer->Address) {
case SMB_SELECTOR_ADDRESS:
//
// We have to do some translation for selector requests depending
// on whether the selector is stand alone or implemented in the
// charger.
//
if ((SubsystemExt->SelectorPresent) && (SubsystemExt->Selector)) {
address = SubsystemExt->Selector->SelectorAddress;
command = IoBuffer->Command;
// Map to Charger if Selector is implemented in the Charger
if (address == SMB_CHARGER_ADDRESS) {
switch (command) {
case SELECTOR_SELECTOR_STATE:
case SELECTOR_SELECTOR_PRESETS:
case SELECTOR_SELECTOR_INFO:
command |= CHARGER_SELECTOR_COMMANDS;
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}
}
} else {
status = STATUS_NO_SUCH_DEVICE;
}
break;
case SMB_CHARGER_ADDRESS:
//
// For this one we currently only support the ChargerStatus and
// ChargerSpecInfo commands.
//
// Other commands are not currently supported.
//
address = IoBuffer->Address;
switch (IoBuffer->Command) {
case CHARGER_SPEC_INFO:
case CHARGER_STATUS:
command = IoBuffer->Command;
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
} // switch (readStruct->Address)
if (status == STATUS_SUCCESS) {
//
// Do the read command
//
smbStatus = SmbBattGenericRW (
SubsystemExt->SmbHcFdo,
address,
command,
&IoBuffer->Data.Ulong
);
if (smbStatus != SMB_STATUS_OK) {
BattPrint (
BAT_ERROR,
("SmbBattDirectDataAccess: Couldn't read from - %x, status - %x\n",
address,
smbStatus)
);
status = STATUS_UNSUCCESSFUL;
}
}
}
SmbBattUnlockSelector (SubsystemExt->Selector);
} else {
status=STATUS_INVALID_DEVICE_REQUEST;
BattPrint (
BAT_ERROR,
("SmbBattDirectDataAccess: Invalid SmbBattFdoType")
);
}
return status;
}
#endif
UCHAR
SmbBattIndex (
IN PBATTERY_SELECTOR Selector,
IN ULONG SelectorNibble,
IN UCHAR SimultaneousIndex
)
/*++
Routine Description:
This routine is provided as a helper routine to determine which
battery is selected in a given selector nibble, based on the number
of batteries supported in the system.
Arguments:
Selector - Structure defining selector address and commands
SelectorNibble - The nibble of the SelectorState, moved to the low
order 4 bits, to check reverse logic on.
SimultaneousIndex - Which batteryindex is requested in simultaneous-
battery situations (0, 1, or 2)
Return Value:
BatteryIndex = 0 - Battery A
1 - Battery B
2 - Battery C
3 - Battery D
FF - No Battery
--*/
{
UCHAR batteryIndex;
PAGED_CODE();
// Assume if SelectorInfo supports 4 batteries, use SelectorBits4 table
if (Selector->SelectorInfo & BATTERY_D_PRESENT) {
batteryIndex = SelectorBits4[SelectorNibble].BatteryIndex;
} else {
batteryIndex = SelectorBits[SelectorNibble].BatteryIndex;
}
// If it's valid
if (batteryIndex != BATTERY_NONE) {
// return index for First Battery
if (SimultaneousIndex == 0) {
return (batteryIndex & 3);
// return index for Second Battery
} else if (SimultaneousIndex == 1) {
batteryIndex = (batteryIndex >> 2) & 3;
if (batteryIndex != BATTERY_A) {
return (batteryIndex);
}
// return index for Third Battery
} else if (SimultaneousIndex == 2) {
batteryIndex = (batteryIndex >> 2) & 3;
if (batteryIndex != BATTERY_A) {
return (batteryIndex);
}
}
}
// return no battery index
return (BATTERY_NONE);
}
BOOLEAN
SmbBattReverseLogic (
IN PBATTERY_SELECTOR Selector,
IN ULONG SelectorNibble
)
/*++
Routine Description:
This routine is provided as a helper routine to determine the reverse
logic on a given selector nibble, based on the number of batteries
supported in the system.
Arguments:
Selector - Structure defining selector address and commands
SelectorNibble - The nibble of the SelectorState, moved to the low
order 4 bits, to check reverse logic on.
Return Value:
FALSE if the nibble is normal
TRUE if the nibble is inverted
--*/
{
PAGED_CODE();
// Assume if SelectorInfo supports 4 batteries, use SelectorBits4 table
if (Selector->SelectorInfo & BATTERY_D_PRESENT) {
return (SelectorBits4[SelectorNibble].ReverseLogic);
} else {
return (SelectorBits[SelectorNibble].ReverseLogic);
}
}
NTSTATUS
SmbBattAcquireGlobalLock (
IN PDEVICE_OBJECT LowerDeviceObject,
OUT PACPI_MANIPULATE_GLOBAL_LOCK_BUFFER GlobalLock
)
/*++
Routine Description:
Call ACPI driver to obtain the global lock
Note: This routine can be called at dispatch level
Arguments:
LowerDeviceObject - The FDO to pass the request to.
Return Value:
Return Value from IOCTL.
--*/
{
NTSTATUS status;
PIRP irp;
PIO_STACK_LOCATION irpSp;
KEVENT event;
BattPrint (BAT_TRACE, ("SmbBattAcquireGlobalLock: Entering\n"));
//
// We wish to acquire the lock
//
GlobalLock->Signature = ACPI_ACQUIRE_GLOBAL_LOCK_SIGNATURE;
GlobalLock->LockObject = NULL;
//
// setup the irp
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoAllocateIrp (LowerDeviceObject->StackSize, FALSE);
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
irpSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_ACPI_ACQUIRE_GLOBAL_LOCK;
irpSp->Parameters.DeviceIoControl.InputBufferLength = sizeof(ACPI_MANIPULATE_GLOBAL_LOCK_BUFFER);
irpSp->Parameters.DeviceIoControl.OutputBufferLength = sizeof(ACPI_MANIPULATE_GLOBAL_LOCK_BUFFER);
irp->AssociatedIrp.SystemBuffer = GlobalLock;
IoSetCompletionRoutine (irp, SmbBattSynchronousRequest, &event, TRUE, TRUE, TRUE);
//
// Send to ACPI driver
//
IoCallDriver (LowerDeviceObject, irp);
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = irp->IoStatus.Status;
IoFreeIrp (irp);
if (!NT_SUCCESS(status)) {
BattPrint(
BAT_ERROR,
("SmbBattAcquireGlobalLock: Acquire Lock failed, status = %08x\n",
status )
);
}
BattPrint (BAT_TRACE, ("SmbBattAcquireGlobalLock: Returning %x\n", status));
return status;
}
NTSTATUS
SmbBattReleaseGlobalLock (
IN PDEVICE_OBJECT LowerDeviceObject,
IN PACPI_MANIPULATE_GLOBAL_LOCK_BUFFER GlobalLock
)
/*++
Routine Description:
Call ACPI driver to release the global lock
Arguments:
LowerDeviceObject - The FDO to pass the request to.
Return Value:
Return Value from IOCTL.
--*/
{
NTSTATUS status;
PIRP irp;
PIO_STACK_LOCATION irpSp;
KEVENT event;
BattPrint (BAT_TRACE, ("SmbBattReleaseGlobalLock: Entering\n"));
//
// We wish to acquire the lock
//
GlobalLock->Signature = ACPI_RELEASE_GLOBAL_LOCK_SIGNATURE;
//
// setup the irp
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoAllocateIrp (LowerDeviceObject->StackSize, FALSE);
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
irpSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_ACPI_RELEASE_GLOBAL_LOCK;
irpSp->Parameters.DeviceIoControl.InputBufferLength = sizeof(ACPI_MANIPULATE_GLOBAL_LOCK_BUFFER);
irpSp->Parameters.DeviceIoControl.OutputBufferLength = sizeof(ACPI_MANIPULATE_GLOBAL_LOCK_BUFFER);
irp->AssociatedIrp.SystemBuffer = GlobalLock;
IoSetCompletionRoutine (irp, SmbBattSynchronousRequest, &event, TRUE, TRUE, TRUE);
//
// Send to ACPI driver
//
IoCallDriver (LowerDeviceObject, irp);
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = irp->IoStatus.Status;
IoFreeIrp (irp);
if (!NT_SUCCESS(status)) {
BattPrint(
BAT_ERROR,
("SmbBattReleaseGlobalLock: Acquire Lock failed, status = %08x\n",
status )
);
}
BattPrint (BAT_TRACE, ("SmbBattReleaseGlobalLock: Returning %x\n", status));
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -