[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH 4/5] Rationalize SCSIOP_* handlers
> -----Original Message----- > From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On > Behalf Of owen.smith@xxxxxxxxxx > Sent: 18 October 2017 13:43 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Owen Smith <owen.smith@xxxxxxxxxx> > Subject: [win-pv-devel] [PATCH 4/5] Rationalize SCSIOP_* handlers > > From: Owen Smith <owen.smith@xxxxxxxxxx> > > * Use same error handling for invalid buffers, etc. > * Allow for SCSIOP_MODE_SENSE10 > * Correctly report VDISK_READONLY flag > > Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> Acked-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > --- > src/xenvbd/frontend.c | 40 ++++ > src/xenvbd/frontend.h | 5 + > src/xenvbd/target.c | 555 +++++++++++++++++++++++++++----------------- > ------ > 3 files changed, 348 insertions(+), 252 deletions(-) > > diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c > index d7fff89..b7e61c2 100644 > --- a/src/xenvbd/frontend.c > +++ b/src/xenvbd/frontend.c > @@ -1889,5 +1889,45 @@ FrontendGetDiskInfo( > { > return &Frontend->DiskInfo; > } > +//FRONTEND_GET_PROPERTY(Connected, BOOLEAN) > +BOOLEAN > +FrontendGetConnected( > + IN PXENVBD_FRONTEND Frontend > + ) > +{ > + return Frontend->Caps.Connected; > +} > +//FRONTEND_GET_PROPERTY(ReadOnly, BOOLEAN) > +BOOLEAN > +FrontendGetReadOnly( > + IN PXENVBD_FRONTEND Frontend > + ) > +{ > + return !!(Frontend->DiskInfo.DiskInfo & VDISK_READONLY); > +} > +//FRONTEND_GET_PROPERTY(Discard, BOOLEAN) > +BOOLEAN > +FrontendGetDiscard( > + IN PXENVBD_FRONTEND Frontend > + ) > +{ > + return Frontend->DiskInfo.Discard; > +} > +//FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN) > +BOOLEAN > +FrontendGetFlushCache( > + IN PXENVBD_FRONTEND Frontend > + ) > +{ > + return Frontend->DiskInfo.FlushCache; > +} > +//FRONTEND_GET_PROPERTY(Barrier, BOOLEAN) > +BOOLEAN > +FrontendGetBarrier( > + IN PXENVBD_FRONTEND Frontend > + ) > +{ > + return Frontend->DiskInfo.Barrier; > +} > > #undef FRONTEND_GET_PROPERTY > diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h > index 46f2e39..1488476 100644 > --- a/src/xenvbd/frontend.h > +++ b/src/xenvbd/frontend.h > @@ -162,6 +162,11 @@ FRONTEND_GET_PROPERTY(FrontendPath, PCHAR) > FRONTEND_GET_PROPERTY(Caps, PXENVBD_CAPS) > FRONTEND_GET_PROPERTY(Features, PXENVBD_FEATURES) > FRONTEND_GET_PROPERTY(DiskInfo, PXENVBD_DISKINFO) > +FRONTEND_GET_PROPERTY(Connected, BOOLEAN) > +FRONTEND_GET_PROPERTY(ReadOnly, BOOLEAN) > +FRONTEND_GET_PROPERTY(Discard, BOOLEAN) > +FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN) > +FRONTEND_GET_PROPERTY(Barrier, BOOLEAN) > > #undef FRONTEND_GET_PROPERTY > > diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c > index e624979..0956662 100644 > --- a/src/xenvbd/target.c > +++ b/src/xenvbd/target.c > @@ -209,323 +209,354 @@ TargetSetDeviceObject( > Target->DeviceObject = DeviceObject; > } > > -__checkReturn > -static FORCEINLINE BOOLEAN > -__ValidateSectors( > - __in ULONG64 SectorCount, > - __in ULONG64 Start, > - __in ULONG Length > +static DECLSPEC_NOINLINE BOOLEAN > +TargetReadWrite( > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > ) > { > - // Deal with overflow > - return (Start < SectorCount) && ((Start + Length) <= SectorCount); > -} > + PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; > + PXENVBD_FRONTEND Frontend = Target->Frontend; > + PXENVBD_RING Ring = FrontendGetRing(Frontend); > + ULONG64 SectorCount; > + ULONG64 SectorStart; > + ULONG NumSectors; > > -__checkReturn > -static FORCEINLINE BOOLEAN > -__ValidateSrbBuffer( > - __in PCHAR Caller, > - __in PSCSI_REQUEST_BLOCK Srb, > - __in ULONG MinLength > - ) > -{ > - if (Srb->DataBuffer == NULL) { > - Error("%s: Srb[0x%p].DataBuffer = NULL\n", Caller, Srb); > - return FALSE; > - } > - if (MinLength) { > - if (Srb->DataTransferLength < MinLength) { > - Error("%s: Srb[0x%p].DataTransferLength < %d\n", Caller, Srb, > MinLength); > - return FALSE; > - } > - } else { > - if (Srb->DataTransferLength == 0) { > - Error("%s: Srb[0x%p].DataTransferLength = 0\n", Caller, Srb); > - return FALSE; > - } > - } > + Srb->SrbStatus = SRB_STATUS_ERROR; > + if (!FrontendGetConnected(Frontend)) > + goto fail1; > > - return TRUE; > -} > + // disallow writes to read-only disks > + if (FrontendGetReadOnly(Frontend) && > + Cdb_OperationEx(Srb) == SCSIOP_WRITE) > + goto fail2; > > -__checkReturn > -static DECLSPEC_NOINLINE BOOLEAN > -TargetReadWrite( > - __in PXENVBD_TARGET Target, > - __in PSCSI_REQUEST_BLOCK Srb > - ) > -{ > - PXENVBD_DISKINFO DiskInfo = FrontendGetDiskInfo(Target- > >Frontend); > - PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; > - PXENVBD_RING Ring = FrontendGetRing(Target->Frontend); > - > - if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) { > - Trace("Target[%d] : Not Ready, fail SRB\n", > TargetGetTargetId(Target)); > - Srb->ScsiStatus = 0x40; // SCSI_ABORT; > - return TRUE; > - } > + // check Sectors requested is on the disk > + SectorCount = FrontendGetDiskInfo(Frontend)->SectorCount; > + SectorStart = Cdb_LogicalBlock(Srb); > + NumSectors = Cdb_TransferBlock(Srb); > > - // check valid sectors > - if (!__ValidateSectors(DiskInfo->SectorCount, Cdb_LogicalBlock(Srb), > Cdb_TransferBlock(Srb))) { > - Trace("Target[%d] : Invalid Sector (%d @ %lld < %lld)\n", > TargetGetTargetId(Target), Cdb_TransferBlock(Srb), Cdb_LogicalBlock(Srb), > DiskInfo->SectorCount); > - Srb->ScsiStatus = 0x40; // SCSI_ABORT > - return TRUE; // Complete now > - } > + if (SectorStart >= SectorCount) > + goto fail3; > + if ((SectorStart + NumSectors) > SectorCount) > + goto fail4; > > + Srb->SrbStatus = SRB_STATUS_PENDING; > RingQueueRequest(Ring, SrbExt); > return FALSE; > + > +fail4: > + Error("fail4\n"); > +fail3: > + Error("fail3\n"); > +fail2: > + Error("fail2\n"); > +fail1: > + Error("fail1\n"); > + return TRUE; > } > > -__checkReturn > static DECLSPEC_NOINLINE BOOLEAN > TargetSyncCache( > - __in PXENVBD_TARGET Target, > - __in PSCSI_REQUEST_BLOCK Srb > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > ) > { > - PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; > - PXENVBD_RING Ring = FrontendGetRing(Target->Frontend); > + PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; > + PXENVBD_FRONTEND Frontend = Target->Frontend; > + PXENVBD_RING Ring = FrontendGetRing(Frontend); > > - if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) { > - Trace("Target[%d] : Not Ready, fail SRB\n", > TargetGetTargetId(Target)); > - Srb->ScsiStatus = 0x40; // SCSI_ABORT; > - return TRUE; > - } > + Srb->SrbStatus = SRB_STATUS_ERROR; > + if (!FrontendGetConnected(Frontend)) > + goto fail1; > > - if (FrontendGetDiskInfo(Target->Frontend)->FlushCache == FALSE && > - FrontendGetDiskInfo(Target->Frontend)->Barrier == FALSE) { > - Trace("Target[%d] : FLUSH and BARRIER not supported, suppressing\n", > TargetGetTargetId(Target)); > - Srb->ScsiStatus = 0x00; // SCSI_GOOD > - Srb->SrbStatus = SRB_STATUS_SUCCESS; > - return TRUE; > - } > + if (FrontendGetReadOnly(Frontend)) > + goto fail2; > + > + // If neither FLUSH or BARRIER is supported, just succceed the SRB > + if (!(FrontendGetFlushCache(Frontend) || > + FrontendGetBarrier(Frontend))) > + goto succeed; > > + Srb->SrbStatus = SRB_STATUS_PENDING; > RingQueueRequest(Ring, SrbExt); > return FALSE; > + > +succeed: > + Srb->SrbStatus = SRB_STATUS_SUCCESS; > + return TRUE; > + > +fail2: > + Error("fail2\n"); > +fail1: > + Error("fail1\n"); > + return TRUE; > } > > -__checkReturn > static DECLSPEC_NOINLINE BOOLEAN > TargetUnmap( > - __in PXENVBD_TARGET Target, > - __in PSCSI_REQUEST_BLOCK Srb > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > ) > { > - PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; > - PXENVBD_RING Ring = FrontendGetRing(Target->Frontend); > + PXENVBD_SRBEXT SrbExt = Srb->SrbExtension; > + PXENVBD_FRONTEND Frontend = Target->Frontend; > + PXENVBD_RING Ring = FrontendGetRing(Frontend); > > - if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) { > - Trace("Target[%d] : Not Ready, fail SRB\n", > TargetGetTargetId(Target)); > - Srb->ScsiStatus = 0x40; // SCSI_ABORT; > - return TRUE; > - } > + Srb->SrbStatus = SRB_STATUS_ERROR; > + if (!FrontendGetConnected(Frontend)) > + goto fail1; > > - if (FrontendGetDiskInfo(Target->Frontend)->Discard == FALSE) { > - Trace("Target[%d] : DISCARD not supported, suppressing\n", > TargetGetTargetId(Target)); > - Srb->ScsiStatus = 0x00; // SCSI_GOOD > - Srb->SrbStatus = SRB_STATUS_SUCCESS; > - return TRUE; > - } > + if (FrontendGetReadOnly(Frontend)) > + goto fail2; > > + if (!FrontendGetDiscard(Frontend)) > + goto succeed; > + > + Srb->SrbStatus = SRB_STATUS_PENDING; > RingQueueRequest(Ring, SrbExt); > return FALSE; > + > +succeed: > + Srb->SrbStatus = SRB_STATUS_SUCCESS; > + return TRUE; > + > +fail2: > + Error("fail2\n"); > +fail1: > + Error("fail1\n"); > + return TRUE; > } > > -#define MODE_CACHING_PAGE_LENGTH 20 > -static DECLSPEC_NOINLINE VOID > -TargetModeSense( > - __in PXENVBD_TARGET Target, > - __in PSCSI_REQUEST_BLOCK Srb > +static FORCEINLINE VOID > +__TargetModeSense( > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb, > + IN PVOID Data, > + IN ULONG Length, > + OUT PULONG Size, > + OUT PULONG ModeDataLength, > + OUT PULONG BlockDescrLength > ) > { > - PMODE_PARAMETER_HEADER Header = Srb->DataBuffer; > - const UCHAR PageCode = Cdb_PageCode(Srb); > - ULONG LengthLeft = Cdb_AllocationLength(Srb); > - PVOID CurrentPage = Srb->DataBuffer; > - > - UNREFERENCED_PARAMETER(Target); > - > - RtlZeroMemory(Srb->DataBuffer, Srb->DataTransferLength); > - > - if (!__ValidateSrbBuffer(__FUNCTION__, Srb, (ULONG)sizeof(struct > _MODE_SENSE))) { > - Srb->ScsiStatus = 0x40; > - Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN; > - Srb->DataTransferLength = 0; > - return; > - } > - > - // TODO : CDROM requires more ModePage entries > - // Header > - Header->ModeDataLength = sizeof(MODE_PARAMETER_HEADER) - 1; > - Header->MediumType = 0; > - Header->DeviceSpecificParameter = 0; > - Header->BlockDescriptorLength = 0; > - LengthLeft -= sizeof(MODE_PARAMETER_HEADER); > - CurrentPage = ((PUCHAR)CurrentPage + > sizeof(MODE_PARAMETER_HEADER)); > + const UCHAR PageCode = Cdb_PageCode(Srb); > > // Fill in Block Parameters (if Specified and space) > // when the DBD (Disable Block Descriptor) is set, ignore the block page > if (Cdb_Dbd(Srb) == 0 && > - LengthLeft >= sizeof(MODE_PARAMETER_BLOCK)) { > - PMODE_PARAMETER_BLOCK Block = > (PMODE_PARAMETER_BLOCK)CurrentPage; > - // Fill in BlockParams > - Block->DensityCode = 0; > - Block->NumberOfBlocks[0] = 0; > - Block->NumberOfBlocks[1] = 0; > - Block->NumberOfBlocks[2] = 0; > - Block->BlockLength[0] = 0; > - Block->BlockLength[1] = 0; > - Block->BlockLength[2] = 0; > - > - Header->BlockDescriptorLength = sizeof(MODE_PARAMETER_BLOCK); > - Header->ModeDataLength += sizeof(MODE_PARAMETER_BLOCK); > - LengthLeft -= sizeof(MODE_PARAMETER_BLOCK); > - CurrentPage = ((PUCHAR)CurrentPage + > sizeof(MODE_PARAMETER_BLOCK)); > + Length - *Size >= sizeof(MODE_PARAMETER_BLOCK)) { > + // PMODE_PARAMETER_BLOCK Block = > (PMODE_PARAMETER_BLOCK)((PUCHAR)Data + *Size); > + > + // Fill in BlockParams - All Zeroes > + > + *BlockDescrLength = sizeof(MODE_PARAMETER_BLOCK); > + *ModeDataLength += sizeof(MODE_PARAMETER_BLOCK); > + *Size += sizeof(MODE_PARAMETER_BLOCK); > } > > // Fill in Cache Parameters (if Specified and space) > if ((PageCode == MODE_PAGE_CACHING || PageCode == > MODE_SENSE_RETURN_ALL) && > - LengthLeft >= MODE_CACHING_PAGE_LENGTH) { > - PMODE_CACHING_PAGE Caching = > (PMODE_CACHING_PAGE)CurrentPage; > + Length - *Size >= sizeof(MODE_CACHING_PAGE)) { > + PMODE_CACHING_PAGE Caching = > (PMODE_CACHING_PAGE)((PUCHAR)Data + *Size); > + > // Fill in CachingParams > - Caching->PageCode = MODE_PAGE_CACHING; > - Caching->PageSavable = 0; > - Caching->PageLength = MODE_CACHING_PAGE_LENGTH; > - Caching->ReadDisableCache = 0; > - Caching->MultiplicationFactor = 0; > - Caching->WriteCacheEnable = FrontendGetDiskInfo(Target- > >Frontend)->FlushCache ? 1 : 0; > - Caching->WriteRetensionPriority = 0; > - Caching->ReadRetensionPriority = 0; > - Caching->DisablePrefetchTransfer[0] = 0; > - Caching->DisablePrefetchTransfer[1] = 0; > - Caching->MinimumPrefetch[0] = 0; > - Caching->MinimumPrefetch[1] = 0; > - Caching->MaximumPrefetch[0] = 0; > - Caching->MaximumPrefetch[1] = 0; > - Caching->MaximumPrefetchCeiling[0] = 0; > - Caching->MaximumPrefetchCeiling[1] = 0; > - > - Header->ModeDataLength += MODE_CACHING_PAGE_LENGTH; > - LengthLeft -= MODE_CACHING_PAGE_LENGTH; > - CurrentPage = ((PUCHAR)CurrentPage + > MODE_CACHING_PAGE_LENGTH); > + Caching->PageCode = MODE_PAGE_CACHING; > + Caching->PageLength = sizeof(MODE_CACHING_PAGE); > + Caching->WriteCacheEnable = FrontendGetFlushCache(Target- > >Frontend) ? 1 : 0; > + > + *ModeDataLength += sizeof(MODE_CACHING_PAGE); > + *Size += sizeof(MODE_CACHING_PAGE); > } > > // Fill in Informational Exception Parameters (if Specified and space) > if ((PageCode == MODE_PAGE_FAULT_REPORTING || PageCode == > MODE_SENSE_RETURN_ALL) && > - LengthLeft >= sizeof(MODE_INFO_EXCEPTIONS)) { > - PMODE_INFO_EXCEPTIONS Exceptions = > (PMODE_INFO_EXCEPTIONS)CurrentPage; > + Length - *Size >= sizeof(MODE_INFO_EXCEPTIONS)) { > + PMODE_INFO_EXCEPTIONS Exceptions = > (PMODE_INFO_EXCEPTIONS)((PUCHAR)Data + *Size); > + > // Fill in Exceptions > - Exceptions->PageCode = MODE_PAGE_FAULT_REPORTING; > - Exceptions->PSBit = 0; > - Exceptions->PageLength = sizeof(MODE_INFO_EXCEPTIONS); > - Exceptions->Flags = 0; > - Exceptions->Dexcpt = 1; // disabled > - Exceptions->ReportMethod = 0; > - Exceptions->IntervalTimer[0] = 0; > - Exceptions->IntervalTimer[1] = 0; > - Exceptions->IntervalTimer[2] = 0; > - Exceptions->IntervalTimer[3] = 0; > - Exceptions->ReportCount[0] = 0; > - Exceptions->ReportCount[1] = 0; > - Exceptions->ReportCount[2] = 0; > - Exceptions->ReportCount[3] = 0; > - > - Header->ModeDataLength += sizeof(MODE_INFO_EXCEPTIONS); > - LengthLeft -= sizeof(MODE_INFO_EXCEPTIONS); > - CurrentPage = ((PUCHAR)CurrentPage + > sizeof(MODE_INFO_EXCEPTIONS)); > + Exceptions->PageCode = MODE_PAGE_FAULT_REPORTING; > + Exceptions->PageLength = sizeof(MODE_INFO_EXCEPTIONS); > + Exceptions->Dexcpt = 1; // disabled > + > + *ModeDataLength += sizeof(MODE_INFO_EXCEPTIONS); > + *Size += sizeof(MODE_INFO_EXCEPTIONS); > } > +} > + > +static DECLSPEC_NOINLINE VOID > +TargetModeSense( > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > + ) > +{ > + PMODE_PARAMETER_HEADER Data = Srb->DataBuffer; > + ULONG Length = Srb->DataTransferLength; > + ULONG BlockDescrLength = 0; > + ULONG ModeDataLength = 0; > + ULONG Size; > + > + Srb->SrbStatus = SRB_STATUS_ERROR; > + > + if (Data == NULL) > + return; > + RtlZeroMemory(Data, Length); > + > + if (Length < sizeof(MODE_PARAMETER_HEADER)) > + return; > + > + // Header > + Data->MediumType = 0; > + Data->DeviceSpecificParameter = FrontendGetReadOnly(Target- > >Frontend) ? > + MODE_DSP_WRITE_PROTECT : > 0; > + Size = sizeof(MODE_PARAMETER_HEADER); > + > + __TargetModeSense(Target, > + Srb, > + Data, > + Length, > + &Size, > + &ModeDataLength, > + &BlockDescrLength); > + ASSERT3U(ModeDataLength, <=, 255 - > (sizeof(MODE_PARAMETER_HEADER) - 1)); > + ASSERT3U(BlockDescrLength, <=, 255); > + > + Data->ModeDataLength = (UCHAR)(ModeDataLength + > sizeof(MODE_PARAMETER_HEADER) - 1); > + Data->BlockDescriptorLength = (UCHAR)BlockDescrLength; > + > + ASSERT3U(Size, <=, Length); > + Srb->DataTransferLength = Size; > + Srb->SrbStatus = SRB_STATUS_SUCCESS; > +} > + > +static DECLSPEC_NOINLINE VOID > +TargetModeSense10( > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > + ) > +{ > + PMODE_PARAMETER_HEADER10 Data = Srb->DataBuffer; > + ULONG Length = Srb->DataTransferLength; > + ULONG BlockDescrLength = 0; > + ULONG ModeDataLength = 0; > + ULONG Size; > + > + Srb->SrbStatus = SRB_STATUS_ERROR; > + > + if (Data == NULL) > + return; > + RtlZeroMemory(Data, Length); > + > + if (Length < sizeof(MODE_PARAMETER_HEADER10)) > + return; > > - // Finish this SRB > + // Header > + Data->MediumType = 0; > + Data->DeviceSpecificParameter = FrontendGetReadOnly(Target- > >Frontend) ? > + MODE_DSP_WRITE_PROTECT : > 0; > + Size = sizeof(MODE_PARAMETER_HEADER10); > + > + __TargetModeSense(Target, > + Srb, > + Data, > + Length, > + &Size, > + &ModeDataLength, > + &BlockDescrLength); > + ASSERT3U(ModeDataLength, <=, 65535 - > (sizeof(MODE_PARAMETER_HEADER10) - 2)); > + ASSERT3U(BlockDescrLength, <=, 65535); > + > + *(PUSHORT)Data->ModeDataLength = > _byteswap_ushort((USHORT)ModeDataLength + > + > sizeof(MODE_PARAMETER_HEADER10) - 2); > + *(PUSHORT)Data->BlockDescriptorLength = > _byteswap_ushort((USHORT)BlockDescrLength); > + > + ASSERT3U(Size, <=, Length); > + Srb->DataTransferLength = Size; > Srb->SrbStatus = SRB_STATUS_SUCCESS; > - Srb->DataTransferLength = __min(Cdb_AllocationLength(Srb), > (ULONG)(Header->ModeDataLength + 1)); > } > > static DECLSPEC_NOINLINE VOID > TargetRequestSense( > - __in PXENVBD_TARGET Target, > - __in PSCSI_REQUEST_BLOCK Srb > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > ) > { > - PSENSE_DATA Sense = Srb->DataBuffer; > + PSENSE_DATA Data = Srb->DataBuffer; > + ULONG Length = Srb->DataTransferLength; > > UNREFERENCED_PARAMETER(Target); > > - if (!__ValidateSrbBuffer(__FUNCTION__, Srb, > (ULONG)sizeof(SENSE_DATA))) { > - Srb->ScsiStatus = 0x40; > - Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN; > + Srb->SrbStatus = SRB_STATUS_ERROR; > + > + if (Data == NULL) > return; > - } > + RtlZeroMemory(Data, Length); > > - RtlZeroMemory(Sense, sizeof(SENSE_DATA)); > + if (Length < sizeof(SENSE_DATA)) > + return; > + > + Data->ErrorCode = 0x70; > + Data->Valid = 1; > + Data->AdditionalSenseCodeQualifier = 0; > + Data->SenseKey = SCSI_SENSE_NO_SENSE; > + Data->AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE; > > - Sense->ErrorCode = 0x70; > - Sense->Valid = 1; > - Sense->AdditionalSenseCodeQualifier = 0; > - Sense->SenseKey = SCSI_SENSE_NO_SENSE; > - Sense->AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE; > Srb->DataTransferLength = sizeof(SENSE_DATA); > Srb->SrbStatus = SRB_STATUS_SUCCESS; > } > > static DECLSPEC_NOINLINE VOID > TargetReportLuns( > - __in PXENVBD_TARGET Target, > - __in PSCSI_REQUEST_BLOCK Srb > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > ) > { > - ULONG Length; > - ULONG Offset; > - ULONG AllocLength = Cdb_AllocationLength(Srb); > - PUCHAR Buffer = Srb->DataBuffer; > + PLUN_LIST Data = Srb->DataBuffer; > + ULONG Length = Srb->DataTransferLength; > > UNREFERENCED_PARAMETER(Target); > > - if (!__ValidateSrbBuffer(__FUNCTION__, Srb, 8)) { > - Srb->ScsiStatus = 0x40; > - Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN; > - Srb->DataTransferLength = 0; > - return; > - } > - > - RtlZeroMemory(Buffer, AllocLength); > - > - Length = 0; > - Offset = 8; > + Srb->SrbStatus = SRB_STATUS_ERROR; > > - if (Offset + 8 <= AllocLength) { > - Buffer[Offset] = 0; > - Offset += 8; > - Length += 8; > - } > + if (Data == NULL) > + return; > + RtlZeroMemory(Data, Length); > > - if (Offset + 8 <= AllocLength) { > - Buffer[Offset] = XENVBD_MAX_TARGETS; > - Offset += 8; > - Length += 8; > - } > + if (Length < 16) > + return; > > - REVERSE_BYTES(Buffer, &Length); > + // UCHAR[4] @ Data > + *(PULONG)Data->LunListLength = _byteswap_ulong(8); > + // UCHAR[8] @ Data + 8 > + *(PULONG64)Data->Lun[0] = > _byteswap_uint64(XENVBD_MAX_TARGETS); > > - Srb->DataTransferLength = __min(Length, AllocLength); > + Srb->DataTransferLength = 16; > Srb->SrbStatus = SRB_STATUS_SUCCESS; > } > > static DECLSPEC_NOINLINE VOID > TargetReadCapacity( > - __in PXENVBD_TARGET Target, > - __in PSCSI_REQUEST_BLOCK Srb > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > ) > { > - PREAD_CAPACITY_DATA Capacity = Srb->DataBuffer; > + PREAD_CAPACITY_DATA Data = Srb->DataBuffer; > + ULONG Length = Srb->DataTransferLength; > PXENVBD_DISKINFO DiskInfo = FrontendGetDiskInfo(Target- > >Frontend); > ULONG64 SectorCount; > ULONG SectorSize; > ULONG LastBlock; > > - if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0) { > - Srb->ScsiStatus = 0x02; // CHECK_CONDITION > + Srb->SrbStatus = SRB_STATUS_ERROR; > + > + if (Data == NULL) > + return; > + RtlZeroMemory(Data, Length); > + > + if (Length < sizeof(READ_CAPACITY_DATA)) > + return; > + > + if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0) > return; > - } > > SectorCount = DiskInfo->SectorCount; > SectorSize = DiskInfo->SectorSize; > @@ -535,21 +566,21 @@ TargetReadCapacity( > else > LastBlock = ~(ULONG)0; > > - if (Capacity) { > - Capacity->LogicalBlockAddress = _byteswap_ulong(LastBlock); > - Capacity->BytesPerBlock = _byteswap_ulong(SectorSize); > - } > + Data->LogicalBlockAddress = _byteswap_ulong(LastBlock); > + Data->BytesPerBlock = _byteswap_ulong(SectorSize); > > + Srb->DataTransferLength = sizeof(READ_CAPACITY_DATA); > Srb->SrbStatus = SRB_STATUS_SUCCESS; > } > > static DECLSPEC_NOINLINE VOID > TargetReadCapacity16( > - __in PXENVBD_TARGET Target, > - __in PSCSI_REQUEST_BLOCK Srb > + IN PXENVBD_TARGET Target, > + IN PSCSI_REQUEST_BLOCK Srb > ) > { > - PREAD_CAPACITY16_DATA Capacity = Srb->DataBuffer; > + PREAD_CAPACITY16_DATA Data = Srb->DataBuffer; > + ULONG Length = Srb->DataTransferLength; > PXENVBD_DISKINFO DiskInfo = FrontendGetDiskInfo(Target- > >Frontend); > ULONG64 SectorCount; > ULONG SectorSize; > @@ -557,10 +588,17 @@ TargetReadCapacity16( > ULONG LogicalPerPhysical; > ULONG LogicalPerPhysicalExponent; > > - if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0) { > - Srb->ScsiStatus = 0x02; // CHECK_CONDITION > + Srb->SrbStatus = SRB_STATUS_ERROR; > + > + if (Data == NULL) > + return; > + RtlZeroMemory(Data, Length); > + > + if (Length < sizeof(READ_CAPACITY16_DATA)) > + return; > + > + if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0) > return; > - } > > SectorCount = DiskInfo->SectorCount; > SectorSize = DiskInfo->SectorSize; > @@ -571,12 +609,11 @@ TargetReadCapacity16( > if (!_BitScanReverse(&LogicalPerPhysicalExponent, LogicalPerPhysical)) > LogicalPerPhysicalExponent = 0; > > - if (Capacity) { > - Capacity->LogicalBlockAddress.QuadPart = > _byteswap_uint64(SectorCount - 1); > - Capacity->BytesPerBlock = _byteswap_ulong(SectorSize); > - Capacity->LogicalPerPhysicalExponent = > (UCHAR)LogicalPerPhysicalExponent; > - } > + Data->LogicalBlockAddress.QuadPart = _byteswap_uint64(SectorCount - > 1); > + Data->BytesPerBlock = _byteswap_ulong(SectorSize); > + Data->LogicalPerPhysicalExponent = (UCHAR)LogicalPerPhysicalExponent; > > + Srb->DataTransferLength = sizeof(READ_CAPACITY16_DATA); > Srb->SrbStatus = SRB_STATUS_SUCCESS; > } > > @@ -592,6 +629,11 @@ TargetInquiryStd( > UNREFERENCED_PARAMETER(Target); > > Srb->SrbStatus = SRB_STATUS_ERROR; > + > + if (Data == NULL) > + return; > + RtlZeroMemory(Data, Length); > + > if (Length < INQUIRYDATABUFFERSIZE) > return; > > @@ -621,9 +663,12 @@ TargetInquiry00( > > UNREFERENCED_PARAMETER(Target); > > + Srb->SrbStatus = SRB_STATUS_ERROR; > + > + if (Data == NULL) > + return; > RtlZeroMemory(Data, Length); > > - Srb->SrbStatus = SRB_STATUS_ERROR; > if (Length < 7) > return; > > @@ -647,18 +692,18 @@ TargetInquiry80( > PVOID Page; > ULONG Size; > > - Page = FrontendGetInquiryOverride(Target->Frontend, 0x80, &Size); > + Srb->SrbStatus = SRB_STATUS_ERROR; > > + if (Data == NULL) > + return; > RtlZeroMemory(Data, Length); > > - Srb->SrbStatus = SRB_STATUS_ERROR; > + Page = FrontendGetInquiryOverride(Target->Frontend, 0x80, &Size); > if (Page && Size) { > if (Length < Size) > return; > > RtlCopyMemory(Data, Page, Size); > - > - Srb->DataTransferLength = Size; > } else { > CHAR Serial[5]; > > @@ -673,9 +718,10 @@ TargetInquiry80( > TargetGetTargetId(Target)); > RtlCopyMemory(Data->SerialNumber, Serial, 4); > > - Srb->DataTransferLength = sizeof(VPD_SERIAL_NUMBER_PAGE) + 4; > + Size = sizeof(VPD_SERIAL_NUMBER_PAGE) + 4; > } > > + Srb->DataTransferLength = Size; > Srb->SrbStatus = SRB_STATUS_SUCCESS; > } > > @@ -690,18 +736,18 @@ TargetInquiry83( > PVOID Page; > ULONG Size; > > - Page = FrontendGetInquiryOverride(Target->Frontend, 0x83, &Size); > + Srb->SrbStatus = SRB_STATUS_ERROR; > > + if (Data == NULL) > + return; > RtlZeroMemory(Data, Length); > > - Srb->SrbStatus = SRB_STATUS_ERROR; > + Page = FrontendGetInquiryOverride(Target->Frontend, 0x83, &Size); > 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]; > @@ -722,10 +768,11 @@ TargetInquiry83( > TargetGetTargetId(Target)); > RtlCopyMemory(Id->Identifier, Identifier, 16); > > - Srb->DataTransferLength = sizeof(VPD_IDENTIFICATION_PAGE) + > - sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16; > + Size = sizeof(VPD_IDENTIFICATION_PAGE) + > + sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16; > } > > + Srb->DataTransferLength = Size; > Srb->SrbStatus = SRB_STATUS_SUCCESS; > } > > @@ -845,6 +892,10 @@ TargetStartIo( > TargetModeSense(Target, Srb); > break; > > + case SCSIOP_MODE_SENSE10: > + TargetModeSense10(Target, Srb); > + break; > + > case SCSIOP_REQUEST_SENSE: > TargetRequestSense(Target, Srb); > break; > -- > 2.8.3 > > > _______________________________________________ > win-pv-devel mailing list > win-pv-devel@xxxxxxxxxxxxxxxxxxxx > https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel _______________________________________________ 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 |