corrupt cdb in scsiport

My scsiport driver has had a regression which appears to just affect XP. For READ (and probably WRITE) operations, the length and sector numbers are always zero. DataTransferLength appears reasonable. Is there anything obvious that might cause this? I check the cdb at StartIo entry and the fields are zero then so I don’t appear to be overwriting the srb anywhere.

Thanks

James

How do you fill HW_INITIALIZATION_DATA and PORT_CONFIGURATION_INFORMATION?

>

How do you fill HW_INITIALIZATION_DATA and
PORT_CONFIGURATION_INFORMATION?

RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
HwInitializationData.AdapterInterfaceType = PNPBus;
HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
HwInitializationData.NumberOfAccessRanges = 1;
HwInitializationData.MapBuffers = TRUE;
HwInitializationData.NeedPhysicalAddresses = FALSE;
HwInitializationData.TaggedQueuing = TRUE;
HwInitializationData.AutoRequestSense = TRUE;
HwInitializationData.MultipleRequestPerLu = TRUE;
HwInitializationData.ReceiveEvent = FALSE;
HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_SCSIPORT_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;

It’s a virtual scsiport and so doesn’t have an Interrupt routine (except in dump mode). srb_list_entry_t is a small struct to keep track of queued srb’s - my scsiport shares a lot of code with my storport driver so it accepts all srb’s and just queue’s them. aligned_buffer_data is a chunk of data on the end of the DeviceExtension to allow aligning unaligned DataBuffer’s (they happen very rarely, mainly once or twice on boot, and also format operations) as the Xen block device interface has a 512 byte alignment restriction.

The virtual scsiport works by having an upper filter that delivers ‘interrupts’ and other events into my miniport as a custom srb. Works great under 2003. I can’t see how the cdb truncation under XP is related as the filter never touches any of the srb’s (scsiport delivers them directly to the miniport) but I guess it’s possible. I suspect I broke something else when I moved away from using a fake interrupt to delivering via custom srb…

ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024;
ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT;
ConfigInfo->ScatterGather = TRUE;
ConfigInfo->Master = TRUE;
ConfigInfo->CachesData = FALSE;
ConfigInfo->MapBuffers = TRUE;
ConfigInfo->AlignmentMask = 0;
ConfigInfo->NumberOfBuses = 1;
ConfigInfo->InitiatorBusId[0] = 1;
ConfigInfo->MaximumNumberOfLogicalUnits = 1;
ConfigInfo->MaximumNumberOfTargets = 2;
if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
}

Thanks

James

I managed to turn on the verifier and I get bug check 0xE6 (0x20, 0, 0, 0), which is a DMA verifier failure of “The driver tried to flush a map register that hasn’t been mapped. The map register base, flushing address, and MDL are displayed.”

Setting Master = FALSE and ScatterGather = FALSE gets it booting again. I guess I can probably lose the SCSI_DMA64_MINIPORT_SUPPORTED too.

Windows isn’t going to start double buffering or anything with those settings is it? I don’t need DMA and only set those settings because not doing so caused a problem, a long time ago…

James

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-533261-
xxxxx@lists.osr.com] On Behalf Of James Harper
Sent: Saturday, 11 May 2013 8:54 PM
To: Windows System Software Devs Interest List
Subject: RE: RE:[ntdev] corrupt cdb in scsiport

>
> How do you fill HW_INITIALIZATION_DATA and
> PORT_CONFIGURATION_INFORMATION?
>

RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
HwInitializationData.HwInitializationDataSize =
sizeof(HW_INITIALIZATION_DATA);
HwInitializationData.AdapterInterfaceType = PNPBus;
HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
HwInitializationData.NumberOfAccessRanges = 1;
HwInitializationData.MapBuffers = TRUE;
HwInitializationData.NeedPhysicalAddresses = FALSE;
HwInitializationData.TaggedQueuing = TRUE;
HwInitializationData.AutoRequestSense = TRUE;
HwInitializationData.MultipleRequestPerLu = TRUE;
HwInitializationData.ReceiveEvent = FALSE;
HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
HwInitializationData.DeviceExtensionSize =
FIELD_OFFSET(XENVBD_SCSIPORT_DATA, aligned_buffer_data) +
UNALIGNED_BUFFER_DATA_SIZE;

It’s a virtual scsiport and so doesn’t have an Interrupt routine (except in
dump mode). srb_list_entry_t is a small struct to keep track of queued srb’s -
my scsiport shares a lot of code with my storport driver so it accepts all srb’s
and just queue’s them. aligned_buffer_data is a chunk of data on the end of
the DeviceExtension to allow aligning unaligned DataBuffer’s (they happen
very rarely, mainly once or twice on boot, and also format operations) as the
Xen block device interface has a 512 byte alignment restriction.

The virtual scsiport works by having an upper filter that delivers ‘interrupts’
and other events into my miniport as a custom srb. Works great under 2003. I
can’t see how the cdb truncation under XP is related as the filter never
touches any of the srb’s (scsiport delivers them directly to the miniport) but I
guess it’s possible. I suspect I broke something else when I moved away from
using a fake interrupt to delivering via custom srb…

ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024;
ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo-
>MaximumTransferLength >> PAGE_SHIFT;
ConfigInfo->ScatterGather = TRUE;
ConfigInfo->Master = TRUE;
ConfigInfo->CachesData = FALSE;
ConfigInfo->MapBuffers = TRUE;
ConfigInfo->AlignmentMask = 0;
ConfigInfo->NumberOfBuses = 1;
ConfigInfo->InitiatorBusId[0] = 1;
ConfigInfo->MaximumNumberOfLogicalUnits = 1;
ConfigInfo->MaximumNumberOfTargets = 2;
if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
{
ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
}

Thanks

James


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

You may want to reduce MaximumTransferLength. A root-enumerated device may not be able to get a DMA_ADAPTER for large transfer size (over 64K) in a legacy OS.

Also keep in mind DEVICE_EXTENSION is usually not aligned to a page (it is aligned to 004 or 008).

>

You may want to reduce MaximumTransferLength. A root-enumerated
device may not be able to get a DMA_ADAPTER for large transfer size (over
64K) in a legacy OS.

It’s not root enumerated, it’s a child of a pci device. It doesn’t do DMA anyway so in theory I don’t need master = true, but I remember having problems without it…

Also keep in mind DEVICE_EXTENSION is usually not aligned to a page (it is
aligned to 004 or 008).

I allocate my aligned buffer as (maximum buffered pages * PAGE_SIZE) + PAGE_SIZE - 1, and then align the buffer to a page boundary within that.

James

>

I managed to turn on the verifier and I get bug check 0xE6 (0x20, 0, 0, 0),
which is a DMA verifier failure of “The driver tried to flush a map register that
hasn’t been mapped. The map register base, flushing address, and MDL are
displayed.”

Setting Master = FALSE and ScatterGather = FALSE gets it booting again. I
guess I can probably lose the SCSI_DMA64_MINIPORT_SUPPORTED too.

Windows isn’t going to start double buffering or anything with those settings
is it? I don’t need DMA and only set those settings because not doing so
caused a problem, a long time ago…

Okay I’m seeing data transfers up to my 4MB limit, so I guess no double buffering is going on.

James