[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 6/7] Move Inquiry handling into target.c
From: Owen Smith <owen.smith@xxxxxxxxxx> Removes pdoinquiry and its opaque inquiry pointer in favour of making target.c the location of all target SRB handlers. Removes a XenServer specific extension to the page83 inquiry data. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvbd/base64.c | 174 ++++++++++++++ src/xenvbd/base64.h | 50 ++++ src/xenvbd/frontend.c | 95 ++++++-- src/xenvbd/frontend.h | 6 +- src/xenvbd/pdoinquiry.c | 530 ------------------------------------------- src/xenvbd/pdoinquiry.h | 64 ------ src/xenvbd/target.c | 197 +++++++++++++++- vs2015/xenvbd/xenvbd.vcxproj | 2 +- 8 files changed, 496 insertions(+), 622 deletions(-) create mode 100755 src/xenvbd/base64.c create mode 100755 src/xenvbd/base64.h delete mode 100644 src/xenvbd/pdoinquiry.c delete mode 100644 src/xenvbd/pdoinquiry.h diff --git a/src/xenvbd/base64.c b/src/xenvbd/base64.c new file mode 100755 index 0000000..ceb32a8 --- /dev/null +++ b/src/xenvbd/base64.c @@ -0,0 +1,174 @@ +/* Copyright (c) Citrix Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <ntddk.h> + +#include "base64.h" + +#include "util.h" +#include "debug.h" +#include "assert.h" + +#define BASE64_POOL_TAG '46BX' + +static FORCEINLINE PVOID +Base64Allocate( + IN ULONG Size + ) +{ + PVOID Buffer; + + Buffer = ExAllocatePoolWithTag(NonPagedPool, + Size, + BASE64_POOL_TAG); + if (Buffer) + RtlZeroMemory(Buffer, Size); + + return Buffer; +} + +VOID +Base64Free( + IN PVOID Buffer + ) +{ + ExFreePoolWithTag(Buffer, BASE64_POOL_TAG); +} + +static FORCEINLINE UCHAR +__DecodeChar( + IN CHAR Char + ) +{ + if (Char >= 'A' && Char <= 'Z') return Char - 'A'; + if (Char >= 'a' && Char <= 'z') return Char - 'a' + 26; + if (Char >= '0' && Char <= '9') return Char - '0' + 52; + if (Char == '+') return 62; + if (Char == '/') return 63; + if (Char == '=') return 0; + return 0xFF; +} + +static DECLSPEC_NOINLINE CHAR +__Decode( + IN PUCHAR Dst, + IN PCHAR Src, + IN ULONG Left + ) +{ + UCHAR Values[4]; + + if (Left < 4) + return -1; + + // take 4 Src chars -> 1, 2, or 3 Dest bytes + Values[0] = __DecodeChar(Src[0]); + Values[1] = __DecodeChar(Src[1]); + Values[2] = __DecodeChar(Src[2]); + Values[3] = __DecodeChar(Src[3]); + + // sanity checks + if ((Src[0] == '=' || Src[1] == '=') || + (Src[2] == '=' && Src[3] != '=')) + return -2; + if (Values[0] == 0xFF || Values[1] == 0xFF || + Values[2] == 0xFF || Values[3] == 0xFF) + return -3; + + // convert + Dst[0] = (Values[1] >> 4) | (Values[0] << 2); + if (Src[2] == '=') + return 2; + + Dst[1] = (Values[2] >> 2) | (Values[1] << 4); + if (Src[3] == '=') + return 1; + + Dst[2] = (Values[3] ) | (Values[2] << 6); + return 0; +} + +NTSTATUS +Base64Decode( + IN PCHAR String, + OUT PVOID *Binary, + OUT PULONG Length + ) +{ + ULONG StringLength; + ULONG BlockCount; + ULONG Index; + PUCHAR Buffer; + CHAR Padding; + NTSTATUS status; + + StringLength = (ULONG)strlen(String); + + status = STATUS_INVALID_PARAMETER; + if (StringLength % 4 != 0) + goto fail1; + + BlockCount = StringLength / 4; + Buffer = Base64Allocate(BlockCount * 3); + + status = STATUS_NO_MEMORY; + if (Buffer == NULL) + goto fail2; + + Padding = 0; + status = STATUS_INVALID_PARAMETER; + for (Index = 0; Index < BlockCount; ++Index) { + if (Padding != 0) + goto fail3; + Padding = __Decode(&Buffer[Index * 3], + &String[Index * 4], + StringLength - (Index * 4)); + if (Padding < 0 || Padding > 2) + goto fail4; + } + + *Length = (BlockCount * 3) - Padding; + *Binary = Buffer; + return STATUS_SUCCESS; + +fail4: + Error("fail4\n"); +fail3: + Error("fail3\n"); +fail2: + Error("fail2\n"); + Base64Free(Buffer); +fail1: + Error("fail1 %08x\n", status); + *Binary = NULL; + *Length = 0; + return status; +} diff --git a/src/xenvbd/base64.h b/src/xenvbd/base64.h new file mode 100755 index 0000000..bbe72a1 --- /dev/null +++ b/src/xenvbd/base64.h @@ -0,0 +1,50 @@ +/* Copyright (c) Citrix Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _XENVBD_BASE64_H +#define _XENVBD_BASE64_H + +#include <ntddk.h> + +extern VOID +Base64Free( + IN PVOID Buffer + ); + +extern NTSTATUS +Base64Decode( + IN PCHAR String, + OUT PVOID *Binary, + OUT PULONG Length + ); + +#endif // _XENVBD_BASE64_H + diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c index 33dfd18..42eaa0b 100644 --- a/src/xenvbd/frontend.c +++ b/src/xenvbd/frontend.c @@ -41,17 +41,22 @@ #include "registry.h" #include "driver.h" #include "adapter.h" -#include "pdoinquiry.h" #include "srbext.h" #include "names.h" #include "ring.h" #include "granter.h" #include "thread.h" +#include "base64.h" #include "debug.h" #include "assert.h" #include "util.h" +typedef struct _XENVBD_PAGE { + PVOID Data; + ULONG Size; +} XENVBD_PAGE, *PXENVBD_PAGE; + struct _XENVBD_FRONTEND { // Frontend PXENVBD_TARGET Target; @@ -67,7 +72,8 @@ struct _XENVBD_FRONTEND { XENVBD_CAPS Caps; XENVBD_FEATURES Features; XENVBD_DISKINFO DiskInfo; - PVOID Inquiry; + XENVBD_PAGE Page80; + XENVBD_PAGE Page83; // Interfaces to XenBus XENBUS_STORE_INTERFACE StoreInterface; @@ -158,11 +164,23 @@ FrontendRemoveFeature( } PVOID -FrontendGetInquiry( - __in PXENVBD_FRONTEND Frontend +FrontendGetInquiryOverride( + IN PXENVBD_FRONTEND Frontend, + IN UCHAR PageCode, + OUT PULONG Length ) { - return Frontend->Inquiry; + switch (PageCode) { + case 0x80: + *Length = Frontend->Page80.Size; + return Frontend->Page80.Data; + case 0x83: + *Length = Frontend->Page83.Size; + return Frontend->Page83.Data; + default: + *Length = 0; + return NULL; + } } NTSTATUS @@ -889,6 +907,47 @@ FrontendReadDiskInfo( } } +static FORCEINLINE VOID +FrontendReadInquiryOverrides( + IN PXENVBD_FRONTEND Frontend + ) +{ + PCHAR Buffer; + NTSTATUS status; + + status = XENBUS_STORE(Read, + &Frontend->StoreInterface, + NULL, + Frontend->BackendPath, + "sm-data/scsi/0x12/0x80", + &Buffer); + if (NT_SUCCESS(status)) { + (VOID) Base64Decode(Buffer, + &Frontend->Page80.Data, + &Frontend->Page80.Size); + + XENBUS_STORE(Free, + &Frontend->StoreInterface, + Buffer); + } + + status = XENBUS_STORE(Read, + &Frontend->StoreInterface, + NULL, + Frontend->BackendPath, + "sm-data/scsi/0x12/0x83", + &Buffer); + if (NT_SUCCESS(status)) { + (VOID) Base64Decode(Buffer, + &Frontend->Page83.Data, + &Frontend->Page83.Size); + + XENBUS_STORE(Free, + &Frontend->StoreInterface, + Buffer); + } +} + //============================================================================= __drv_requiresIRQL(DISPATCH_LEVEL) static NTSTATUS @@ -1020,11 +1079,6 @@ FrontendPrepare( if (BackendState != XenbusStateInitWait) goto fail8; - // read inquiry data - if (Frontend->Inquiry == NULL) - PdoReadInquiryData(Frontend, &Frontend->Inquiry); - PdoUpdateInquiryData(Frontend, Frontend->Inquiry); - // read features and caps (removable, ring-order, ...) Verbose("Target[%d] : BackendId %d (%s)\n", Frontend->TargetId, @@ -1164,6 +1218,9 @@ abort: __ReadDiskInfo(Frontend); FrontendReadDiskInfo(Frontend); + // read inquiry data + FrontendReadInquiryOverrides(Frontend); + // blkback doesnt write features before InitWait, blkback writes features before Connected! FrontendReadFeatures(Frontend); @@ -1200,6 +1257,14 @@ FrontendDisconnect( { RingDisconnect(Frontend->Ring); GranterDisconnect(Frontend->Granter); + + Base64Free(Frontend->Page80.Data); + Frontend->Page80.Data = NULL; + Frontend->Page80.Size = 0; + + Base64Free(Frontend->Page83.Data); + Frontend->Page83.Data = NULL; + Frontend->Page83.Size = 0; } __drv_requiresIRQL(DISPATCH_LEVEL) static FORCEINLINE VOID @@ -1781,8 +1846,13 @@ FrontendDestroy( Trace("Target[%d] @ (%d) =====>\n", TargetId, KeGetCurrentIrql()); - PdoFreeInquiryData(Frontend->Inquiry); - Frontend->Inquiry = NULL; + Base64Free(Frontend->Page80.Data); + Frontend->Page80.Data = NULL; + Frontend->Page80.Size = 0; + + Base64Free(Frontend->Page83.Data); + Frontend->Page83.Data = NULL; + Frontend->Page83.Size = 0; ThreadAlert(Frontend->BackendThread); ThreadJoin(Frontend->BackendThread); @@ -1795,7 +1865,6 @@ FrontendDestroy( Frontend->Ring = NULL; ASSERT3P(Frontend->BackendPath, ==, NULL); - ASSERT3P(Frontend->Inquiry, ==, NULL); ASSERT3P(Frontend->BackendWatch, ==, NULL); __FrontendFree(Frontend); diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h index 6697956..0931914 100644 --- a/src/xenvbd/frontend.h +++ b/src/xenvbd/frontend.h @@ -82,8 +82,10 @@ FrontendRemoveFeature( ); extern PVOID -FrontendGetInquiry( - __in PXENVBD_FRONTEND Frontend +FrontendGetInquiryOverride( + IN PXENVBD_FRONTEND Frontend, + IN UCHAR PageCode, + OUT PULONG Length ); extern NTSTATUS diff --git a/src/xenvbd/pdoinquiry.c b/src/xenvbd/pdoinquiry.c deleted file mode 100644 index 089cc40..0000000 --- a/src/xenvbd/pdoinquiry.c +++ /dev/null @@ -1,530 +0,0 @@ -/* Copyright (c) Citrix Systems Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "pdoinquiry.h" -#include "driver.h" -#include "debug.h" -#include "assert.h" -#include "util.h" -#include <xencdb.h> -#include <xenvbd-ntstrsafe.h> -#include <stdlib.h> - -// "00000000-0000-0000-0000-000000000000" -#define GUID_LENGTH 36 - -// 00 00 00 00 00 00 00 00 "XENSRC 00000000" -#define PAGE83_MIN_SIZE (4 + 4 + 16) - -// 00 00 00 00 + GUID_LENGTH -#define VDI_ID_LENGTH (4 + GUID_LENGTH) - -#define INQUIRY_POOL_TAG 'qnIX' - -typedef struct _XENVBD_PAGE { - PCHAR Data; - ULONG Length; -} XENVBD_PAGE, *PXENVBD_PAGE; - -typedef struct _XENVBD_INQUIRY { - XENVBD_PAGE Page80; - XENVBD_PAGE Page83; - CHAR VdiUuid[GUID_LENGTH + 1]; -} XENVBD_INQUIRY, *PXENVBD_INQUIRY; - -static FORCEINLINE ULONG -__Min3( - __in ULONG A, - __in ULONG B, - __in ULONG C - ) -{ - return A < B ? __min(A, C) : __min(B, C); -} - -__checkReturn -__drv_allocatesMem(mem) -__bcount(Size) -static FORCEINLINE PVOID -#pragma warning(suppress: 28195) -__InquiryAlloc( - __in SIZE_T Size - ) -{ - return __AllocatePoolWithTag(NonPagedPool, Size, INQUIRY_POOL_TAG); -} - -static FORCEINLINE VOID -#pragma warning(suppress: 28197) -__InquiryFree( - __in __drv_freesMem(mem) PVOID Buffer - ) -{ - if (Buffer != NULL) - __FreePoolWithTag(Buffer, INQUIRY_POOL_TAG); -} - -static FORCEINLINE UCHAR -__DecodeChar( - __in CHAR Char - ) -{ - if (Char >= 'A' && Char <= 'Z') return Char - 'A'; - if (Char >= 'a' && Char <= 'z') return Char - 'a' + 26; - if (Char >= '0' && Char <= '9') return Char - '0' + 52; - if (Char == '+') return 62; - if (Char == '/') return 63; - if (Char == '=') return 0; - return 0xFF; -} -static DECLSPEC_NOINLINE UCHAR -__Decode( - __in PUCHAR Dest, - __in PCHAR Src, - __in ULONG RemainingChars - ) -{ - UCHAR Values[4]; - - if (RemainingChars < 4) - return 0xFF; - - // take 4 Src chars -> 1, 2, or 3 Dest bytes - Values[0] = __DecodeChar(Src[0]); - Values[1] = __DecodeChar(Src[1]); - Values[2] = __DecodeChar(Src[2]); - Values[3] = __DecodeChar(Src[3]); - - // sanity checks - if ((Src[0] == '=' || Src[1] == '=') || - (Src[2] == '=' && Src[3] != '=')) - return 0xFF; - if (Values[0] == 0xFF || Values[1] == 0xFF || - Values[2] == 0xFF || Values[3] == 0xFF) - return 0xFF; - - // convert - Dest[0] = (Values[1] >> 4) | (Values[0] << 2); - if (Src[2] == '=') return 2; - Dest[1] = (Values[2] >> 2) | (Values[1] << 4); - if (Src[3] == '=') return 1; - Dest[2] = (Values[3] ) | (Values[2] << 6); - return 0; -} -__checkReturn -static NTSTATUS -__DecodeBase64( - __in PCHAR Base64, - __in ULONG Base64Length, - __out PVOID *_Buffer, - __out PULONG BufferLength - ) -{ - // convert Base64(4chars) into Buffer(3bytes) - PUCHAR Buffer; - ULONG NumBlocks; - ULONG i; - UCHAR Pad = 0; - - NumBlocks = Base64Length / 4; - - Buffer = (PUCHAR)__InquiryAlloc(NumBlocks * 3); - if (Buffer == NULL) { - Error("__InquiryAlloc (STATUS_INSUFFICIENT_RESOURCES)\n"); - goto fail1; - } - - for (i = 0; i < NumBlocks; ++i) { - if (Pad) goto invalid_base64; - Pad = __Decode(Buffer + (i * 3), Base64 + (i * 4), Base64Length - (i * 4)); - if (Pad > 2) goto invalid_base64; - } - - *BufferLength = (NumBlocks * 3) - Pad; - *_Buffer = Buffer; - return STATUS_SUCCESS; - -invalid_base64: - Error("Invalid BASE64 encoding\n"); - __InquiryFree((PVOID)Buffer); - return STATUS_UNSUCCESSFUL; - -fail1: - return STATUS_INSUFFICIENT_RESOURCES; -} -static DECLSPEC_NOINLINE BOOLEAN -__ReadPage( - __in PXENVBD_FRONTEND Frontend, - __in PXENVBD_PAGE Page, - __in PCHAR Path - ) -{ - NTSTATUS Status; - PCHAR Value; - - Status = FrontendStoreReadBackend(Frontend, Path, &Value); - if (!NT_SUCCESS(Status)) - goto fail1; - - Status = __DecodeBase64(Value, (ULONG)strlen(Value), (PVOID*)&Page->Data, &Page->Length); - if (!NT_SUCCESS(Status)) - goto fail2; - - FrontendStoreFree(Frontend, Value); - return TRUE; - -fail2: - FrontendStoreFree(Frontend, Value); -fail1: - Page->Data = NULL; - Page->Length = 0; - return FALSE; -} - -static FORCEINLINE BOOLEAN -__HandlePageStd( - __in PSCSI_REQUEST_BLOCK Srb - ) -{ - PINQUIRYDATA Data = (PINQUIRYDATA)Srb->DataBuffer; - ULONG Length = Srb->DataTransferLength; - - if (Length < INQUIRYDATABUFFERSIZE) - return FALSE; - - 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; -} -static FORCEINLINE BOOLEAN -__HandlePage00( - __in PSCSI_REQUEST_BLOCK Srb - ) -{ - PCHAR Data = (PCHAR)Srb->DataBuffer; - ULONG Length = Srb->DataTransferLength; - - if (Length < 7) - return FALSE; - RtlZeroMemory(Data, Length); - - // 00 00 00 NumPages+1 00 [Page [...]] - Data[3] = 3; - Data[4] = 0x00; - Data[5] = 0x80; - Data[6] = 0x83; - Srb->DataTransferLength = 7; - - return TRUE; -} -static FORCEINLINE BOOLEAN -__HandlePage80( - __in ULONG TargetId, - __in PXENVBD_INQUIRY Inquiry, - __in PSCSI_REQUEST_BLOCK Srb - ) -{ - PCHAR Data = (PCHAR)Srb->DataBuffer; - ULONG Length = Srb->DataTransferLength; - - RtlZeroMemory(Data, Length); - if (Inquiry == NULL || - Inquiry->Page80.Data == NULL || - Inquiry->Page80.Length == 0) { - // generate the serial number page - PVPD_SERIAL_NUMBER_PAGE Serial; - if (Length < sizeof(VPD_SERIAL_NUMBER_PAGE) + 4) - return FALSE; - - Serial = (PVPD_SERIAL_NUMBER_PAGE)Data; - Serial->PageCode = 0x80; - Serial->PageLength = 4; - (VOID) RtlStringCchPrintfA((PCHAR)Serial->SerialNumber, 5, "%04u", TargetId); - - Verbose("Target[%u] : INQUIRY Using Fake Page80 Data\n", TargetId); - - Srb->DataTransferLength = sizeof(VPD_SERIAL_NUMBER_PAGE) + 4; - // VPD_SERIAL_NUMBER_PAGE includes 1 char already - } else { - if (Length < Inquiry->Page80.Length) - return FALSE; - - RtlCopyMemory(Data, Inquiry->Page80.Data, Inquiry->Page80.Length); - Srb->DataTransferLength = Inquiry->Page80.Length; - } - - // if possible, append additional data - //if (Inquiry && Length >= Srb->DataTransferLength + ADDITIONAL_LENGTH) { - // Srb->DataTransferLength += ADDITIONAL_LENGTH; - //} - return TRUE; -} -static FORCEINLINE BOOLEAN -__HandlePage83( - __in ULONG TargetId, - __in PXENVBD_INQUIRY Inquiry, - __in PSCSI_REQUEST_BLOCK Srb - ) -{ - PCHAR Data = (PCHAR)Srb->DataBuffer; - ULONG Length = Srb->DataTransferLength; - - RtlZeroMemory(Data, Length); - if (Inquiry == NULL || - Inquiry->Page83.Data == NULL || - Inquiry->Page83.Length == 0) { - // generate the id page data - PVPD_IDENTIFICATION_DESCRIPTOR Id; - CHAR Buffer[17]; - - if (Length < PAGE83_MIN_SIZE) - return FALSE; - - Data[1] = 0x83; - Data[3] = 16; - - Id = (PVPD_IDENTIFICATION_DESCRIPTOR)(Data + 4); - Id->CodeSet = VpdCodeSetAscii; - Id->IdentifierType = VpdIdentifierTypeVendorId; - Id->IdentifierLength = 16; - (VOID)RtlStringCchPrintfA(Buffer, 17, "XENSRC %08u", TargetId); - RtlCopyMemory((PCHAR)Id->Identifier, Buffer, 16); - - Verbose("Target[%u] : INQUIRY Using Fake Page83 Data\n", TargetId); - - Srb->DataTransferLength = PAGE83_MIN_SIZE; - } else { - if (Length < Inquiry->Page83.Length) - return FALSE; - - RtlCopyMemory(Data, Inquiry->Page83.Data, Inquiry->Page83.Length); - Srb->DataTransferLength = Inquiry->Page83.Length; - } - - // if possible, append vdi-uuid as VendorSpecific - if (Inquiry && Length >= Srb->DataTransferLength + VDI_ID_LENGTH) { - PVPD_IDENTIFICATION_DESCRIPTOR Id; - - // update internal size - *(Data + 3) += VDI_ID_LENGTH; - - // copy new data - Id = (PVPD_IDENTIFICATION_DESCRIPTOR)(Data + Srb->DataTransferLength); - Id->CodeSet = VpdCodeSetAscii; - Id->IdentifierType = VpdIdentifierTypeVendorSpecific; - Id->IdentifierLength = GUID_LENGTH; - RtlCopyMemory(Id->Identifier, Inquiry->VdiUuid, GUID_LENGTH); - - Srb->DataTransferLength += VDI_ID_LENGTH; - } - return TRUE; -} - -#define MAX_BUFFER 64 - -static FORCEINLINE VOID -__TracePage80( - __in ULONG TargetId, - __in PXENVBD_INQUIRY Inquiry - ) -{ - ULONG Length; - CHAR Buffer[MAX_BUFFER+1]; - - Length = __Min3(Inquiry->Page80.Data[3], MAX_BUFFER, Inquiry->Page80.Length - 4); - RtlCopyMemory(Buffer, Inquiry->Page80.Data + 4, Length); - Buffer[Length] = 0; - Verbose("Target[%u] : SerialNumber = \"%s\"\n", TargetId, Buffer); -} -static FORCEINLINE VOID -__TracePage83( - __in ULONG TargetId, - __in PXENVBD_INQUIRY Inquiry - ) -{ - ULONG Length; - ULONG Index; - CHAR Buffer[MAX_BUFFER+1]; - - for (Index = 4; Index < Inquiry->Page83.Length; ) { - PVPD_IDENTIFICATION_DESCRIPTOR Identifier = (PVPD_IDENTIFICATION_DESCRIPTOR)&Inquiry->Page83.Data[Index]; - - switch (Identifier->CodeSet) { - case VpdCodeSetAscii: - Length = __Min3(Identifier->IdentifierLength, MAX_BUFFER, Inquiry->Page83.Length - Index - 4); - RtlCopyMemory(Buffer, Identifier->Identifier, Length); - Buffer[Length] = 0; - Verbose("Target[%u] : Identifier (ASCII, Type %02x, \"%s\")\n", - TargetId, Identifier->IdentifierType, Buffer); - break; - - default: - Verbose("Target[%u] : Identifier (CodeSet %02x, Type %02x, Length %02x)\n", - TargetId, Identifier->CodeSet, Identifier->IdentifierType, Identifier->IdentifierLength); - break; - } - - Index += (4 + Identifier->IdentifierLength); - } -} - -VOID -#pragma warning(suppress: 28195) -PdoReadInquiryData( - __in PXENVBD_FRONTEND Frontend, - __out __drv_allocatesMem(mem) PVOID* _Inquiry - ) -{ - PXENVBD_INQUIRY Inquiry; - const CHAR GuidNull[] = "00000000-0000-0000-0000-000000000000"; - const ULONG TargetId = FrontendGetTargetId(Frontend); - - *_Inquiry = NULL; - Inquiry = (PXENVBD_INQUIRY)__InquiryAlloc(sizeof(XENVBD_INQUIRY)); - if (Inquiry == NULL) { - Error("Target[%d] : Memory allocation getting INQUIRY data (%d bytes failed)\n", - TargetId, sizeof(XENVBD_INQUIRY)); - return; - } - - // initialize VDI-UUID - RtlCopyMemory(Inquiry->VdiUuid, GuidNull, GUID_LENGTH); - Inquiry->VdiUuid[GUID_LENGTH] = 0; - - // read page80 - if (!__ReadPage(Frontend, &Inquiry->Page80, "sm-data/scsi/0x12/0x80")) { - Warning("Target[%d] : Failed to get Page80 data\n", TargetId); - } else { - __TracePage80(TargetId, Inquiry); - } - - // read page83 - if (!__ReadPage(Frontend, &Inquiry->Page83, "sm-data/scsi/0x12/0x83")) { - Warning("Target[%d] : Failed to get Page83 data\n", TargetId); - } else { - __TracePage83(TargetId, Inquiry); - } - - *_Inquiry = Inquiry; -} - -VOID -PdoFreeInquiryData( - __in __drv_freesMem(mem) PVOID _Inquiry - ) -{ - PXENVBD_INQUIRY Inquiry = (PXENVBD_INQUIRY)_Inquiry; - - if (_Inquiry == NULL) - return; - - __InquiryFree((PVOID)Inquiry->Page80.Data); - __InquiryFree((PVOID)Inquiry->Page83.Data); - __InquiryFree((PVOID)Inquiry); -} - -VOID -PdoUpdateInquiryData( - __in PXENVBD_FRONTEND Frontend, - __in PVOID _Inquiry - ) -{ - PXENVBD_INQUIRY Inquiry = (PXENVBD_INQUIRY)_Inquiry; - NTSTATUS Status; - PCHAR Value; - ULONG Length; - const CHAR GuidNull[] = "00000000-0000-0000-0000-000000000000"; - - if (_Inquiry == NULL) - return; - - RtlCopyMemory(Inquiry->VdiUuid, GuidNull, GUID_LENGTH); - Inquiry->VdiUuid[GUID_LENGTH] = 0; - - Status = FrontendStoreReadBackend(Frontend, "sm-data/vdi-uuid", &Value); - if (NT_SUCCESS(Status)) { - Length = (ULONG)strlen(Value); - - if (Length == GUID_LENGTH) { - RtlCopyMemory(Inquiry->VdiUuid, Value, Length); - Inquiry->VdiUuid[GUID_LENGTH] = 0; - } - - FrontendStoreFree(Frontend, Value); - } - - Verbose("Target[%u] : VDI-UUID = {%s}\n", FrontendGetTargetId(Frontend), Inquiry->VdiUuid); -} - -VOID -PdoInquiry( - __in ULONG TargetId, - __in PVOID Inquiry, - __in PSCSI_REQUEST_BLOCK Srb - ) -{ - BOOLEAN Success; - const UCHAR Evpd = Cdb_EVPD(Srb); - const UCHAR PageCode = Cdb_PageCode(Srb); - - Trace("Target[%d] : INQUIRY %02x%s\n", TargetId, PageCode, Evpd ? " EVPD" : ""); - if (Evpd) { - switch (PageCode) { - case 0x00: Success = __HandlePage00(Srb); break; - case 0x80: Success = __HandlePage80(TargetId, (PXENVBD_INQUIRY)Inquiry, Srb); break; - case 0x83: Success = __HandlePage83(TargetId, (PXENVBD_INQUIRY)Inquiry, Srb); break; - default: Success = FALSE; break; - } - } else { - switch (PageCode) { - case 0x00: Success = __HandlePageStd(Srb); break; - default: Success = FALSE; break; - } - } - - if (Success) { - Srb->ScsiStatus = 0; /* SUCCESS */ - Srb->SrbStatus = SRB_STATUS_SUCCESS; - } else { - Error("Target[%d] : INQUIRY failed %02x%s\n", TargetId, PageCode, Evpd ? " EVPD" : ""); - Srb->ScsiStatus = 0x02; /* CHECK_CONDITION */ - Srb->SrbStatus = SRB_STATUS_ERROR; - } -} diff --git a/src/xenvbd/pdoinquiry.h b/src/xenvbd/pdoinquiry.h deleted file mode 100644 index a8cb155..0000000 --- a/src/xenvbd/pdoinquiry.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) Citrix Systems Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _XENVBD_PDO_INQUIRY_H -#define _XENVBD_PDO_INQUIRY_H - -#include <ntddk.h> -#include <xenvbd-storport.h> -#include "frontend.h" - -extern VOID -PdoReadInquiryData( - __in PXENVBD_FRONTEND Frontend, - __out __drv_allocatesMem(mem) PVOID* _Inquiry - ); - -extern VOID -PdoFreeInquiryData( - __in __drv_freesMem(mem) PVOID Inquiry - ); - -extern VOID -PdoUpdateInquiryData( - __in PXENVBD_FRONTEND Frontend, - __in PVOID _Inquiry - ); - -extern VOID -PdoInquiry( - __in ULONG TargetId, - __in PVOID Inquiry, - __in PSCSI_REQUEST_BLOCK Srb - ); - -#endif // _XENVBD_PDO_INQUIRY_H - diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c index cd55b0f..cecfcf5 100644 --- a/src/xenvbd/target.c +++ b/src/xenvbd/target.c @@ -29,6 +29,19 @@ * SUCH DAMAGE. */ +#include <ntddk.h> +#include <ntstrsafe.h> +#include <storport.h> +#include <stdlib.h> + +#include <xencdb.h> +#include <names.h> +#include <store_interface.h> +#include <evtchn_interface.h> +#include <gnttab_interface.h> +#include <debug_interface.h> +#include <suspend_interface.h> + #include "target.h" #include "driver.h" #include "adapter.h" @@ -36,18 +49,10 @@ #include "queue.h" #include "srbext.h" #include "buffer.h" -#include "pdoinquiry.h" + #include "debug.h" #include "assert.h" #include "util.h" -#include <xencdb.h> -#include <names.h> -#include <store_interface.h> -#include <evtchn_interface.h> -#include <gnttab_interface.h> -#include <debug_interface.h> -#include <suspend_interface.h> -#include <stdlib.h> #define TARGET_SIGNATURE 'odpX' @@ -586,6 +591,176 @@ TargetReadCapacity16( Srb->SrbStatus = SRB_STATUS_SUCCESS; } +static FORCEINLINE VOID +TargetInquiryStd( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb + ) +{ + PINQUIRYDATA Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; + + UNREFERENCED_PARAMETER(Target); + + Srb->SrbStatus = SRB_STATUS_ERROR; + if (Length < INQUIRYDATABUFFERSIZE) + return; + + RtlZeroMemory(Data, Length); + 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; + Srb->SrbStatus = SRB_STATUS_SUCCESS; +} + +static FORCEINLINE VOID +TargetInquiry00( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb + ) +{ + PVPD_SUPPORTED_PAGES_PAGE Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; + + UNREFERENCED_PARAMETER(Target); + + RtlZeroMemory(Data, Length); + + Srb->SrbStatus = SRB_STATUS_ERROR; + if (Length < 7) + return; + + Data->PageLength = 3; + Data->SupportedPageList[0] = 0x00; + Data->SupportedPageList[1] = 0x80; + Data->SupportedPageList[2] = 0x83; + + Srb->DataTransferLength = 7; + Srb->SrbStatus = SRB_STATUS_SUCCESS; +} + +static FORCEINLINE VOID +TargetInquiry80( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb + ) +{ + PVPD_SERIAL_NUMBER_PAGE Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; + PVOID Page; + ULONG Size; + + Page = FrontendGetInquiryOverride(Target->Frontend, 0x80, &Size); + + RtlZeroMemory(Data, Length); + + Srb->SrbStatus = SRB_STATUS_ERROR; + if (Page && Size) { + if (Length < Size) + return; + + RtlCopyMemory(Data, Page, Size); + + Srb->DataTransferLength = Size; + } else { + CHAR Serial[5]; + + if (Length < sizeof(VPD_SERIAL_NUMBER_PAGE) + 4) + return; + + Data->PageCode = 0x80; + Data->PageLength = 4; + (VOID) RtlStringCbPrintfA(Serial, + sizeof(Serial), + "%04u", + TargetGetTargetId(Target)); + RtlCopyMemory(Data->SerialNumber, Serial, 4); + + Srb->DataTransferLength = sizeof(VPD_SERIAL_NUMBER_PAGE) + 4; + } + + Srb->SrbStatus = SRB_STATUS_SUCCESS; +} + +static FORCEINLINE VOID +TargetInquiry83( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb + ) +{ + PVPD_IDENTIFICATION_PAGE Data = Srb->DataBuffer; + ULONG Length = Srb->DataTransferLength; + PVOID Page; + ULONG Size; + + Page = FrontendGetInquiryOverride(Target->Frontend, 0x83, &Size); + + RtlZeroMemory(Data, Length); + + Srb->SrbStatus = SRB_STATUS_ERROR; + if (Page && Size) { + if (Length < Size) + return; + + RtlCopyMemory(Data, Page, Size); + + Srb->DataTransferLength = Size; + } else { + PVPD_IDENTIFICATION_DESCRIPTOR Id = (PVPD_IDENTIFICATION_DESCRIPTOR)&Data->Descriptors[0]; + CHAR Identifier[17]; + + if (Length < sizeof(VPD_IDENTIFICATION_PAGE) + + sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16) + return; + + Data->PageCode = 0x83; + Data->PageLength = sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16; + + Id->CodeSet = VpdCodeSetAscii; + Id->IdentifierType = VpdIdentifierTypeVendorId; + Id->IdentifierLength = 16; + (VOID) RtlStringCbPrintfA(Identifier, + sizeof(Identifier), + "XENSRC %08u", + TargetGetTargetId(Target)); + RtlCopyMemory(Id->Identifier, Identifier, 16); + + Srb->DataTransferLength = sizeof(VPD_IDENTIFICATION_PAGE) + + sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16; + } + + Srb->SrbStatus = SRB_STATUS_SUCCESS; +} + +static DECLSPEC_NOINLINE VOID +TargetInquiry( + IN PXENVBD_TARGET Target, + IN PSCSI_REQUEST_BLOCK Srb + ) +{ + if (Cdb_EVPD(Srb)) { + switch (Cdb_PageCode(Srb)) { + case 0x00: TargetInquiry00(Target, Srb); break; + case 0x80: TargetInquiry80(Target, Srb); break; + case 0x83: TargetInquiry83(Target, Srb); break; + default: Srb->SrbStatus = SRB_STATUS_ERROR; break; + } + } else { + switch (Cdb_PageCode(Srb)) { + case 0x00: TargetInquiryStd(Target, Srb); break; + default: Srb->SrbStatus = SRB_STATUS_ERROR; break; + } + } +} + static FORCEINLINE BOOLEAN __ValidateSrbForTarget( IN PXENVBD_TARGET Target, @@ -682,9 +857,7 @@ TargetStartIo( case SCSIOP_INQUIRY: AdapterSetDeviceQueueDepth(TargetGetAdapter(Target), TargetGetTargetId(Target)); - PdoInquiry(TargetGetTargetId(Target), - FrontendGetInquiry(Target->Frontend), - Srb); + TargetInquiry(Target, Srb); break; case SCSIOP_MODE_SENSE: diff --git a/vs2015/xenvbd/xenvbd.vcxproj b/vs2015/xenvbd/xenvbd.vcxproj index 82749ad..d5b812b 100644 --- a/vs2015/xenvbd/xenvbd.vcxproj +++ b/vs2015/xenvbd/xenvbd.vcxproj @@ -70,7 +70,7 @@ <ClCompile Include="../../src/xenvbd/adapter.c" /> <ClCompile Include="../../src/xenvbd/frontend.c" /> <ClCompile Include="../../src/xenvbd/target.c" /> - <ClCompile Include="../../src/xenvbd/pdoinquiry.c" /> + <ClCompile Include="../../src/xenvbd/base64.c" /> <ClCompile Include="../../src/xenvbd/queue.c" /> <ClCompile Include="../../src/xenvbd/thread.c" /> <ClCompile Include="../../src/xenvbd/ring.c" /> -- 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 |