win-pvdrivers

view xenpci/xenpci_pdo.c @ 266:b88529df8b60

More wdm updates
author James Harper <james.harper@bendigoit.com.au>
date Wed May 07 10:47:03 2008 +1000 (2008-05-07)
parents aef4bd71120b
children f157f82e0293
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenpci.h"
21 #include <stdlib.h>
23 #pragma warning(disable : 4200) // zero-sized array
25 NTSTATUS
26 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
27 {
28 UNREFERENCED_PARAMETER(device_object);
30 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
32 irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
33 IoCompleteRequest(irp, IO_NO_INCREMENT);
35 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
37 return irp->IoStatus.Status;
38 }
40 static NTSTATUS
41 XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
42 {
43 PIO_STACK_LOCATION stack;
44 PCM_PARTIAL_RESOURCE_LIST res_list;
45 PCM_PARTIAL_RESOURCE_DESCRIPTOR res_descriptor;
46 ULONG i;
48 UNREFERENCED_PARAMETER(device_object);
50 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
52 stack = IoGetCurrentIrpStackLocation(irp);
54 res_list = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
55 for (i = 0; i < res_list->Count; i++)
56 {
57 res_descriptor = &res_list->PartialDescriptors[i];
58 switch (res_descriptor->Type)
59 {
60 case CmResourceTypeInterrupt:
61 KdPrint((__DRIVER_NAME " irq_number = %d\n", res_descriptor->u.Interrupt.Vector));
62 break;
63 }
64 }
66 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
67 for (i = 0; i < res_list->Count; i++)
68 {
69 res_descriptor = &res_list->PartialDescriptors[i];
70 switch (res_descriptor->Type) {
71 case CmResourceTypeInterrupt:
72 KdPrint((__DRIVER_NAME " irq_vector = %d\n", res_descriptor->u.Interrupt.Vector));
73 break;
74 }
75 }
77 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
79 return STATUS_SUCCESS;
80 }
82 static NTSTATUS
83 XenPci_QueryResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
84 {
85 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
86 PIO_RESOURCE_REQUIREMENTS_LIST irrl;
87 PIO_RESOURCE_DESCRIPTOR ird;
88 ULONG length;
90 length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
91 FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
92 sizeof(IO_RESOURCE_DESCRIPTOR) * 3;
93 irrl = ExAllocatePoolWithTag(PagedPool,
94 length,
95 XENPCI_POOL_TAG);
97 irrl->ListSize = length;
98 irrl->InterfaceType = Internal;
99 irrl->BusNumber = 0;
100 irrl->SlotNumber = 0;
101 irrl->AlternativeLists = 1;
102 irrl->List[0].Version = 1;
103 irrl->List[0].Revision = 1;
104 irrl->List[0].Count = 3;
106 ird = &irrl->List[0].Descriptors[0];
107 ird->Option = 0;
108 ird->Type = CmResourceTypeInterrupt;
109 ird->ShareDisposition = CmResourceShareDeviceExclusive;
110 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
111 ird->u.Interrupt.MinimumVector = 1;
112 ird->u.Interrupt.MaximumVector = 6;
114 ird = &irrl->List[0].Descriptors[1];
115 ird->Option = IO_RESOURCE_ALTERNATIVE;
116 ird->Type = CmResourceTypeInterrupt;
117 ird->ShareDisposition = CmResourceShareDeviceExclusive;
118 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
119 ird->u.Interrupt.MinimumVector = 8;
120 ird->u.Interrupt.MaximumVector = 14;
122 //irq 7 = 0x93
123 //irq 11 = 0x81
124 //irq ? = 0x52 mouse
125 //irq ? = 0xb3 keybouard
126 //irq ? = 0x72 atapi
127 //irq ? = 0x92 atappi
128 //irq 28 = 0x83 xen - 0x183
130 ird = &irrl->List[0].Descriptors[2];
131 ird->Option = 0;
132 ird->Type = CmResourceTypeMemory;
133 ird->ShareDisposition = CmResourceShareShared;
134 ird->Flags = CM_RESOURCE_MEMORY_READ_WRITE; //|CM_RESOURCE_MEMORY_PREFETCHABLE|CM_RESOURCE_MEMORY_CACHEABLE;
135 ird->u.Memory.Length = PAGE_SIZE;
136 ird->u.Memory.Alignment = PAGE_SIZE;
137 ird->u.Memory.MinimumAddress.QuadPart = xppdd->mmio_phys.QuadPart;
138 ird->u.Memory.MaximumAddress.QuadPart = xppdd->mmio_phys.QuadPart + PAGE_SIZE - 1;
140 irp->IoStatus.Information = (ULONG_PTR)irrl;
141 return STATUS_SUCCESS;
142 }
144 static NTSTATUS
145 XenPci_Pnp_QueryTargetRelations(PDEVICE_OBJECT device_object, PIRP irp)
146 {
147 PDEVICE_RELATIONS dr;
148 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
150 dr = (PDEVICE_RELATIONS)ExAllocatePoolWithTag (PagedPool, sizeof(DEVICE_RELATIONS), XENPCI_POOL_TAG);
151 dr->Count = 1;
152 dr->Objects[0] = xppdd->common.pdo;
153 ObReferenceObject(xppdd->common.pdo);
154 irp->IoStatus.Information = (ULONG_PTR)dr;
156 return STATUS_SUCCESS;
157 }
159 static NTSTATUS
160 XenPci_Pnp_QueryCapabilities(PDEVICE_OBJECT device_object, PIRP irp)
161 {
162 PIO_STACK_LOCATION stack;
163 PDEVICE_CAPABILITIES dc;
165 UNREFERENCED_PARAMETER(device_object);
167 stack = IoGetCurrentIrpStackLocation(irp);
168 dc = stack->Parameters.DeviceCapabilities.Capabilities;
169 dc->LockSupported = FALSE;
170 dc->EjectSupported = FALSE;
171 dc->Removable = FALSE;
172 dc->DockDevice = FALSE;
173 dc->UniqueID = FALSE;
174 dc->SilentInstall = FALSE;
175 dc->RawDeviceOK = FALSE;
176 dc->SurpriseRemovalOK = FALSE;
177 dc->HardwareDisabled = FALSE;
178 dc->NoDisplayInUI = FALSE;
179 dc->DeviceWake = PowerDeviceUnspecified;
180 dc->D1Latency = 0;
181 dc->D2Latency = 0;
182 dc->D3Latency = 0;
183 /* we are really supposed to get the DeviceState entries from the parent... */
184 dc->DeviceState[PowerSystemWorking] = PowerDeviceD0;
185 dc->DeviceState[PowerSystemSleeping1] = PowerDeviceUnspecified;
186 dc->DeviceState[PowerSystemSleeping2] = PowerDeviceUnspecified;
187 dc->DeviceState[PowerSystemSleeping3] = PowerDeviceUnspecified;
188 dc->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
189 dc->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
190 return STATUS_SUCCESS;
191 }
193 NTSTATUS
194 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
195 {
196 NTSTATUS status;
197 PIO_STACK_LOCATION stack;
198 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
199 LPWSTR buffer;
200 WCHAR widebuf[256];
201 unsigned int i;
202 PPNP_BUS_INFORMATION pbi;
203 PCM_RESOURCE_LIST crl;
204 KIRQL old_irql;
206 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
208 stack = IoGetCurrentIrpStackLocation(irp);
210 switch (stack->MinorFunction)
211 {
212 case IRP_MN_START_DEVICE:
213 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE (status = %08x)\n", irp->IoStatus.Status));
214 status = XenPci_Pnp_StartDevice(device_object, irp);
215 break;
217 case IRP_MN_QUERY_STOP_DEVICE:
218 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
219 status = STATUS_SUCCESS;
220 break;
222 case IRP_MN_STOP_DEVICE:
223 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
224 status = STATUS_SUCCESS;
225 break;
227 case IRP_MN_CANCEL_STOP_DEVICE:
228 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
229 status = STATUS_SUCCESS;
230 break;
232 case IRP_MN_QUERY_REMOVE_DEVICE:
233 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
234 status = STATUS_SUCCESS;
235 break;
237 case IRP_MN_REMOVE_DEVICE:
238 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
239 status = STATUS_SUCCESS;
240 break;
242 case IRP_MN_CANCEL_REMOVE_DEVICE:
243 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
244 status = STATUS_SUCCESS;
245 break;
247 case IRP_MN_SURPRISE_REMOVAL:
248 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL (status = %08x)\n", irp->IoStatus.Status));
249 status = STATUS_SUCCESS;
250 break;
252 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
253 KdPrint((__DRIVER_NAME " IRP_MN_DEVICE_USAGE_NOTIFICATION (status = %08x)\n", irp->IoStatus.Status));
254 status = STATUS_SUCCESS;
255 break;
257 case IRP_MN_QUERY_ID:
258 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_ID (status = %08x)\n", irp->IoStatus.Status));
259 switch (stack->Parameters.QueryId.IdType)
260 {
261 case BusQueryDeviceID: /* REG_SZ */
262 KdPrint((__DRIVER_NAME " BusQueryDeviceID\n"));
263 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
264 for (i = 0; i < strlen(xppdd->path); i++)
265 widebuf[i] = xppdd->path[i];
266 widebuf[i] = 0;
267 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
268 KdPrint((__DRIVER_NAME " %ls\n", buffer));
269 irp->IoStatus.Information = (ULONG_PTR)buffer;
270 status = STATUS_SUCCESS;
271 break;
272 case BusQueryHardwareIDs: /* REG_MULTI_SZ */
273 KdPrint((__DRIVER_NAME " BusQueryHardwareIDs\n"));
274 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
275 for (i = 0; i < strlen(xppdd->path); i++)
276 widebuf[i] = xppdd->path[i];
277 widebuf[i] = 0;
278 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
279 for (i = 0; buffer[i] != 0; i++);
280 buffer[i + 1] = 0;
281 // for (i = 0; i < 256; i++)
282 // KdPrint((__DRIVER_NAME " %04X: %04X %wc\n", i, buffer[i], buffer[i]));
283 KdPrint((__DRIVER_NAME " %ls\n", buffer));
284 irp->IoStatus.Information = (ULONG_PTR)buffer;
285 status = STATUS_SUCCESS;
286 break;
287 case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
288 KdPrint((__DRIVER_NAME " BusQueryCompatibleIDs\n"));
289 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
290 for (i = 0; i < strlen(xppdd->path); i++)
291 widebuf[i] = xppdd->path[i];
292 widebuf[i] = 0;
293 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
294 for (i = 0; buffer[i] != 0; i++);
295 buffer[i + 1] = 0;
296 KdPrint((__DRIVER_NAME " %ls\n", buffer));
297 irp->IoStatus.Information = (ULONG_PTR)buffer;
298 status = STATUS_SUCCESS;
299 break;
300 case BusQueryInstanceID: /* REG_SZ */
301 KdPrint((__DRIVER_NAME " BusQueryInstanceID\n"));
302 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
303 RtlStringCbPrintfW(buffer, 512, L"%02d", xppdd->index);
304 KdPrint((__DRIVER_NAME " %ls\n", buffer));
305 irp->IoStatus.Information = (ULONG_PTR)buffer;
306 status = STATUS_SUCCESS;
307 break;
308 default:
309 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryId.IdType));
310 irp->IoStatus.Information = 0;
311 status = STATUS_NOT_SUPPORTED;
312 break;
313 }
314 break;
316 case IRP_MN_QUERY_DEVICE_TEXT:
317 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_TEXT (status = %08x)\n", irp->IoStatus.Status));
318 switch (stack->Parameters.QueryDeviceText.DeviceTextType)
319 {
320 case DeviceTextDescription:
321 KdPrint((__DRIVER_NAME " DeviceTextDescription\n"));
322 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
323 for (i = 0; i < strlen(xppdd->path); i++)
324 widebuf[i] = xppdd->path[i];
325 widebuf[i] = 0;
326 RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
327 KdPrint((__DRIVER_NAME " %ls\n", buffer));
328 irp->IoStatus.Information = (ULONG_PTR)buffer;
329 status = STATUS_SUCCESS;
330 break;
331 case DeviceTextLocationInformation:
332 KdPrint((__DRIVER_NAME " DeviceTextLocationInformation\n"));
333 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
334 RtlStringCbPrintfW(buffer, 512, L"Xen Bus");
335 KdPrint((__DRIVER_NAME " %ls\n", buffer));
336 irp->IoStatus.Information = (ULONG_PTR)buffer;
337 status = STATUS_SUCCESS;
338 break;
339 default:
340 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryDeviceText.DeviceTextType));
341 irp->IoStatus.Information = 0;
342 status = STATUS_NOT_SUPPORTED;
343 break;
344 }
345 break;
347 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
348 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCE_REQUIREMENTS (status = %08x)\n", irp->IoStatus.Status));
349 status = XenPci_QueryResourceRequirements(device_object, irp);
350 break;
352 case IRP_MN_QUERY_CAPABILITIES:
353 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_CAPABILITIES (status = %08x)\n", irp->IoStatus.Status));
354 status = XenPci_Pnp_QueryCapabilities(device_object, irp);
355 break;
357 case IRP_MN_QUERY_BUS_INFORMATION:
358 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_BUS_INFORMATION (status = %08x)\n", irp->IoStatus.Status));
359 pbi = (PPNP_BUS_INFORMATION)ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION), XENPCI_POOL_TAG);
360 pbi->BusTypeGuid = GUID_XENPCI_DEVCLASS;
361 pbi->LegacyBusType = Internal;
362 pbi->BusNumber = 0;
363 irp->IoStatus.Information = (ULONG_PTR)pbi;
364 status = STATUS_SUCCESS;
365 break;
367 case IRP_MN_QUERY_RESOURCES:
368 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCES (status = %08x)\n", irp->IoStatus.Status));
369 status = irp->IoStatus.Status;
370 #if 0
371 crl = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), XENPCI_POOL_TAG);
372 crl->Count = 1;
373 crl->List[0].InterfaceType = Internal;
374 crl->List[0].BusNumber = 0;
375 crl->List[0].PartialResourceList.Version = 0;
376 crl->List[0].PartialResourceList.Revision = 0;
377 crl->List[0].PartialResourceList.Count = 0;
378 irp->IoStatus.Information = (ULONG_PTR)crl;
379 status = STATUS_SUCCESS;
380 #endif
381 break;
383 case IRP_MN_QUERY_PNP_DEVICE_STATE:
384 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_PNP_DEVICE_STATE (status = %08x)\n", irp->IoStatus.Status));
385 irp->IoStatus.Information = 0;
386 status = STATUS_SUCCESS;
387 break;
389 case IRP_MN_QUERY_DEVICE_RELATIONS:
390 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS (status = %08x)\n", irp->IoStatus.Status));
391 switch (stack->Parameters.QueryDeviceRelations.Type)
392 {
393 case TargetDeviceRelation:
394 KdPrint((__DRIVER_NAME " BusRelations\n"));
395 status = XenPci_Pnp_QueryTargetRelations(device_object, irp);
396 break;
397 default:
398 KeRaiseIrql(7, &old_irql);
399 KdPrint((__DRIVER_NAME " int 0x81 (xenvbd) (from xenpci)"));
400 __asm {
401 int 0x81
402 };
403 KeLowerIrql(old_irql);
405 KeRaiseIrql(7, &old_irql);
406 KdPrint((__DRIVER_NAME " int 0x81 (xenvbd) (from xenpci)"));
407 __asm {
408 cli
409 int 0x81
410 sti
411 };
412 KeLowerIrql(old_irql);
414 status = irp->IoStatus.Status;
415 break;
416 }
417 break;
419 default:
420 KdPrint((__DRIVER_NAME " Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
421 status = irp->IoStatus.Status;
422 break;
423 }
425 irp->IoStatus.Status = status;
426 IoCompleteRequest(irp, IO_NO_INCREMENT);
428 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
430 return status;
431 }