How to implement Command Queue in SCSI miniport?

Hi:
I’m writing a SCSI miniport driver for a PCI device in Windows XP, and the driver is running correctly. The device support command queue, but the Tagged Command Queue did not implement as I expected.

  1. I’ve set TaggedQueueing and MultipleRequestPerlu to TRUE in DriverEntry, and set CommandQueue in INQUIRY data to TRUE. Is there any other parameter that I am missing?

  2. ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb->TargetId,Srb->Lun) is called in StartIo routine, and ScsiPortNotification(RequestComplete,…) is called in EnableInterruptsCallback routine, is it the correct way?

  3. IoMeter is used for test and outstanding I/O is set to 32. I use Windbg on another machine during the test, but the process is always as StartIo->Interrupt->EnableInterruptsCallback ->DisableInterruptsCallback->StartIo, just sequentially. Why is this happening while I am expecting StartIo->StartIo->…->StartIo->Interrupt->EnableInterruptsCallback ->DisableInterruptsCallback->StartIo?

Much appreciate for ur help!

Is this a SCSIPORT or STORPORT driver? I may be wrong but I do not believe SCSIPORT supports tagged queueing. That you have to u se STORPORT and I’m not sure if STORPORT does an adequate job of supporting queueing. The only time I have done queuing was in a native SCSI driver where neither SCSIPORT nor STORPORT were used, specifically because tagged queuing was not supported.

Gary G. Little

----- Original Message -----
From: xxxxx@gmail.com
To: “Windows System Software Devs Interest List”
Sent: Monday, March 28, 2011 4:42:13 AM
Subject: [ntdev] How to implement Command Queue in SCSI miniport?

Hi:
I’m writing a SCSI miniport driver for a PCI device in Windows XP, and the driver is running correctly. The device support command queue, but the Tagged Command Queue did not implement as I expected.

1) I’ve set TaggedQueueing and MultipleRequestPerlu to TRUE in DriverEntry, and set CommandQueue in INQUIRY data to TRUE. Is there any other parameter that I am missing?

2) ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb->TargetId,Srb->Lun) is called in StartIo routine, and ScsiPortNotification(RequestComplete,…) is called in EnableInterruptsCallback routine, is it the correct way?

3) IoMeter is used for test and outstanding I/O is set to 32. I use Windbg on another machine during the test, but the process is always as StartIo->Interrupt->EnableInterruptsCallback ->DisableInterruptsCallback->StartIo, just sequentially. Why is this happening while I am expecting StartIo->StartIo->…->StartIo->Interrupt->EnableInterruptsCallback ->DisableInterruptsCallback->StartIo?

Much appreciate for ur help!


NTDEV is sponsored by OSR

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

SCSIPORT has always supported tagged queuing.

“Gary G. Little”
Sent by: xxxxx@lists.osr.com
03/28/2011 10:08 AM
Please respond to
“Windows System Software Devs Interest List”

To
“Windows System Software Devs Interest List”
cc

Subject
Re: [ntdev] How to implement Command Queue in SCSI miniport?

Is this a SCSIPORT or STORPORT driver? I may be wrong but I do not believe
SCSIPORT supports tagged queueing. That you have to u se STORPORT and I’m
not sure if STORPORT does an adequate job of supporting queueing. The only
time I have done queuing was in a native SCSI driver where neither
SCSIPORT nor STORPORT were used, specifically because tagged queuing was
not supported.

Gary G. Little

----- Original Message -----
From: xxxxx@gmail.com
To: “Windows System Software Devs Interest List”
Sent: Monday, March 28, 2011 4:42:13 AM
Subject: [ntdev] How to implement Command Queue in SCSI miniport?

Hi:
I’m writing a SCSI miniport driver for a PCI device in Windows XP, and
the driver is running correctly. The device support command queue, but the
Tagged Command Queue did not implement as I expected.

1) I’ve set TaggedQueueing and MultipleRequestPerlu to TRUE in
DriverEntry, and set CommandQueue in INQUIRY data to TRUE. Is there any
other parameter that I am missing?

2)
ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb->TargetId,Srb->Lun)
is called in StartIo routine, and
ScsiPortNotification(RequestComplete,…) is called in
EnableInterruptsCallback routine, is it the correct way?

3) IoMeter is used for test and outstanding I/O is set to 32. I use
Windbg on another machine during the test, but the process is always as
StartIo->Interrupt->EnableInterruptsCallback
->DisableInterruptsCallback->StartIo, just sequentially. Why is this
happening while I am expecting
StartIo->StartIo->…->StartIo->Interrupt->EnableInterruptsCallback
->DisableInterruptsCallback->StartIo?

Much appreciate for ur help!


NTDEV is sponsored by OSR

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


NTDEV is sponsored by OSR

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

>Is this a SCSIPORT or STORPORT driver? I may be wrong but I do not believe SCSIPORT supports tagged

queueing.

Absolutely wrong.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

then I absolutely stand corrected … :slight_smile:

Gary G. Little

----- Original Message -----
From: “Maxim S. Shatskih”
To: “Windows System Software Devs Interest List”
Sent: Monday, March 28, 2011 11:09:59 AM
Subject: Re:[ntdev] How to implement Command Queue in SCSI miniport?

>Is this a SCSIPORT or STORPORT driver? I may be wrong but I do not believe SCSIPORT supports tagged
>queueing.

Absolutely wrong.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com


NTDEV is sponsored by OSR

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

Now that SCSI miniport support tagged queue, what is my problem?

Using IoMeter with outstanding setting to 32 and Windbg to catch the
operations. All the commands are just sent out sequentially with
Srb->QueueTag == 0x02 and Srb->QueueAcion == 0x20. Are there any missing
operation expect
ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb->TargetId,Srb->Lun)
?

BTW: What should I response for SCSI_MODE_SENSE command with Page Code
setting to 0x3F?

Sorry, the BTW is asking for Page Code seting to 0x1C.

2011/3/29 wangkun

> Now that SCSI miniport support tagged queue, what is my problem?
>
> Using IoMeter with outstanding setting to 32 and Windbg to catch the
> operations. All the commands are just sent out sequentially with
> Srb->QueueTag == 0x02 and Srb->QueueAcion == 0x20. Are there any missing
> operation expect ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb->TargetId,Srb->Lun)
> ?
>
> BTW: What should I response for SCSI_MODE_SENSE command with Page Code
> setting to 0x3F?
>

Please check if device reports CmdQue = 1 , RMB = 0 in standard inquiry
data.
In the host driver side, please check TaggedQueuing & MultipleRequestPerLu
fields in PORT_CONFIGURATION_INFORMATION.

2011/3/29 wangkun

> Sorry, the BTW is asking for Page Code seting to 0x1C.
>
>
> 2011/3/29 wangkun
>
>> Now that SCSI miniport support tagged queue, what is my problem?
>>
>> Using IoMeter with outstanding setting to 32 and Windbg to catch the
>> operations. All the commands are just sent out sequentially with
>> Srb->QueueTag == 0x02 and Srb->QueueAcion == 0x20. Are there any missing
>> operation expect ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb->TargetId,Srb->Lun)
>> ?
>>
>> BTW: What should I response for SCSI_MODE_SENSE command with Page Code
>> setting to 0x3F?
>>
>
> — NTDEV is sponsored by OSR 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
>

I set CmdQue and RMB as you suggested, as well as TaggedQueueing and
MultipleRequetPerLu.

And during the testing using IoMeter with Outstanding IO set to 32, I found
that SrbFlags has set SRB_FLAGS_QUEUE_ACTION_ENABLE to 1, QueueTag == 2 and
QueueAction being SRB_SIMPLE_TAG_REQUEST. I think this should indicate that
this is a tagged command.

But the system just did NOT send outstanding commands in parallel, and all
the commands the driver recieved have a QueueTag == 2. I can only recieve
the next command after I finished the previous command in DPC routine.

2011/3/29 Lin JiaBang

> Please check if device reports CmdQue = 1 , RMB = 0 in standard inquiry
> data.
> In the host driver side, please check TaggedQueuing & MultipleRequestPerLu
> fields in PORT_CONFIGURATION_INFORMATION.
>
>
> 2011/3/29 wangkun
>
>> Sorry, the BTW is asking for Page Code seting to 0x1C.
>>
>>
>> 2011/3/29 wangkun
>>
>>> Now that SCSI miniport support tagged queue, what is my problem?
>>>
>>> Using IoMeter with outstanding setting to 32 and Windbg to catch the
>>> operations. All the commands are just sent out sequentially with
>>> Srb->QueueTag == 0x02 and Srb->QueueAcion == 0x20. Are there any missing
>>> operation expect ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb->TargetId,Srb->Lun)
>>> ?
>>>
>>> BTW: What should I response for SCSI_MODE_SENSE command with Page Code
>>> setting to 0x3F?
>>>
>>
>> — NTDEV is sponsored by OSR 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
>>
>
> — NTDEV is sponsored by OSR 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

>But the system just did NOT send outstanding commands in parallel,

Check your IOMeter settings.

and all the commands the driver recieved have a QueueTag == 2.

This means - tagging works. Otherwise, you would have QueueTag == 255


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

I believe IoMeter setting is correct and tagging really works.

But I just cannot recieve commands in parallel, can there be any problem in
my StartIo or Interrupt routine?

2011/3/29 Maxim S. Shatskih

> >But the system just did NOT send outstanding commands in parallel,
>
> Check your IOMeter settings.
>
> >and all the commands the driver recieved have a QueueTag == 2.
>
> This means - tagging works. Otherwise, you would have QueueTag == 255
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> NTDEV is sponsored by OSR
>
> 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
>

Hi wangkun,
You can try to modify driver that didn’t ScsiPortNotification in
interrupt routine but in timer routine. It can help you check, whether
scsiport driver can support queue.
According my experience, scsiport support queue.

And when you use windbg to check it may slower the computer. So you’d
better to write some code in the driver to help to check the depth of
the disk queue. And use if to break the condition.

On Mon, Mar 28, 2011 at 5:42 PM, ? wrote:
> Hi:
> ? I’m writing a SCSI miniport driver for a PCI device in Windows XP, and the driver is running correctly. The device support command queue, but the Tagged Command Queue did not implement as I expected.
>
> ? 1) I’ve set TaggedQueueing and MultipleRequestPerlu to TRUE in DriverEntry, ?and set CommandQueue in INQUIRY data to TRUE. Is there any other parameter that I am missing?
>
> ? 2) ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb->TargetId,Srb->Lun) is called in StartIo routine, and ScsiPortNotification(RequestComplete,…) is called in EnableInterruptsCallback routine, is it the correct way?
>
> ? 3) IoMeter is used for test and outstanding I/O is set to 32. I use Windbg on another machine during the test, but the process is always as StartIo->Interrupt->EnableInterruptsCallback ->DisableInterruptsCallback->StartIo, just sequentially. Why is this happening while I am expecting StartIo->StartIo->…->StartIo->Interrupt->EnableInterruptsCallback ->DisableInterruptsCallback->StartIo?
>
> ? Much appreciate for ur help!
>
> —
> NTDEV is sponsored by OSR
>
> 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
>
>

> Hi:

I’m writing a SCSI miniport driver for a PCI device in Windows XP,
and the
driver is running correctly. The device support command queue, but the
Tagged
Command Queue did not implement as I expected.

  1. I’ve set TaggedQueueing and MultipleRequestPerlu to TRUE in
    DriverEntry,
    and set CommandQueue in INQUIRY data to TRUE. Is there any other
    parameter
    that I am missing?

I think that CommandQueue exists as AdditionalData in the INQUIRY data,
so make sure you set the AdditionalLength field accordingly. My code
(virtual scsi device) looks like:

PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
id->DeviceType = DIRECT_ACCESS_DEVICE;
id->Versions = 4; /* minimum that WHQL says we must support */
id->ResponseDataFormat = 2; /* not sure about this but WHQL complains
otherwise */
id->HiSupport = 1; /* WHQL test says we should set this */
id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA,
AdditionalLength) - 1;
id->CommandQueue = 1;
memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
memcpy(id->ProductId, scsi_disk_model, 16); // product id
memcpy(id->ProductRevisionLevel, “0000”, 4); // product revision level
data_transfer_length = sizeof(INQUIRYDATA);

You also need to support AutoRequestSense for scsiport to support
command queuing (otherwise how would scsiport know what request matched
the sense data?).

I can’t think of anything else…

  1. ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb-
    >TargetId,Srb->Lun) is called in StartIo routine, and
    ScsiPortNotification(RequestComplete,…) is called in
    EnableInterruptsCallback routine, is it the correct way?

Try also calling NextLuRequest after calling RequestComplete.

What is EnableInterruptsCallback? Is that just the name of your ISR?

James

Hi James:
Thanks for your help.

  1. I set the parameters u seggested, as well as AutoRequestSense, but
    how to handle sense data? Do I need to fill in sense data?
  2. EnableInterruptsCallback is act like a DPC, and it is a SCSI
    Miniport Driver Routine
  3. Is there a possibility that SCSI port queued the IOs internally,
    but send those requests to miniport sequentially? Now that the HBA can
    handle requests simutaneously, and send out an interrupt after it finished
    those commands. I just cannot write more than 1 SRB to HBA before HBA send
    out an interrupt. That is really the bottleneck of this driver.

2011/3/29 James Harper

> > Hi:
> > I’m writing a SCSI miniport driver for a PCI device in Windows XP,
> and the
> > driver is running correctly. The device support command queue, but the
> Tagged
> > Command Queue did not implement as I expected.
> >
> > 1) I’ve set TaggedQueueing and MultipleRequestPerlu to TRUE in
> DriverEntry,
> > and set CommandQueue in INQUIRY data to TRUE. Is there any other
> parameter
> > that I am missing?
>
> I think that CommandQueue exists as AdditionalData in the INQUIRY data,
> so make sure you set the AdditionalLength field accordingly. My code
> (virtual scsi device) looks like:
>
> PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
> id->DeviceType = DIRECT_ACCESS_DEVICE;
> id->Versions = 4; /* minimum that WHQL says we must support /
> id->ResponseDataFormat = 2; /
not sure about this but WHQL complains
> otherwise /
> id->HiSupport = 1; /
WHQL test says we should set this */
> id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA,
> AdditionalLength) - 1;
> id->CommandQueue = 1;
> memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
> memcpy(id->ProductId, scsi_disk_model, 16); // product id
> memcpy(id->ProductRevisionLevel, “0000”, 4); // product revision level
> data_transfer_length = sizeof(INQUIRYDATA);
>
> You also need to support AutoRequestSense for scsiport to support
> command queuing (otherwise how would scsiport know what request matched
> the sense data?).
>
> I can’t think of anything else…
>
> >
> > 2) ScsiPortNotification(NextLuRequest,pDevExt,Srb->PathId,Srb-
> > >TargetId,Srb->Lun) is called in StartIo routine, and
> > ScsiPortNotification(RequestComplete,…) is called in
> > EnableInterruptsCallback routine, is it the correct way?
> >
>
> Try also calling NextLuRequest after calling RequestComplete.
>
> What is EnableInterruptsCallback? Is that just the name of your ISR?
>
> James
>
>
> —
> NTDEV is sponsored by OSR
>
> 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
>

> -----Original Message-----

From: xxxxx@lists.osr.com [mailto:bounce-447124-
xxxxx@lists.osr.com] On Behalf Of James Harper
Sent: Tuesday, March 29, 2011 4:17 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] How to implement Command Queue in SCSI miniport?

[snip]

Try also calling NextLuRequest after calling RequestComplete.

That will ensure that you have exactly one IO outstanding at a time. Call
NextLuRequest as soon as you’re done doing whatever processing can’t be done
in parallel. Possibly that might be immediately after you’ve submitted the
request to your hardware. If this is really a SCSIPORT miniport instead of
StorPort, there’s really not much point in calling it any earlier than the
end of your StartIo, as ScsiPort serializes (almost) everything with the
Interrupt spinlock, so you won’t get another StartIo until you return from
the current one.

See this thread:
http://www.osronline.com/showthread.cfm?link=149287

What is EnableInterruptsCallback? Is that just the name of your ISR?

That’s a good question. It shouldn’t be an ISR, it should be the callback
invoked by a call to ScsiPortNotification(CallEnableInterrupts).
Here’s the documentation of what it should be:
http://msdn.microsoft.com/en-us/library/ff557295(v=VS.85).aspx
I’m still a bit confused about the usage of those. Doing a minifilter now,
so I don’t need to understand it … today anyway.

Phil

Philip D. Barila (303) 776-1264

>

> Try also calling NextLuRequest after calling RequestComplete.

That will ensure that you have exactly one IO outstanding at a time.
Call
NextLuRequest as soon as you’re done doing whatever processing can’t
be done
in parallel. Possibly that might be immediately after you’ve
submitted the
request to your hardware. If this is really a SCSIPORT miniport
instead of
StorPort, there’s really not much point in calling it any earlier than
the
end of your StartIo, as ScsiPort serializes (almost) everything with
the
Interrupt spinlock, so you won’t get another StartIo until you return
from
the current one.

I think you didn’t read the ‘also’ in my suggestion. Certainly call it
in StartIo if you can accept another request, but I also call it after
calling RequestComplete. In StartIo I check the status of my queue and
if I can accept another request I call NextLuRequest. At
RequestComplete, there is now by definition room for one more request on
the queue because I just completed one, so I call NextLuRequest there
too which will ensure that Windows knows it can send another request
even if the last call to StartIo didn’t announce the fact (because the
queue was full).

In a virtual driver the queue management is a bit trickier, and in my
driver I actually maintain my own queue (like StorPort) and always
accept another request, so there is no decision to make about whether my
queue is full.

> What is EnableInterruptsCallback? Is that just the name of your ISR?

That’s a good question. It shouldn’t be an ISR, it should be the
callback
invoked by a call to ScsiPortNotification(CallEnableInterrupts).
Here’s the documentation of what it should be:
http://msdn.microsoft.com/en-us/library/ff557295(v=VS.85).aspx
I’m still a bit confused about the usage of those. Doing a minifilter
now,
so I don’t need to understand it … today anyway.

I’ve never actually used HwScsiEnableInterrupts. I was barely aware it
existed as it wasn’t used in any other drivers I’d seen… I guess I
should time my ISR and see if it takes longer than the 50us prescribed
by the documentation!

The documentation for HwScsiEnableInterrupts
(http://msdn.microsoft.com/en-us/library/ff565323(v=VS.85).aspx)
says that you should call NextLuRequest after RequestComplete.

James

> 1) I set the parameters u seggested, as well as
AutoRequestSense, but

how to handle sense data? Do I need to fill in sense data?

When you have an error to report, you copy/make the sense data into the
SenseInfoBuffer for that request.

My routine that does this is:

static ULONG
XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb,
UCHAR sense_key, UCHAR additional_sense_code)
{
PSENSE_DATA sd = srb->SenseInfoBuffer;

UNREFERENCED_PARAMETER(xvdd);

if (!srb->SenseInfoBuffer)
return 0;

sd->ErrorCode = 0x70;
sd->Valid = 1;
sd->SenseKey = sense_key;
sd->AdditionalSenseLength = sizeof(SENSE_DATA) -
FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
sd->AdditionalSenseCode = additional_sense_code;
return sizeof(SENSE_DATA);
}

Which is called by:

static VOID
XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
{
if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags &
SRB_FLAGS_DISABLE_AUTOSENSE)
return;
XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key,
xvdd->last_additional_sense_code);
srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
}

I can’t remember if you are dealing with a physical block device that
might report real errors. In my case all I get from my underlying
storage is a flag that tells me an error occurred, so my last_sense_key
is SCSI_SENSE_MEDIUM_ERROR and my last_additional_sense_code is
SCSI_ADSENSE_NO_SENSE. There really isn’t much else to report in my
case, but you may get more information so maybe you can map your errors
to SCSI errors in a useful way.

  1. Is there a possibility that SCSI port queued the IOs
    internally, but
    send those requests to miniport sequentially? Now that the HBA can
    handle
    requests simutaneously, and send out an interrupt after it finished
    those
    commands. I just cannot write more than 1 SRB to HBA before HBA send
    out an
    interrupt. That is really the bottleneck of this driver.

Are you saying that your HBA can only accept one request at a time, or
that you get an interrupt per request and you only want an interrupt
once a few requests are ready?

James

Thanks!

  1. I think I realise the usage of sense data.
  2. my HBA can accept 256 requests at a time, and it can also generate an
    interrupt after it finish plenty of requests. But my SCSI miniport driver
    can only send out ONE request to HBA at a time, and than the next request
    after the ISR, which makes no possibility for the HBA to recieve more than 1
    request at the same time.

2011/3/30 James Harper

> > 1) I set the parameters u seggested, as well as
> AutoRequestSense, but
> > how to handle sense data? Do I need to fill in sense data?
>
> When you have an error to report, you copy/make the sense data into the
> SenseInfoBuffer for that request.
>
> My routine that does this is:
>
> static ULONG
> XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb,
> UCHAR sense_key, UCHAR additional_sense_code)
> {
> PSENSE_DATA sd = srb->SenseInfoBuffer;
>
> UNREFERENCED_PARAMETER(xvdd);
>
> if (!srb->SenseInfoBuffer)
> return 0;
>
> sd->ErrorCode = 0x70;
> sd->Valid = 1;
> sd->SenseKey = sense_key;
> sd->AdditionalSenseLength = sizeof(SENSE_DATA) -
> FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
> sd->AdditionalSenseCode = additional_sense_code;
> return sizeof(SENSE_DATA);
> }
>
> Which is called by:
>
> static VOID
> XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
> {
> if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags &
> SRB_FLAGS_DISABLE_AUTOSENSE)
> return;
> XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key,
> xvdd->last_additional_sense_code);
> srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
> }
>
> I can’t remember if you are dealing with a physical block device that
> might report real errors. In my case all I get from my underlying
> storage is a flag that tells me an error occurred, so my last_sense_key
> is SCSI_SENSE_MEDIUM_ERROR and my last_additional_sense_code is
> SCSI_ADSENSE_NO_SENSE. There really isn’t much else to report in my
> case, but you may get more information so maybe you can map your errors
> to SCSI errors in a useful way.
>
> > 3) Is there a possibility that SCSI port queued the IOs
> internally, but
> > send those requests to miniport sequentially? Now that the HBA can
> handle
> > requests simutaneously, and send out an interrupt after it finished
> those
> > commands. I just cannot write more than 1 SRB to HBA before HBA send
> out an
> > interrupt. That is really the bottleneck of this driver.
> >
>
> Are you saying that your HBA can only accept one request at a time, or
> that you get an interrupt per request and you only want an interrupt
> once a few requests are ready?
>
> James
>
>
> —
> NTDEV is sponsored by OSR
>
> 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
>