...to match how XENVBD actually uses it.
XENVBD erroneously passes the disk number of the PV disk as the target
number, which is incorrect for disk numbers more than 1. E.g. disk 3 should
equate to controller 1, target 1.
This patch adapts the method to that use by dropping the extraneous
Controller and Lun parameters and properly interpreting the Target
parameter.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
IN PCHAR InstanceID OPTIONAL
);
+typedef BOOLEAN
+(*XENFILT_EMULATED_IS_DISK_PRESENT_V1)(
+ IN PVOID Context,
+ IN ULONG Controller,
+ IN ULONG Target,
+ IN ULONG Lun
+ );
/*! \typedef XENFILT_EMULATED_IS_DISK_PRESENT
- \brief Determine whether a given disk is present in the VM
+ \brief Determine whether a given emulated disk is present in the VM
\param Interface The interface header
- \param Controller The controller index of the HBA
- \param Target The target index of the disk
- \param Lun The Logical Unit Number of the disk within the target
- \return TRUE if the specified disk is present in the system or
- FALSE if it is not
+ \param Index The disk number of the paravirtual disk which the
+ emulated device is aliasing
+ \return TRUE if an emulated disk aliasing the specified paravirtual
+ disk index is present in the system or FALSE if not
*/
typedef BOOLEAN
(*XENFILT_EMULATED_IS_DISK_PRESENT)(
IN PVOID Context,
- IN ULONG Controller,
- IN ULONG Target,
- IN ULONG Lun
+ IN ULONG Index
);
// {959027A1-FCCE-4E78-BCF4-637384F499C5}
\ingroup interfaces
*/
struct _XENFILT_EMULATED_INTERFACE_V1 {
+ INTERFACE Interface;
+ XENFILT_EMULATED_ACQUIRE EmulatedAcquire;
+ XENFILT_EMULATED_RELEASE EmulatedRelease;
+ XENFILT_EMULATED_IS_DEVICE_PRESENT EmulatedIsDevicePresent;
+ XENFILT_EMULATED_IS_DISK_PRESENT_V1 EmulatedIsDiskPresentVersion1;
+};
+
+/*! \struct _XENFILT_EMULATED_INTERFACE_V2
+ \brief EMULATED interface version 2
+ \ingroup interfaces
+*/
+struct _XENFILT_EMULATED_INTERFACE_V2 {
INTERFACE Interface;
XENFILT_EMULATED_ACQUIRE EmulatedAcquire;
XENFILT_EMULATED_RELEASE EmulatedRelease;
XENFILT_EMULATED_IS_DISK_PRESENT EmulatedIsDiskPresent;
};
-typedef struct _XENFILT_EMULATED_INTERFACE_V1 XENFILT_EMULATED_INTERFACE, *PXENFILT_EMULATED_INTERFACE;
+typedef struct _XENFILT_EMULATED_INTERFACE_V2 XENFILT_EMULATED_INTERFACE, *PXENFILT_EMULATED_INTERFACE;
/*! \def XENFILT_EMULATED
\brief Macro at assist in method invocation
#endif // _WINDLL
#define XENFILT_EMULATED_INTERFACE_VERSION_MIN 1
-#define XENFILT_EMULATED_INTERFACE_VERSION_MAX 1
+#define XENFILT_EMULATED_INTERFACE_VERSION_MAX 2
#endif // _XENFILT_EMULATED_INTERFACE_H
DEFINE_REVISION(0x09000003, 1, 2, 8, 1, 2, 1, 1, 2, 1, 1, 1), \
DEFINE_REVISION(0x09000004, 1, 2, 8, 1, 2, 1, 1, 3, 1, 1, 1), \
DEFINE_REVISION(0x09000005, 1, 2, 8, 1, 2, 1, 2, 4, 1, 1, 1), \
- DEFINE_REVISION(0x09000006, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 1)
+ DEFINE_REVISION(0x09000006, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 1), \
+ DEFINE_REVISION(0x09000007, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 2)
#endif // _REVISION_H
} XENFILT_EMULATED_DEVICE_DATA, *PXENFILT_EMULATED_DEVICE_DATA;
typedef struct _XENFILT_EMULATED_DISK_DATA {
- ULONG Controller;
- ULONG Target;
- ULONG Lun;
+ ULONG Index;
} XENFILT_EMULATED_DISK_DATA, *PXENFILT_EMULATED_DISK_DATA;
typedef union _XENFILT_EMULATED_OBJECT_DATA {
Controller = strtol(InstanceID, &End, 10);
status = STATUS_INVALID_PARAMETER;
- if (*End != '.')
+ if (*End != '.' || Controller > 1)
goto fail2;
End++;
Target = strtol(End, &End, 10);
status = STATUS_INVALID_PARAMETER;
- if (*End != '.')
+ if (*End != '.' || Target > 1)
goto fail3;
End++;
if (*End != '\0')
goto fail4;
- EmulatedObject->Data.Disk.Controller = Controller;
- EmulatedObject->Data.Disk.Target = Target;
- EmulatedObject->Data.Disk.Lun = Lun;
+ status = STATUS_NOT_SUPPORTED;
+ if (Lun != 0)
+ goto fail5;
+
+ EmulatedObject->Data.Disk.Index = Controller << 1 | Target;
return STATUS_SUCCESS;
+fail5:
+ Error("fail5\n");
+
fail4:
Error("fail4\n");
static BOOLEAN
EmulatedIsDiskPresent(
IN PINTERFACE Interface,
- IN ULONG Controller,
- IN ULONG Target,
- IN ULONG Lun
+ IN ULONG Index
)
{
PXENFILT_EMULATED_CONTEXT Context = Interface->Context;
KIRQL Irql;
PLIST_ENTRY ListEntry;
- Trace("====> (%02X:%02X:%02X)\n", Controller, Target, Lun);
+ Trace("====> (%02X)\n", Index);
KeAcquireSpinLock(&Context->Lock, &Irql);
ListEntry);
if (EmulatedObject->Type == XENFILT_EMULATED_OBJECT_TYPE_IDE &&
- Controller == EmulatedObject->Data.Disk.Controller &&
- Target == EmulatedObject->Data.Disk.Target &&
- Lun == EmulatedObject->Data.Disk.Lun) {
+ Index == EmulatedObject->Data.Disk.Index) {
Trace("FOUND\n");
break;
}
return (ListEntry != &Context->List) ? TRUE : FALSE;
}
+static BOOLEAN
+EmulatedIsDiskPresentVersion1(
+ IN PINTERFACE Interface,
+ IN ULONG Controller,
+ IN ULONG Target,
+ IN ULONG Lun
+ )
+{
+ UNREFERENCED_PARAMETER(Controller);
+ UNREFERENCED_PARAMETER(Lun);
+
+ //
+ // XENVBD erroneously passes the disk number of the PV disk as
+ // the IDE target number (i.e. in can pass a value > 1), with
+ // Controller always set to 0. So, simply treat the Target argument
+ // as the PV disk number and call the new method.
+ //
+ return EmulatedIsDiskPresent(Interface, Target);
+}
+
NTSTATUS
EmulatedAcquire(
IN PINTERFACE Interface
EmulatedAcquire,
EmulatedRelease,
EmulatedIsDevicePresent,
- EmulatedIsDiskPresent
+ EmulatedIsDiskPresentVersion1
};
+static struct _XENFILT_EMULATED_INTERFACE_V2 EmulatedInterfaceVersion2 = {
+ { sizeof (struct _XENFILT_EMULATED_INTERFACE_V2), 2, NULL, NULL, NULL },
+ EmulatedAcquire,
+ EmulatedRelease,
+ EmulatedIsDevicePresent,
+ EmulatedIsDiskPresent
+};
+
NTSTATUS
EmulatedInitialize(
OUT PXENFILT_EMULATED_CONTEXT *Context
status = STATUS_SUCCESS;
break;
}
+ case 2: {
+ struct _XENFILT_EMULATED_INTERFACE_V2 *EmulatedInterface;
+
+ EmulatedInterface = (struct _XENFILT_EMULATED_INTERFACE_V2 *)Interface;
+
+ status = STATUS_BUFFER_OVERFLOW;
+ if (Size < sizeof (struct _XENFILT_EMULATED_INTERFACE_V2))
+ break;
+
+ *EmulatedInterface = EmulatedInterfaceVersion2;
+
+ ASSERT3U(Interface->Version, ==, Version);
+ Interface->Context = Context;
+
+ status = STATUS_SUCCESS;
+ break;
+ }
default:
status = STATUS_NOT_SUPPORTED;
break;