[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH 07/14 v2] Enumerate non-default consoles
> -----Original Message----- > From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On > Behalf Of owen.smith@xxxxxxxxxx > Sent: 23 February 2018 14:22 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Owen Smith <owen.smith@xxxxxxxxxx> > Subject: [win-pv-devel] [PATCH 07/14 v2] Enumerate non-default consoles > > From: Owen Smith <owen.smith@xxxxxxxxxx> > > * Add enumeration thread and watch > * Non-default consoles will fail any read/write/iocontrol IRPs > > Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> Acked-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > --- > src/xencons/fdo.c | 316 > +++++++++++++++++++++++++++++++++++++++++++++++++++++- > src/xencons/pdo.c | 64 +++++++++-- > src/xencons/pdo.h | 5 + > 3 files changed, 376 insertions(+), 9 deletions(-) > > diff --git a/src/xencons/fdo.c b/src/xencons/fdo.c > index 45a1fdd..4046acf 100644 > --- a/src/xencons/fdo.c > +++ b/src/xencons/fdo.c > @@ -85,6 +85,9 @@ struct _XENCONS_FDO { > > CHAR VendorName[MAXNAMELEN]; > > + PXENCONS_THREAD ScanThread; > + KEVENT ScanEvent; > + PXENBUS_STORE_WATCH ScanWatch; > MUTEX Mutex; > ULONG References; > > @@ -653,6 +656,9 @@ done: > RemoveEntryList(&Dx->ListEntry); > ASSERT3U(Fdo->References, != , 0); > --Fdo->References; > + > + if (Fdo->ScanThread) > + ThreadWake(Fdo->ScanThread); > } > > static FORCEINLINE VOID > @@ -690,6 +696,112 @@ FdoReleaseMutex( > FdoDestroy(Fdo); > } > > +static FORCEINLINE BOOLEAN > +__FdoEnumerate( > + IN PXENCONS_FDO Fdo, > + IN PANSI_STRING Devices > + ) > +{ > + BOOLEAN NeedInvalidate; > + HANDLE ParametersKey; > + ULONG Enumerate; > + PLIST_ENTRY ListEntry; > + ULONG Index; > + NTSTATUS status; > + > + Trace("====>\n"); > + > + NeedInvalidate = FALSE; > + > + ParametersKey = DriverGetParametersKey(); > + > + status = RegistryQueryDwordValue(ParametersKey, > + "Enumerate", > + &Enumerate); > + if (!NT_SUCCESS(status)) > + Enumerate = 1; > + > + if (Enumerate == 0) > + goto done; > + > + __FdoAcquireMutex(Fdo); > + > + ListEntry = Fdo->Dx->ListEntry.Flink; > + while (ListEntry != &Fdo->Dx->ListEntry) { > + PLIST_ENTRY Next = ListEntry->Flink; > + PXENCONS_DX Dx = CONTAINING_RECORD(ListEntry, XENCONS_DX, > ListEntry); > + PXENCONS_PDO Pdo = Dx->Pdo; > + > + // If the PDO is the default console, it wont exist in the > + // the device list, as its statically created > + if (PdoIsDefault(Pdo)) > + continue; > + > + if (PdoGetDevicePnpState(Pdo) != Deleted) { > + PCHAR Name; > + BOOLEAN Missing; > + > + Name = PdoGetName(Pdo); > + Missing = TRUE; > + > + // If the PDO already exists and its name is in the device list > + // then we don't want to remove it. > + for (Index = 0; Devices[Index].Buffer != NULL; Index++) { > + PANSI_STRING Device = &Devices[Index]; > + > + if (Device->Length == 0) > + continue; > + > + if (strcmp(Name, Device->Buffer) == 0) { > + Missing = FALSE; > + Device->Length = 0; // avoid duplication > + break; > + } > + } > + > + if (!PdoIsMissing(Pdo)) { > + if (PdoIsEjectRequested(Pdo)) { > + IoRequestDeviceEject(PdoGetDeviceObject(Pdo)); > + } else if (Missing) { > + PdoSetMissing(Pdo, "device disappeared"); > + > + // If the PDO has not yet been enumerated then we can > + // go ahead and mark it as deleted, otherwise we need > + // to notify PnP manager and wait for the REMOVE_DEVICE > + // IRP. > + if (PdoGetDevicePnpState(Pdo) == Present) { > + PdoSetDevicePnpState(Pdo, Deleted); > + PdoDestroy(Pdo); > + } else { > + NeedInvalidate = TRUE; > + } > + } > + } > + } > + > + ListEntry = Next; > + } > + > + // Walk the class list and create PDOs for any new device > + for (Index = 0; Devices[Index].Buffer != NULL; Index++) { > + PANSI_STRING Device = &Devices[Index]; > + > + if (Device->Length == 0) > + continue; > + > + status = PdoCreate(Fdo, Device); > + if (NT_SUCCESS(status)) > + NeedInvalidate = TRUE; > + } > + > + __FdoReleaseMutex(Fdo); > + > +done: > + Trace("<====\n"); > + > + return NeedInvalidate; > +} > + > static FORCEINLINE PANSI_STRING > __FdoMultiSzToUpcaseAnsi( > IN PCHAR Buffer > @@ -768,6 +880,125 @@ __FdoFreeAnsi( > __FdoFree(Ansi); > } > > +static NTSTATUS > +FdoScan( > + PXENCONS_THREAD Self, > + PVOID Context > + ) > +{ > + PXENCONS_FDO Fdo = Context; > + PKEVENT Event; > + HANDLE ParametersKey; > + NTSTATUS status; > + > + Trace("====>\n"); > + > + Event = ThreadGetEvent(Self); > + > + ParametersKey = DriverGetParametersKey(); > + > + for (;;) { > + PCHAR Buffer; > + PANSI_STRING Devices; > + PANSI_STRING UnsupportedDevices; > + ULONG Index; > + BOOLEAN NeedInvalidate; > + > + Trace("waiting...\n"); > + > + (VOID)KeWaitForSingleObject(Event, > + Executive, > + KernelMode, > + FALSE, > + NULL); > + KeClearEvent(Event); > + > + if (ThreadIsAlerted(Self)) > + break; > + > + // It is not safe to use interfaces before this point > + if (__FdoGetDevicePnpState(Fdo) != Started) { > + KeSetEvent(&Fdo->ScanEvent, IO_NO_INCREMENT, FALSE); > + continue; > + } > + > + status = XENBUS_STORE(Directory, > + &Fdo->StoreInterface, > + NULL, > + "device", > + "console", > + &Buffer); > + if (NT_SUCCESS(status)) { > + Devices = __FdoMultiSzToUpcaseAnsi(Buffer); > + > + XENBUS_STORE(Free, > + &Fdo->StoreInterface, > + Buffer); > + } else { > + Devices = NULL; > + } > + > + if (Devices == NULL) > + goto loop; > + > + if (ParametersKey != NULL) { > + status = RegistryQuerySzValue(ParametersKey, > + "UnsupportedDevices", > + NULL, > + &UnsupportedDevices); > + if (!NT_SUCCESS(status)) > + UnsupportedDevices = NULL; > + } else { > + UnsupportedDevices = NULL; > + } > + > + // NULL out anything in the Devices list that is in the > + // UnsupportedDevices list > + for (Index = 0; Devices[Index].Buffer != NULL; Index++) { > + PANSI_STRING Device = &Devices[Index]; > + ULONG Entry; > + BOOLEAN Supported; > + > + Supported = TRUE; > + > + for (Entry = 0; > + UnsupportedDevices != NULL && > UnsupportedDevices[Entry].Buffer != NULL; > + Entry++) { > + if (strncmp(Device->Buffer, > + UnsupportedDevices[Entry].Buffer, > + Device->Length) == 0) { > + Supported = FALSE; > + break; > + } > + } > + > + if (!Supported) > + Device->Length = 0; > + } > + > + if (UnsupportedDevices != NULL) > + RegistryFreeSzValue(UnsupportedDevices); > + > + NeedInvalidate = __FdoEnumerate(Fdo, Devices); > + > + __FdoFreeAnsi(Devices); > + > + if (NeedInvalidate) { > + NeedInvalidate = FALSE; > + IoInvalidateDeviceRelations(__FdoGetPhysicalDeviceObject(Fdo), > + BusRelations); > + } > + > + loop: > + KeSetEvent(&Fdo->ScanEvent, IO_NO_INCREMENT, FALSE); > + } > + > + KeSetEvent(&Fdo->ScanEvent, IO_NO_INCREMENT, FALSE); > + > + Trace("<====\n"); > + return STATUS_SUCCESS; > +} > + > static FORCEINLINE BOOLEAN > __FdoMatchDistribution( > IN PXENCONS_FDO Fdo, > @@ -989,15 +1220,39 @@ __FdoD3ToD0( > IN PXENCONS_FDO Fdo > ) > { > + NTSTATUS status; > + > Trace("====>\n"); > > ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); > > (VOID) FdoSetDistribution(Fdo); > > + status = XENBUS_STORE(WatchAdd, > + &Fdo->StoreInterface, > + "device", > + "console", > + ThreadGetEvent(Fdo->ScanThread), > + &Fdo->ScanWatch); > + if (!NT_SUCCESS(status)) > + goto fail1; > + > + (VOID)XENBUS_STORE(Printf, > + &Fdo->StoreInterface, > + NULL, > + "feature/hotplug", > + "console", > + "%u", > + TRUE); > + > Trace("<====\n"); > > return STATUS_SUCCESS; > + > +fail1: > + Error("fail1 (%08x)\n", status); > + > + return status; > } > > static FORCEINLINE VOID > @@ -1009,6 +1264,17 @@ __FdoD0ToD3( > > ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); > > + (VOID)XENBUS_STORE(Remove, > + &Fdo->StoreInterface, > + NULL, > + "feature/hotplug", > + "console"); > + > + (VOID)XENBUS_STORE(WatchRemove, > + &Fdo->StoreInterface, > + Fdo->ScanWatch); > + Fdo->ScanWatch = NULL; > + > FdoClearDistribution(Fdo); > > Trace("<====\n"); > @@ -1221,17 +1487,31 @@ FdoStartDevice( > > StackLocation->Parameters.StartDevice.AllocatedResources, > StackLocation- > >Parameters.StartDevice.AllocatedResourcesTranslated); > > - status = FdoD3ToD0(Fdo); > + KeInitializeEvent(&Fdo->ScanEvent, NotificationEvent, FALSE); > + > + status = ThreadCreate(FdoScan, Fdo, &Fdo->ScanThread); > if (!NT_SUCCESS(status)) > goto fail2; > > + status = FdoD3ToD0(Fdo); > + if (!NT_SUCCESS(status)) > + goto fail3; > + > __FdoSetDevicePnpState(Fdo, Started); > + ThreadWake(Fdo->ScanThread); > > status = Irp->IoStatus.Status; > IoCompleteRequest(Irp, IO_NO_INCREMENT); > > return status; > > +fail3: > + Error("fail3\n"); > + > + ThreadAlert(Fdo->ScanThread); > + ThreadJoin(Fdo->ScanThread); > + Fdo->ScanThread = NULL; > + > fail2: > Error("fail2\n"); > > @@ -1292,6 +1572,12 @@ FdoStopDevice( > if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0) > FdoD0ToD3(Fdo); > > + ThreadAlert(Fdo->ScanThread); > + ThreadJoin(Fdo->ScanThread); > + Fdo->ScanThread = NULL; > + > + RtlZeroMemory(&Fdo->ScanEvent, sizeof(KEVENT)); > + > RtlZeroMemory(&Fdo->Resource, sizeof (FDO_RESOURCE) * > RESOURCE_COUNT); > > __FdoSetDevicePnpState(Fdo, Stopped); > @@ -1387,6 +1673,17 @@ FdoRemoveDevice( > if (__FdoGetPreviousDevicePnpState(Fdo) != Started) > goto done; > > + KeClearEvent(&Fdo->ScanEvent); > + ThreadWake(Fdo->ScanThread); > + > + Trace("waiting for scan thread\n"); > + > + (VOID)KeWaitForSingleObject(&Fdo->ScanEvent, > + Executive, > + KernelMode, > + FALSE, > + NULL); > + > __FdoAcquireMutex(Fdo); > > ListEntry = Fdo->Dx->ListEntry.Flink; > @@ -1414,6 +1711,12 @@ FdoRemoveDevice( > if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0) > FdoD0ToD3(Fdo); > > + ThreadAlert(Fdo->ScanThread); > + ThreadJoin(Fdo->ScanThread); > + Fdo->ScanThread = NULL; > + > + RtlZeroMemory(&Fdo->ScanEvent, sizeof(KEVENT)); > + > RtlZeroMemory(&Fdo->Resource, sizeof (FDO_RESOURCE) * > RESOURCE_COUNT); > > done: > @@ -1463,6 +1766,17 @@ FdoQueryDeviceRelations( > goto done; > } > > + KeClearEvent(&Fdo->ScanEvent); > + ThreadWake(Fdo->ScanThread); > + > + Trace("waiting for scan thread\n"); > + > + (VOID)KeWaitForSingleObject(&Fdo->ScanEvent, > + Executive, > + KernelMode, > + FALSE, > + NULL); > + > __FdoAcquireMutex(Fdo); > > Count = 0; > diff --git a/src/xencons/pdo.c b/src/xencons/pdo.c > index 62f366c..2acd86a 100755 > --- a/src/xencons/pdo.c > +++ b/src/xencons/pdo.c > @@ -71,6 +71,7 @@ struct _XENCONS_PDO { > XENBUS_SUSPEND_INTERFACE SuspendInterface; > PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate; > > + BOOLEAN IsDefault; > PXENCONS_CONSOLE Console; > }; > > @@ -286,6 +287,14 @@ __PdoGetName( > return Dx->Name; > } > > +PCHAR > +PdoGetName( > + IN PXENCONS_PDO Pdo > + ) > +{ > + return __PdoGetName(Pdo); > +} > + > static FORCEINLINE PCHAR > __PdoGetVendorName( > IN PXENCONS_PDO Pdo > @@ -295,6 +304,22 @@ __PdoGetVendorName( > } > > static FORCEINLINE BOOLEAN > +__PdoIsDefault( > + IN PXENCONS_PDO Pdo > + ) > +{ > + return Pdo->IsDefault; > +} > + > +BOOLEAN > +PdoIsDefault( > + IN PXENCONS_PDO Pdo > + ) > +{ > + return __PdoIsDefault(Pdo); > +} > + > +static FORCEINLINE BOOLEAN > __PdoSetEjectRequested( > IN PXENCONS_PDO Pdo > ) > @@ -441,7 +466,10 @@ PdoD3ToD0( > > KeLowerIrql(Irql); > > - status = ConsoleD3ToD0(Pdo->Console); > + if (__PdoIsDefault(Pdo)) > + status = ConsoleD3ToD0(Pdo->Console); > + else > + status = STATUS_SUCCESS; > if (!NT_SUCCESS(status)) > goto fail4; > > @@ -495,7 +523,8 @@ PdoD0ToD3( > #pragma prefast(suppress:28123) > (VOID) IoSetDeviceInterfaceState(&Pdo->Dx->Link, FALSE); > > - ConsoleD0ToD3(Pdo->Console); > + if (__PdoIsDefault(Pdo)) > + ConsoleD0ToD3(Pdo->Console); > > KeRaiseIrql(DISPATCH_LEVEL, &Irql); > > @@ -1689,7 +1718,10 @@ PdoDispatchCreate( > > StackLocation = IoGetCurrentIrpStackLocation(Irp); > > - status = ConsoleOpen(Pdo->Console, StackLocation->FileObject); > + if (__PdoIsDefault(Pdo)) > + status = ConsoleOpen(Pdo->Console, StackLocation->FileObject); > + else > + status = STATUS_SUCCESS; > > Irp->IoStatus.Status = status; > IoCompleteRequest(Irp, IO_NO_INCREMENT); > @@ -1708,7 +1740,10 @@ PdoDispatchCleanup( > > StackLocation = IoGetCurrentIrpStackLocation(Irp); > > - status = ConsoleClose(Pdo->Console, StackLocation->FileObject); > + if (__PdoIsDefault(Pdo)) > + status = ConsoleClose(Pdo->Console, StackLocation->FileObject); > + else > + status = STATUS_SUCCESS; > > Irp->IoStatus.Status = status; > IoCompleteRequest(Irp, IO_NO_INCREMENT); > @@ -1742,7 +1777,10 @@ PdoDispatchReadWriteControl( > { > NTSTATUS status; > > - status = ConsolePutQueue(Pdo->Console, Irp); > + if (__PdoIsDefault(Pdo)) > + status = ConsolePutQueue(Pdo->Console, Irp); > + else > + status = STATUS_DEVICE_NOT_READY; > if (status == STATUS_SUCCESS) > goto done; > if (status != STATUS_PENDING) > @@ -1895,7 +1933,11 @@ PdoCreate( > > Dx->Pdo = Pdo; > > - status = ConsoleCreate(Fdo, &Pdo->Console); > + Pdo->IsDefault = (Device == NULL); > + if (Pdo->IsDefault) > + status = ConsoleCreate(Fdo, &Pdo->Console); > + else > + status = STATUS_SUCCESS; > if (!NT_SUCCESS(status)) > goto fail5; > > @@ -1925,9 +1967,12 @@ fail6: > > (VOID)__PdoClearEjectRequested(Pdo); > > - ConsoleDestroy(Pdo->Console); > + if (__PdoIsDefault(Pdo)) > + ConsoleDestroy(Pdo->Console); > Pdo->Console = NULL; > > + Pdo->IsDefault = FALSE; > + > fail5: > Error("fail5\n"); > > @@ -1994,9 +2039,12 @@ PdoDestroy( > > Dx->Pdo = NULL; > > - ConsoleDestroy(Pdo->Console); > + if (__PdoIsDefault(Pdo)) > + ConsoleDestroy(Pdo->Console); > Pdo->Console = NULL; > > + Pdo->IsDefault = FALSE; > + > RtlFreeUnicodeString(&Pdo->Dx->Link); > > RtlZeroMemory(&Pdo->SuspendInterface, > diff --git a/src/xencons/pdo.h b/src/xencons/pdo.h > index 0605483..85f73a3 100755 > --- a/src/xencons/pdo.h > +++ b/src/xencons/pdo.h > @@ -83,6 +83,11 @@ PdoGetDeviceObject( > IN PXENCONS_PDO Pdo > ); > > +extern BOOLEAN > +PdoIsDefault( > + IN PXENCONS_PDO Pdo > + ); > + > extern NTSTATUS > PdoCreate( > IN PXENCONS_FDO Fdo, > -- > 2.8.3 > > > _______________________________________________ > win-pv-devel mailing list > win-pv-devel@xxxxxxxxxxxxxxxxxxxx > https://lists.xenproject.org/mailman/listinfo/win-pv-devel _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |