[CMBATT]
[reactos.git] / reactos / drivers / battery / cmbatt / cmbatt.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/battery/cmbatt/cmbatt.c
5 * PURPOSE: Control Method Battery Miniclass Driver
6 * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
7 */
8
9 #include <cmbatt.h>
10
11 #define NDEBUG
12 #include <debug.h>
13
14 LIST_ENTRY BatteryList;
15 KSPIN_LOCK BatteryListLock;
16
17 VOID
18 NTAPI
19 CmBattUnload(PDRIVER_OBJECT DriverObject)
20 {
21 DPRINT("Control method battery miniclass driver unloaded\n");
22 }
23
24 NTSTATUS
25 NTAPI
26 CmBattDeviceControl(PDEVICE_OBJECT DeviceObject,
27 PIRP Irp)
28 {
29 PCMBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
30 NTSTATUS Status;
31
32 Status = BatteryClassIoctl(DeviceExtension->BattClassHandle,
33 Irp);
34
35 if (Status == STATUS_NOT_SUPPORTED)
36 {
37 Irp->IoStatus.Status = Status;
38 Irp->IoStatus.Information = 0;
39
40 IoCompleteRequest(Irp, IO_NO_INCREMENT);
41 }
42
43 return Status;
44 }
45
46 NTSTATUS
47 NTAPI
48 CmBattPnP(PDEVICE_OBJECT DeviceObject,
49 PIRP Irp)
50 {
51 PCMBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
52
53 UNIMPLEMENTED
54
55 IoSkipCurrentIrpStackLocation(Irp);
56
57 return IoCallDriver(DeviceExtension->Ldo, Irp);
58 }
59
60 NTSTATUS
61 NTAPI
62 CmBattSystemControl(PDEVICE_OBJECT DeviceObject,
63 PIRP Irp)
64 {
65 UNIMPLEMENTED
66
67 Irp->IoStatus.Status = STATUS_WMI_GUID_NOT_FOUND;
68 Irp->IoStatus.Information = 0;
69
70 IoCompleteRequest(Irp, IO_NO_INCREMENT);
71
72 return STATUS_WMI_GUID_NOT_FOUND;
73 }
74
75 NTSTATUS
76 NTAPI
77 CmBattPower(PDEVICE_OBJECT DeviceObject,
78 PIRP Irp)
79 {
80 PCMBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
81
82 UNIMPLEMENTED
83
84 IoSkipCurrentIrpStackLocation(Irp);
85
86 PoStartNextPowerIrp(Irp);
87
88 return PoCallDriver(DeviceExtension->Ldo, Irp);
89 }
90
91 NTSTATUS
92 NTAPI
93 CmBattCreateClose(PDEVICE_OBJECT DeviceObject,
94 PIRP Irp)
95 {
96 Irp->IoStatus.Status = STATUS_SUCCESS;
97 Irp->IoStatus.Information = 0;
98
99 IoCompleteRequest(Irp, IO_NO_INCREMENT);
100
101 return STATUS_SUCCESS;
102 }
103
104 NTSTATUS
105 NTAPI
106 CmBattAddDevice(PDRIVER_OBJECT DriverObject,
107 PDEVICE_OBJECT PhysicalDeviceObject)
108 {
109 NTSTATUS Status;
110 PDEVICE_OBJECT DeviceObject;
111 PCMBATT_DEVICE_EXTENSION DeviceExtension;
112 BATTERY_MINIPORT_INFO BattInfo;
113
114 Status = IoCreateDevice(DriverObject,
115 sizeof(CMBATT_DEVICE_EXTENSION),
116 NULL,
117 FILE_DEVICE_BATTERY,
118 0,
119 FALSE,
120 &DeviceObject);
121 if (!NT_SUCCESS(Status))
122 return Status;
123
124 DeviceExtension = DeviceObject->DeviceExtension;
125
126 DeviceExtension->Pdo = PhysicalDeviceObject;
127 DeviceExtension->Fdo = DeviceObject;
128 DeviceExtension->Ldo = IoAttachDeviceToDeviceStack(DeviceObject,
129 PhysicalDeviceObject);
130
131 DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
132
133 /* We require an extra stack entry */
134 DeviceObject->StackSize = PhysicalDeviceObject->StackSize + 2;
135
136 BattInfo.MajorVersion = BATTERY_CLASS_MAJOR_VERSION;
137 BattInfo.MinorVersion = BATTERY_CLASS_MINOR_VERSION;
138 BattInfo.Context = DeviceExtension;
139 BattInfo.QueryTag = CmBattQueryTag;
140 BattInfo.QueryInformation = CmBattQueryInformation;
141 BattInfo.SetInformation = CmBattSetInformation;
142 BattInfo.QueryStatus = CmBattQueryStatus;
143 BattInfo.SetStatusNotify = CmBattSetStatusNotify;
144 BattInfo.DisableStatusNotify = CmBattDisableStatusNotify;
145 BattInfo.Pdo = PhysicalDeviceObject;
146 BattInfo.DeviceName = NULL;
147
148 Status = BatteryClassInitializeDevice(&BattInfo,
149 &DeviceExtension->BattClassHandle);
150 if (!NT_SUCCESS(Status))
151 {
152 IoDetachDevice(DeviceExtension->Ldo);
153 IoDeleteDevice(DeviceObject);
154 return Status;
155 }
156
157 ExInterlockedInsertTailList(&BatteryList,
158 &DeviceExtension->ListEntry,
159 &BatteryListLock);
160
161 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
162
163 DPRINT("Successfully registered battery with battc (0x%x)\n", DeviceExtension->BattClassHandle);
164
165 return STATUS_SUCCESS;
166 }
167
168 NTSTATUS
169 NTAPI
170 DriverEntry(PDRIVER_OBJECT DriverObject,
171 PUNICODE_STRING RegistryPath)
172 {
173 DPRINT("Control method battery miniclass driver initialized\n");
174
175 DriverObject->DriverUnload = CmBattUnload;
176 DriverObject->DriverExtension->AddDevice = CmBattAddDevice;
177 DriverObject->MajorFunction[IRP_MJ_POWER] = CmBattPower;
178 DriverObject->MajorFunction[IRP_MJ_PNP] = CmBattPnP;
179 DriverObject->MajorFunction[IRP_MJ_CREATE] = CmBattCreateClose;
180 DriverObject->MajorFunction[IRP_MJ_CLOSE] = CmBattCreateClose;
181 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CmBattDeviceControl;
182 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = CmBattSystemControl;
183
184 KeInitializeSpinLock(&BatteryListLock);
185 InitializeListHead(&BatteryList);
186
187 return STATUS_SUCCESS;
188 }