win-pvdrivers

annotate xenenum/xenenum.c @ 76:dfa772949c6e

Working on xennet
author James Harper <james.harper@bendigoit.com.au>
date Thu Dec 27 22:23:33 2007 +1100 (2007-12-27)
parents b7863ede7a37
children b9b4b731f890
rev   line source
james@75 1 #include "xenenum.h"
james@75 2 #include <io/blkif.h>
james@75 3 #include <srb.h>
james@75 4 #include <scsi.h>
james@75 5 #include <ntddscsi.h>
james@75 6 #include <ntdddisk.h>
james@75 7 #include <stdlib.h>
james@75 8 #include <xen_public.h>
james@75 9 #include <io/xenbus.h>
james@75 10 #include <ntddft.h>
james@75 11
james@75 12 #define wmb() KeMemoryBarrier()
james@75 13 #define mb() KeMemoryBarrier()
james@75 14
james@75 15 DRIVER_INITIALIZE DriverEntry;
james@75 16
james@75 17 static NTSTATUS
james@75 18 XenEnum_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
james@75 19 static NTSTATUS
james@75 20 XenEnum_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
james@75 21 static NTSTATUS
james@75 22 XenEnum_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
james@75 23 static NTSTATUS
james@75 24 XenEnum_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
james@75 25 static NTSTATUS
james@75 26 XenEnum_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
james@75 27 static NTSTATUS
james@75 28 XenEnum_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
james@75 29 static NTSTATUS
james@75 30 XenEnum_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath);
james@75 31
james@75 32 static NTSTATUS
james@75 33 XenEnum_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
james@75 34
james@75 35 static VOID
james@75 36 XenEnum_WatchHandler(char *Path, PVOID Data);
james@75 37
james@75 38 #ifdef ALLOC_PRAGMA
james@75 39 #pragma alloc_text (INIT, DriverEntry)
james@75 40 #pragma alloc_text (PAGE, XenEnum_AddDevice)
james@75 41 #endif
james@75 42
james@75 43 LIST_ENTRY DeviceListHead;
james@75 44 //XEN_IFACE_EVTCHN EvtChnInterface;
james@75 45 //XEN_IFACE_XENBUS XenBusInterface;
james@75 46 XEN_IFACE XenInterface;
james@75 47 //XEN_IFACE_GNTTBL GntTblInterface;
james@75 48
james@75 49 static BOOLEAN AutoEnumerate;
james@75 50
james@75 51 NTSTATUS
james@75 52 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
james@75 53 {
james@75 54 WDF_DRIVER_CONFIG config;
james@75 55 ULONG status;
james@75 56 UNICODE_STRING RegKeyName;
james@75 57 UNICODE_STRING RegValueName;
james@75 58 HANDLE RegHandle;
james@75 59 OBJECT_ATTRIBUTES RegObjectAttributes;
james@75 60 char Buf[200];
james@75 61 ULONG BufLen = 200;
james@75 62 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
james@75 63 int State = 0;
james@75 64 int StartPos = 0;
james@75 65 WCHAR *SystemStartOptions;
james@75 66 size_t SystemStartOptionsLen;
james@75 67 size_t i;
james@75 68
james@75 69 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
james@75 70
james@75 71 WDF_DRIVER_CONFIG_INIT(&config, XenEnum_AddDevice);
james@75 72 status = WdfDriverCreate(
james@75 73 DriverObject,
james@75 74 RegistryPath,
james@75 75 WDF_NO_OBJECT_ATTRIBUTES,
james@75 76 &config,
james@75 77 WDF_NO_HANDLE);
james@75 78 if(!NT_SUCCESS(status))
james@75 79 {
james@75 80 KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
james@75 81 }
james@75 82
james@75 83 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
james@75 84 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
james@75 85 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
james@75 86 if(!NT_SUCCESS(status))
james@75 87 {
james@75 88 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
james@75 89 }
james@75 90
james@75 91 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
james@75 92 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
james@75 93 if(!NT_SUCCESS(status))
james@75 94 {
james@75 95 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
james@75 96 }
james@75 97 //KdPrint((__DRIVER_NAME " BufLen = %d\n", BufLen));
james@75 98 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
james@75 99 KdPrint((__DRIVER_NAME " Buf = %ws\n", KeyPartialValue->Data));
james@75 100 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
james@75 101
james@75 102 AutoEnumerate = FALSE;
james@75 103
james@75 104 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
james@75 105
james@75 106 for (i = 0; i <= SystemStartOptionsLen/2; i++)
james@75 107 {
james@75 108 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
james@75 109
james@75 110 switch (State)
james@75 111 {
james@75 112 case 0:
james@75 113 if (SystemStartOptions[i] == L'G')
james@75 114 {
james@75 115 StartPos = i;
james@75 116 State = 2;
james@75 117 } else if (SystemStartOptions[i] != L' ')
james@75 118 {
james@75 119 State = 1;
james@75 120 }
james@75 121 break;
james@75 122 case 1:
james@75 123 if (SystemStartOptions[i] == L' ')
james@75 124 State = 0;
james@75 125 break;
james@75 126 case 2:
james@75 127 if (SystemStartOptions[i] == L'P')
james@75 128 State = 3;
james@75 129 else
james@75 130 State = 0;
james@75 131 break;
james@75 132 case 3:
james@75 133 if (SystemStartOptions[i] == L'L')
james@75 134 State = 4;
james@75 135 else
james@75 136 State = 0;
james@75 137 break;
james@75 138 case 4:
james@75 139 if (SystemStartOptions[i] == L'P')
james@75 140 State = 5;
james@75 141 else
james@75 142 State = 0;
james@75 143 break;
james@75 144 case 5:
james@75 145 if (SystemStartOptions[i] == L'V')
james@75 146 State = 6;
james@75 147 else
james@75 148 State = 0;
james@75 149 break;
james@75 150 case 6:
james@75 151 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
james@75 152 AutoEnumerate = TRUE;
james@75 153 State = 0;
james@75 154 break;
james@75 155 }
james@75 156 }
james@75 157
james@75 158 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
james@75 159
james@75 160 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
james@75 161
james@75 162 return status;
james@75 163 }
james@75 164
james@75 165 DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
james@75 166
james@75 167 static WDFDEVICE GlobalDevice;
james@75 168 static PDEVICE_OBJECT Pdo;
james@75 169
james@75 170 static NTSTATUS
james@75 171 XenEnum_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit)
james@75 172 {
james@75 173 WDF_CHILD_LIST_CONFIG ChildListConfig;
james@75 174 NTSTATUS status;
james@75 175 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
james@75 176 PNP_BUS_INFORMATION BusInfo;
james@75 177
james@75 178 UNREFERENCED_PARAMETER(Driver);
james@75 179
james@75 180 KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
james@75 181
james@75 182 Pdo = WdfFdoInitWdmGetPhysicalDevice(DeviceInit);
james@75 183
james@75 184 WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
james@75 185 WDF_CHILD_LIST_CONFIG_INIT(&ChildListConfig, sizeof(XENPCI_IDENTIFICATION_DESCRIPTION), XenEnum_ChildListCreateDevice);
james@75 186 WdfFdoInitSetDefaultChildListConfig(DeviceInit, &ChildListConfig, WDF_NO_OBJECT_ATTRIBUTES);
james@75 187 WdfDeviceInitSetExclusive(DeviceInit, FALSE);
james@75 188
james@75 189 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
james@75 190 pnpPowerCallbacks.EvtDevicePrepareHardware = XenEnum_PrepareHardware;
james@75 191 pnpPowerCallbacks.EvtDeviceReleaseHardware = XenEnum_ReleaseHardware;
james@75 192 pnpPowerCallbacks.EvtDeviceD0Entry = XenEnum_D0Entry;
james@75 193 pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenEnum_D0EntryPostInterruptsEnabled;
james@75 194 pnpPowerCallbacks.EvtDeviceD0Exit = XenEnum_D0Exit;
james@75 195 pnpPowerCallbacks.EvtDeviceUsageNotification = XenEnum_DeviceUsageNotification;
james@75 196 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
james@75 197
james@75 198 /*create a device instance.*/
james@75 199 status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &GlobalDevice);
james@75 200 if(!NT_SUCCESS(status))
james@75 201 {
james@75 202 KdPrint((__DRIVER_NAME "WdfDeviceCreate failed with status 0x%08x\n", status));
james@75 203 return status;
james@75 204 }
james@75 205
james@75 206 BusInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
james@75 207 BusInfo.LegacyBusType = Internal;
james@75 208 BusInfo.BusNumber = 0;
james@75 209
james@75 210 WdfDeviceSetBusInformationForChildren(GlobalDevice, &BusInfo);
james@75 211
james@75 212 /*
james@75 213 WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFilePaging, TRUE);
james@75 214 WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileHibernation, TRUE);
james@75 215 WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileDump, TRUE);
james@75 216 */
james@75 217
james@75 218 status = STATUS_SUCCESS;
james@75 219
james@75 220 KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
james@75 221 return status;
james@75 222 }
james@75 223
james@75 224 static NTSTATUS
james@75 225 XenEnum_PrepareHardware(
james@75 226 IN WDFDEVICE Device,
james@75 227 IN WDFCMRESLIST ResourceList,
james@75 228 IN WDFCMRESLIST ResourceListTranslated)
james@75 229 {
james@75 230 NTSTATUS status = STATUS_SUCCESS;
james@75 231
james@75 232 UNREFERENCED_PARAMETER(ResourceList);
james@75 233 UNREFERENCED_PARAMETER(ResourceListTranslated);
james@75 234
james@75 235 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
james@75 236
james@75 237 status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE, (PINTERFACE)&XenInterface, sizeof(XEN_IFACE), 1, NULL);
james@75 238 if(!NT_SUCCESS(status))
james@75 239 {
james@75 240 KdPrint((__DRIVER_NAME " WdfFdoQueryForInterface (EvtChn) failed with status 0x%08x\n", status));
james@75 241 }
james@75 242
james@75 243 InitializeListHead(&DeviceListHead);
james@75 244
james@75 245 KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
james@75 246
james@75 247 return status;
james@75 248 }
james@75 249
james@75 250 static NTSTATUS
james@75 251 XenEnum_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
james@75 252 {
james@75 253 UNREFERENCED_PARAMETER(Device);
james@75 254 UNREFERENCED_PARAMETER(ResourcesTranslated);
james@75 255
james@75 256 // release interfaces here...
james@75 257
james@75 258 return STATUS_SUCCESS;
james@75 259 }
james@75 260
james@75 261 static NTSTATUS
james@75 262 XenEnum_D0Entry(
james@75 263 IN WDFDEVICE Device,
james@75 264 IN WDF_POWER_DEVICE_STATE PreviousState
james@75 265 )
james@75 266 {
james@75 267 NTSTATUS status = STATUS_SUCCESS;
james@75 268
james@75 269 UNREFERENCED_PARAMETER(Device);
james@75 270 UNREFERENCED_PARAMETER(PreviousState);
james@75 271
james@75 272 //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
james@75 273
james@75 274 //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
james@75 275
james@75 276 return status;
james@75 277 }
james@75 278
james@75 279 static int EnumeratedDevices;
james@75 280 static KEVENT WaitDevicesEvent;
james@75 281
james@75 282 static NTSTATUS
james@75 283 XenEnum_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
james@75 284 {
james@75 285 NTSTATUS status = STATUS_SUCCESS;
james@75 286 PXENPCI_XEN_DEVICE_DATA PdoDeviceData;
james@75 287 char **Devices;
james@75 288 char *msg;
james@75 289 char buffer[128];
james@75 290 int i;
james@75 291 LARGE_INTEGER WaitTimeout;
james@75 292
james@75 293 UNREFERENCED_PARAMETER(Device);
james@75 294 UNREFERENCED_PARAMETER(PreviousState);
james@75 295
james@75 296 KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
james@75 297
james@75 298 PdoDeviceData = (PXENPCI_XEN_DEVICE_DATA)Pdo->DeviceExtension; //GetXenDeviceData(Device);
james@75 299
james@76 300 //KdPrint((__DRIVER_NAME " Path = %s\n", PdoDeviceData->Path));
james@75 301 PdoDeviceData->WatchHandler = XenEnum_WatchHandler;
james@75 302 PdoDeviceData->WatchContext = Device;
james@75 303
james@75 304 EnumeratedDevices = 0;
james@75 305 KeInitializeEvent(&WaitDevicesEvent, SynchronizationEvent, FALSE);
james@75 306
james@75 307 // TODO: Should probably do this in an EvtChildListScanForChildren
james@75 308 if (AutoEnumerate)
james@75 309 {
james@75 310 // TODO: Get the correct path from parent here...
james@76 311 msg = XenInterface.XenBus_List(XenInterface.InterfaceHeader.Context, XBT_NIL, PdoDeviceData->Path, &Devices);
james@75 312 if (!msg)
james@75 313 {
james@75 314 for (i = 0; Devices[i]; i++)
james@75 315 {
james@75 316 KdPrint((__DRIVER_NAME " found existing device %s\n", Devices[i]));
james@76 317 KdPrint((__DRIVER_NAME " faking watch event for %s/%s", PdoDeviceData->Path, Devices[i]));
james@76 318 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "%s/%s", PdoDeviceData->Path, Devices[i]);
james@75 319 XenEnum_WatchHandler(buffer, Device);
james@75 320 //ExFreePoolWithTag(Devices[i], XENPCI_POOL_TAG);
james@75 321 }
james@75 322 /*
james@75 323 KdPrint((__DRIVER_NAME " Waiting for devices to be enumerated\n"));
james@75 324 while (EnumeratedDevices != i)
james@75 325 {
james@75 326 WaitTimeout.QuadPart = -600000000;
james@75 327 if (KeWaitForSingleObject(&WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
james@75 328 {
james@75 329 KdPrint((__DRIVER_NAME " Wait timed out\n"));
james@75 330 break;
james@75 331 }
james@75 332 KdPrint((__DRIVER_NAME " %d out of %d devices enumerated\n", EnumeratedDevices, i));
james@75 333 }
james@75 334 */
james@75 335 }
james@75 336 }
james@75 337
james@75 338 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
james@75 339
james@75 340 return status;
james@75 341 }
james@75 342
james@75 343 static NTSTATUS
james@75 344 XenEnum_D0Exit(
james@75 345 IN WDFDEVICE Device,
james@75 346 IN WDF_POWER_DEVICE_STATE TargetState
james@75 347 )
james@75 348 {
james@75 349 NTSTATUS status = STATUS_SUCCESS;
james@75 350 //char *response;
james@75 351
james@75 352 UNREFERENCED_PARAMETER(Device);
james@75 353 UNREFERENCED_PARAMETER(TargetState);
james@75 354
james@75 355 //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Exit\n"));
james@75 356
james@75 357 //response = XenBusInterface.RemWatch(XBT_NIL, XenBusInterface.InterfaceHeader.Context, XenEnum_WatchHandler, NULL);
james@75 358
james@75 359 //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Exit\n"));
james@75 360
james@75 361 return status;
james@75 362 }
james@75 363
james@75 364 static NTSTATUS
james@75 365 XenEnum_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath)
james@75 366 {
james@75 367 KdPrint((__DRIVER_NAME " --> DeviceUsageNotification\n"));
james@75 368
james@75 369 switch (NotificationType)
james@75 370 {
james@75 371 case WdfSpecialFilePaging:
james@75 372 KdPrint((__DRIVER_NAME " NotificationType = WdfSpecialFilePaging, Using = %d\n", IsInNotificationPath));
james@75 373 break;
james@75 374 case WdfSpecialFileHibernation:
james@75 375 KdPrint((__DRIVER_NAME " NotificationType = WdfSpecialFileHibernation, Using = %d\n", IsInNotificationPath));
james@75 376 break;
james@75 377 case WdfSpecialFileDump:
james@75 378 KdPrint((__DRIVER_NAME " NotificationType = WdfSpecialFileDump, Using = %d\n", IsInNotificationPath));
james@75 379 break;
james@75 380 default:
james@75 381 KdPrint((__DRIVER_NAME " NotificationType = %d, Using = %d\n", NotificationType, IsInNotificationPath));
james@75 382 break;
james@75 383 }
james@75 384 KdPrint((__DRIVER_NAME " <-- DeviceUsageNotification\n"));
james@75 385
james@75 386 return TRUE;
james@75 387 }
james@75 388
james@75 389 static VOID
james@75 390 XenEnum_IoDefault(
james@75 391 IN WDFQUEUE Queue,
james@75 392 IN WDFREQUEST Request
james@75 393 )
james@75 394 {
james@75 395 UNREFERENCED_PARAMETER(Queue);
james@75 396
james@75 397 //KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
james@75 398
james@75 399 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
james@75 400
james@75 401 //KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
james@75 402 }
james@75 403
james@75 404 static VOID
james@75 405 XenEnum_WatchHandler(char *Path, PVOID Data)
james@75 406 {
james@75 407 NTSTATUS Status;
james@75 408 XENPCI_IDENTIFICATION_DESCRIPTION IdentificationDescription;
james@75 409 char **Bits;
james@75 410 int Count;
james@75 411 char TmpPath[128];
james@75 412 char *Value;
james@75 413 ANSI_STRING AnsiBuf;
james@75 414 WDFCHILDLIST ChildList;
james@75 415 WDFDEVICE Device = Data;
james@75 416 WDF_CHILD_LIST_ITERATOR ChildIterator;
james@75 417 WDFDEVICE ChildDevice;
james@75 418 PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
james@75 419
james@75 420 UNREFERENCED_PARAMETER(Data);
james@75 421
james@75 422 KdPrint((__DRIVER_NAME " --> WatchHandler\n"));
james@75 423
james@75 424 KdPrint((__DRIVER_NAME " Path = %s\n", Path));
james@75 425
james@75 426 Bits = SplitString(Path, '/', 4, &Count);
james@75 427 if (Count == 3)
james@75 428 {
james@75 429 KdPrint((__DRIVER_NAME " Creating %s\n", Bits[2]));
james@75 430 ChildList = WdfFdoGetDefaultChildList(Device);
james@75 431 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&IdentificationDescription.Header, sizeof(IdentificationDescription));
james@75 432 strncpy(IdentificationDescription.Path, Path, 128);
james@75 433 RtlInitAnsiString(&AnsiBuf, Bits[1]);
james@75 434 RtlAnsiStringToUnicodeString(&IdentificationDescription.DeviceType, &AnsiBuf, TRUE);
james@75 435 IdentificationDescription.DeviceIndex = atoi(Bits[2]);
james@75 436 Status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &IdentificationDescription.Header, NULL);
james@75 437 }
james@75 438 else if (Count > 3)
james@75 439 {
james@75 440 WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
james@75 441 ChildList = WdfFdoGetDefaultChildList(Device);
james@75 442 WdfChildListBeginIteration(ChildList, &ChildIterator);
james@75 443 while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
james@75 444 {
james@75 445 ChildDeviceData = GetXenDeviceData(ChildDevice);
james@75 446 if (!ChildDeviceData)
james@75 447 {
james@75 448 KdPrint((__FUNCTION__ " No child device data, should never happen\n"));
james@75 449 continue;
james@75 450 }
james@76 451 if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
james@75 452 {
james@76 453 KdPrint((__DRIVER_NAME " Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->Path, ChildDeviceData->WatchHandler));
james@75 454 if (ChildDeviceData->WatchHandler != NULL)
james@75 455 ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
james@75 456 }
james@75 457 else
james@75 458 {
james@76 459 //KdPrint((__DRIVER_NAME " Child Path = %s (No Match)\n", ChildDeviceData->Path));
james@75 460 }
james@75 461 }
james@75 462 WdfChildListEndIteration(ChildList, &ChildIterator);
james@75 463 }
james@75 464 FreeSplitString(Bits, Count);
james@75 465
james@75 466 KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));
james@75 467
james@75 468 return;
james@75 469 }
james@75 470
james@75 471 static NTSTATUS
james@75 472 XenEnum_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit)
james@75 473 {
james@75 474 NTSTATUS status;
james@75 475 WDFDEVICE ChildDevice;
james@75 476 PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
james@75 477 DECLARE_UNICODE_STRING_SIZE(buffer, 50);
james@75 478 WDF_OBJECT_ATTRIBUTES PdoAttributes;
james@75 479 DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
james@75 480 PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
james@75 481 WDF_QUERY_INTERFACE_CONFIG qiConfig;
james@75 482 // WDF_PDO_EVENT_CALLBACKS PdoCallbacks;
james@75 483 // UCHAR PnpMinors[2] = { IRP_MN_START_DEVICE, IRP_MN_STOP_DEVICE };
james@75 484
james@75 485 UNREFERENCED_PARAMETER(ChildList);
james@75 486
james@75 487 KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
james@75 488
james@75 489 XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
james@75 490
james@75 491 // ChildDeviceData = XenEnumIdentificationDesc->DeviceData;
james@75 492
james@75 493 WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_UNKNOWN);
james@75 494
james@75 495 status = RtlUnicodeStringPrintf(&buffer, L"XEN\\%wsdev\0", XenIdentificationDesc->DeviceType.Buffer);
james@75 496
james@75 497 KdPrint((__DRIVER_NAME " %ws", buffer.Buffer));
james@75 498
james@75 499 status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
james@75 500 status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
james@75 501 status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
james@75 502
james@75 503 status = RtlUnicodeStringPrintf(&buffer, L"%02d\0", XenIdentificationDesc->DeviceIndex);
james@75 504 status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
james@75 505
james@75 506 status = RtlUnicodeStringPrintf(&buffer, L"Xen %ws Device (%d)", XenIdentificationDesc->DeviceType.Buffer, XenIdentificationDesc->DeviceIndex);
james@75 507 status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
james@75 508 WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
james@75 509
james@75 510 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
james@75 511
james@75 512 status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
james@75 513 if (!NT_SUCCESS(status))
james@75 514 {
james@75 515 KdPrint((__DRIVER_NAME " WdfDeviceCreate status = %08X\n", status));
james@75 516 }
james@75 517
james@75 518 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
james@75 519 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
james@75 520 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
james@75 521
james@75 522 ChildDeviceData = GetXenDeviceData(ChildDevice);
james@75 523 ChildDeviceData->Magic = XEN_DATA_MAGIC;
james@75 524 ChildDeviceData->AutoEnumerate = AutoEnumerate;
james@75 525 ChildDeviceData->WatchHandler = NULL;
james@76 526 strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
james@75 527 // memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
james@75 528 // memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
james@75 529
james@75 530 ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
james@75 531 ChildDeviceData->XenInterface.InterfaceHeader.Version = 1;
james@75 532 ChildDeviceData->XenInterface.InterfaceHeader.Context = XenInterface.InterfaceHeader.Context;
james@75 533 ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
james@75 534 ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
james@75 535
james@75 536 ChildDeviceData->XenInterface.AllocMMIO = XenInterface.AllocMMIO;
james@75 537
james@75 538 ChildDeviceData->XenInterface.EvtChn_Bind = XenInterface.EvtChn_Bind;
james@75 539 ChildDeviceData->XenInterface.EvtChn_Unbind = XenInterface.EvtChn_Unbind;
james@75 540 ChildDeviceData->XenInterface.EvtChn_Mask = XenInterface.EvtChn_Mask;
james@75 541 ChildDeviceData->XenInterface.EvtChn_Unmask = XenInterface.EvtChn_Unmask;
james@75 542 ChildDeviceData->XenInterface.EvtChn_Notify = XenInterface.EvtChn_Notify;
james@75 543 ChildDeviceData->XenInterface.EvtChn_AllocUnbound = XenInterface.EvtChn_AllocUnbound;
james@75 544 ChildDeviceData->XenInterface.EvtChn_BindDpc = XenInterface.EvtChn_BindDpc;
james@75 545
james@75 546 ChildDeviceData->XenInterface.GntTbl_GrantAccess = XenInterface.GntTbl_GrantAccess;
james@75 547 ChildDeviceData->XenInterface.GntTbl_EndAccess = XenInterface.GntTbl_EndAccess;
james@75 548
james@75 549 ChildDeviceData->XenInterface.XenBus_Read = XenInterface.XenBus_Read;
james@75 550 ChildDeviceData->XenInterface.XenBus_Write = XenInterface.XenBus_Write;
james@75 551 ChildDeviceData->XenInterface.XenBus_Printf = XenInterface.XenBus_Printf;
james@75 552 ChildDeviceData->XenInterface.XenBus_StartTransaction = XenInterface.XenBus_StartTransaction;
james@75 553 ChildDeviceData->XenInterface.XenBus_EndTransaction = XenInterface.XenBus_EndTransaction;
james@75 554 ChildDeviceData->XenInterface.XenBus_List = XenInterface.XenBus_List;
james@75 555 ChildDeviceData->XenInterface.XenBus_AddWatch = XenInterface.XenBus_AddWatch;
james@75 556 ChildDeviceData->XenInterface.XenBus_RemWatch = XenInterface.XenBus_RemWatch;
james@75 557
james@75 558 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
james@75 559 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
james@75 560 if (!NT_SUCCESS(status)) {
james@75 561 return status;
james@75 562 }
james@75 563
james@75 564
james@75 565
james@75 566
james@75 567
james@75 568
james@75 569 KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice (status = %08x)\n", status));
james@75 570
james@75 571 return status;
james@75 572 }