win-pvdrivers

annotate xenpci/xenpci_pdo.c @ 267:f157f82e0293

Continued porting to WDM. vbd is almost working.
author James Harper <james.harper@bendigoit.com.au>
date Mon May 12 00:20:02 2008 +1000 (2008-05-12)
parents b88529df8b60
children 6128d5c1e7a8
rev   line source
james@259 1 /*
james@259 2 PV Drivers for Windows Xen HVM Domains
james@259 3 Copyright (C) 2007 James Harper
james@259 4
james@259 5 This program is free software; you can redistribute it and/or
james@259 6 modify it under the terms of the GNU General Public License
james@259 7 as published by the Free Software Foundation; either version 2
james@259 8 of the License, or (at your option) any later version.
james@259 9
james@259 10 This program is distributed in the hope that it will be useful,
james@259 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
james@259 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
james@259 13 GNU General Public License for more details.
james@259 14
james@259 15 You should have received a copy of the GNU General Public License
james@259 16 along with this program; if not, write to the Free Software
james@259 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
james@259 18 */
james@259 19
james@259 20 #include "xenpci.h"
james@259 21 #include <stdlib.h>
james@267 22 #include <io/ring.h>
james@259 23
james@259 24 #pragma warning(disable : 4200) // zero-sized array
james@267 25 #pragma warning(disable: 4127) // conditional expression is constant
james@259 26
james@259 27 NTSTATUS
james@259 28 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
james@259 29 {
james@259 30 UNREFERENCED_PARAMETER(device_object);
james@259 31
james@259 32 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
james@259 33
james@259 34 irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
james@259 35 IoCompleteRequest(irp, IO_NO_INCREMENT);
james@259 36
james@259 37 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
james@259 38
james@259 39 return irp->IoStatus.Status;
james@259 40 }
james@259 41
james@267 42 static VOID
james@267 43 XenPci_BackEndStateHandler(char *Path, PVOID Context)
james@267 44 {
james@267 45 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)Context;
james@267 46 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
james@267 47 char *value;
james@267 48 char *err;
james@267 49 ULONG new_backend_state;
james@267 50 char path[128];
james@267 51
james@267 52 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
james@267 53
james@267 54 /* check that path == device/id/state */
james@267 55 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
james@267 56 err = XenBus_Read(xpdd, XBT_NIL, Path, &value);
james@267 57 if (err)
james@267 58 {
james@267 59 KdPrint(("Failed to read %s\n", path, err));
james@267 60 return;
james@267 61 }
james@267 62 new_backend_state = atoi(value);
james@267 63 XenPci_FreeMem(value);
james@267 64
james@267 65 if (xppdd->backend_state == new_backend_state)
james@267 66 {
james@267 67 KdPrint((__DRIVER_NAME " state unchanged\n"));
james@267 68 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
james@267 69 return;
james@267 70 }
james@267 71
james@267 72 xppdd->backend_state = new_backend_state;
james@267 73
james@267 74 switch (xppdd->backend_state)
james@267 75 {
james@267 76 case XenbusStateUnknown:
james@267 77 KdPrint((__DRIVER_NAME " Backend State Changed to Unknown\n"));
james@267 78 break;
james@267 79
james@267 80 case XenbusStateInitialising:
james@267 81 KdPrint((__DRIVER_NAME " Backend State Changed to Initialising\n"));
james@267 82 break;
james@267 83
james@267 84 case XenbusStateInitWait:
james@267 85 KdPrint((__DRIVER_NAME " Backend State Changed to InitWait\n"));
james@267 86 break;
james@267 87
james@267 88 case XenbusStateInitialised:
james@267 89 KdPrint((__DRIVER_NAME " Backend State Changed to Initialised\n"));
james@267 90 break;
james@267 91
james@267 92 case XenbusStateConnected:
james@267 93 KdPrint((__DRIVER_NAME " Backend State Changed to Connected\n"));
james@267 94 break;
james@267 95
james@267 96 case XenbusStateClosing:
james@267 97 KdPrint((__DRIVER_NAME " Backend State Changed to Closing\n"));
james@267 98 /* check our current PNP statue - this may be a surprise removal... */
james@267 99 break;
james@267 100
james@267 101 case XenbusStateClosed:
james@267 102 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
james@267 103 break;
james@267 104
james@267 105 default:
james@267 106 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", xppdd->backend_state));
james@267 107 break;
james@267 108 }
james@267 109
james@267 110 KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
james@267 111
james@267 112 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
james@267 113
james@267 114 return;
james@267 115 }
james@267 116
james@267 117 struct dummy_sring {
james@267 118 RING_IDX req_prod, req_event;
james@267 119 RING_IDX rsp_prod, rsp_event;
james@267 120 uint8_t pad[48];
james@267 121 };
james@267 122
james@260 123 static NTSTATUS
james@266 124 XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
james@266 125 {
james@267 126 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
james@267 127 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
james@266 128 PIO_STACK_LOCATION stack;
james@266 129 PCM_PARTIAL_RESOURCE_LIST res_list;
james@266 130 PCM_PARTIAL_RESOURCE_DESCRIPTOR res_descriptor;
james@266 131 ULONG i;
james@267 132 char path[128];
james@267 133 PCHAR setting, value;
james@267 134 PCHAR res;
james@267 135 PMDL mdl;
james@267 136 PVOID address;
james@267 137 grant_ref_t gref;
james@267 138 evtchn_port_t event_channel;
james@267 139 UCHAR type;
james@267 140 PUCHAR in_ptr = NULL, in_start = NULL;
james@267 141 PUCHAR out_ptr, out_start = NULL;
james@267 142 XENPCI_VECTORS vectors;
james@266 143
james@266 144 UNREFERENCED_PARAMETER(device_object);
james@266 145
james@266 146 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
james@266 147
james@266 148 stack = IoGetCurrentIrpStackLocation(irp);
james@266 149
james@267 150 /* Get backend path */
james@267 151 RtlStringCbPrintfA(path, ARRAY_SIZE(path),
james@267 152 "%s/backend", xppdd->path);
james@267 153 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
james@267 154 if (res)
james@267 155 {
james@267 156 KdPrint((__DRIVER_NAME " Failed to read backend path\n"));
james@267 157 XenPci_FreeMem(res);
james@267 158 }
james@267 159 RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
james@267 160 XenPci_FreeMem(value);
james@267 161
james@267 162 /* Add watch on backend state */
james@267 163 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
james@267 164 XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
james@267 165
james@267 166 /* Tell backend we're coming up */
james@267 167 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
james@267 168 XenBus_Printf(xpdd, XBT_NIL, path, "%d", XenbusStateInitialising);
james@267 169
james@267 170 // wait here for signal that we are all set up - we should probably add a timeout to make sure we don't hang forever
james@267 171 while (xppdd->backend_state != XenbusStateInitWait)
james@267 172 KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, NULL);
james@267 173
james@266 174 res_list = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
james@266 175 for (i = 0; i < res_list->Count; i++)
james@266 176 {
james@266 177 res_descriptor = &res_list->PartialDescriptors[i];
james@266 178 switch (res_descriptor->Type)
james@266 179 {
james@266 180 case CmResourceTypeInterrupt:
james@266 181 KdPrint((__DRIVER_NAME " irq_number = %d\n", res_descriptor->u.Interrupt.Vector));
james@267 182 KdPrint((__DRIVER_NAME " irq_level = %03x\n", res_descriptor->u.Interrupt.Level));
james@266 183 break;
james@266 184 }
james@266 185 }
james@266 186
james@266 187 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
james@266 188 for (i = 0; i < res_list->Count; i++)
james@266 189 {
james@266 190 res_descriptor = &res_list->PartialDescriptors[i];
james@266 191 switch (res_descriptor->Type) {
james@266 192 case CmResourceTypeInterrupt:
james@267 193 KdPrint((__DRIVER_NAME " CmResourceTypeInterrupt\n"));
james@267 194 KdPrint((__DRIVER_NAME " irq_vector = %03x\n", res_descriptor->u.Interrupt.Vector));
james@267 195 KdPrint((__DRIVER_NAME " irq_level = %d\n", res_descriptor->u.Interrupt.Level));
james@267 196 xppdd->irq_vector = res_descriptor->u.Interrupt.Vector;
james@267 197 xppdd->irq_level = (KIRQL)res_descriptor->u.Interrupt.Level;
james@266 198 break;
james@267 199 case CmResourceTypeMemory:
james@267 200 KdPrint((__DRIVER_NAME " CmResourceTypeMemory\n"));
james@267 201 KdPrint((__DRIVER_NAME " Start = %08x, Length = %d\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Length));
james@267 202 out_ptr = out_start = MmMapIoSpace(res_descriptor->u.Memory.Start, res_descriptor->u.Memory.Length, MmNonCached);
james@267 203 in_ptr = in_start = ExAllocatePoolWithTag(PagedPool, res_descriptor->u.Memory.Length, XENPCI_POOL_TAG);
james@267 204 memcpy(in_ptr, out_ptr, res_descriptor->u.Memory.Length);
james@267 205
james@267 206 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
james@267 207 {
james@267 208 switch (type)
james@267 209 {
james@267 210 case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
james@267 211 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
james@267 212 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
james@267 213 XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
james@267 214 break;
james@267 215 case XEN_INIT_TYPE_RING: /* frontend ring */
james@267 216 /* we only allocate and do the SHARED_RING_INIT here */
james@267 217 mdl = AllocatePage();
james@267 218 address = MmGetMdlVirtualAddress(mdl);
james@267 219 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
james@267 220 SHARED_RING_INIT((struct dummy_sring *)address);
james@267 221 gref = GntTbl_GrantAccess(xpdd, 0, *MmGetMdlPfnArray(mdl), FALSE, 0);
james@267 222 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
james@267 223 XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
james@267 224 ADD_XEN_INIT_RSP(&out_ptr, type, setting, address);
james@267 225 break;
james@267 226 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
james@267 227 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
james@267 228 event_channel = EvtChn_AllocUnbound(xpdd, 0);
james@267 229 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, event_channel));
james@267 230 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
james@267 231 XenBus_Printf(xpdd, XBT_NIL, path, "%d", event_channel);
james@267 232 ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel));
james@267 233 if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
james@267 234 EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector);
james@267 235 break;
james@267 236 }
james@267 237 }
james@267 238 }
james@267 239 }
james@267 240
james@267 241 /* We are all ready to go */
james@267 242 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
james@267 243 XenBus_Printf(xpdd, XBT_NIL, path, "%d", XenbusStateConnected);
james@267 244
james@267 245 // wait here for signal that we are all set up - we should probably add a timeout to make sure we don't hang forever
james@267 246 while (xppdd->backend_state != XenbusStateConnected)
james@267 247 KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, NULL);
james@267 248
james@267 249 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
james@267 250 for (i = 0; i < res_list->Count; i++)
james@267 251 {
james@267 252 res_descriptor = &res_list->PartialDescriptors[i];
james@267 253 switch (res_descriptor->Type) {
james@267 254 case CmResourceTypeMemory:
james@267 255 in_ptr = in_start;
james@267 256 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
james@267 257 {
james@267 258 switch(type)
james@267 259 {
james@267 260 case XEN_INIT_TYPE_READ_STRING_BACK:
james@267 261 case XEN_INIT_TYPE_READ_STRING_FRONT:
james@267 262 if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
james@267 263 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
james@267 264 else
james@267 265 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
james@267 266 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
james@267 267 if (res)
james@267 268 {
james@267 269 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
james@267 270 XenPci_FreeMem(res);
james@267 271 ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL);
james@267 272 }
james@267 273 else
james@267 274 {
james@267 275 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
james@267 276 ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
james@267 277 XenPci_FreeMem(value);
james@267 278 }
james@267 279 break;
james@267 280 case XEN_INIT_TYPE_VECTORS:
james@267 281 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
james@267 282 vectors.magic = XEN_DATA_MAGIC;
james@267 283 vectors.length = sizeof(XENPCI_VECTORS);
james@267 284 vectors.context = xpdd;
james@267 285 vectors.EvtChn_Bind = EvtChn_Bind;
james@267 286 vectors.EvtChn_BindDpc = EvtChn_BindDpc;
james@267 287 vectors.EvtChn_Unbind = EvtChn_Unbind;
james@267 288 vectors.EvtChn_Mask = EvtChn_Mask;
james@267 289 vectors.EvtChn_Unmask = EvtChn_Unmask;
james@267 290 vectors.EvtChn_Notify = EvtChn_Notify;
james@267 291 vectors.GntTbl_GetRef = GntTbl_GetRef;
james@267 292 vectors.GntTbl_PutRef = GntTbl_PutRef;
james@267 293 vectors.GntTbl_GrantAccess = GntTbl_GrantAccess;
james@267 294 vectors.GntTbl_EndAccess = GntTbl_EndAccess;
james@267 295 ADD_XEN_INIT_RSP(&out_ptr, type, NULL, &vectors);
james@267 296 break;
james@267 297 case XEN_INIT_TYPE_GRANT_ENTRIES:
james@267 298 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(setting)));
james@267 299 __ADD_XEN_INIT_UCHAR(&out_ptr, type);
james@267 300 __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(setting));
james@267 301 for (i = 0; i < PtrToUlong(setting); i++)
james@267 302 __ADD_XEN_INIT_ULONG(&out_ptr, GntTbl_GetRef(xpdd));
james@267 303 break;
james@267 304 }
james@267 305 }
james@267 306 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
james@267 307 MmUnmapIoSpace(out_start, res_descriptor->u.Memory.Length);
james@267 308 ExFreePoolWithTag(in_start, XENPCI_POOL_TAG);
james@266 309 }
james@266 310 }
james@266 311
james@266 312 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
james@266 313
james@266 314 return STATUS_SUCCESS;
james@266 315 }
james@266 316
james@266 317 static NTSTATUS
james@260 318 XenPci_QueryResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
james@260 319 {
james@267 320 //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
james@267 321 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
james@260 322 PIO_RESOURCE_REQUIREMENTS_LIST irrl;
james@260 323 PIO_RESOURCE_DESCRIPTOR ird;
james@260 324 ULONG length;
james@260 325
james@267 326 UNREFERENCED_PARAMETER(device_object);
james@267 327
james@260 328 length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
james@260 329 FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
james@266 330 sizeof(IO_RESOURCE_DESCRIPTOR) * 3;
james@260 331 irrl = ExAllocatePoolWithTag(PagedPool,
james@260 332 length,
james@260 333 XENPCI_POOL_TAG);
james@260 334
james@260 335 irrl->ListSize = length;
james@260 336 irrl->InterfaceType = Internal;
james@260 337 irrl->BusNumber = 0;
james@260 338 irrl->SlotNumber = 0;
james@260 339 irrl->AlternativeLists = 1;
james@260 340 irrl->List[0].Version = 1;
james@260 341 irrl->List[0].Revision = 1;
james@267 342 irrl->List[0].Count = 0;
james@260 343
james@267 344 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
james@260 345 ird->Option = 0;
james@260 346 ird->Type = CmResourceTypeInterrupt;
james@267 347 ird->ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
james@260 348 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
james@260 349 ird->u.Interrupt.MinimumVector = 1;
james@266 350 ird->u.Interrupt.MaximumVector = 6;
james@260 351
james@267 352 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
james@266 353 ird->Option = IO_RESOURCE_ALTERNATIVE;
james@266 354 ird->Type = CmResourceTypeInterrupt;
james@267 355 ird->ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
james@266 356 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
james@267 357 ird->u.Interrupt.MinimumVector = 10;
james@266 358 ird->u.Interrupt.MaximumVector = 14;
james@266 359
james@260 360 irp->IoStatus.Information = (ULONG_PTR)irrl;
james@260 361 return STATUS_SUCCESS;
james@260 362 }
james@260 363
james@261 364 static NTSTATUS
james@261 365 XenPci_Pnp_QueryTargetRelations(PDEVICE_OBJECT device_object, PIRP irp)
james@261 366 {
james@261 367 PDEVICE_RELATIONS dr;
james@261 368 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
james@261 369
james@261 370 dr = (PDEVICE_RELATIONS)ExAllocatePoolWithTag (PagedPool, sizeof(DEVICE_RELATIONS), XENPCI_POOL_TAG);
james@261 371 dr->Count = 1;
james@261 372 dr->Objects[0] = xppdd->common.pdo;
james@261 373 ObReferenceObject(xppdd->common.pdo);
james@261 374 irp->IoStatus.Information = (ULONG_PTR)dr;
james@261 375
james@261 376 return STATUS_SUCCESS;
james@261 377 }
james@261 378
james@261 379 static NTSTATUS
james@261 380 XenPci_Pnp_QueryCapabilities(PDEVICE_OBJECT device_object, PIRP irp)
james@261 381 {
james@261 382 PIO_STACK_LOCATION stack;
james@261 383 PDEVICE_CAPABILITIES dc;
james@261 384
james@261 385 UNREFERENCED_PARAMETER(device_object);
james@261 386
james@261 387 stack = IoGetCurrentIrpStackLocation(irp);
james@261 388 dc = stack->Parameters.DeviceCapabilities.Capabilities;
james@261 389 dc->LockSupported = FALSE;
james@261 390 dc->EjectSupported = FALSE;
james@261 391 dc->Removable = FALSE;
james@261 392 dc->DockDevice = FALSE;
james@261 393 dc->UniqueID = FALSE;
james@261 394 dc->SilentInstall = FALSE;
james@261 395 dc->RawDeviceOK = FALSE;
james@261 396 dc->SurpriseRemovalOK = FALSE;
james@261 397 dc->HardwareDisabled = FALSE;
james@261 398 dc->NoDisplayInUI = FALSE;
james@261 399 dc->DeviceWake = PowerDeviceUnspecified;
james@261 400 dc->D1Latency = 0;
james@261 401 dc->D2Latency = 0;
james@261 402 dc->D3Latency = 0;
james@261 403 /* we are really supposed to get the DeviceState entries from the parent... */
james@261 404 dc->DeviceState[PowerSystemWorking] = PowerDeviceD0;
james@261 405 dc->DeviceState[PowerSystemSleeping1] = PowerDeviceUnspecified;
james@261 406 dc->DeviceState[PowerSystemSleeping2] = PowerDeviceUnspecified;
james@261 407 dc->DeviceState[PowerSystemSleeping3] = PowerDeviceUnspecified;
james@261 408 dc->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
james@261 409 dc->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
james@261 410 return STATUS_SUCCESS;
james@261 411 }
james@261 412
james@259 413 NTSTATUS
james@259 414 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
james@259 415 {
james@259 416 NTSTATUS status;
james@259 417 PIO_STACK_LOCATION stack;
james@259 418 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
james@259 419 LPWSTR buffer;
james@259 420 WCHAR widebuf[256];
james@259 421 unsigned int i;
james@260 422 PPNP_BUS_INFORMATION pbi;
james@259 423
james@259 424 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
james@259 425
james@259 426 stack = IoGetCurrentIrpStackLocation(irp);
james@259 427
james@259 428 switch (stack->MinorFunction)
james@259 429 {
james@259 430 case IRP_MN_START_DEVICE:
james@261 431 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE (status = %08x)\n", irp->IoStatus.Status));
james@266 432 status = XenPci_Pnp_StartDevice(device_object, irp);
james@259 433 break;
james@259 434
james@259 435 case IRP_MN_QUERY_STOP_DEVICE:
james@261 436 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
james@259 437 status = STATUS_SUCCESS;
james@259 438 break;
james@259 439
james@259 440 case IRP_MN_STOP_DEVICE:
james@261 441 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
james@259 442 status = STATUS_SUCCESS;
james@259 443 break;
james@259 444
james@259 445 case IRP_MN_CANCEL_STOP_DEVICE:
james@261 446 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
james@259 447 status = STATUS_SUCCESS;
james@259 448 break;
james@259 449
james@259 450 case IRP_MN_QUERY_REMOVE_DEVICE:
james@261 451 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
james@259 452 status = STATUS_SUCCESS;
james@259 453 break;
james@259 454
james@259 455 case IRP_MN_REMOVE_DEVICE:
james@261 456 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
james@259 457 status = STATUS_SUCCESS;
james@259 458 break;
james@259 459
james@259 460 case IRP_MN_CANCEL_REMOVE_DEVICE:
james@261 461 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
james@259 462 status = STATUS_SUCCESS;
james@259 463 break;
james@259 464
james@259 465 case IRP_MN_SURPRISE_REMOVAL:
james@261 466 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL (status = %08x)\n", irp->IoStatus.Status));
james@259 467 status = STATUS_SUCCESS;
james@259 468 break;
james@259 469
james@259 470 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
james@261 471 KdPrint((__DRIVER_NAME " IRP_MN_DEVICE_USAGE_NOTIFICATION (status = %08x)\n", irp->IoStatus.Status));
james@259 472 status = STATUS_SUCCESS;
james@259 473 break;
james@259 474
james@259 475 case IRP_MN_QUERY_ID:
james@261 476 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_ID (status = %08x)\n", irp->IoStatus.Status));
james@259 477 switch (stack->Parameters.QueryId.IdType)
james@259 478 {
james@259 479 case BusQueryDeviceID: /* REG_SZ */
james@259 480 KdPrint((__DRIVER_NAME " BusQueryDeviceID\n"));
james@259 481 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
james@267 482 for (i = 0; i < strlen(xppdd->device); i++)
james@267 483 widebuf[i] = xppdd->device[i];
james@259 484 widebuf[i] = 0;
james@260 485 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
james@259 486 KdPrint((__DRIVER_NAME " %ls\n", buffer));
james@259 487 irp->IoStatus.Information = (ULONG_PTR)buffer;
james@259 488 status = STATUS_SUCCESS;
james@259 489 break;
james@259 490 case BusQueryHardwareIDs: /* REG_MULTI_SZ */
james@259 491 KdPrint((__DRIVER_NAME " BusQueryHardwareIDs\n"));
james@259 492 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
james@267 493 for (i = 0; i < strlen(xppdd->device); i++)
james@267 494 widebuf[i] = xppdd->device[i];
james@259 495 widebuf[i] = 0;
james@260 496 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
james@260 497 for (i = 0; buffer[i] != 0; i++);
james@260 498 buffer[i + 1] = 0;
james@260 499 // for (i = 0; i < 256; i++)
james@260 500 // KdPrint((__DRIVER_NAME " %04X: %04X %wc\n", i, buffer[i], buffer[i]));
james@259 501 KdPrint((__DRIVER_NAME " %ls\n", buffer));
james@259 502 irp->IoStatus.Information = (ULONG_PTR)buffer;
james@259 503 status = STATUS_SUCCESS;
james@259 504 break;
james@259 505 case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
james@259 506 KdPrint((__DRIVER_NAME " BusQueryCompatibleIDs\n"));
james@259 507 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
james@267 508 for (i = 0; i < strlen(xppdd->device); i++)
james@267 509 widebuf[i] = xppdd->device[i];
james@259 510 widebuf[i] = 0;
james@260 511 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
james@260 512 for (i = 0; buffer[i] != 0; i++);
james@260 513 buffer[i + 1] = 0;
james@259 514 KdPrint((__DRIVER_NAME " %ls\n", buffer));
james@259 515 irp->IoStatus.Information = (ULONG_PTR)buffer;
james@259 516 status = STATUS_SUCCESS;
james@259 517 break;
james@259 518 case BusQueryInstanceID: /* REG_SZ */
james@259 519 KdPrint((__DRIVER_NAME " BusQueryInstanceID\n"));
james@259 520 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
james@259 521 RtlStringCbPrintfW(buffer, 512, L"%02d", xppdd->index);
james@259 522 KdPrint((__DRIVER_NAME " %ls\n", buffer));
james@259 523 irp->IoStatus.Information = (ULONG_PTR)buffer;
james@259 524 status = STATUS_SUCCESS;
james@259 525 break;
james@259 526 default:
james@259 527 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryId.IdType));
james@259 528 irp->IoStatus.Information = 0;
james@259 529 status = STATUS_NOT_SUPPORTED;
james@259 530 break;
james@259 531 }
james@259 532 break;
james@259 533
james@259 534 case IRP_MN_QUERY_DEVICE_TEXT:
james@261 535 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_TEXT (status = %08x)\n", irp->IoStatus.Status));
james@259 536 switch (stack->Parameters.QueryDeviceText.DeviceTextType)
james@259 537 {
james@259 538 case DeviceTextDescription:
james@259 539 KdPrint((__DRIVER_NAME " DeviceTextDescription\n"));
james@260 540 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
james@267 541 for (i = 0; i < strlen(xppdd->device); i++)
james@267 542 widebuf[i] = xppdd->device[i];
james@259 543 widebuf[i] = 0;
james@259 544 RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
james@259 545 KdPrint((__DRIVER_NAME " %ls\n", buffer));
james@259 546 irp->IoStatus.Information = (ULONG_PTR)buffer;
james@259 547 status = STATUS_SUCCESS;
james@259 548 break;
james@259 549 case DeviceTextLocationInformation:
james@259 550 KdPrint((__DRIVER_NAME " DeviceTextLocationInformation\n"));
james@260 551 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
james@259 552 RtlStringCbPrintfW(buffer, 512, L"Xen Bus");
james@259 553 KdPrint((__DRIVER_NAME " %ls\n", buffer));
james@259 554 irp->IoStatus.Information = (ULONG_PTR)buffer;
james@259 555 status = STATUS_SUCCESS;
james@259 556 break;
james@259 557 default:
james@259 558 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryDeviceText.DeviceTextType));
james@259 559 irp->IoStatus.Information = 0;
james@259 560 status = STATUS_NOT_SUPPORTED;
james@259 561 break;
james@259 562 }
james@259 563 break;
james@260 564
james@261 565 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
james@261 566 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCE_REQUIREMENTS (status = %08x)\n", irp->IoStatus.Status));
james@266 567 status = XenPci_QueryResourceRequirements(device_object, irp);
james@261 568 break;
james@260 569
james@261 570 case IRP_MN_QUERY_CAPABILITIES:
james@261 571 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_CAPABILITIES (status = %08x)\n", irp->IoStatus.Status));
james@266 572 status = XenPci_Pnp_QueryCapabilities(device_object, irp);
james@261 573 break;
james@260 574
james@261 575 case IRP_MN_QUERY_BUS_INFORMATION:
james@261 576 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_BUS_INFORMATION (status = %08x)\n", irp->IoStatus.Status));
james@261 577 pbi = (PPNP_BUS_INFORMATION)ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION), XENPCI_POOL_TAG);
james@261 578 pbi->BusTypeGuid = GUID_XENPCI_DEVCLASS;
james@261 579 pbi->LegacyBusType = Internal;
james@261 580 pbi->BusNumber = 0;
james@261 581 irp->IoStatus.Information = (ULONG_PTR)pbi;
james@261 582 status = STATUS_SUCCESS;
james@261 583 break;
james@261 584
james@261 585 case IRP_MN_QUERY_RESOURCES:
james@261 586 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCES (status = %08x)\n", irp->IoStatus.Status));
james@261 587 status = irp->IoStatus.Status;
james@261 588 #if 0
james@261 589 crl = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), XENPCI_POOL_TAG);
james@261 590 crl->Count = 1;
james@261 591 crl->List[0].InterfaceType = Internal;
james@261 592 crl->List[0].BusNumber = 0;
james@261 593 crl->List[0].PartialResourceList.Version = 0;
james@261 594 crl->List[0].PartialResourceList.Revision = 0;
james@261 595 crl->List[0].PartialResourceList.Count = 0;
james@261 596 irp->IoStatus.Information = (ULONG_PTR)crl;
james@261 597 status = STATUS_SUCCESS;
james@261 598 #endif
james@261 599 break;
james@261 600
james@261 601 case IRP_MN_QUERY_PNP_DEVICE_STATE:
james@261 602 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_PNP_DEVICE_STATE (status = %08x)\n", irp->IoStatus.Status));
james@261 603 irp->IoStatus.Information = 0;
james@261 604 status = STATUS_SUCCESS;
james@261 605 break;
james@261 606
james@261 607 case IRP_MN_QUERY_DEVICE_RELATIONS:
james@261 608 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS (status = %08x)\n", irp->IoStatus.Status));
james@261 609 switch (stack->Parameters.QueryDeviceRelations.Type)
james@261 610 {
james@261 611 case TargetDeviceRelation:
james@261 612 KdPrint((__DRIVER_NAME " BusRelations\n"));
james@261 613 status = XenPci_Pnp_QueryTargetRelations(device_object, irp);
james@261 614 break;
james@261 615 default:
james@267 616 /*
james@267 617 KdPrint((__DRIVER_NAME " int 0xb1 (xenvbd) (from xenpci)"));
james@266 618 __asm {
james@266 619 int 0x81
james@267 620 int 0xb1
james@266 621 };
james@267 622 */
james@261 623 status = irp->IoStatus.Status;
james@260 624 break;
james@261 625 }
james@261 626 break;
james@260 627
james@261 628 default:
james@261 629 KdPrint((__DRIVER_NAME " Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
james@261 630 status = irp->IoStatus.Status;
james@261 631 break;
james@259 632 }
james@259 633
james@259 634 irp->IoStatus.Status = status;
james@259 635 IoCompleteRequest(irp, IO_NO_INCREMENT);
james@259 636
james@259 637 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
james@259 638
james@259 639 return status;
james@259 640 }