[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 04/26] Refactor Adapter.c
From: Owen Smith <owen.smith@xxxxxxxxxx> Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvbd/adapter.c | 2301 ++++++++++++++++++++++------------------------- src/xenvbd/adapter.h | 123 +-- src/xenvbd/blockring.c | 22 +- src/xenvbd/driver.c | 185 +--- src/xenvbd/driver.h | 5 + src/xenvbd/frontend.c | 133 +-- src/xenvbd/frontend.h | 4 + src/xenvbd/granter.c | 26 +- src/xenvbd/notifier.c | 51 +- src/xenvbd/pdoinquiry.c | 44 +- src/xenvbd/pdoinquiry.h | 3 +- src/xenvbd/target.c | 133 ++- src/xenvbd/target.h | 27 +- 13 files changed, 1292 insertions(+), 1765 deletions(-) diff --git a/src/xenvbd/adapter.c b/src/xenvbd/adapter.c index 1e0340b..7fb786f 100644 --- a/src/xenvbd/adapter.c +++ b/src/xenvbd/adapter.c @@ -44,6 +44,7 @@ #include <debug_interface.h> #include <suspend_interface.h> #include <emulated_interface.h> +#include <unplug_interface.h> #include "adapter.h" #include "driver.h" @@ -58,553 +59,59 @@ #include "assert.h" #define MAXNAMELEN 128 - -#define ADAPTER_SIGNATURE 'odfX' +#define ADAPTER_POOL_TAG 'adAX' struct _XENVBD_ADAPTER { - ULONG Signature; PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT LowerDeviceObject; PDEVICE_OBJECT PhysicalDeviceObject; KSPIN_LOCK Lock; DEVICE_POWER_STATE DevicePower; - ANSI_STRING Enumerator; - - // Power PXENVBD_THREAD DevicePowerThread; PIRP DevicePowerIrp; - // Interfaces to XenBus - XENBUS_EVTCHN_INTERFACE Evtchn; - XENBUS_STORE_INTERFACE Store; - XENBUS_GNTTAB_INTERFACE Gnttab; - XENBUS_DEBUG_INTERFACE Debug; - XENBUS_SUSPEND_INTERFACE Suspend; - XENBUS_UNPLUG_INTERFACE Unplug; - XENFILT_EMULATED_INTERFACE Emulated; + XENBUS_EVTCHN_INTERFACE EvtchnInterface; + XENBUS_STORE_INTERFACE StoreInterface; + XENBUS_GNTTAB_INTERFACE GnttabInterface; + XENBUS_DEBUG_INTERFACE DebugInterface; + XENBUS_SUSPEND_INTERFACE SuspendInterface; + XENBUS_UNPLUG_INTERFACE UnplugInterface; + XENFILT_EMULATED_INTERFACE EmulatedInterface; - // Debug Callback PXENBUS_DEBUG_CALLBACK DebugCallback; PXENBUS_SUSPEND_CALLBACK SuspendCallback; - // Targets KSPIN_LOCK TargetLock; - PXENVBD_TARGET Targets[XENVBD_MAX_TARGETS]; - - // Target Enumeration + PXENVBD_TARGET TargetList[XENVBD_MAX_TARGETS]; PXENVBD_THREAD ScanThread; KEVENT ScanEvent; PXENBUS_STORE_WATCH ScanWatch; - // Statistics - LONG CurrentSrbs; - LONG MaximumSrbs; - LONG TotalSrbs; + ULONG BuildIo; + ULONG StartIo; + ULONG Completed; }; -//============================================================================= -static FORCEINLINE BOOLEAN -__AdapterSetDevicePowerState( - __in PXENVBD_ADAPTER Adapter, - __in DEVICE_POWER_STATE State - ) -{ - KIRQL Irql; - BOOLEAN Changed = FALSE; - - KeAcquireSpinLock(&Adapter->Lock, &Irql); - - if (Adapter->DevicePower != State) { - Verbose("POWER %s to %s\n", PowerDeviceStateName(Adapter->DevicePower), PowerDeviceStateName(State)); - Changed = TRUE; - Adapter->DevicePower = State; - } - - KeReleaseSpinLock(&Adapter->Lock, Irql); - - return Changed; -} - -static FORCEINLINE DEVICE_POWER_STATE -__AdapterGetDevicePowerState( - __in PXENVBD_ADAPTER Adapter - ) -{ - KIRQL Irql; - DEVICE_POWER_STATE State; - - KeAcquireSpinLock(&Adapter->Lock, &Irql); - State = Adapter->DevicePower; - KeReleaseSpinLock(&Adapter->Lock, Irql); - - return State; -} - -__checkReturn -static FORCEINLINE PXENVBD_TARGET -__AdapterGetTargetAlways( - __in PXENVBD_ADAPTER Adapter, - __in ULONG TargetId, - __in PCHAR Caller - ) -{ - PXENVBD_TARGET Target; - KIRQL Irql; - - ASSERT3U(TargetId, <, XENVBD_MAX_TARGETS); - - KeAcquireSpinLock(&Adapter->TargetLock, &Irql); - Target = Adapter->Targets[TargetId]; - if (Target) { - __TargetReference(Target, Caller); - } - KeReleaseSpinLock(&Adapter->TargetLock, Irql); - - return Target; -} - -__checkReturn -static FORCEINLINE PXENVBD_TARGET -___AdapterGetTarget( - __in PXENVBD_ADAPTER Adapter, - __in ULONG TargetId, - __in PCHAR Caller - ) -{ - PXENVBD_TARGET Target = NULL; - KIRQL Irql; - - ASSERT3U(TargetId, <, XENVBD_MAX_TARGETS); - - KeAcquireSpinLock(&Adapter->TargetLock, &Irql); - if (Adapter->Targets[TargetId] && - __TargetReference(Adapter->Targets[TargetId], Caller) > 0) { - Target = Adapter->Targets[TargetId]; - } - KeReleaseSpinLock(&Adapter->TargetLock, Irql); - - return Target; -} -#define __AdapterGetTarget(f, t) ___AdapterGetTarget(f, t, __FUNCTION__) - -BOOLEAN -AdapterLinkTarget( - __in PXENVBD_ADAPTER Adapter, - __in PXENVBD_TARGET Target - ) -{ - KIRQL Irql; - PXENVBD_TARGET Current; - BOOLEAN Result = FALSE; - ULONG TargetId = TargetGetTargetId(Target); - - KeAcquireSpinLock(&Adapter->TargetLock, &Irql); - Current = Adapter->Targets[TargetId]; - if (Adapter->Targets[TargetId] == NULL) { - Adapter->Targets[TargetId] = Target; - Result = TRUE; - } - KeReleaseSpinLock(&Adapter->TargetLock, Irql); - - if (!Result) { - Warning("Target[%d] : Current 0x%p, New 0x%p\n", TargetId, Current, Target); - } - return Result; -} -BOOLEAN -AdapterUnlinkTarget( - __in PXENVBD_ADAPTER Adapter, - __in PXENVBD_TARGET Target - ) -{ - KIRQL Irql; - PXENVBD_TARGET Current; - BOOLEAN Result = FALSE; - ULONG TargetId = TargetGetTargetId(Target); - - KeAcquireSpinLock(&Adapter->TargetLock, &Irql); - Current = Adapter->Targets[TargetId]; - if (Adapter->Targets[TargetId] == Target) { - Adapter->Targets[TargetId] = NULL; - Result = TRUE; - } - KeReleaseSpinLock(&Adapter->TargetLock, Irql); - - if (!Result) { - Warning("Target[%d] : Current 0x%p, Expected 0x%p\n", TargetId, Current, Target); - } - return Result; -} - -//============================================================================= -// QueryInterface - -__drv_requiresIRQL(PASSIVE_LEVEL) -static NTSTATUS -AdapterQueryInterface( - IN PXENVBD_ADAPTER Adapter, - IN const GUID *Guid, - IN ULONG Version, - OUT PINTERFACE Interface, - IN ULONG Size, - IN BOOLEAN Optional - ) -{ - KEVENT Event; - IO_STATUS_BLOCK StatusBlock; - PIRP Irp; - PIO_STACK_LOCATION StackLocation; - NTSTATUS status; - - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); - - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, - Adapter->LowerDeviceObject, - NULL, - 0, - NULL, - &Event, - &StatusBlock); - - status = STATUS_UNSUCCESSFUL; - if (Irp == NULL) - goto fail1; - - StackLocation = IoGetNextIrpStackLocation(Irp); - StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; - - StackLocation->Parameters.QueryInterface.InterfaceType = Guid; - StackLocation->Parameters.QueryInterface.Size = (USHORT)Size; - StackLocation->Parameters.QueryInterface.Version = (USHORT)Version; - StackLocation->Parameters.QueryInterface.Interface = Interface; - - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; - - status = IoCallDriver(Adapter->LowerDeviceObject, Irp); - if (status == STATUS_PENDING) { - (VOID) KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); - status = StatusBlock.Status; - } - - if (!NT_SUCCESS(status)) { - if (status == STATUS_NOT_SUPPORTED && Optional) - goto done; - - goto fail2; - } - -done: - return STATUS_SUCCESS; - -fail2: - Error("fail2\n"); - -fail1: - Error("fail1 (%08x)\n", status); - - return status; -} - -#define QUERY_INTERFACE( \ - _Adapter, \ - _ProviderName, \ - _InterfaceName, \ - _Interface, \ - _Size, \ - _Optional) \ - AdapterQueryInterface((_Adapter), \ - &GUID_ ## _ProviderName ## _ ## _InterfaceName ## _INTERFACE, \ - _ProviderName ## _ ## _InterfaceName ## _INTERFACE_VERSION_MAX, \ - (_Interface), \ - (_Size), \ - (_Optional)) - -//============================================================================= -// Debug - -static DECLSPEC_NOINLINE VOID -AdapterDebugCallback( - __in PVOID Context, - __in BOOLEAN Crashing - ) -{ - PXENVBD_ADAPTER Adapter = Context; - ULONG TargetId; - - if (Adapter == NULL || Adapter->DebugCallback == NULL) - return; - - XENBUS_DEBUG(Printf, &Adapter->Debug, - "ADAPTER: Version: %d.%d.%d.%d (%d/%d/%d)\n", - MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION, BUILD_NUMBER, - DAY, MONTH, YEAR); - XENBUS_DEBUG(Printf, &Adapter->Debug, - "ADAPTER: Adapter: 0x%p %s\n", - Context, - Crashing ? "CRASHING" : ""); - XENBUS_DEBUG(Printf, &Adapter->Debug, - "ADAPTER: DevObj 0x%p LowerDevObj 0x%p PhysDevObj 0x%p\n", - Adapter->DeviceObject, - Adapter->LowerDeviceObject, - Adapter->PhysicalDeviceObject); - XENBUS_DEBUG(Printf, &Adapter->Debug, - "ADAPTER: DevicePowerState: %s\n", - PowerDeviceStateName(Adapter->DevicePower)); - XENBUS_DEBUG(Printf, &Adapter->Debug, - "ADAPTER: Enumerator : %s (0x%p)\n", - AdapterEnum(Adapter), Adapter->Enumerator.Buffer); - XENBUS_DEBUG(Printf, &Adapter->Debug, - "ADAPTER: Srbs : %d / %d (%d Total)\n", - Adapter->CurrentSrbs, Adapter->MaximumSrbs, Adapter->TotalSrbs); - - BufferDebugCallback(&Adapter->Debug); - - for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { - // no need to use __AdapterGetTarget (which is locked at DISPATCH) as called at HIGH_LEVEL - PXENVBD_TARGET Target = Adapter->Targets[TargetId]; - if (Target == NULL) - continue; - - XENBUS_DEBUG(Printf, &Adapter->Debug, - "ADAPTER: ====> Target[%-3d] : 0x%p\n", - TargetId, Target); - - // call Target's debug callback directly - TargetDebugCallback(Target, &Adapter->Debug); - - XENBUS_DEBUG(Printf, &Adapter->Debug, - "ADAPTER: <==== Target[%-3d] : 0x%p\n", - TargetId, Target); - } - - Adapter->MaximumSrbs = Adapter->CurrentSrbs; - Adapter->TotalSrbs = 0; -} - -//============================================================================= -// Enumeration -static FORCEINLINE ULONG -__ParseVbd( - __in PCHAR DeviceIdStr - ) -{ - ULONG DeviceId = strtoul(DeviceIdStr, NULL, 10); - - ASSERT3U((DeviceId & ~((1 << 29) - 1)), ==, 0); - - if (DeviceId & (1 << 28)) { - return (DeviceId & ((1 << 20) - 1)) >> 8; /* xvd */ - } else { - switch (DeviceId >> 8) { - case 202: return (DeviceId & 0xF0) >> 4; /* xvd */ - case 8: return (DeviceId & 0xF0) >> 4; /* sd */ - case 3: return (DeviceId & 0xC0) >> 6; /* hda..b */ - case 22: return ((DeviceId & 0xC0) >> 6) + 2; /* hdc..d */ - case 33: return ((DeviceId & 0xC0) >> 6) + 4; /* hde..f */ - case 34: return ((DeviceId & 0xC0) >> 6) + 6; /* hdg..h */ - case 56: return ((DeviceId & 0xC0) >> 6) + 8; /* hdi..j */ - case 57: return ((DeviceId & 0xC0) >> 6) + 10; /* hdk..l */ - case 88: return ((DeviceId & 0xC0) >> 6) + 12; /* hdm..n */ - case 89: return ((DeviceId & 0xC0) >> 6) + 14; /* hdo..p */ - default: break; - } - } - Error("Invalid DeviceId %s (%08x)\n", DeviceIdStr, DeviceId); - return 0xFFFFFFFF; // OBVIOUS ERROR VALUE -} -static FORCEINLINE XENVBD_DEVICE_TYPE -__DeviceType( - __in PCHAR Type - ) -{ - if (strcmp(Type, "disk") == 0) - return XENVBD_DEVICE_TYPE_DISK; - if (strcmp(Type, "cdrom") == 0) - return XENVBD_DEVICE_TYPE_CDROM; - return XENVBD_DEVICE_TYPE_UNKNOWN; -} - -static FORCEINLINE BOOLEAN -__AdapterHiddenTarget( - IN PXENVBD_ADAPTER Adapter, - IN PCHAR DeviceId, - OUT PXENVBD_DEVICE_TYPE DeviceType - ) -{ - NTSTATUS status; - PCHAR Buffer; - CHAR Path[sizeof("device/vbd/XXXXXXXX")]; - ULONG Value; - - *DeviceType = XENVBD_DEVICE_TYPE_UNKNOWN; - status = RtlStringCbPrintfA(Path, - sizeof(Path), - "device/vbd/%s", - DeviceId); - if (!NT_SUCCESS(status)) - goto fail; - - // Ejected? - status = XENBUS_STORE(Read, &Adapter->Store, NULL, Path, "ejected", &Buffer); - if (NT_SUCCESS(status)) { - Value = strtoul(Buffer, NULL, 10); - XENBUS_STORE(Free, &Adapter->Store, Buffer); - - if (Value) - goto ignore; - } - - // Not Disk? - status = XENBUS_STORE(Read, &Adapter->Store, NULL, Path, "device-type", &Buffer); - if (!NT_SUCCESS(status)) - goto ignore; - *DeviceType = __DeviceType(Buffer); - XENBUS_STORE(Free, &Adapter->Store, Buffer); - - switch (*DeviceType) { - case XENVBD_DEVICE_TYPE_DISK: - break; - default: - goto ignore; - } - - // Try to Create - return FALSE; - -fail: - Error("Fail\n"); - return TRUE; - -ignore: - return TRUE; -} -__checkReturn -static FORCEINLINE BOOLEAN -__AdapterIsTargetUnplugged( - __in PXENVBD_ADAPTER Adapter, - __in PCHAR Enumerator, - __in PCHAR Device, - __in ULONG Target +static FORCEINLINE PVOID +__AdapterAllocate( + IN ULONG Size ) { - // Only check targets that could be emulated - if (Target > 3) { - Verbose("Target[%d] : (%s/%s) Emulated NOT_APPLICABLE (non-IDE device)\n", - Target, Enumerator, Device); - return TRUE; - } - - // Check presense of Emulated interface. Absence indicates emulated cannot be unplugged - if (Adapter->Emulated.Interface.Context == NULL) { - Warning("Target[%d] : (%s/%s) Emulated NOT_KNOWN (assumed PRESENT)\n", - Target, Enumerator, Device); - return FALSE; - } - - // Ask XenFilt if Ctrlr(0), Target(Target), Lun(0) is present - if (XENFILT_EMULATED(IsDiskPresent, &Adapter->Emulated, 0, Target, 0)) { - Verbose("Target[%d] : (%s/%s) Emulated PRESENT\n", - Target, Enumerator, Device); - return FALSE; - } else { - Verbose("Target[%d] : (%s/%s) Emulated NOT_PRESENT\n", - Target, Enumerator, Device); - return TRUE; - } + PVOID Buffer; + Buffer = ExAllocatePoolWithTag(NonPagedPool, + Size, + ADAPTER_POOL_TAG); + if (Buffer) + RtlZeroMemory(Buffer, Size); + return Buffer; } static FORCEINLINE VOID -__AdapterEnumerate( - __in PXENVBD_ADAPTER Adapter, - __in PANSI_STRING Devices, - __out PBOOLEAN NeedInvalidate, - __out PBOOLEAN NeedReboot +__AdapterFree( + IN PVOID Buffer ) { - ULONG TargetId; - PANSI_STRING Device; - ULONG Index; - PXENVBD_TARGET Target; - - *NeedInvalidate = FALSE; - *NeedReboot = FALSE; - - for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { - BOOLEAN Missing = TRUE; - - Target = __AdapterGetTarget(Adapter, TargetId); - if (Target == NULL) - continue; - - for (Index = 0; Devices[Index].Buffer != NULL; ++Index) { - ULONG DeviceTargetId; - Device = &Devices[Index]; - DeviceTargetId = __ParseVbd(Device->Buffer); - if (TargetId == DeviceTargetId) { - Missing = FALSE; - break; - } - } - - if (Missing && !TargetIsMissing(Target)) { - TargetSetMissing(Target, "Device Disappeared"); - if (TargetGetDevicePnpState(Target) == Present) - TargetSetDevicePnpState(Target, Deleted); - else - *NeedInvalidate = TRUE; - } - - if (TargetGetDevicePnpState(Target) == Deleted) { - TargetDereference(Target); - TargetDestroy(Target); - } else { - TargetDereference(Target); - } - } - - // add new targets - for (Index = 0; Devices[Index].Buffer != NULL; ++Index) { - XENVBD_DEVICE_TYPE DeviceType; - - Device = &Devices[Index]; - - TargetId = __ParseVbd(Device->Buffer); - if (TargetId == 0xFFFFFFFF) { - continue; - } - - Target = __AdapterGetTarget(Adapter, TargetId); - if (Target) { - TargetDereference(Target); - continue; - } - - if (__AdapterHiddenTarget(Adapter, Device->Buffer, &DeviceType)) { - continue; - } - - if (!__AdapterIsTargetUnplugged(Adapter, - AdapterEnum(Adapter), - Device->Buffer, - TargetId)) { - *NeedReboot = TRUE; - continue; - } - - if (TargetCreate(Adapter, - Device->Buffer, - TargetId, - DeviceType)) { - *NeedInvalidate = TRUE; - } - } + ExFreePoolWithTag(Buffer, ADAPTER_POOL_TAG); } static FORCEINLINE PANSI_STRING @@ -632,10 +139,7 @@ __AdapterMultiSzToAnsi( } } - Ansi = __AllocatePoolWithTag(NonPagedPool, - sizeof (ANSI_STRING) * (Count + 1), - ADAPTER_SIGNATURE); - + Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1)); status = STATUS_NO_MEMORY; if (Ansi == NULL) goto fail1; @@ -645,9 +149,7 @@ __AdapterMultiSzToAnsi( Length = (ULONG)strlen(Buffer); Ansi[Index].MaximumLength = (USHORT)(Length + 1); - Ansi[Index].Buffer = __AllocatePoolWithTag(NonPagedPool, - Ansi[Index].MaximumLength, - ADAPTER_SIGNATURE); + Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength); status = STATUS_NO_MEMORY; if (Ansi[Index].Buffer == NULL) @@ -665,9 +167,9 @@ fail2: Error("fail2\n"); while (--Index >= 0) - __FreePoolWithTag(Ansi[Index].Buffer, ADAPTER_SIGNATURE); + __AdapterFree(Ansi[Index].Buffer); - __FreePoolWithTag(Ansi, ADAPTER_SIGNATURE); + __AdapterFree(Ansi); fail1: Error("fail1 (%08x)\n", status); @@ -701,105 +203,322 @@ __AdapterMultiSzToUpcaseAnsi( } } - Ansi = __AllocatePoolWithTag(NonPagedPool, - sizeof (ANSI_STRING) * (Count + 1), - ADAPTER_SIGNATURE); - + Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1)); status = STATUS_NO_MEMORY; if (Ansi == NULL) goto fail1; - for (Index = 0; Index < Count; Index++) { - ULONG Length; + for (Index = 0; Index < Count; Index++) { + ULONG Length; + + Length = (ULONG)strlen(Buffer); + Ansi[Index].MaximumLength = (USHORT)(Length + 1); + Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength); + + status = STATUS_NO_MEMORY; + if (Ansi[Index].Buffer == NULL) + goto fail2; + + RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length); + Ansi[Index].Length = (USHORT)Length; + + Buffer += Length + 1; + } + + return Ansi; + +fail2: + Error("fail2\n"); + + while (--Index >= 0) + __AdapterFree(Ansi[Index].Buffer); + + __AdapterFree(Ansi); + +fail1: + Error("fail1 (%08x)\n", status); + + return NULL; +} + +static FORCEINLINE VOID +__AdapterFreeAnsi( + IN PANSI_STRING Ansi + ) +{ + ULONG Index; + + for (Index = 0; Ansi[Index].Buffer != NULL; Index++) + __AdapterFree(Ansi[Index].Buffer); + + __AdapterFree(Ansi); +} + +static FORCEINLINE BOOLEAN +__AdapterSetDevicePowerState( + IN PXENVBD_ADAPTER Adapter, + IN DEVICE_POWER_STATE State + ) +{ + KIRQL Irql; + BOOLEAN Changed = FALSE; + + KeAcquireSpinLock(&Adapter->Lock, &Irql); + + if (Adapter->DevicePower != State) { + Verbose("POWER %s to %s\n", PowerDeviceStateName(Adapter->DevicePower), PowerDeviceStateName(State)); + Changed = TRUE; + Adapter->DevicePower = State; + } + + KeReleaseSpinLock(&Adapter->Lock, Irql); + + return Changed; +} + +static FORCEINLINE DEVICE_POWER_STATE +__AdapterGetDevicePowerState( + IN PXENVBD_ADAPTER Adapter + ) +{ + KIRQL Irql; + DEVICE_POWER_STATE State; + + KeAcquireSpinLock(&Adapter->Lock, &Irql); + State = Adapter->DevicePower; + KeReleaseSpinLock(&Adapter->Lock, Irql); + + return State; +} + +static FORCEINLINE PXENVBD_TARGET +AdapterGetTarget( + IN PXENVBD_ADAPTER Adapter, + IN ULONG TargetId + ) +{ + PXENVBD_TARGET Target; + KIRQL Irql; + + ASSERT3U(TargetId, <, XENVBD_MAX_TARGETS); + + KeAcquireSpinLock(&Adapter->TargetLock, &Irql); + Target = Adapter->TargetList[TargetId]; + KeReleaseSpinLock(&Adapter->TargetLock, Irql); + + return Target; +} + +static FORCEINLINE BOOLEAN +__AdapterHiddenTarget( + IN PXENVBD_ADAPTER Adapter, + IN PCHAR DeviceId + ) +{ + NTSTATUS status; + PCHAR Buffer; + CHAR Path[sizeof("device/vbd/XXXXXXXX")]; + BOOLEAN Ejected; + BOOLEAN IsDisk; + + status = RtlStringCbPrintfA(Path, + sizeof(Path), + "device/vbd/%s", + DeviceId); + if (!NT_SUCCESS(status)) + goto fail1; + + // Ejected? + status = XENBUS_STORE(Read, + &Adapter->StoreInterface, + NULL, + Path, + "ejected", + &Buffer); + if (NT_SUCCESS(status)) { + Ejected = (BOOLEAN)strtoul(Buffer, NULL, 2); + + XENBUS_STORE(Free, + &Adapter->StoreInterface, + Buffer); + + if (Ejected) + goto ignore; + } + + // Not Disk? + status = XENBUS_STORE(Read, + &Adapter->StoreInterface, + NULL, + Path, + "device-type", + &Buffer); + if (!NT_SUCCESS(status)) + goto ignore; + + IsDisk = (strcmp(Buffer, "disk") == 0); + + XENBUS_STORE(Free, + &Adapter->StoreInterface, + Buffer); + + if (!IsDisk) + goto ignore; - Length = (ULONG)strlen(Buffer); - Ansi[Index].MaximumLength = (USHORT)(Length + 1); - Ansi[Index].Buffer = __AllocatePoolWithTag(NonPagedPool, - Ansi[Index].MaximumLength, - ADAPTER_SIGNATURE); + // Try to Create + return FALSE; - status = STATUS_NO_MEMORY; - if (Ansi[Index].Buffer == NULL) - goto fail2; +fail1: + Error("fail1\n"); + return TRUE; - RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length); - Ansi[Index].Length = (USHORT)Length; +ignore: + return TRUE; +} - Buffer += Length + 1; - } +BOOLEAN +AdapterIsTargetEmulated( + IN PXENVBD_ADAPTER Adapter, + IN ULONG TargetId + ) +{ + BOOLEAN Emulated; + NTSTATUS status; - return Ansi; + // Only check targets that could be emulated + if (TargetId > 3) + return FALSE; -fail2: - Error("fail2\n"); + // Check presense of Emulated interface. Absence indicates emulated cannot be unplugged + if (Adapter->EmulatedInterface.Interface.Context == NULL) + return TRUE; - while (--Index >= 0) - __FreePoolWithTag(Ansi[Index].Buffer, ADAPTER_SIGNATURE); + // Acquire failed, assume emulated + status = XENFILT_EMULATED(Acquire, &Adapter->EmulatedInterface); + if (!NT_SUCCESS(status)) + return TRUE; - __FreePoolWithTag(Ansi, ADAPTER_SIGNATURE); + // Ask XenFilt if Ctrlr(0), Target(Target), Lun(0) is present + Emulated = XENFILT_EMULATED(IsDiskPresent, + &Adapter->EmulatedInterface, + 0, + TargetId, + 0); -fail1: - Error("fail1 (%08x)\n", status); + XENFILT_EMULATED(Release, &Adapter->EmulatedInterface); - return NULL; + return Emulated; } static FORCEINLINE VOID -__AdapterFreeAnsi( - IN PANSI_STRING Ansi +__AdapterEnumerate( + IN PXENVBD_ADAPTER Adapter, + IN PANSI_STRING Devices ) { + KIRQL Irql; + ULONG TargetId; + ULONG DeviceId; + PANSI_STRING Device; ULONG Index; + PXENVBD_TARGET Target; + BOOLEAN NeedInvalidate; + BOOLEAN NeedReboot; - for (Index = 0; Ansi[Index].Buffer != NULL; Index++) - __FreePoolWithTag(Ansi[Index].Buffer, ADAPTER_SIGNATURE); + NeedInvalidate = FALSE; + NeedReboot = FALSE; - __FreePoolWithTag(Ansi, ADAPTER_SIGNATURE); -} + for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { + BOOLEAN Missing = TRUE; -static DECLSPEC_NOINLINE VOID -AdapterScanTargets( - __in PXENVBD_ADAPTER Adapter - ) -{ - NTSTATUS Status; - PCHAR Buffer; - PANSI_STRING Devices; - BOOLEAN NeedInvalidate; - BOOLEAN NeedReboot; + Target = AdapterGetTarget(Adapter, TargetId); + if (Target == NULL) + continue; - Status = XENBUS_STORE(Directory, &Adapter->Store, NULL, "device", AdapterEnum(Adapter), &Buffer); - if (!NT_SUCCESS(Status)) - return; + for (Index = 0; Devices[Index].Buffer != NULL; ++Index) { + Device = &Devices[Index]; - Devices = __AdapterMultiSzToAnsi(Buffer); - XENBUS_STORE(Free, &Adapter->Store, Buffer); + if (Device->Length == 0) + continue; - if (Devices == NULL) - return; + DeviceId = strtoul(Device->Buffer, NULL, 10); + if (TargetGetDeviceId(Target) == DeviceId) { + Device->Length = 0; + Missing = FALSE; + break; + } + } + + if (Missing && !TargetIsMissing(Target)) { + TargetSetMissing(Target, "Device Disappeared"); + if (TargetGetDevicePnpState(Target) == Present) + TargetSetDevicePnpState(Target, Deleted); + else + NeedInvalidate = TRUE; + } - __AdapterEnumerate(Adapter, Devices, &NeedInvalidate, &NeedReboot); - __AdapterFreeAnsi(Devices); + if (TargetGetDevicePnpState(Target) == Deleted) { + KeAcquireSpinLock(&Adapter->TargetLock, &Irql); + ASSERT3P(Adapter->TargetList[TargetId], ==, Target); + Adapter->TargetList[TargetId] = NULL; + KeReleaseSpinLock(&Adapter->TargetLock, Irql); - if (NeedInvalidate) { - StorPortNotification(BusChangeDetected, Adapter, 0); + TargetDestroy(Target); + } } - if (NeedReboot) { - DriverRequestReboot(); + + // add new targets + for (Index = 0; Devices[Index].Buffer != NULL; ++Index) { + NTSTATUS status; + + Device = &Devices[Index]; + + if (Device->Length == 0) + continue; + + if (__AdapterHiddenTarget(Adapter, Device->Buffer)) + continue; + + status = TargetCreate(Adapter, + Device->Buffer, + &Target); + if (status == STATUS_RETRY) + NeedReboot = TRUE; + if (!NT_SUCCESS(status)) + continue; + + TargetId = TargetGetTargetId(Target); + + KeAcquireSpinLock(&Adapter->TargetLock, &Irql); + ASSERT3P(Adapter->TargetList[TargetId], ==, NULL); + Adapter->TargetList[TargetId] = Target; + KeReleaseSpinLock(&Adapter->TargetLock, Irql); + + NeedInvalidate = TRUE; } + + if (NeedInvalidate) + StorPortNotification(BusChangeDetected, + Adapter, + NULL); + if (NeedReboot) + DriverRequestReboot(); } -__checkReturn static DECLSPEC_NOINLINE NTSTATUS -AdapterScan( - __in PXENVBD_THREAD Thread, - __in PVOID Context +AdapterScanThread( + IN PXENVBD_THREAD Thread, + IN PVOID Context ) { PXENVBD_ADAPTER Adapter = Context; - PKEVENT Event = ThreadGetEvent(Thread); + PKEVENT Event = ThreadGetEvent(Thread); for (;;) { + NTSTATUS status; + PCHAR Buffer; + PANSI_STRING Devices; + Trace("waiting...\n"); (VOID) KeWaitForSingleObject(Event, @@ -811,204 +530,39 @@ AdapterScan( if (ThreadIsAlerted(Thread)) break; + if (__AdapterGetDevicePowerState(Adapter) != PowerDeviceD0) + goto done; + + status = XENBUS_STORE(Directory, + &Adapter->StoreInterface, + NULL, + "device", + "vbd", + &Buffer); + if (NT_SUCCESS(status)) { + Devices = __AdapterMultiSzToAnsi(Buffer); - if (__AdapterGetDevicePowerState(Adapter) == PowerDeviceD0) - AdapterScanTargets(Adapter); - - KeSetEvent(&Adapter->ScanEvent, IO_NO_INCREMENT, FALSE); - } - KeSetEvent(&Adapter->ScanEvent, IO_NO_INCREMENT, FALSE); - - return STATUS_SUCCESS; -} - -//============================================================================= -// Initialize, Start, Stop - -__drv_requiresIRQL(PASSIVE_LEVEL) -static FORCEINLINE NTSTATUS -__AdapterQueryInterfaces( - __in PXENVBD_ADAPTER Adapter - ) -{ - NTSTATUS Status; - - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - - // Get STORE Interface - Status = QUERY_INTERFACE(Adapter, - XENBUS, - STORE, - (PINTERFACE)&Adapter->Store, - sizeof (Adapter->Store), - FALSE); - if (!NT_SUCCESS(Status)) - goto fail1; - - // Get EVTCHN Interface - Status = QUERY_INTERFACE(Adapter, - XENBUS, - EVTCHN, - (PINTERFACE)&Adapter->Evtchn, - sizeof (Adapter->Evtchn), - FALSE); - if (!NT_SUCCESS(Status)) - goto fail2; - - // Get GNTTAB Interface - Status = QUERY_INTERFACE(Adapter, - XENBUS, - GNTTAB, - (PINTERFACE)&Adapter->Gnttab, - sizeof (Adapter->Gnttab), - FALSE); - if (!NT_SUCCESS(Status)) - goto fail3; - - // Get SUSPEND Interface - Status = QUERY_INTERFACE(Adapter, - XENBUS, - SUSPEND, - (PINTERFACE)&Adapter->Suspend, - sizeof (Adapter->Suspend), - FALSE); - if (!NT_SUCCESS(Status)) - goto fail4; - - // Get DEBUG Interface - Status = QUERY_INTERFACE(Adapter, - XENBUS, - DEBUG, - (PINTERFACE)&Adapter->Debug, - sizeof (Adapter->Debug), - FALSE); - if (!NT_SUCCESS(Status)) - goto fail5; - - // Get UNPLUG Interface - Status = QUERY_INTERFACE(Adapter, - XENBUS, - UNPLUG, - (PINTERFACE)&Adapter->Unplug, - sizeof (Adapter->Unplug), - FALSE); - if (!NT_SUCCESS(Status)) - goto fail6; + XENBUS_STORE(Free, + &Adapter->StoreInterface, + Buffer); + } else { + Devices = NULL; + } - // Get EMULATED Interface (optional) - Status = QUERY_INTERFACE(Adapter, - XENFILT, - EMULATED, - (PINTERFACE)&Adapter->Emulated, - sizeof (Adapter->Emulated), - TRUE); - if (!NT_SUCCESS(Status)) - goto fail7; + if (Devices == NULL) + goto done; - return STATUS_SUCCESS; + __AdapterEnumerate(Adapter, + Devices); -fail7: - RtlZeroMemory(&Adapter->Unplug, - sizeof (XENBUS_UNPLUG_INTERFACE)); -fail6: - RtlZeroMemory(&Adapter->Debug, - sizeof (XENBUS_DEBUG_INTERFACE)); -fail5: - RtlZeroMemory(&Adapter->Suspend, - sizeof (XENBUS_SUSPEND_INTERFACE)); -fail4: - RtlZeroMemory(&Adapter->Gnttab, - sizeof (XENBUS_GNTTAB_INTERFACE)); -fail3: - RtlZeroMemory(&Adapter->Evtchn, - sizeof (XENBUS_EVTCHN_INTERFACE)); -fail2: - RtlZeroMemory(&Adapter->Store, - sizeof (XENBUS_STORE_INTERFACE)); -fail1: - return Status; -} -static FORCEINLINE VOID -__AdapterZeroInterfaces( - __in PXENVBD_ADAPTER Adapter - ) -{ - RtlZeroMemory(&Adapter->Emulated, - sizeof (XENFILT_EMULATED_INTERFACE)); - RtlZeroMemory(&Adapter->Unplug, - sizeof (XENBUS_UNPLUG_INTERFACE)); - RtlZeroMemory(&Adapter->Debug, - sizeof (XENBUS_DEBUG_INTERFACE)); - RtlZeroMemory(&Adapter->Suspend, - sizeof (XENBUS_SUSPEND_INTERFACE)); - RtlZeroMemory(&Adapter->Gnttab, - sizeof (XENBUS_GNTTAB_INTERFACE)); - RtlZeroMemory(&Adapter->Evtchn, - sizeof (XENBUS_EVTCHN_INTERFACE)); - RtlZeroMemory(&Adapter->Store, - sizeof (XENBUS_STORE_INTERFACE)); -} -static FORCEINLINE NTSTATUS -__AdapterAcquire( - __in PXENVBD_ADAPTER Adapter - ) -{ - NTSTATUS status; + __AdapterFreeAnsi(Devices); - if (Adapter->Emulated.Interface.Context) { - status = XENFILT_EMULATED(Acquire, &Adapter->Emulated); - if (!NT_SUCCESS(status)) - goto fail1; +done: + KeSetEvent(&Adapter->ScanEvent, IO_NO_INCREMENT, FALSE); } - - status = XENBUS_SUSPEND(Acquire, &Adapter->Suspend); - if (!NT_SUCCESS(status)) - goto fail2; - - status = XENBUS_DEBUG(Acquire, &Adapter->Debug); - if (!NT_SUCCESS(status)) - goto fail3; - - status = XENBUS_GNTTAB(Acquire, &Adapter->Gnttab); - if (!NT_SUCCESS(status)) - goto fail4; - - status = XENBUS_EVTCHN(Acquire, &Adapter->Evtchn); - if (!NT_SUCCESS(status)) - goto fail5; - - status = XENBUS_STORE(Acquire, &Adapter->Store); - if (!NT_SUCCESS(status)) - goto fail6; + KeSetEvent(&Adapter->ScanEvent, IO_NO_INCREMENT, FALSE); return STATUS_SUCCESS; - -fail6: - XENBUS_EVTCHN(Release, &Adapter->Evtchn); -fail5: - XENBUS_GNTTAB(Release, &Adapter->Gnttab); -fail4: - XENBUS_DEBUG(Release, &Adapter->Debug); -fail3: - XENBUS_SUSPEND(Release, &Adapter->Suspend); -fail2: - if (Adapter->Emulated.Interface.Context) - XENFILT_EMULATED(Release, &Adapter->Emulated); -fail1: - return status; -} -static FORCEINLINE VOID -__AdapterRelease( - __in PXENVBD_ADAPTER Adapter - ) -{ - XENBUS_STORE(Release, &Adapter->Store); - XENBUS_EVTCHN(Release, &Adapter->Evtchn); - XENBUS_GNTTAB(Release, &Adapter->Gnttab); - XENBUS_DEBUG(Release, &Adapter->Debug); - XENBUS_SUSPEND(Release, &Adapter->Suspend); - if (Adapter->Emulated.Interface.Context) - XENFILT_EMULATED(Release, &Adapter->Emulated); } static FORCEINLINE BOOLEAN @@ -1084,7 +638,7 @@ AdapterClearDistribution( Trace("====>\n"); status = XENBUS_STORE(Directory, - &Adapter->Store, + &Adapter->StoreInterface, NULL, NULL, "drivers", @@ -1093,7 +647,7 @@ AdapterClearDistribution( Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer); XENBUS_STORE(Free, - &Adapter->Store, + &Adapter->StoreInterface, Buffer); } else { Distributions = NULL; @@ -1106,7 +660,7 @@ AdapterClearDistribution( PANSI_STRING Distribution = &Distributions[Index]; status = XENBUS_STORE(Read, - &Adapter->Store, + &Adapter->StoreInterface, NULL, "drivers", Distribution->Buffer, @@ -1116,13 +670,13 @@ AdapterClearDistribution( if (__AdapterMatchDistribution(Adapter, Buffer)) (VOID) XENBUS_STORE(Remove, - &Adapter->Store, + &Adapter->StoreInterface, NULL, "drivers", Distribution->Buffer); XENBUS_STORE(Free, - &Adapter->Store, + &Adapter->StoreInterface, Buffer); } @@ -1158,7 +712,7 @@ AdapterSetDistribution( ASSERT(NT_SUCCESS(status)); status = XENBUS_STORE(Read, - &Adapter->Store, + &Adapter->StoreInterface, NULL, "drivers", Distribution, @@ -1171,7 +725,7 @@ AdapterSetDistribution( } XENBUS_STORE(Free, - &Adapter->Store, + &Adapter->StoreInterface, Buffer); Index++; @@ -1200,7 +754,7 @@ update: #endif (VOID) XENBUS_STORE(Printf, - &Adapter->Store, + &Adapter->StoreInterface, NULL, "drivers", Distribution, @@ -1229,27 +783,30 @@ fail1: static FORCEINLINE NTSTATUS __AdapterD3ToD0( - __in PXENVBD_ADAPTER Adapter + IN PXENVBD_ADAPTER Adapter ) { - NTSTATUS Status; + NTSTATUS status; Trace("=====>\n"); + status = XENBUS_STORE(Acquire, &Adapter->StoreInterface); + if (!NT_SUCCESS(status)) + goto fail1; + (VOID) AdapterSetDistribution(Adapter); - ASSERT3P(Adapter->ScanWatch, ==, NULL); - Status = XENBUS_STORE(WatchAdd, - &Adapter->Store, + status = XENBUS_STORE(WatchAdd, + &Adapter->StoreInterface, "device", - AdapterEnum(Adapter), + "vbd", ThreadGetEvent(Adapter->ScanThread), &Adapter->ScanWatch); - if (!NT_SUCCESS(Status)) - goto fail1; + if (!NT_SUCCESS(status)) + goto fail2; (VOID) XENBUS_STORE(Printf, - &Adapter->Store, + &Adapter->StoreInterface, NULL, "feature/hotplug", "vbd", @@ -1259,193 +816,257 @@ __AdapterD3ToD0( Trace("<=====\n"); return STATUS_SUCCESS; +fail2: + Error("fail2\n"); + + XENBUS_STORE(Release, &Adapter->StoreInterface); + fail1: - Error("fail1 (%08x)\n", Status); + Error("fail1 (%08x)\n", status); - return Status; + return status; } static FORCEINLINE VOID __AdapterD0ToD3( - __in PXENVBD_ADAPTER Adapter + IN PXENVBD_ADAPTER Adapter ) { Trace("=====>\n"); (VOID) XENBUS_STORE(Remove, - &Adapter->Store, + &Adapter->StoreInterface, NULL, "feature/hotplug", "vbd"); (VOID) XENBUS_STORE(WatchRemove, - &Adapter->Store, + &Adapter->StoreInterface, Adapter->ScanWatch); Adapter->ScanWatch = NULL; AdapterClearDistribution(Adapter); + XENBUS_STORE(Release, &Adapter->StoreInterface); + Trace("<=====\n"); } -__drv_requiresIRQL(DISPATCH_LEVEL) static VOID AdapterSuspendLateCallback( - __in PVOID Argument + IN PVOID Argument ) { - PXENVBD_ADAPTER Adapter = Argument; - NTSTATUS Status; + PXENVBD_ADAPTER Adapter = Argument; + NTSTATUS status; - Verbose("%s (%s)\n", - MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR, - DAY_STR "/" MONTH_STR "/" YEAR_STR); + Verbose("%u.%u.%u.%u (%02u/%02u/%04u)\n", + MAJOR_VERSION, + MINOR_VERSION, + MICRO_VERSION, + BUILD_NUMBER, + DAY, + MONTH, + YEAR); __AdapterD0ToD3(Adapter); - Status = __AdapterD3ToD0(Adapter); - ASSERT(NT_SUCCESS(Status)); + status = __AdapterD3ToD0(Adapter); + ASSERT(NT_SUCCESS(status)); +} + +static DECLSPEC_NOINLINE VOID +AdapterDebugCallback( + IN PVOID Context, + IN BOOLEAN Crashing + ) +{ + PXENVBD_ADAPTER Adapter = Context; + ULONG TargetId; + + XENBUS_DEBUG(Printf, + &Adapter->DebugInterface, + "ADAPTER: Version: %u.%u.%u.%u (%02u/%02u/%04u)\n", + MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION, BUILD_NUMBER, + DAY, MONTH, YEAR); + XENBUS_DEBUG(Printf, + &Adapter->DebugInterface, + "ADAPTER: Adapter: 0x%p %s\n", + Context, + Crashing ? "CRASHING" : ""); + XENBUS_DEBUG(Printf, + &Adapter->DebugInterface, + "ADAPTER: DevObj 0x%p LowerDevObj 0x%p PhysDevObj 0x%p\n", + Adapter->DeviceObject, + Adapter->LowerDeviceObject, + Adapter->PhysicalDeviceObject); + XENBUS_DEBUG(Printf, + &Adapter->DebugInterface, + "ADAPTER: DevicePowerState: %s\n", + PowerDeviceStateName(Adapter->DevicePower)); + XENBUS_DEBUG(Printf, + &Adapter->DebugInterface, + "ADAPTER: Srbs : %u built, %u started, %u completed\n", + Adapter->BuildIo, + Adapter->StartIo, + Adapter->Completed); + + BufferDebugCallback(&Adapter->DebugInterface); + + for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { + // no need to use AdapterGetTarget (which is locked at DISPATCH) as called at HIGH_LEVEL + PXENVBD_TARGET Target = Adapter->TargetList[TargetId]; + if (Target == NULL) + continue; + + XENBUS_DEBUG(Printf, &Adapter->DebugInterface, + "ADAPTER: ====> Target[%-3d] : 0x%p\n", + TargetId, Target); + + // call Target's debug callback directly + TargetDebugCallback(Target, &Adapter->DebugInterface); + + XENBUS_DEBUG(Printf, &Adapter->DebugInterface, + "ADAPTER: <==== Target[%-3d] : 0x%p\n", + TargetId, Target); + } } static NTSTATUS AdapterD3ToD0( - __in PXENVBD_ADAPTER Adapter + IN PXENVBD_ADAPTER Adapter ) { - NTSTATUS Status; - ULONG TargetId; + NTSTATUS status; + ULONG TargetId; if (!__AdapterSetDevicePowerState(Adapter, PowerDeviceD0)) return STATUS_SUCCESS; - Trace("=====> (%d)\n", KeGetCurrentIrql()); Verbose("D3->D0\n"); - // Get Interfaces - Status = __AdapterAcquire(Adapter); - if (!NT_SUCCESS(Status)) + status = XENBUS_SUSPEND(Acquire, &Adapter->SuspendInterface); + if (!NT_SUCCESS(status)) goto fail1; - - // register debug callback - ASSERT3P(Adapter->DebugCallback, ==, NULL); - Status = XENBUS_DEBUG(Register, - &Adapter->Debug, + + status = XENBUS_DEBUG(Acquire, &Adapter->DebugInterface); + if (!NT_SUCCESS(status)) + goto fail2; + + status = XENBUS_DEBUG(Register, + &Adapter->DebugInterface, __MODULE__, AdapterDebugCallback, Adapter, &Adapter->DebugCallback); - if (!NT_SUCCESS(Status)) - goto fail2; + if (!NT_SUCCESS(status)) + goto fail3; + + status = __AdapterD3ToD0(Adapter); + if (!NT_SUCCESS(status)) + goto fail4; - // Power UP any TARGETs for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { - PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId); - if (Target) { - Status = TargetD3ToD0(Target); - TargetDereference(Target); + PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId); + if (Target == NULL) + continue; - if (!NT_SUCCESS(Status)) - goto fail3; - } - } + status = TargetD3ToD0(Target); - Status = __AdapterD3ToD0(Adapter); - if (!NT_SUCCESS(Status)) - goto fail4; + if (!NT_SUCCESS(status)) + goto fail5; + } - // register suspend callback to re-register the watch - ASSERT3P(Adapter->SuspendCallback, ==, NULL); - Status = XENBUS_SUSPEND(Register, - &Adapter->Suspend, + status = XENBUS_SUSPEND(Register, + &Adapter->SuspendInterface, SUSPEND_CALLBACK_LATE, AdapterSuspendLateCallback, Adapter, &Adapter->SuspendCallback); - if (!NT_SUCCESS(Status)) - goto fail5; + if (!NT_SUCCESS(status)) + goto fail6; - Trace("<===== (%d)\n", KeGetCurrentIrql()); return STATUS_SUCCESS; +fail6: + Error("fail6\n"); fail5: - Error("Fail5\n"); + Error("fail5\n"); + + for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { + PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId); + if (Target == NULL) + continue; + TargetD0ToD3(Target); + } __AdapterD0ToD3(Adapter); fail4: - Error("Fail4\n"); + Error("fail4\n"); -fail3: - Error("Fail3\n"); + XENBUS_DEBUG(Deregister, + &Adapter->DebugInterface, + Adapter->DebugCallback); + Adapter->DebugCallback = NULL; - for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { - PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId); - if (Target) { - TargetD0ToD3(Target); - TargetDereference(Target); - } - } +fail3: + Error("fail3\n"); - XENBUS_DEBUG(Deregister, &Adapter->Debug, Adapter->DebugCallback); - Adapter->DebugCallback = NULL; + XENBUS_DEBUG(Release, &Adapter->DebugInterface); fail2: - Error("Fail2\n"); + Error("fail2\n"); + + XENBUS_SUSPEND(Release, &Adapter->SuspendInterface); - __AdapterRelease(Adapter); - fail1: - Error("Fail1 (%08x)\n", Status); + Error("fail1 (%08x)\n", status); __AdapterSetDevicePowerState(Adapter, PowerDeviceD3); - return Status; + return status; } static VOID AdapterD0ToD3( - __in PXENVBD_ADAPTER Adapter + IN PXENVBD_ADAPTER Adapter ) { - ULONG TargetId; + ULONG TargetId; if (!__AdapterSetDevicePowerState(Adapter, PowerDeviceD3)) return; - Trace("=====> (%d)\n", KeGetCurrentIrql()); Verbose("D0->D3\n"); - // remove suspend callback - XENBUS_SUSPEND(Deregister, &Adapter->Suspend, Adapter->SuspendCallback); + XENBUS_SUSPEND(Deregister, + &Adapter->SuspendInterface, + Adapter->SuspendCallback); Adapter->SuspendCallback = NULL; - __AdapterD0ToD3(Adapter); - - // Power DOWN any TARGETs for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { - PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId); - if (Target) { - TargetD0ToD3(Target); - TargetDereference(Target); - } + PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId); + if (Target == NULL) + continue; + TargetD0ToD3(Target); } - // free debug callback - if (Adapter->DebugCallback != NULL) { - XENBUS_DEBUG(Deregister, &Adapter->Debug, Adapter->DebugCallback); - Adapter->DebugCallback = NULL; - } + __AdapterD0ToD3(Adapter); - // Release Interfaces - __AdapterRelease(Adapter); + XENBUS_DEBUG(Deregister, + &Adapter->DebugInterface, + Adapter->DebugCallback); + Adapter->DebugCallback = NULL; - Trace("<===== (%d)\n", KeGetCurrentIrql()); + XENBUS_DEBUG(Release, &Adapter->DebugInterface); + + XENBUS_SUSPEND(Release, &Adapter->SuspendInterface); } -__checkReturn static DECLSPEC_NOINLINE NTSTATUS -AdapterDevicePower( - __in PXENVBD_THREAD Thread, - __in PVOID Context +AdapterDevicePowerThread( + IN PXENVBD_THREAD Thread, + IN PVOID Context ) { PXENVBD_ADAPTER Adapter = Context; @@ -1455,7 +1076,6 @@ AdapterDevicePower( PIO_STACK_LOCATION Stack; DEVICE_POWER_STATE DeviceState; POWER_ACTION Action; - NTSTATUS Status; if (!ThreadWait(Thread)) break; @@ -1474,12 +1094,10 @@ AdapterDevicePower( case IRP_MN_SET_POWER: switch (DeviceState) { case PowerDeviceD0: - Verbose("ADAPTER:PowerDeviceD0\n"); AdapterD3ToD0(Adapter); break; case PowerDeviceD3: - Verbose("ADAPTER:PowerDeviceD3 (%s)\n", PowerActionName(Action)); AdapterD0ToD3(Adapter); break; @@ -1491,381 +1109,341 @@ AdapterDevicePower( default: break; } - Status = DriverDispatchPower(Adapter->DeviceObject, Irp); - if (!NT_SUCCESS(Status)) { - Warning("StorPort failed PowerIRP with %08x\n", Status); - } + (VOID) DriverDispatchPower(Adapter->DeviceObject, Irp); } return STATUS_SUCCESS; } -__checkReturn -__drv_requiresIRQL(PASSIVE_LEVEL) static NTSTATUS -__AdapterInitialize( - __in PXENVBD_ADAPTER Adapter +__AdapterQueryInterface( + IN PXENVBD_ADAPTER Adapter, + IN const GUID *Guid, + IN ULONG Version, + OUT PINTERFACE Interface, + IN ULONG Size, + IN BOOLEAN Optional ) { - ULONG StorStatus; - NTSTATUS Status; + KEVENT Event; + IO_STATUS_BLOCK StatusBlock; + PIRP Irp; + PIO_STACK_LOCATION StackLocation; + NTSTATUS status; + + ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); + + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, + Adapter->LowerDeviceObject, + NULL, + 0, + NULL, + &Event, + &StatusBlock); + + status = STATUS_UNSUCCESSFUL; + if (Irp == NULL) + goto fail1; + + StackLocation = IoGetNextIrpStackLocation(Irp); + StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; + + StackLocation->Parameters.QueryInterface.InterfaceType = Guid; + StackLocation->Parameters.QueryInterface.Size = (USHORT)Size; + StackLocation->Parameters.QueryInterface.Version = (USHORT)Version; + StackLocation->Parameters.QueryInterface.Interface = Interface; + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + status = IoCallDriver(Adapter->LowerDeviceObject, Irp); + if (status == STATUS_PENDING) { + (VOID) KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + status = StatusBlock.Status; + } + + if (!NT_SUCCESS(status)) { + if (status == STATUS_NOT_SUPPORTED && Optional) + goto done; + + goto fail2; + } + +done: + return STATUS_SUCCESS; + +fail2: + Error("fail2\n"); + +fail1: + Error("fail1 (%08x)\n", status); - Trace("=====> (%d)\n", KeGetCurrentIrql()); + return status; +} + +#define AdapterQueryInterface(_adapter, _name, _itf, _opt) \ + __AdapterQueryInterface((_adapter), \ + &GUID_ ## _name ## _INTERFACE, \ + _name ## _INTERFACE_VERSION_MAX, \ + (PINTERFACE)(_itf), \ + sizeof( ## _name ## _INTERFACE), \ + (_opt)) +static NTSTATUS +AdapterInitialize( + IN PXENVBD_ADAPTER Adapter, + IN PDEVICE_OBJECT DeviceObject, + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN PDEVICE_OBJECT LowerDeviceObject + ) +{ + NTSTATUS status; ASSERT3U(KeGetCurrentIrql(), <=, DISPATCH_LEVEL); - // initialize the memory - Adapter->DevicePower = PowerDeviceD3; + + Adapter->DeviceObject = DeviceObject; + Adapter->PhysicalDeviceObject = PhysicalDeviceObject; + Adapter->LowerDeviceObject = LowerDeviceObject; + Adapter->DevicePower = PowerDeviceD3; + KeInitializeSpinLock(&Adapter->TargetLock); KeInitializeSpinLock(&Adapter->Lock); KeInitializeEvent(&Adapter->ScanEvent, SynchronizationEvent, FALSE); - Adapter->Signature = ADAPTER_SIGNATURE; - - StorStatus = StorPortGetDeviceObjects(Adapter, - &Adapter->DeviceObject, - &Adapter->PhysicalDeviceObject, - &Adapter->LowerDeviceObject); - Status = STATUS_UNSUCCESSFUL; - if (StorStatus != STOR_STATUS_SUCCESS) { - Error("StorPortGetDeviceObjects() (%x:%s)\n", StorStatus, StorStatusName(StorStatus)); + status = AdapterQueryInterface(Adapter, + XENBUS_STORE, + &Adapter->StoreInterface, + FALSE); + if (!NT_SUCCESS(status)) goto fail1; - } - // get interfaces - Status = __AdapterQueryInterfaces(Adapter); - if (!NT_SUCCESS(Status)) + status = AdapterQueryInterface(Adapter, + XENBUS_EVTCHN, + &Adapter->EvtchnInterface, + FALSE); + if (!NT_SUCCESS(status)) goto fail2; - // start enum thread - Status = ThreadCreate(AdapterScan, Adapter, &Adapter->ScanThread); - if (!NT_SUCCESS(Status)) + status = AdapterQueryInterface(Adapter, + XENBUS_GNTTAB, + &Adapter->GnttabInterface, + FALSE); + if (!NT_SUCCESS(status)) goto fail3; - Status = ThreadCreate(AdapterDevicePower, Adapter, &Adapter->DevicePowerThread); - if (!NT_SUCCESS(Status)) + status = AdapterQueryInterface(Adapter, + XENBUS_SUSPEND, + &Adapter->SuspendInterface, + FALSE); + if (!NT_SUCCESS(status)) goto fail4; - Trace("<===== (%d)\n", KeGetCurrentIrql()); + status = AdapterQueryInterface(Adapter, + XENBUS_DEBUG, + &Adapter->DebugInterface, + FALSE); + if (!NT_SUCCESS(status)) + goto fail5; + + status = AdapterQueryInterface(Adapter, + XENBUS_UNPLUG, + &Adapter->UnplugInterface, + FALSE); + if (!NT_SUCCESS(status)) + goto fail6; + + status = AdapterQueryInterface(Adapter, + XENFILT_EMULATED, + &Adapter->EmulatedInterface, + TRUE); + if (!NT_SUCCESS(status)) + goto fail7; + + status = ThreadCreate(AdapterScanThread, + Adapter, + &Adapter->ScanThread); + if (!NT_SUCCESS(status)) + goto fail8; + + status = ThreadCreate(AdapterDevicePowerThread, + Adapter, + &Adapter->DevicePowerThread); + if (!NT_SUCCESS(status)) + goto fail9; + return STATUS_SUCCESS; -fail4: - Error("fail4\n"); +fail9: + Error("fail9\n"); ThreadAlert(Adapter->ScanThread); ThreadJoin(Adapter->ScanThread); Adapter->ScanThread = NULL; +fail8: + Error("fail8\n"); + RtlZeroMemory(&Adapter->EmulatedInterface, + sizeof (XENFILT_EMULATED_INTERFACE)); +fail7: + Error("fail7\n"); + RtlZeroMemory(&Adapter->UnplugInterface, + sizeof (XENBUS_UNPLUG_INTERFACE)); +fail6: + Error("fail6\n"); + RtlZeroMemory(&Adapter->DebugInterface, + sizeof (XENBUS_DEBUG_INTERFACE)); +fail5: + Error("fail5\n"); + RtlZeroMemory(&Adapter->SuspendInterface, + sizeof (XENBUS_SUSPEND_INTERFACE)); +fail4: + Error("fail4\n"); + RtlZeroMemory(&Adapter->GnttabInterface, + sizeof (XENBUS_GNTTAB_INTERFACE)); fail3: Error("fail3\n"); - __AdapterZeroInterfaces(Adapter); + RtlZeroMemory(&Adapter->EvtchnInterface, + sizeof (XENBUS_EVTCHN_INTERFACE)); fail2: Error("fail2\n"); - Adapter->DeviceObject = NULL; - Adapter->PhysicalDeviceObject = NULL; - Adapter->LowerDeviceObject = NULL; + RtlZeroMemory(&Adapter->StoreInterface, + sizeof (XENBUS_STORE_INTERFACE)); fail1: - Error("fail1 (%08x)\n", Status); - return Status; + Error("fail1 (%08x)\n", status); + + RtlZeroMemory(&Adapter->TargetLock, sizeof(KSPIN_LOCK)); + RtlZeroMemory(&Adapter->Lock, sizeof(KSPIN_LOCK)); + RtlZeroMemory(&Adapter->ScanEvent, sizeof(KEVENT)); + + Adapter->DevicePower = 0; + Adapter->DeviceObject = NULL; + Adapter->PhysicalDeviceObject = NULL; + Adapter->LowerDeviceObject = NULL; + + return status; } -__drv_maxIRQL(PASSIVE_LEVEL) + static VOID -__AdapterTerminate( - __in PXENVBD_ADAPTER Adapter +AdapterTeardown( + IN PXENVBD_ADAPTER Adapter ) { - ULONG TargetId; - - Trace("=====> (%d)\n", KeGetCurrentIrql()); + ULONG TargetId; ASSERT3U(Adapter->DevicePower, ==, PowerDeviceD3); - // stop device power thread ThreadAlert(Adapter->DevicePowerThread); ThreadJoin(Adapter->DevicePowerThread); Adapter->DevicePowerThread = NULL; - // stop enum thread ThreadAlert(Adapter->ScanThread); ThreadJoin(Adapter->ScanThread); Adapter->ScanThread = NULL; - // clear device objects - Adapter->DeviceObject = NULL; - Adapter->PhysicalDeviceObject = NULL; - Adapter->LowerDeviceObject = NULL; - - // delete targets - for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { - PXENVBD_TARGET Target = __AdapterGetTargetAlways(Adapter, TargetId, __FUNCTION__); - if (Target) { - // Target may not be in Deleted state yet, force it as Adapter is terminating - if (TargetGetDevicePnpState(Target) != Deleted) - TargetSetDevicePnpState(Target, Deleted); - // update missing (for debug output more than anything else - TargetSetMissing(Target, "AdapterTerminate"); - // drop ref-count acquired in __AdapterGetTarget *before* destroying Target - TargetDereference(Target); - TargetDestroy(Target); - } - } - - // cleanup memory - ASSERT3U(Adapter->DevicePower, ==, PowerDeviceD3); - ASSERT3P(Adapter->DebugCallback, ==, NULL); - ASSERT3P(Adapter->SuspendCallback, ==, NULL); - - Adapter->Signature = 0; - Adapter->DevicePower = 0; - Adapter->CurrentSrbs = Adapter->MaximumSrbs = Adapter->TotalSrbs = 0; - RtlZeroMemory(&Adapter->Enumerator, sizeof(ANSI_STRING)); - RtlZeroMemory(&Adapter->TargetLock, sizeof(KSPIN_LOCK)); - RtlZeroMemory(&Adapter->Lock, sizeof(KSPIN_LOCK)); - RtlZeroMemory(&Adapter->ScanEvent, sizeof(KEVENT)); - __AdapterZeroInterfaces(Adapter); - - ASSERT(IsZeroMemory(Adapter, sizeof(XENVBD_ADAPTER))); - Trace("<===== (%d)\n", KeGetCurrentIrql()); -} -//============================================================================= -// Query Methods -__checkReturn -FORCEINLINE PDEVICE_OBJECT -AdapterGetDeviceObject( - __in PXENVBD_ADAPTER Adapter - ) -{ - if (Adapter) - return Adapter->DeviceObject; - return NULL; -} - -FORCEINLINE ULONG -AdapterSizeofXenvbdAdapter( - ) -{ - return (ULONG)sizeof(XENVBD_ADAPTER); -} - -FORCEINLINE PCHAR -AdapterEnum( - __in PXENVBD_ADAPTER Adapter - ) -{ - if (Adapter->Enumerator.Buffer) - return Adapter->Enumerator.Buffer; - else - return "vbd"; -} - -//============================================================================= -// SRB Methods -FORCEINLINE VOID -AdapterStartSrb( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_REQUEST_BLOCK Srb - ) -{ - LONG Value; - - UNREFERENCED_PARAMETER(Srb); - - Value = InterlockedIncrement(&Adapter->CurrentSrbs); - if (Value > Adapter->MaximumSrbs) - Adapter->MaximumSrbs = Value; - InterlockedIncrement(&Adapter->TotalSrbs); -} - -FORCEINLINE VOID -AdapterCompleteSrb( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_REQUEST_BLOCK Srb - ) -{ - ASSERT3U(Srb->SrbStatus, !=, SRB_STATUS_PENDING); - - InterlockedDecrement(&Adapter->CurrentSrbs); - - StorPortNotification(RequestComplete, Adapter, Srb); -} - -//============================================================================= -// StorPort Methods -BOOLEAN -AdapterResetBus( - __in PXENVBD_ADAPTER Adapter - ) -{ - ULONG TargetId; - - Verbose("====>\n"); for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { - PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId); - if (Target) { - TargetReset(Target); - TargetDereference(Target); - } - } - Verbose("<====\n"); - - return TRUE; -} - -static VOID -AdapterUnplugRequest( - IN PXENVBD_ADAPTER Adapter, - IN BOOLEAN Make - ) -{ - NTSTATUS status; - - status = XENBUS_UNPLUG(Acquire, &Adapter->Unplug); - if (!NT_SUCCESS(status)) - return; + PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId); + if (Target == NULL) + continue; - XENBUS_UNPLUG(Request, - &Adapter->Unplug, - XENBUS_UNPLUG_DEVICE_TYPE_DISKS, - Make); + // Target may not be in Deleted state yet, force it as Adapter is terminating + if (TargetGetDevicePnpState(Target) != Deleted) + TargetSetDevicePnpState(Target, Deleted); + // update missing (for debug output more than anything else + TargetSetMissing(Target, "AdapterTeardown"); + // drop ref-count acquired in __AdapterGetTarget *before* destroying Target + TargetDestroy(Target); + } - XENBUS_UNPLUG(Release, &Adapter->Unplug); -} + RtlZeroMemory(&Adapter->EmulatedInterface, + sizeof (XENFILT_EMULATED_INTERFACE)); -ULONG -AdapterFindAdapter( - __in PXENVBD_ADAPTER Adapter, - __inout PPORT_CONFIGURATION_INFORMATION ConfigInfo - ) -{ - // setup config info - ConfigInfo->MaximumTransferLength = XENVBD_MAX_TRANSFER_LENGTH; - ConfigInfo->NumberOfPhysicalBreaks = XENVBD_MAX_PHYSICAL_BREAKS; - ConfigInfo->AlignmentMask = 0; // Byte-Aligned - ConfigInfo->NumberOfBuses = 1; - ConfigInfo->InitiatorBusId[0] = 1; - ConfigInfo->ScatterGather = TRUE; - ConfigInfo->Master = TRUE; - ConfigInfo->CachesData = FALSE; - ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS; - ConfigInfo->MaximumNumberOfTargets = XENVBD_MAX_TARGETS; - ConfigInfo->MaximumNumberOfLogicalUnits = 1; - ConfigInfo->WmiDataProvider = FALSE; // should be TRUE - ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex; + RtlZeroMemory(&Adapter->UnplugInterface, + sizeof (XENBUS_UNPLUG_INTERFACE)); - if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) { - Trace("64bit DMA\n"); - ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED; - } + RtlZeroMemory(&Adapter->DebugInterface, + sizeof (XENBUS_DEBUG_INTERFACE)); - // gets called on resume from hibernate, so only setup if not already done - if (Adapter->Signature == ADAPTER_SIGNATURE) { - Verbose("ADAPTER already initalized (0x%p)\n", Adapter); - return SP_RETURN_FOUND; - } + RtlZeroMemory(&Adapter->SuspendInterface, + sizeof (XENBUS_SUSPEND_INTERFACE)); - // We need to do this to avoid an assertion in a checked kernel - (VOID) StorPortGetUncachedExtension(Adapter, ConfigInfo, PAGE_SIZE); + RtlZeroMemory(&Adapter->GnttabInterface, + sizeof (XENBUS_GNTTAB_INTERFACE)); - if (!NT_SUCCESS(__AdapterInitialize(Adapter))) - return SP_RETURN_ERROR; + RtlZeroMemory(&Adapter->EvtchnInterface, + sizeof (XENBUS_EVTCHN_INTERFACE)); - AdapterUnplugRequest(Adapter, TRUE); + RtlZeroMemory(&Adapter->StoreInterface, + sizeof (XENBUS_STORE_INTERFACE)); - if (!NT_SUCCESS(AdapterD3ToD0(Adapter))) - return SP_RETURN_ERROR; + RtlZeroMemory(&Adapter->TargetLock, sizeof(KSPIN_LOCK)); + RtlZeroMemory(&Adapter->Lock, sizeof(KSPIN_LOCK)); + RtlZeroMemory(&Adapter->ScanEvent, sizeof(KEVENT)); - return SP_RETURN_FOUND; -} + Adapter->DevicePower = 0; + Adapter->DeviceObject = NULL; + Adapter->PhysicalDeviceObject = NULL; + Adapter->LowerDeviceObject = NULL; -static FORCEINLINE VOID -__AdapterSrbPnp( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_PNP_REQUEST_BLOCK Srb - ) -{ - if (!(Srb->SrbPnPFlags & SRB_PNP_FLAGS_ADAPTER_REQUEST)) { - PXENVBD_TARGET Target; + Adapter->BuildIo = 0; + Adapter->StartIo = 0; + Adapter->Completed = 0; - Target = __AdapterGetTarget(Adapter, Srb->TargetId); - if (Target) { - TargetSrbPnp(Target, Srb); - TargetDereference(Target); - } - } + ASSERT(IsZeroMemory(Adapter, sizeof(XENVBD_ADAPTER))); + Trace("<===== (%d)\n", KeGetCurrentIrql()); } -BOOLEAN -AdapterBuildIo( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_REQUEST_BLOCK Srb +VOID +AdapterCompleteSrb( + IN PXENVBD_ADAPTER Adapter, + IN PSCSI_REQUEST_BLOCK Srb ) { - InitSrbExt(Srb); + ASSERT3U(Srb->SrbStatus, !=, SRB_STATUS_PENDING); - switch (Srb->Function) { - case SRB_FUNCTION_EXECUTE_SCSI: - case SRB_FUNCTION_RESET_DEVICE: - case SRB_FUNCTION_FLUSH: - case SRB_FUNCTION_SHUTDOWN: - AdapterStartSrb(Adapter, Srb); - return TRUE; + ++Adapter->Completed; - // dont pass to StartIo - case SRB_FUNCTION_PNP: - __AdapterSrbPnp(Adapter, (PSCSI_PNP_REQUEST_BLOCK)Srb); - Srb->SrbStatus = SRB_STATUS_SUCCESS; - break; - case SRB_FUNCTION_ABORT_COMMAND: - Srb->SrbStatus = SRB_STATUS_ABORT_FAILED; - break; - case SRB_FUNCTION_RESET_BUS: - Srb->SrbStatus = SRB_STATUS_SUCCESS; - AdapterResetBus(Adapter); - break; - - default: - break; - } - StorPortNotification(RequestComplete, Adapter, Srb); - return FALSE; -} +} -BOOLEAN -AdapterStartIo( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_REQUEST_BLOCK Srb +static VOID +AdapterUnplugRequest( + IN PXENVBD_ADAPTER Adapter, + IN BOOLEAN Make ) { - PXENVBD_TARGET Target; - BOOLEAN CompleteSrb = TRUE; + NTSTATUS status; - Target = __AdapterGetTarget(Adapter, Srb->TargetId); - if (Target) { - CompleteSrb = TargetStartIo(Target, Srb); - TargetDereference(Target); - } + status = XENBUS_UNPLUG(Acquire, &Adapter->UnplugInterface); + if (!NT_SUCCESS(status)) + return; - if (CompleteSrb) { - AdapterCompleteSrb(Adapter, Srb); - } - return TRUE; + XENBUS_UNPLUG(Request, + &Adapter->UnplugInterface, + XENBUS_UNPLUG_DEVICE_TYPE_DISKS, + Make); + + XENBUS_UNPLUG(Release, &Adapter->UnplugInterface); } static PXENVBD_TARGET AdapterGetTargetFromDeviceObject( - __in PXENVBD_ADAPTER Adapter, - __in PDEVICE_OBJECT DeviceObject + IN PXENVBD_ADAPTER Adapter, + IN PDEVICE_OBJECT DeviceObject ) { - ULONG TargetId; + ULONG TargetId; ASSERT3P(DeviceObject, !=, NULL); for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { - PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId); - if (Target) { - if (TargetGetDeviceObject(Target) == DeviceObject) - return Target; - TargetDereference(Target); - } + PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId); + if (Target == NULL) + continue; + if (TargetGetDeviceObject(Target) == DeviceObject) + return Target; } return NULL; @@ -1873,18 +1451,18 @@ AdapterGetTargetFromDeviceObject( static PXENVBD_TARGET AdapterMapDeviceObjectToTarget( - __in PXENVBD_ADAPTER Adapter, - __in PDEVICE_OBJECT DeviceObject + IN PXENVBD_ADAPTER Adapter, + IN PDEVICE_OBJECT DeviceObject ) { - PXENVBD_TARGET Target; - KEVENT Complete; - PIRP Irp; - IO_STATUS_BLOCK StatusBlock; - PIO_STACK_LOCATION Stack; - NTSTATUS Status; - PWCHAR String; - ULONG TargetId; + PXENVBD_TARGET Target; + KEVENT Complete; + PIRP Irp; + IO_STATUS_BLOCK StatusBlock; + PIO_STACK_LOCATION Stack; + NTSTATUS Status; + PWCHAR String; + ULONG TargetId; DECLARE_UNICODE_STRING_SIZE(UniStr, 4); KeInitializeEvent(&Complete, NotificationEvent, FALSE); @@ -1928,7 +1506,7 @@ AdapterMapDeviceObjectToTarget( if (!NT_SUCCESS(Status)) goto fail4; - Target = __AdapterGetTarget(Adapter, TargetId); + Target = AdapterGetTarget(Adapter, TargetId); if (Target == NULL) goto fail5; @@ -1946,16 +1524,15 @@ fail1: return NULL; } -__checkReturn -NTSTATUS +static NTSTATUS AdapterForwardPnp( - __in PXENVBD_ADAPTER Adapter, - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp + IN PXENVBD_ADAPTER Adapter, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ) { PIO_STACK_LOCATION Stack; - PXENVBD_TARGET Target; + PXENVBD_TARGET Target; ASSERT3P(DeviceObject, !=, Adapter->DeviceObject); @@ -1976,26 +1553,25 @@ AdapterForwardPnp( return DriverDispatchPnp(DeviceObject, Irp); } -__checkReturn NTSTATUS AdapterDispatchPnp( - __in PXENVBD_ADAPTER Adapter, - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp + IN PXENVBD_ADAPTER Adapter, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ) { PIO_STACK_LOCATION Stack; - ASSERT3P(DeviceObject, ==, Adapter->DeviceObject); + if (Adapter->DeviceObject != DeviceObject) + return AdapterForwardPnp(Adapter, DeviceObject, Irp); Stack = IoGetCurrentIrpStackLocation(Irp); switch (Stack->MinorFunction) { case IRP_MN_REMOVE_DEVICE: - Verbose("ADAPTER:IRP_MN_REMOVE_DEVICE\n"); AdapterD0ToD3(Adapter); AdapterUnplugRequest(Adapter, FALSE); - __AdapterTerminate(Adapter); + AdapterTeardown(Adapter); break; case IRP_MN_QUERY_DEVICE_RELATIONS: @@ -2004,12 +1580,12 @@ AdapterDispatchPnp( ThreadWake(Adapter->ScanThread); Trace("waiting for scan thread\n"); - (VOID) KeWaitForSingleObject(&Adapter->ScanEvent, Executive, KernelMode, FALSE, NULL); + Trace("scan thread wait complete\n"); } break; @@ -2020,19 +1596,19 @@ AdapterDispatchPnp( return DriverDispatchPnp(DeviceObject, Irp); } -__checkReturn NTSTATUS AdapterDispatchPower( - __in PXENVBD_ADAPTER Adapter, - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp + IN PXENVBD_ADAPTER Adapter, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ) { PIO_STACK_LOCATION Stack; POWER_STATE_TYPE PowerType; NTSTATUS status; - ASSERT3P(DeviceObject, ==, Adapter->DeviceObject); + if (Adapter->DeviceObject != DeviceObject) + return DriverDispatchPower(DeviceObject, Irp); Stack = IoGetCurrentIrpStackLocation(Irp); PowerType = Stack->Parameters.Power.Type; @@ -2065,72 +1641,299 @@ AdapterDispatchPower( return status; } -PXENBUS_STORE_INTERFACE -AdapterAcquireStore( - __in PXENVBD_ADAPTER Adapter +HW_RESET_BUS AdapterHwResetBus; + +BOOLEAN +AdapterHwResetBus( + IN PVOID DevExt, + IN ULONG PathId ) { - NTSTATUS status; + PXENVBD_ADAPTER Adapter = DevExt; + ULONG TargetId; - status = XENBUS_STORE(Acquire, &Adapter->Store); - if (!NT_SUCCESS(status)) - return NULL; + UNREFERENCED_PARAMETER(PathId); + + Verbose("====>\n"); + for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) { + PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId); + if (Target == NULL) + continue; + + TargetReset(Target); + } + Verbose("<====\n"); - return &Adapter->Store; + return TRUE; } -PXENBUS_EVTCHN_INTERFACE -AdapterAcquireEvtchn( - __in PXENVBD_ADAPTER Adapter + +static FORCEINLINE VOID +__AdapterSrbPnp( + IN PXENVBD_ADAPTER Adapter, + IN PSCSI_PNP_REQUEST_BLOCK Srb ) { - NTSTATUS status; + if (!(Srb->SrbPnPFlags & SRB_PNP_FLAGS_ADAPTER_REQUEST)) { + PXENVBD_TARGET Target; - status = XENBUS_EVTCHN(Acquire, &Adapter->Evtchn); - if (!NT_SUCCESS(status)) - return NULL; + Target = AdapterGetTarget(Adapter, Srb->TargetId); + if (Target) { + TargetSrbPnp(Target, Srb); + } + } +} + +HW_BUILDIO AdapterHwBuildIo; + +BOOLEAN +AdapterHwBuildIo( + IN PVOID DevExt, + IN PSCSI_REQUEST_BLOCK Srb + ) +{ + PXENVBD_ADAPTER Adapter = DevExt; + + InitSrbExt(Srb); + + switch (Srb->Function) { + case SRB_FUNCTION_EXECUTE_SCSI: + case SRB_FUNCTION_RESET_DEVICE: + case SRB_FUNCTION_FLUSH: + case SRB_FUNCTION_SHUTDOWN: + ++Adapter->BuildIo; + return TRUE; - return &Adapter->Evtchn; + // dont pass to StartIo + case SRB_FUNCTION_PNP: + __AdapterSrbPnp(Adapter, (PSCSI_PNP_REQUEST_BLOCK)Srb); + Srb->SrbStatus = SRB_STATUS_SUCCESS; + break; + case SRB_FUNCTION_ABORT_COMMAND: + Srb->SrbStatus = SRB_STATUS_ABORT_FAILED; + break; + case SRB_FUNCTION_RESET_BUS: + Srb->SrbStatus = SRB_STATUS_SUCCESS; + AdapterHwResetBus(Adapter, Srb->PathId); + break; + + default: + break; + } + + StorPortNotification(RequestComplete, Adapter, Srb); + return FALSE; } -PXENBUS_GNTTAB_INTERFACE -AdapterAcquireGnttab( - __in PXENVBD_ADAPTER Adapter +HW_STARTIO AdapterHwStartIo; + +BOOLEAN +AdapterHwStartIo( + IN PVOID DevExt, + IN PSCSI_REQUEST_BLOCK Srb ) { - NTSTATUS status; + PXENVBD_ADAPTER Adapter = DevExt; + PXENVBD_TARGET Target; - status = XENBUS_GNTTAB(Acquire, &Adapter->Gnttab); - if (!NT_SUCCESS(status)) - return NULL; + Target = AdapterGetTarget(Adapter, Srb->TargetId); + if (Target == NULL) + goto fail1; + + ++Adapter->StartIo; + if (TargetStartIo(Target, Srb)) + AdapterCompleteSrb(Adapter, Srb); - return &Adapter->Gnttab; + return TRUE; + +fail1: + AdapterCompleteSrb(Adapter, Srb); + return TRUE; } -PXENBUS_DEBUG_INTERFACE -AdapterAcquireDebug( - __in PXENVBD_ADAPTER Adapter +HW_ADAPTER_CONTROL AdapterHwAdapterControl; + +SCSI_ADAPTER_CONTROL_STATUS +AdapterHwAdapterControl( + IN PVOID DevExt, + IN SCSI_ADAPTER_CONTROL_TYPE ControlType, + IN PVOID Parameters ) { - NTSTATUS status; + PSCSI_SUPPORTED_CONTROL_TYPE_LIST List; + + UNREFERENCED_PARAMETER(DevExt); + + switch (ControlType) { + case ScsiQuerySupportedControlTypes: + List = Parameters; + List->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE; + break; + + default: + break; + } + return ScsiAdapterControlSuccess; +} + +HW_FIND_ADAPTER AdapterHwFindAdapter; + +ULONG +AdapterHwFindAdapter( + IN PVOID DevExt, + IN PVOID Context, + IN PVOID BusInformation, + IN PCHAR ArgumentString, + IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, + OUT PBOOLEAN Again + ) +{ + PXENVBD_ADAPTER Adapter = DevExt; + PDEVICE_OBJECT DeviceObject; + PDEVICE_OBJECT PhysicalDeviceObject; + PDEVICE_OBJECT LowerDeviceObject; + NTSTATUS status; + + UNREFERENCED_PARAMETER(Context); + UNREFERENCED_PARAMETER(BusInformation); + UNREFERENCED_PARAMETER(ArgumentString); + UNREFERENCED_PARAMETER(Again); + + // setup config info + ConfigInfo->MaximumTransferLength = XENVBD_MAX_TRANSFER_LENGTH; + ConfigInfo->NumberOfPhysicalBreaks = XENVBD_MAX_PHYSICAL_BREAKS; + ConfigInfo->AlignmentMask = 0; // Byte-Aligned + ConfigInfo->NumberOfBuses = 1; + ConfigInfo->InitiatorBusId[0] = 1; + ConfigInfo->ScatterGather = TRUE; + ConfigInfo->Master = TRUE; + ConfigInfo->CachesData = FALSE; + ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS; + ConfigInfo->MaximumNumberOfTargets = XENVBD_MAX_TARGETS; + ConfigInfo->MaximumNumberOfLogicalUnits = 1; + ConfigInfo->WmiDataProvider = FALSE; // should be TRUE + ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex; + + if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) + ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED; + + // We need to do this to avoid an assertion in a checked kernel + (VOID) StorPortGetUncachedExtension(DevExt, ConfigInfo, PAGE_SIZE); + + (VOID) StorPortGetDeviceObjects(DevExt, + &DeviceObject, + &PhysicalDeviceObject, + &LowerDeviceObject); + if (Adapter->DeviceObject == DeviceObject) + return SP_RETURN_FOUND; + + status = AdapterInitialize(Adapter, + DeviceObject, + PhysicalDeviceObject, + LowerDeviceObject); + if (!NT_SUCCESS(status)) + goto fail1; - status = XENBUS_DEBUG(Acquire, &Adapter->Debug); + AdapterUnplugRequest(Adapter, TRUE); + + status = AdapterD3ToD0(Adapter); if (!NT_SUCCESS(status)) - return NULL; + goto fail2; + + DriverSetAdapter(Adapter); + return SP_RETURN_FOUND; - return &Adapter->Debug; +fail2: + Error("fail2\n"); + AdapterUnplugRequest(Adapter, FALSE); + AdapterTeardown(Adapter); +fail1: + Error("fail1\n"); + return SP_RETURN_ERROR; } -PXENBUS_SUSPEND_INTERFACE -AdapterAcquireSuspend( - __in PXENVBD_ADAPTER Adapter +HW_INITIALIZE AdapterHwInitialize; + +BOOLEAN +AdapterHwInitialize( + IN PVOID DevExt ) { - NTSTATUS status; + UNREFERENCED_PARAMETER(DevExt); + return TRUE; +} + +HW_INTERRUPT AdapterHwInterrupt; + +BOOLEAN +AdapterHwInterrupt( + IN PVOID DevExt + ) +{ + UNREFERENCED_PARAMETER(DevExt); + return TRUE; +} - status = XENBUS_SUSPEND(Acquire, &Adapter->Suspend); +NTSTATUS +AdapterDriverEntry( + IN PUNICODE_STRING RegistryPath, + IN PDRIVER_OBJECT DriverObject + ) +{ + HW_INITIALIZATION_DATA InitData; + NTSTATUS status; + + RtlZeroMemory(&InitData, sizeof(InitData)); + InitData.HwInitializationDataSize = sizeof(InitData); + InitData.AdapterInterfaceType = Internal; + InitData.HwInitialize = AdapterHwInitialize; + InitData.HwStartIo = AdapterHwStartIo; + InitData.HwInterrupt = AdapterHwInterrupt; +#pragma warning(suppress : 4152) + InitData.HwFindAdapter = AdapterHwFindAdapter; + InitData.HwResetBus = AdapterHwResetBus; + InitData.HwDmaStarted = NULL; + InitData.HwAdapterState = NULL; + InitData.DeviceExtensionSize = sizeof(XENVBD_ADAPTER); + InitData.SpecificLuExtensionSize = sizeof(ULONG); // not actually used + InitData.SrbExtensionSize = sizeof(XENVBD_SRBEXT); + InitData.NumberOfAccessRanges = 2; + InitData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS; + InitData.NeedPhysicalAddresses = TRUE; + InitData.TaggedQueuing = TRUE; + InitData.AutoRequestSense = TRUE; + InitData.MultipleRequestPerLu = TRUE; + InitData.HwAdapterControl = AdapterHwAdapterControl; + InitData.HwBuildIo = AdapterHwBuildIo; + + status = StorPortInitialize(DriverObject, + RegistryPath, + &InitData, + NULL); if (!NT_SUCCESS(status)) - return NULL; + goto fail1; - return &Adapter->Suspend; + return STATUS_SUCCESS; + +fail1: + Error("fail1 %08x\n", status); + return status; } + +#define ADAPTER_GET_INTERFACE(_name, _type) \ +VOID \ +AdapterGet ## _name ## Interface( \ + IN PXENVBD_ADAPTER Adapter, \ + OUT _type _name ## Interface \ + ) \ +{ \ + * ## _name ## Interface = Adapter-> ## _name ## Interface; \ +} + +ADAPTER_GET_INTERFACE(Store, PXENBUS_STORE_INTERFACE) +ADAPTER_GET_INTERFACE(Debug, PXENBUS_DEBUG_INTERFACE) +ADAPTER_GET_INTERFACE(Evtchn, PXENBUS_EVTCHN_INTERFACE) +ADAPTER_GET_INTERFACE(Gnttab, PXENBUS_GNTTAB_INTERFACE) +ADAPTER_GET_INTERFACE(Suspend, PXENBUS_SUSPEND_INTERFACE) + +#undef ADAPTER_GET_INTERFACE diff --git a/src/xenvbd/adapter.h b/src/xenvbd/adapter.h index 09d5ee6..2867398 100644 --- a/src/xenvbd/adapter.h +++ b/src/xenvbd/adapter.h @@ -37,126 +37,57 @@ typedef struct _XENVBD_ADAPTER XENVBD_ADAPTER, *PXENVBD_ADAPTER; #include <storport.h> -#include "target.h" #include <store_interface.h> #include <evtchn_interface.h> #include <gnttab_interface.h> #include <debug_interface.h> #include <suspend_interface.h> -#include <unplug_interface.h> -// Link TARGETs -extern BOOLEAN -AdapterLinkTarget( - __in PXENVBD_ADAPTER Adapter, - __in PXENVBD_TARGET Target - ); - -extern BOOLEAN -AdapterUnlinkTarget( - __in PXENVBD_ADAPTER Adapter, - __in PXENVBD_TARGET Target - ); -// Query Methods -__checkReturn -extern PDEVICE_OBJECT -AdapterGetDeviceObject( - __in PXENVBD_ADAPTER Adapter +#define ADAPTER_GET_INTERFACE(_name, _type) \ +extern VOID \ +AdapterGet ## _name ## Interface( \ + IN PXENVBD_ADAPTER Adapter, \ + OUT _type _name ## Interface \ ); -extern ULONG -AdapterSizeofXenvbdAdapter( - ); +ADAPTER_GET_INTERFACE(Store, PXENBUS_STORE_INTERFACE) +ADAPTER_GET_INTERFACE(Debug, PXENBUS_DEBUG_INTERFACE) +ADAPTER_GET_INTERFACE(Evtchn, PXENBUS_EVTCHN_INTERFACE) +ADAPTER_GET_INTERFACE(Gnttab, PXENBUS_GNTTAB_INTERFACE) +ADAPTER_GET_INTERFACE(Suspend, PXENBUS_SUSPEND_INTERFACE) -extern PCHAR -AdapterEnum( - __in PXENVBD_ADAPTER Adapter - ); +#undef ADAPTER_GET_INTERFACE -// SRB Methods -extern VOID -AdapterStartSrb( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_REQUEST_BLOCK Srb +extern BOOLEAN +AdapterIsTargetEmulated( + IN PXENVBD_ADAPTER Adapter, + IN ULONG TargetId ); extern VOID AdapterCompleteSrb( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_REQUEST_BLOCK Srb - ); - -// StorPort Methods -extern BOOLEAN -AdapterResetBus( - __in PXENVBD_ADAPTER Adapter - ); - -extern ULONG -AdapterFindAdapter( - __in PXENVBD_ADAPTER Adapter, - __inout PPORT_CONFIGURATION_INFORMATION ConfigInfo - ); - -extern BOOLEAN -AdapterBuildIo( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_REQUEST_BLOCK Srb - ); - -extern BOOLEAN -AdapterStartIo( - __in PXENVBD_ADAPTER Adapter, - __in PSCSI_REQUEST_BLOCK Srb - ); - -__checkReturn -extern NTSTATUS -AdapterForwardPnp( - __in PXENVBD_ADAPTER Adapter, - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp + IN PXENVBD_ADAPTER Adapter, + IN PSCSI_REQUEST_BLOCK Srb ); -__checkReturn extern NTSTATUS AdapterDispatchPnp( - __in PXENVBD_ADAPTER Adapter, - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp + IN PXENVBD_ADAPTER Adapter, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ); -__checkReturn extern NTSTATUS AdapterDispatchPower( - __in PXENVBD_ADAPTER Adapter, - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp - ); - -extern PXENBUS_STORE_INTERFACE -AdapterAcquireStore( - __in PXENVBD_ADAPTER Adapter + IN PXENVBD_ADAPTER Adapter, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ); -extern PXENBUS_EVTCHN_INTERFACE -AdapterAcquireEvtchn( - __in PXENVBD_ADAPTER Adapter - ); - -extern PXENBUS_GNTTAB_INTERFACE -AdapterAcquireGnttab( - __in PXENVBD_ADAPTER Adapter - ); - -extern PXENBUS_DEBUG_INTERFACE -AdapterAcquireDebug( - __in PXENVBD_ADAPTER Adapter - ); - -extern PXENBUS_SUSPEND_INTERFACE -AdapterAcquireSuspend( - __in PXENVBD_ADAPTER Adapter +extern NTSTATUS +AdapterDriverEntry( + IN PUNICODE_STRING RegistryPath, + IN PDRIVER_OBJECT DriverObject ); #endif // _XENVBD_ADAPTER_H diff --git a/src/xenvbd/blockring.c b/src/xenvbd/blockring.c index a0ba7c7..bcef877 100644 --- a/src/xenvbd/blockring.c +++ b/src/xenvbd/blockring.c @@ -49,7 +49,7 @@ struct _XENVBD_BLOCKRING { BOOLEAN Connected; BOOLEAN Enabled; - PXENBUS_STORE_INTERFACE StoreInterface; + XENBUS_STORE_INTERFACE StoreInterface; KSPIN_LOCK Lock; PMDL Mdl; @@ -284,10 +284,10 @@ BlockRingConnect( ASSERT(BlockRing->Connected == FALSE); - BlockRing->StoreInterface = AdapterAcquireStore(Adapter); - - status = STATUS_UNSUCCESSFUL; - if (BlockRing->StoreInterface == NULL) + AdapterGetStoreInterface(Adapter, &BlockRing->StoreInterface); + + status = XENBUS_STORE(Acquire, &BlockRing->StoreInterface); + if (!NT_SUCCESS(status)) goto fail1; status = FrontendStoreReadBackend(BlockRing->Frontend, "max-ring-page-order", &Value); @@ -355,7 +355,7 @@ BlockRingStoreWrite( if (BlockRing->Order == 0) { status = XENBUS_STORE(Printf, - BlockRing->StoreInterface, + &BlockRing->StoreInterface, Transaction, FrontendPath, "ring-ref", @@ -367,7 +367,7 @@ BlockRingStoreWrite( ULONG Index, RingPages; status = XENBUS_STORE(Printf, - BlockRing->StoreInterface, + &BlockRing->StoreInterface, Transaction, FrontendPath, "ring-page-order", @@ -383,7 +383,7 @@ BlockRingStoreWrite( if (!NT_SUCCESS(status)) return status; status = XENBUS_STORE(Printf, - BlockRing->StoreInterface, + &BlockRing->StoreInterface, Transaction, FrontendPath, Name, @@ -395,7 +395,7 @@ BlockRingStoreWrite( } status = XENBUS_STORE(Printf, - BlockRing->StoreInterface, + &BlockRing->StoreInterface, Transaction, FrontendPath, "protocol", @@ -453,8 +453,8 @@ BlockRingDisconnect( BlockRing->Order = 0; - XENBUS_STORE(Release, BlockRing->StoreInterface); - BlockRing->StoreInterface = NULL; + XENBUS_STORE(Release, &BlockRing->StoreInterface); + RtlZeroMemory(&BlockRing->StoreInterface, sizeof(XENBUS_STORE_INTERFACE)); BlockRing->Connected = FALSE; } diff --git a/src/xenvbd/driver.c b/src/xenvbd/driver.c index 233318f..d45c6b6 100644 --- a/src/xenvbd/driver.c +++ b/src/xenvbd/driver.c @@ -59,6 +59,16 @@ static XENVBD_DRIVER Driver; #define XENVBD_POOL_TAG 'dbvX' +VOID +DriverSetAdapter( + IN PVOID Adapter + ) +{ + ASSERT3P(Driver.Adapter, ==, NULL); + ASSERT3P(Adapter, !=, NULL); + Driver.Adapter = Adapter; +} + static FORCEINLINE HANDLE __DriverGetParametersKey( VOID @@ -168,141 +178,6 @@ fail1: Error("fail1 (%08x)\n", status); } -HW_INITIALIZE HwInitialize; - -BOOLEAN -HwInitialize( - IN PVOID DevExt - ) -{ - UNREFERENCED_PARAMETER(DevExt); - return TRUE; -} - -HW_INTERRUPT HwInterrupt; - -BOOLEAN -HwInterrupt( - IN PVOID DevExt - ) -{ - UNREFERENCED_PARAMETER(DevExt); - return TRUE; -} - -HW_ADAPTER_CONTROL HwAdapterControl; - -SCSI_ADAPTER_CONTROL_STATUS -HwAdapterControl( - IN PVOID DevExt, - IN SCSI_ADAPTER_CONTROL_TYPE ControlType, - IN PVOID Parameters - ) -{ - PSCSI_SUPPORTED_CONTROL_TYPE_LIST List; - - UNREFERENCED_PARAMETER(DevExt); - - switch (ControlType) { - case ScsiQuerySupportedControlTypes: - List = Parameters; - List->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE; - break; - - case ScsiStopAdapter: - case ScsiRestartAdapter: - case ScsiSetBootConfig: - case ScsiSetRunningConfig: - default: - break; - } - return ScsiAdapterControlSuccess; -} - -HW_RESET_BUS HwResetBus; - -BOOLEAN -HwResetBus( - IN PVOID DevExt, - IN ULONG PathId - ) -{ - UNREFERENCED_PARAMETER(PathId); - - return AdapterResetBus(DevExt); -} - -HW_FIND_ADAPTER HwFindAdapter; - -ULONG -HwFindAdapter( - IN PVOID DevExt, - IN PVOID Context, - IN PVOID BusInformation, - IN PCHAR ArgumentString, - IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, - OUT PBOOLEAN Again - ) -{ - ULONG Return; - - UNREFERENCED_PARAMETER(Context); - UNREFERENCED_PARAMETER(BusInformation); - UNREFERENCED_PARAMETER(ArgumentString); - UNREFERENCED_PARAMETER(Again); - - Return = AdapterFindAdapter(DevExt, ConfigInfo); - if (Return == SP_RETURN_FOUND) - Driver.Adapter = DevExt; - return Return; -} - -static FORCEINLINE BOOLEAN -__FailStorageRequest( - IN PVOID DevExt, - IN PSCSI_REQUEST_BLOCK Srb - ) -{ - if (Srb->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK) { - // Win8 and above storport request. not supported - // complete the request (with fail code) - Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST; - StorPortNotification(RequestComplete, DevExt, Srb); - Error("(0x%p) STORAGE_REQUEST_BLOCK not supported\n", DevExt); - return TRUE; - } - - return FALSE; -} - -HW_BUILDIO HwBuildIo; - -BOOLEAN -HwBuildIo( - IN PVOID DevExt, - IN PSCSI_REQUEST_BLOCK Srb - ) -{ - if (__FailStorageRequest(DevExt, Srb)) - return FALSE; // dont pass to HwStartIo - - return AdapterBuildIo(DevExt, Srb); -} - -HW_STARTIO HwStartIo; - -BOOLEAN -HwStartIo( - IN PVOID DevExt, - IN PSCSI_REQUEST_BLOCK Srb - ) -{ - if (__FailStorageRequest(DevExt, Srb)) - return TRUE; // acknowledge the srb - - return AdapterStartIo(DevExt, Srb); -} - __drv_dispatchType(IRP_MJ_PNP) DRIVER_DISPATCH DispatchPnp; @@ -315,10 +190,7 @@ DispatchPnp( if (Driver.Adapter == NULL) return DriverDispatchPnp(DeviceObject, Irp); - if (AdapterGetDeviceObject(Driver.Adapter) == DeviceObject) - return AdapterDispatchPnp(Driver.Adapter, DeviceObject, Irp); - - return AdapterForwardPnp(Driver.Adapter, DeviceObject, Irp); + return AdapterDispatchPnp(Driver.Adapter, DeviceObject, Irp); } __drv_dispatchType(IRP_MJ_POWER) @@ -333,10 +205,7 @@ DispatchPower( if (Driver.Adapter == NULL) return DriverDispatchPower(DeviceObject, Irp); - if (AdapterGetDeviceObject(Driver.Adapter) == DeviceObject) - return AdapterDispatchPower(Driver.Adapter, DeviceObject, Irp); - - return DriverDispatchPower(DeviceObject, Irp); + return AdapterDispatchPower(Driver.Adapter, DeviceObject, Irp); } DRIVER_UNLOAD DriverUnload; @@ -378,7 +247,6 @@ DriverEntry( IN PUNICODE_STRING RegistryPath ) { - HW_INITIALIZATION_DATA InitData; HANDLE ServiceKey; HANDLE ParametersKey; NTSTATUS status; @@ -418,33 +286,8 @@ DriverEntry( Driver.Adapter = NULL; BufferInitialize(); - RtlZeroMemory(&InitData, sizeof(InitData)); - InitData.HwInitializationDataSize = sizeof(InitData); - InitData.AdapterInterfaceType = Internal; - InitData.HwInitialize = HwInitialize; - InitData.HwStartIo = HwStartIo; - InitData.HwInterrupt = HwInterrupt; -#pragma warning(suppress : 4152) - InitData.HwFindAdapter = HwFindAdapter; - InitData.HwResetBus = HwResetBus; - InitData.HwDmaStarted = NULL; - InitData.HwAdapterState = NULL; - InitData.DeviceExtensionSize = AdapterSizeofXenvbdAdapter(); - InitData.SpecificLuExtensionSize = sizeof(ULONG); // not actually used - InitData.SrbExtensionSize = sizeof(XENVBD_SRBEXT); - InitData.NumberOfAccessRanges = 2; - InitData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS; - InitData.NeedPhysicalAddresses = TRUE; - InitData.TaggedQueuing = TRUE; - InitData.AutoRequestSense = TRUE; - InitData.MultipleRequestPerLu = TRUE; - InitData.HwAdapterControl = HwAdapterControl; - InitData.HwBuildIo = HwBuildIo; - - status = StorPortInitialize(DriverObject, - RegistryPath, - &InitData, - NULL); + status = AdapterDriverEntry(RegistryPath, + DriverObject); if (!NT_SUCCESS(status)) goto fail4; diff --git a/src/xenvbd/driver.h b/src/xenvbd/driver.h index 13c6135..6b73c4d 100644 --- a/src/xenvbd/driver.h +++ b/src/xenvbd/driver.h @@ -39,6 +39,11 @@ #define XENVBD_MAX_TRANSFER_LENGTH (XENVBD_MAX_PAGES_PER_SRB * PAGE_SIZE) #define XENVBD_MAX_PHYSICAL_BREAKS (XENVBD_MAX_PAGES_PER_SRB - 1) +extern VOID +DriverSetAdapter( + IN PVOID Adapter + ); + extern HANDLE DriverGetParametersKey( VOID diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c index 150710d..d82eaa2 100644 --- a/src/xenvbd/frontend.c +++ b/src/xenvbd/frontend.c @@ -66,8 +66,8 @@ struct _XENVBD_FRONTEND { PVOID Inquiry; // Interfaces to XenBus - PXENBUS_STORE_INTERFACE Store; - PXENBUS_SUSPEND_INTERFACE Suspend; + XENBUS_STORE_INTERFACE StoreInterface; + XENBUS_SUSPEND_INTERFACE SuspendInterface; PXENBUS_SUSPEND_CALLBACK SuspendLateCallback; @@ -181,6 +181,13 @@ FrontendGetTargetId( { return Frontend->TargetId; } +ULONG +FrontendGetDeviceId( + __in PXENVBD_FRONTEND Frontend + ) +{ + return Frontend->DeviceId; +} PVOID FrontendGetInquiry( __in PXENVBD_FRONTEND Frontend @@ -225,7 +232,7 @@ FrontendStoreWriteFrontend( ) { return XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->FrontendPath, Name, @@ -241,24 +248,20 @@ FrontendStoreReadBackend( NTSTATUS Status; Status = STATUS_INVALID_PARAMETER; - if (Frontend->Store == NULL) - goto fail1; - if (Frontend->BackendPath == NULL) - goto fail2; + goto fail1; Status = XENBUS_STORE(Read, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->BackendPath, Name, Value); if (!NT_SUCCESS(Status)) - goto fail3; + goto fail2; return STATUS_SUCCESS; -fail3: fail2: fail1: return Status; @@ -270,7 +273,7 @@ FrontendStoreFree( ) { XENBUS_STORE(Free, - Frontend->Store, + &Frontend->StoreInterface, Value); } __drv_maxIRQL(DISPATCH_LEVEL) @@ -282,7 +285,7 @@ FrontendWriteUsage( NTSTATUS Status; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->TargetPath, "paging", @@ -292,7 +295,7 @@ FrontendWriteUsage( goto out; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->TargetPath, "hibernation", @@ -302,7 +305,7 @@ FrontendWriteUsage( goto out; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->TargetPath, "dump", @@ -343,7 +346,7 @@ __UpdateBackendPath( ULONG Length; Status = XENBUS_STORE(Read, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->FrontendPath, "backend-id", @@ -351,14 +354,14 @@ __UpdateBackendPath( if (NT_SUCCESS(Status)) { Frontend->BackendId = (USHORT)strtoul(Value, NULL, 10); XENBUS_STORE(Free, - Frontend->Store, + &Frontend->StoreInterface, Value); } else { Frontend->BackendId = 0; } Status = XENBUS_STORE(Read, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->FrontendPath, "backend", @@ -379,7 +382,7 @@ __UpdateBackendPath( } XENBUS_STORE(Free, - Frontend->Store, + &Frontend->StoreInterface, Value); } else { Warning("Failed to read \'backend\' from \'%s\' (%08x)\n", @@ -401,7 +404,7 @@ __ReadState( PCHAR Buffer; Status = XENBUS_STORE(Read, - Frontend->Store, + &Frontend->StoreInterface, Transaction, Path, "state", @@ -411,7 +414,7 @@ __ReadState( *State = (XenbusState)strtoul(Buffer, NULL, 10); XENBUS_STORE(Free, - Frontend->Store, + &Frontend->StoreInterface, Buffer); return STATUS_SUCCESS; @@ -442,7 +445,7 @@ __WaitState( ASSERT3P(Frontend->BackendPath, !=, NULL); Status = XENBUS_STORE(WatchAdd, - Frontend->Store, + &Frontend->StoreInterface, Frontend->BackendPath, "state", &Event, @@ -458,7 +461,7 @@ __WaitState( if (KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &Timeout) == STATUS_TIMEOUT) { XENBUS_STORE(Poll, - Frontend->Store); + &Frontend->StoreInterface); KeQuerySystemTime(&CurrentTime); if ((CurrentTime.QuadPart - StartTime.QuadPart) > 10000) { @@ -477,7 +480,7 @@ __WaitState( } XENBUS_STORE(WatchRemove, - Frontend->Store, + &Frontend->StoreInterface, Watch); Trace("Target[%d] : BACKEND_STATE -> %s\n", @@ -490,7 +493,7 @@ fail2: Error("Fail2\n"); XENBUS_STORE(WatchRemove, - Frontend->Store, + &Frontend->StoreInterface, Watch); fail1: Error("Fail1 (%08x)\n", Status); @@ -507,7 +510,7 @@ ___SetState( NTSTATUS Status; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->FrontendPath, "state", @@ -535,8 +538,6 @@ __CheckBackendForEject( ULONG Attempt; NTSTATUS Status; - if (Frontend->Store == NULL) - return; if (Frontend->FrontendPath == NULL) return; if (Frontend->BackendPath == NULL) @@ -552,7 +553,7 @@ __CheckBackendForEject( PCHAR Buffer; Status = XENBUS_STORE(TransactionStart, - Frontend->Store, + &Frontend->StoreInterface, &Transaction); if (!NT_SUCCESS(Status)) break; @@ -572,7 +573,7 @@ __CheckBackendForEject( goto abort; Status = XENBUS_STORE(Read, - Frontend->Store, + &Frontend->StoreInterface, Transaction, Frontend->BackendPath, "online", @@ -582,11 +583,11 @@ __CheckBackendForEject( Online = (BOOLEAN)strtol(Buffer, NULL, 2); XENBUS_STORE(Free, - Frontend->Store, + &Frontend->StoreInterface, Buffer); Status = XENBUS_STORE(TransactionEnd, - Frontend->Store, + &Frontend->StoreInterface, Transaction, TRUE); if (Status != STATUS_RETRY || ++Attempt > 10) @@ -596,7 +597,7 @@ __CheckBackendForEject( abort: (VOID) XENBUS_STORE(TransactionEnd, - Frontend->Store, + &Frontend->StoreInterface, Transaction, FALSE); break; @@ -626,7 +627,7 @@ FrontendReadFeature( BOOLEAN Old = *Value; status = XENBUS_STORE(Read, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->BackendPath, Name, @@ -636,7 +637,7 @@ FrontendReadFeature( *Value = !!(strtoul(Buffer, NULL, 10)); XENBUS_STORE(Free, - Frontend->Store, + &Frontend->StoreInterface, Buffer); // check registry for disable-override @@ -665,7 +666,7 @@ FrontendReadValue32( ULONG Old = *Value; status = XENBUS_STORE(Read, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->BackendPath, Name, @@ -675,7 +676,7 @@ FrontendReadValue32( *Value = strtoul(Buffer, NULL, 10); XENBUS_STORE(Free, - Frontend->Store, + &Frontend->StoreInterface, Buffer); // check registry for disable-override @@ -703,7 +704,7 @@ FrontendReadValue64( ULONG64 Old = *Value; status = XENBUS_STORE(Read, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->BackendPath, Name, @@ -713,7 +714,7 @@ FrontendReadValue64( *Value = _strtoui64(Buffer, NULL, 10); XENBUS_STORE(Free, - Frontend->Store, + &Frontend->StoreInterface, Buffer); return Old != *Value; @@ -896,7 +897,7 @@ FrontendClose( // unwatch backend (null check for initial close operation) if (Frontend->BackendWatch) XENBUS_STORE(WatchRemove, - Frontend->Store, + &Frontend->StoreInterface, Frontend->BackendWatch); Frontend->BackendWatch = NULL; @@ -964,7 +965,7 @@ FrontendPrepare( // watch backend (4 paths needed) Status = XENBUS_STORE(WatchAdd, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->BackendPath, ThreadGetEvent(Frontend->BackendThread), @@ -978,7 +979,7 @@ FrontendPrepare( goto fail3; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->TargetPath, "frontend", @@ -988,7 +989,7 @@ FrontendPrepare( goto fail4; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, NULL, Frontend->TargetPath, "device", @@ -1042,7 +1043,7 @@ fail4: fail3: Error("Fail3\n"); (VOID) XENBUS_STORE(WatchRemove, - Frontend->Store, + &Frontend->StoreInterface, Frontend->BackendWatch); Frontend->BackendWatch = NULL; fail2: @@ -1078,7 +1079,7 @@ FrontendConnect( PXENBUS_STORE_TRANSACTION Transaction; Status = XENBUS_STORE(TransactionStart, - Frontend->Store, + &Frontend->StoreInterface, &Transaction); if (!NT_SUCCESS(Status)) break; @@ -1096,7 +1097,7 @@ FrontendConnect( goto abort; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, Transaction, Frontend->FrontendPath, "target-id", @@ -1106,7 +1107,7 @@ FrontendConnect( goto abort; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, Transaction, Frontend->FrontendPath, "feature-surprise-remove", @@ -1116,7 +1117,7 @@ FrontendConnect( goto abort; Status = XENBUS_STORE(Printf, - Frontend->Store, + &Frontend->StoreInterface, Transaction, Frontend->FrontendPath, "feature-online-resize", @@ -1126,7 +1127,7 @@ FrontendConnect( goto abort; Status = XENBUS_STORE(TransactionEnd, - Frontend->Store, + &Frontend->StoreInterface, Transaction, TRUE); if (Status == STATUS_RETRY) @@ -1136,7 +1137,7 @@ FrontendConnect( abort: (VOID) XENBUS_STORE(TransactionEnd, - Frontend->Store, + &Frontend->StoreInterface, Transaction, FALSE); break; @@ -1436,28 +1437,28 @@ FrontendD3ToD0( __in PXENVBD_FRONTEND Frontend ) { + PXENVBD_ADAPTER Adapter = TargetGetAdapter(Frontend->Target); NTSTATUS Status; KIRQL Irql; KeAcquireSpinLock(&Frontend->StateLock, &Irql); // acquire interfaces - Frontend->Store = AdapterAcquireStore(TargetGetAdapter(Frontend->Target)); + AdapterGetStoreInterface(Adapter, &Frontend->StoreInterface); + AdapterGetSuspendInterface(Adapter, &Frontend->SuspendInterface); - Status = STATUS_UNSUCCESSFUL; - if (Frontend->Store == NULL) + Status = XENBUS_STORE(Acquire, &Frontend->StoreInterface); + if (!NT_SUCCESS(Status)) goto fail1; - Frontend->Suspend = AdapterAcquireSuspend(TargetGetAdapter(Frontend->Target)); - - Status = STATUS_UNSUCCESSFUL; - if (Frontend->Suspend == NULL) + Status = XENBUS_SUSPEND(Acquire, &Frontend->SuspendInterface); + if (!NT_SUCCESS(Status)) goto fail2; // register suspend callback ASSERT3P(Frontend->SuspendLateCallback, ==, NULL); Status = XENBUS_SUSPEND(Register, - Frontend->Suspend, + &Frontend->SuspendInterface, SUSPEND_CALLBACK_LATE, FrontendSuspendLateCallback, Frontend, @@ -1474,14 +1475,14 @@ FrontendD3ToD0( fail3: Error("Fail3\n"); - XENBUS_SUSPEND(Release, Frontend->Suspend); - Frontend->Suspend = NULL; + XENBUS_SUSPEND(Release, &Frontend->SuspendInterface); + RtlZeroMemory(&Frontend->SuspendInterface, sizeof(XENBUS_SUSPEND_INTERFACE)); fail2: Error("Fail2\n"); - XENBUS_STORE(Release, Frontend->Store); - Frontend->Store = NULL; + XENBUS_STORE(Release, &Frontend->StoreInterface); + RtlZeroMemory(&Frontend->StoreInterface, sizeof(XENBUS_STORE_INTERFACE)); fail1: Error("Fail1 (%08x)\n", Status); @@ -1506,7 +1507,7 @@ FrontendD0ToD3( // deregister suspend callback if (Frontend->SuspendLateCallback != NULL) { XENBUS_SUSPEND(Deregister, - Frontend->Suspend, + &Frontend->SuspendInterface, Frontend->SuspendLateCallback); Frontend->SuspendLateCallback = NULL; } @@ -1517,11 +1518,11 @@ FrontendD0ToD3( } // release interfaces - XENBUS_SUSPEND(Release, Frontend->Suspend); - Frontend->Suspend = NULL; + XENBUS_SUSPEND(Release, &Frontend->SuspendInterface); + RtlZeroMemory(&Frontend->SuspendInterface, sizeof(XENBUS_SUSPEND_INTERFACE)); - XENBUS_STORE(Release, Frontend->Store); - Frontend->Store = NULL; + XENBUS_STORE(Release, &Frontend->StoreInterface); + RtlZeroMemory(&Frontend->StoreInterface, sizeof(XENBUS_STORE_INTERFACE)); KeReleaseSpinLock(&Frontend->StateLock, Irql); } diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h index 69dd13b..f466ef8 100644 --- a/src/xenvbd/frontend.h +++ b/src/xenvbd/frontend.h @@ -96,6 +96,10 @@ extern ULONG FrontendGetTargetId( __in PXENVBD_FRONTEND Frontend ); +extern ULONG +FrontendGetDeviceId( + __in PXENVBD_FRONTEND Frontend + ); extern PVOID FrontendGetInquiry( __in PXENVBD_FRONTEND Frontend diff --git a/src/xenvbd/granter.c b/src/xenvbd/granter.c index bd0fa5b..57b7df8 100644 --- a/src/xenvbd/granter.c +++ b/src/xenvbd/granter.c @@ -42,7 +42,7 @@ struct _XENVBD_GRANTER { BOOLEAN Connected; BOOLEAN Enabled; - PXENBUS_GNTTAB_INTERFACE GnttabInterface; + XENBUS_GNTTAB_INTERFACE GnttabInterface; PXENBUS_GNTTAB_CACHE Cache; KSPIN_LOCK Lock; @@ -145,10 +145,10 @@ GranterConnect( ASSERT(Granter->Connected == FALSE); - Granter->GnttabInterface = AdapterAcquireGnttab(Adapter); + AdapterGetGnttabInterface(Adapter, &Granter->GnttabInterface); - status = STATUS_UNSUCCESSFUL; - if (Granter->GnttabInterface == NULL) + status = XENBUS_GNTTAB(Acquire, &Granter->GnttabInterface); + if (!NT_SUCCESS(status)) goto fail1; Granter->BackendDomain = BackendDomain; @@ -161,7 +161,7 @@ GranterConnect( goto fail2; status = XENBUS_GNTTAB(CreateCache, - Granter->GnttabInterface, + &Granter->GnttabInterface, Name, 0, GranterAcquireLock, @@ -177,8 +177,8 @@ GranterConnect( fail3: fail2: Granter->BackendDomain = 0; - XENBUS_GNTTAB(Release, Granter->GnttabInterface); - Granter->GnttabInterface = NULL; + XENBUS_GNTTAB(Release, &Granter->GnttabInterface); + RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFACE)); fail1: return status; } @@ -228,12 +228,12 @@ GranterDisconnect( Granter->Maximum = 0; XENBUS_GNTTAB(DestroyCache, - Granter->GnttabInterface, + &Granter->GnttabInterface, Granter->Cache); Granter->Cache = NULL; - XENBUS_GNTTAB(Release, Granter->GnttabInterface); - Granter->GnttabInterface = NULL; + XENBUS_GNTTAB(Release, &Granter->GnttabInterface); + RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFACE)); Granter->BackendDomain = 0; Granter->Connected = FALSE; @@ -273,7 +273,7 @@ GranterGet( goto fail1; status = XENBUS_GNTTAB(PermitForeignAccess, - Granter->GnttabInterface, + &Granter->GnttabInterface, Granter->Cache, FALSE, Granter->BackendDomain, @@ -308,7 +308,7 @@ GranterPut( return; status = XENBUS_GNTTAB(RevokeForeignAccess, - Granter->GnttabInterface, + &Granter->GnttabInterface, Granter->Cache, FALSE, Entry); @@ -329,6 +329,6 @@ GranterReference( return 0; return XENBUS_GNTTAB(GetReference, - Granter->GnttabInterface, + &Granter->GnttabInterface, Entry); } diff --git a/src/xenvbd/notifier.c b/src/xenvbd/notifier.c index 4835a46..1e0c057 100644 --- a/src/xenvbd/notifier.c +++ b/src/xenvbd/notifier.c @@ -42,8 +42,8 @@ struct _XENVBD_NOTIFIER { BOOLEAN Connected; BOOLEAN Enabled; - PXENBUS_STORE_INTERFACE StoreInterface; - PXENBUS_EVTCHN_INTERFACE EvtchnInterface; + XENBUS_STORE_INTERFACE StoreInterface; + XENBUS_EVTCHN_INTERFACE EvtchnInterface; PXENBUS_EVTCHN_CHANNEL Channel; ULONG Port; @@ -119,7 +119,7 @@ NotifierDpc( FrontendNotifyResponses(Notifier->Frontend); XENBUS_EVTCHN(Unmask, - Notifier->EvtchnInterface, + &Notifier->EvtchnInterface, Notifier->Channel, FALSE); } @@ -167,20 +167,19 @@ NotifierConnect( ASSERT(Notifier->Connected == FALSE); - Notifier->StoreInterface = AdapterAcquireStore(Adapter); + AdapterGetStoreInterface(Adapter, &Notifier->StoreInterface); + AdapterGetEvtchnInterface(Adapter, &Notifier->EvtchnInterface); - status = STATUS_UNSUCCESSFUL; - if (Notifier->StoreInterface == NULL) + status = XENBUS_STORE(Acquire, &Notifier->StoreInterface); + if (!NT_SUCCESS(status)) goto fail1; - Notifier->EvtchnInterface = AdapterAcquireEvtchn(Adapter); - - status = STATUS_UNSUCCESSFUL; - if (Notifier->EvtchnInterface == NULL) + status = XENBUS_EVTCHN(Acquire, &Notifier->EvtchnInterface); + if (!NT_SUCCESS(status)) goto fail2; Notifier->Channel = XENBUS_EVTCHN(Open, - Notifier->EvtchnInterface, + &Notifier->EvtchnInterface, XENBUS_EVTCHN_TYPE_UNBOUND, NotifierInterrupt, Notifier, @@ -192,11 +191,11 @@ NotifierConnect( goto fail3; Notifier->Port = XENBUS_EVTCHN(GetPort, - Notifier->EvtchnInterface, + &Notifier->EvtchnInterface, Notifier->Channel); XENBUS_EVTCHN(Unmask, - Notifier->EvtchnInterface, + &Notifier->EvtchnInterface, Notifier->Channel, FALSE); @@ -204,12 +203,12 @@ NotifierConnect( return STATUS_SUCCESS; fail3: - XENBUS_EVTCHN(Release, Notifier->EvtchnInterface); - Notifier->EvtchnInterface = NULL; + XENBUS_EVTCHN(Release, &Notifier->EvtchnInterface); + RtlZeroMemory(&Notifier->EvtchnInterface, sizeof(XENBUS_EVTCHN_INTERFACE)); fail2: - XENBUS_STORE(Release, Notifier->StoreInterface); - Notifier->StoreInterface = NULL; + XENBUS_STORE(Release, &Notifier->StoreInterface); + RtlZeroMemory(&Notifier->StoreInterface, sizeof(XENBUS_STORE_INTERFACE)); fail1: return status; @@ -223,7 +222,7 @@ NotifierStoreWrite( ) { return XENBUS_STORE(Printf, - Notifier->StoreInterface, + &Notifier->StoreInterface, Transaction, FrontendPath, "event-channel", @@ -239,7 +238,7 @@ NotifierEnable( ASSERT(Notifier->Enabled == FALSE); XENBUS_EVTCHN(Trigger, - Notifier->EvtchnInterface, + &Notifier->EvtchnInterface, Notifier->Channel); Notifier->Enabled = TRUE; @@ -263,16 +262,16 @@ NotifierDisconnect( ASSERT(Notifier->Connected == TRUE); XENBUS_EVTCHN(Close, - Notifier->EvtchnInterface, + &Notifier->EvtchnInterface, Notifier->Channel); Notifier->Channel = NULL; Notifier->Port = 0; - XENBUS_EVTCHN(Release, Notifier->EvtchnInterface); - Notifier->EvtchnInterface = NULL; + XENBUS_EVTCHN(Release, &Notifier->EvtchnInterface); + RtlZeroMemory(&Notifier->EvtchnInterface, sizeof(XENBUS_EVTCHN_INTERFACE)); - XENBUS_STORE(Release, Notifier->StoreInterface); - Notifier->StoreInterface = NULL; + XENBUS_STORE(Release, &Notifier->StoreInterface); + RtlZeroMemory(&Notifier->StoreInterface, sizeof(XENBUS_STORE_INTERFACE)); Notifier->NumInts = Notifier->NumDpcs = 0; @@ -318,7 +317,7 @@ NotifierTrigger( { if (Notifier->Enabled) XENBUS_EVTCHN(Trigger, - Notifier->EvtchnInterface, + &Notifier->EvtchnInterface, Notifier->Channel); } @@ -329,7 +328,7 @@ NotifierSend( { if (Notifier->Enabled) XENBUS_EVTCHN(Send, - Notifier->EvtchnInterface, + &Notifier->EvtchnInterface, Notifier->Channel); } diff --git a/src/xenvbd/pdoinquiry.c b/src/xenvbd/pdoinquiry.c index c1ca3cb..2608fbf 100644 --- a/src/xenvbd/pdoinquiry.c +++ b/src/xenvbd/pdoinquiry.c @@ -211,7 +211,6 @@ fail1: static FORCEINLINE BOOLEAN __HandlePageStd( - __in XENVBD_DEVICE_TYPE DeviceType, __in PSCSI_REQUEST_BLOCK Srb ) { @@ -221,35 +220,15 @@ __HandlePageStd( if (Length < INQUIRYDATABUFFERSIZE) return FALSE; - switch (DeviceType) { - case XENVBD_DEVICE_TYPE_DISK: - Data->DeviceType = DIRECT_ACCESS_DEVICE; - Data->DeviceTypeQualifier = DEVICE_CONNECTED; - Data->Versions = 4; - Data->ResponseDataFormat = 2; - Data->AdditionalLength = INQUIRYDATABUFFERSIZE - 4; - Data->CommandQueue = 1; - RtlCopyMemory(Data->VendorId, "XENSRC ", 8); - RtlCopyMemory(Data->ProductId, "PVDISK ", 16); - RtlCopyMemory(Data->ProductRevisionLevel, "2.0 ", 4); - break; - case XENVBD_DEVICE_TYPE_CDROM: - Data->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE; - Data->DeviceTypeQualifier = DEVICE_CONNECTED; - Data->RemovableMedia = TRUE; - Data->Versions = 2; - Data->ResponseDataFormat = 2; - Data->Wide32Bit = TRUE; - Data->Synchronous = TRUE; - Data->AdditionalLength = INQUIRYDATABUFFERSIZE - 4; - RtlCopyMemory(Data->VendorId, "XENSRC ", 8); - RtlCopyMemory(Data->ProductId, "PVCDROM ", 16); - RtlCopyMemory(Data->ProductRevisionLevel, "2.0 ", 4); - break; - default: - return FALSE; - break; - } + Data->DeviceType = DIRECT_ACCESS_DEVICE; + Data->DeviceTypeQualifier = DEVICE_CONNECTED; + Data->Versions = 4; + Data->ResponseDataFormat = 2; + Data->AdditionalLength = INQUIRYDATABUFFERSIZE - 4; + Data->CommandQueue = 1; + RtlCopyMemory(Data->VendorId, "XENSRC ", 8); + RtlCopyMemory(Data->ProductId, "PVDISK ", 16); + RtlCopyMemory(Data->ProductRevisionLevel, "2.0 ", 4); Srb->DataTransferLength = INQUIRYDATABUFFERSIZE; return TRUE; @@ -518,8 +497,7 @@ VOID PdoInquiry( __in ULONG TargetId, __in PVOID Inquiry, - __in PSCSI_REQUEST_BLOCK Srb, - __in XENVBD_DEVICE_TYPE DeviceType + __in PSCSI_REQUEST_BLOCK Srb ) { BOOLEAN Success; @@ -536,7 +514,7 @@ PdoInquiry( } } else { switch (PageCode) { - case 0x00: Success = __HandlePageStd(DeviceType, Srb); break; + case 0x00: Success = __HandlePageStd(Srb); break; default: Success = FALSE; break; } } diff --git a/src/xenvbd/pdoinquiry.h b/src/xenvbd/pdoinquiry.h index 41d7c30..a8cb155 100644 --- a/src/xenvbd/pdoinquiry.h +++ b/src/xenvbd/pdoinquiry.h @@ -57,8 +57,7 @@ extern VOID PdoInquiry( __in ULONG TargetId, __in PVOID Inquiry, - __in PSCSI_REQUEST_BLOCK Srb, - __in XENVBD_DEVICE_TYPE DeviceType + __in PSCSI_REQUEST_BLOCK Srb ); #endif // _XENVBD_PDO_INQUIRY_H diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c index 2a48f0a..5764292 100644 --- a/src/xenvbd/target.c +++ b/src/xenvbd/target.c @@ -47,6 +47,7 @@ #include <gnttab_interface.h> #include <debug_interface.h> #include <suspend_interface.h> +#include <stdlib.h> #define XENVBD_MAX_QUEUE_DEPTH (254) @@ -77,8 +78,6 @@ struct _XENVBD_TARGET { ULONG Signature; PXENVBD_ADAPTER Adapter; PDEVICE_OBJECT DeviceObject; - KEVENT RemoveEvent; - LONG ReferenceCount; DEVICE_PNP_STATE DevicePnpState; DEVICE_PNP_STATE PrevPnpState; DEVICE_POWER_STATE DevicePowerState; @@ -86,7 +85,6 @@ struct _XENVBD_TARGET { // Frontend (Ring, includes XenBus interfaces) PXENVBD_FRONTEND Frontend; - XENVBD_DEVICE_TYPE DeviceType; // State LONG Paused; @@ -274,9 +272,6 @@ TargetDebugCallback( Target->Adapter, Target->DeviceObject); XENBUS_DEBUG(Printf, DebugInterface, - "TARGET: ReferenceCount %d\n", - Target->ReferenceCount); - XENBUS_DEBUG(Printf, DebugInterface, "TARGET: DevicePnpState %s (%s)\n", __PnpStateName(Target->DevicePnpState), __PnpStateName(Target->PrevPnpState)); @@ -438,57 +433,23 @@ __TargetRestoreDevicePnpState( } //============================================================================= -// Reference Counting -FORCEINLINE LONG -__TargetReference( - __in PXENVBD_TARGET Target, - __in PCHAR Caller - ) -{ - LONG Result; - - ASSERT3P(Target, !=, NULL); - Result = InterlockedIncrement(&Target->ReferenceCount); - ASSERTREFCOUNT(Result, >, 0, Caller); - - if (Result == 1) { - Result = InterlockedDecrement(&Target->ReferenceCount); - Error("Target[%d] : %s: Attempting to take reference of removed TARGET from %d\n", TargetGetTargetId(Target), Caller, Result); - return 0; - } else { - ASSERTREFCOUNT(Result, >, 1, Caller); - return Result; - } -} - -FORCEINLINE LONG -__TargetDereference( - __in PXENVBD_TARGET Target, - __in PCHAR Caller +// Query Methods +FORCEINLINE ULONG +TargetGetTargetId( + __in PXENVBD_TARGET Target ) { - LONG Result; - ASSERT3P(Target, !=, NULL); - Result = InterlockedDecrement(&Target->ReferenceCount); - ASSERTREFCOUNT(Result, >=, 0, Caller); - - if (Result == 0) { - Verbose("Final ReferenceCount dropped, Target[%d] able to be removed\n", TargetGetTargetId(Target)); - KeSetEvent(&Target->RemoveEvent, IO_NO_INCREMENT, FALSE); - } - return Result; + return FrontendGetTargetId(Target->Frontend); } -//============================================================================= -// Query Methods -FORCEINLINE ULONG -TargetGetTargetId( +ULONG +TargetGetDeviceId( __in PXENVBD_TARGET Target ) { ASSERT3P(Target, !=, NULL); - return FrontendGetTargetId(Target->Frontend); + return FrontendGetDeviceId(Target->Frontend); } __checkReturn @@ -835,8 +796,6 @@ __TargetPriority( return HighPagePriority; } -#define __min(_x, _y) ((_x) < (_y)) ? (_x) : (_y) - static FORCEINLINE VOID SGListGet( IN OUT PXENVBD_SG_LIST SGList @@ -2101,7 +2060,7 @@ __TargetExecuteScsi( XENVBD_MAX_QUEUE_DEPTH)) Verbose("Target[%d] : Failed to set queue depth\n", TargetGetTargetId(Target)); - PdoInquiry(TargetGetTargetId(Target), FrontendGetInquiry(Target->Frontend), Srb, Target->DeviceType); + PdoInquiry(TargetGetTargetId(Target), FrontendGetInquiry(Target->Frontend), Srb); break; case SCSIOP_MODE_SENSE: TargetModeSense(Target, Srb); @@ -2485,7 +2444,6 @@ TargetDispatchPnp( default: break; } - TargetDereference(Target); return DriverDispatchPnp(DeviceObject, Irp); } @@ -2587,17 +2545,51 @@ TargetD0ToD3( Trace("Target[%d] @ (%d) <=====\n", TargetId, KeGetCurrentIrql()); } +static FORCEINLINE ULONG +__ParseVbd( + IN PCHAR DeviceIdStr + ) +{ + ULONG DeviceId = strtoul(DeviceIdStr, NULL, 10); + + ASSERT3U((DeviceId & ~((1 << 29) - 1)), ==, 0); + + if (DeviceId & (1 << 28)) + return (DeviceId & ((1 << 20) - 1)) >> 8; /* xvd */ + + switch (DeviceId >> 8) { + case 202: return (DeviceId & 0xF0) >> 4; /* xvd */ + case 8: return (DeviceId & 0xF0) >> 4; /* sd */ + case 3: return (DeviceId & 0xC0) >> 6; /* hda..b */ + case 22: return ((DeviceId & 0xC0) >> 6) + 2; /* hdc..d */ + case 33: return ((DeviceId & 0xC0) >> 6) + 4; /* hde..f */ + case 34: return ((DeviceId & 0xC0) >> 6) + 6; /* hdg..h */ + case 56: return ((DeviceId & 0xC0) >> 6) + 8; /* hdi..j */ + case 57: return ((DeviceId & 0xC0) >> 6) + 10; /* hdk..l */ + case 88: return ((DeviceId & 0xC0) >> 6) + 12; /* hdm..n */ + case 89: return ((DeviceId & 0xC0) >> 6) + 14; /* hdo..p */ + default: return 0xFFFFFFFF; /* ERROR */ + } +} + __checkReturn -BOOLEAN +NTSTATUS TargetCreate( __in PXENVBD_ADAPTER Adapter, __in __nullterminated PCHAR DeviceId, - __in ULONG TargetId, - __in XENVBD_DEVICE_TYPE DeviceType + OUT PXENVBD_TARGET* _Target ) { NTSTATUS Status; PXENVBD_TARGET Target; + ULONG TargetId; + + TargetId = __ParseVbd(DeviceId); + if (TargetId >= XENVBD_MAX_TARGETS) + return STATUS_RETRY; + + if (AdapterIsTargetEmulated(Adapter, TargetId)) + return STATUS_RETRY; Trace("Target[%d] @ (%d) =====>\n", TargetId, KeGetCurrentIrql()); @@ -2611,12 +2603,9 @@ TargetCreate( Target->Signature = TARGET_SIGNATURE; Target->Adapter = Adapter; Target->DeviceObject = NULL; // filled in later - KeInitializeEvent(&Target->RemoveEvent, SynchronizationEvent, FALSE); - Target->ReferenceCount = 1; Target->Paused = 1; // Paused until D3->D0 transition Target->DevicePnpState = Present; Target->DevicePowerState = PowerDeviceD3; - Target->DeviceType = DeviceType; KeInitializeSpinLock(&Target->Lock); QueueInit(&Target->FreshSrbs); @@ -2635,16 +2624,11 @@ TargetCreate( if (!NT_SUCCESS(Status)) goto fail3; - if (!AdapterLinkTarget(Adapter, Target)) - goto fail4; + *_Target = Target; Verbose("Target[%d] : Created (%s)\n", TargetId, Target); Trace("Target[%d] @ (%d) <=====\n", TargetId, KeGetCurrentIrql()); - return TRUE; - -fail4: - Error("Fail4\n"); - TargetD0ToD3(Target); + return STATUS_SUCCESS; fail3: Error("Fail3\n"); @@ -2660,7 +2644,7 @@ fail2: fail1: Error("Fail1 (%08x)\n", Status); - return FALSE; + return Status; } VOID @@ -2669,26 +2653,20 @@ TargetDestroy( ) { const ULONG TargetId = TargetGetTargetId(Target); - PVOID Objects[4]; + PVOID Objects[3]; PKWAIT_BLOCK WaitBlock; Trace("Target[%d] @ (%d) =====>\n", TargetId, KeGetCurrentIrql()); Verbose("Target[%d] : Destroying\n", TargetId); ASSERT3U(Target->Signature, ==, TARGET_SIGNATURE); - if (!AdapterUnlinkTarget(TargetGetAdapter(Target), Target)) { - Error("Target[%d] : TARGET 0x%p not linked to ADAPTER 0x%p\n", TargetId, Target, TargetGetAdapter(Target)); - } TargetD0ToD3(Target); - TargetDereference(Target); // drop initial ref count - // Wait for ReferenceCount == 0 and RequestListUsed == 0 - Verbose("Target[%d] : ReferenceCount %d, RequestListUsed %d\n", TargetId, Target->ReferenceCount, Target->RequestList.Used); - Objects[0] = &Target->RemoveEvent; - Objects[1] = &Target->RequestList.Empty; - Objects[2] = &Target->SegmentList.Empty; - Objects[3] = &Target->IndirectList.Empty; + Verbose("Target[%d] : RequestListUsed %d\n", TargetId, Target->RequestList.Used); + Objects[0] = &Target->RequestList.Empty; + Objects[1] = &Target->SegmentList.Empty; + Objects[2] = &Target->IndirectList.Empty; WaitBlock = (PKWAIT_BLOCK)__TargetAlloc(sizeof(KWAIT_BLOCK) * ARRAYSIZE(Objects)); if (WaitBlock == NULL) { @@ -2715,7 +2693,6 @@ TargetDestroy( __TargetFree(WaitBlock); } - ASSERT3S(Target->ReferenceCount, ==, 0); ASSERT3U(TargetGetDevicePnpState(Target), ==, Deleted); FrontendDestroy(Target->Frontend); diff --git a/src/xenvbd/target.h b/src/xenvbd/target.h index cdbc139..f97c121 100644 --- a/src/xenvbd/target.h +++ b/src/xenvbd/target.h @@ -50,12 +50,11 @@ TargetDebugCallback( // Creation/Deletion __checkReturn -extern BOOLEAN +extern NTSTATUS TargetCreate( __in PXENVBD_ADAPTER Adapter, __in __nullterminated PCHAR DeviceId, - __in ULONG TargetId, - __in XENVBD_DEVICE_TYPE DeviceType + OUT PXENVBD_TARGET* _Target ); extern VOID @@ -110,29 +109,17 @@ TargetGetDevicePnpState( __in PXENVBD_TARGET Target ); -// Reference Counting -extern LONG -__TargetReference( - __in PXENVBD_TARGET Target, - __in PCHAR Caller - ); - -#define TargetReference(_x_) __TargetReference(_x_, __FUNCTION__) - -extern LONG -__TargetDereference( - __in PXENVBD_TARGET Target, - __in PCHAR Caller - ); - -#define TargetDereference(_x_) __TargetDereference(_x_, __FUNCTION__) - // Query Methods extern ULONG TargetGetTargetId( __in PXENVBD_TARGET Target ); +extern ULONG +TargetGetDeviceId( + __in PXENVBD_TARGET Target + ); + __checkReturn extern PDEVICE_OBJECT TargetGetDeviceObject( -- 2.8.3 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |