SCSI passthrough target/path/lun data

Hi guys,

I have a function that looks at the SCSI_PASS_THROUGH_DIRECT structure data sent to a device with IRP_MJ_DEVICE_CONTROL to determine the target/path/lun numbers. This works fine, however… when I do a similar check on the data that “comes back” from the device in a completion routine, the target/path/lun data has all been set to 0.

Is there a way of accessing the target/path/lun data from the IRPs that come back in the completion routine that I’ve got for SCSI passthrough direct requests?

The code I’m using is:

switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_SCSI_PASS_THROUGH_DIRECT:
if ( (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof( SCSI_PASS_THROUGH_DIRECT ) && (Irp->AssociatedIrp.SystemBuffer != NULL))) {

PSCSI_PASS_THROUGH_DIRECT Spt = Irp->AssociatedIrp.SystemBuffer;

//Print info to debug…
KdPrint((“%s: TARGET: %d PATH: %d LUN: %d”,FUNCTION,Spt->TargetId,Spt->PathId,Spt->Lun));

Thanks,

Ben

Create an associated data structure object for the IRP that records
the data of interest and set that object as the Context parameter to
IoSetCompletetionRoutine(Ex).

Mark Roddy

On Thu, Sep 3, 2009 at 10:05 AM, Simpson, Ben<ben.simpson> wrote:
> Hi guys,
>
>
>
> I have a function that looks at the SCSI_PASS_THROUGH_DIRECT structure data
> sent to a device with IRP_MJ_DEVICE_CONTROL to determine the target/path/lun
> numbers. This works fine, however… when I do a similar check on the data
> that “comes back” from the device in a completion routine, the
> target/path/lun data has all been set to 0.
>
>
>
> Is there a way of accessing the target/path/lun data from the IRPs that come
> back in the completion routine that I’ve got for SCSI passthrough direct
> requests?
>
>
>
> The code I’m using is:
>
>
>
> …
>
>
>
> switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode)
>
> {
>
> ??? case IOCTL_SCSI_PASS_THROUGH_DIRECT:
>
> ??? if ( (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength
>>= sizeof( SCSI_PASS_THROUGH_DIRECT ) && (Irp->AssociatedIrp.SystemBuffer !=
> NULL))) {
>
>
>
> ??? PSCSI_PASS_THROUGH_DIRECT Spt = Irp->AssociatedIrp.SystemBuffer;
>
>
>
> ??? //Print info to debug…
>
> ??? KdPrint((“%s: TARGET: %d PATH: %d LUN:
> %d”, FUNCTION ,Spt->TargetId,Spt->PathId,Spt->Lun));
>
>
>
> …
>
>
>
>
>
> Thanks,
>
>
>
> Ben
>
> —
> 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</ben.simpson>

You could store the PTL information in your IRP stack location and then you can access it in your completion routine.

-p

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Simpson, Ben
Sent: Thursday, September 03, 2009 7:05 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] SCSI passthrough target/path/lun data

Hi guys,

I have a function that looks at the SCSI_PASS_THROUGH_DIRECT structure data sent to a device with IRP_MJ_DEVICE_CONTROL to determine the target/path/lun numbers. This works fine, however… when I do a similar check on the data that “comes back” from the device in a completion routine, the target/path/lun data has all been set to 0.

Is there a way of accessing the target/path/lun data from the IRPs that come back in the completion routine that I’ve got for SCSI passthrough direct requests?

The code I’m using is:

switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_SCSI_PASS_THROUGH_DIRECT:
if ( (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof( SCSI_PASS_THROUGH_DIRECT ) && (Irp->AssociatedIrp.SystemBuffer != NULL))) {

PSCSI_PASS_THROUGH_DIRECT Spt = Irp->AssociatedIrp.SystemBuffer;

//Print info to debug…
KdPrint((“%s: TARGET: %d PATH: %d LUN: %d”,FUNCTION,Spt->TargetId,Spt->PathId,Spt->Lun));

Thanks,

Ben


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

Thanks for the help guys, I’ve got that working fine now.

I have encountered a similar error in my routine for handling IRP_MJ_SCSI’s though, when I access the Target/Path/Lun data in the SRB (i.e. currentIrpStack->Parameters.Scsi.Srb->TargetId etc) they are all 0 for any device. Can someone tell me why I’m seeing all 0’s here, and how to get round it?

Thanks,

Ben

I think that SRBs sent to the LUN PDO are always such. The PDO sets the correct numbers itself.


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

<ben.simpson> wrote in message news:xxxxx@ntdev…
> Thanks for the help guys, I’ve got that working fine now.
>
> I have encountered a similar error in my routine for handling IRP_MJ_SCSI’s though, when I access the Target/Path/Lun data in the SRB (i.e. currentIrpStack->Parameters.Scsi.Srb->TargetId etc) they are all 0 for any device. Can someone tell me why I’m seeing all 0’s here, and how to get round it?
>
> Thanks,
>
> Ben
></ben.simpson>

Ok, thanks I’ve got that sorted now, using another completion routine for the IRP_MJ_SCSIs. Going back to the original problem I had with the PTL info, I’ve now realised that the info I’m capturing from the SCSI_PASS_THROUGH_DIRECT structure isn’t correct. The numbers are almost random every time for different devices, it was just that the original devices I was testing with happened to throw out the correct numbers by coincidence. Now that I’ve hooked up more devices I’ve found the PTL info is not changing between devices, I think the numbers I’m seeing are ones left on the stack from previous commands…

Can someone help advise why these numbers are not being set correctly, either in the initial IRP_MJ_DEVICE_CONTROL’s, or the completion routine for these IRPs? Whilst I implemented the suggested fix of passing the PTL info using the Context parameter of the IoSetCompletionRoutine call, I have also tested for the correct PTL info being set in the completion routine, but no luck.

Thanks,

Ben

Offhand PTL is inferred from the target device object. If I recall
correctly, a long time ago SPT used to go to the HBA FDO and the
caller had to specify the device address in the request. Then it got
changed to go directly to the device FDO and in the process PTL in the
request became irrelevant.

You can ask the device FDO what its PTL is.

"This structure includes a SCSI CDB, which must be initialized by the
caller except for the path, target ID, and LUN, which are filled in by
the port driver. " some version or other of the WDK docs, the sample
of course ignores this advice just to confuse the innocent.

Mark Roddy

On Tue, Sep 8, 2009 at 12:00 PM, <ben.simpson> wrote:
> Ok, thanks I’ve got that sorted now, using another completion routine for the IRP_MJ_SCSIs. Going back to the original problem I had with the PTL info, I’ve now realised that the info I’m capturing from the SCSI_PASS_THROUGH_DIRECT structure isn’t correct. The numbers are almost random every time for different devices, it was just that the original devices I was testing with happened to throw out the correct numbers by coincidence. Now that I’ve hooked up more devices I’ve found the PTL info is not changing between devices, I think the numbers I’m seeing are ones left on the stack from previous commands…
>
> Can someone help advise why these numbers are not being set correctly, either in the initial IRP_MJ_DEVICE_CONTROL’s, or the completion routine for these IRPs? Whilst I implemented the suggested fix of passing the PTL info using the Context parameter of the IoSetCompletionRoutine call, I have also tested for the correct PTL info being set in the completion routine, but no luck.
>
>
> Thanks,
>
> Ben
>
> —
> 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
></ben.simpson>

I may be stating the obvious but AFAIK spt requests can be directed to
either disk(or other FDOs) or port instances. If directed to disk, you
don’t need to pass in PTL because disk class driver already knows PTL.
If directed to port, you need to supply the PTL thereby telling the port
as to which lun do you want to send the command.

Harish

-----Original Message-----
From: Mark Roddy [mailto:xxxxx@hollistech.com]
Sent: Wednesday, September 09, 2009 10:06 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] SCSI passthrough target/path/lun data

Offhand PTL is inferred from the target device object. If I recall
correctly, a long time ago SPT used to go to the HBA FDO and the
caller had to specify the device address in the request. Then it got
changed to go directly to the device FDO and in the process PTL in the
request became irrelevant.

You can ask the device FDO what its PTL is.

"This structure includes a SCSI CDB, which must be initialized by the
caller except for the path, target ID, and LUN, which are filled in by
the port driver. " some version or other of the WDK docs, the sample
of course ignores this advice just to confuse the innocent.

Mark Roddy

On Tue, Sep 8, 2009 at 12:00 PM, <ben.simpson> wrote:
> Ok, thanks I’ve got that sorted now, using another completion routine
for the IRP_MJ_SCSIs. Going back to the original problem I had with the
PTL info, I’ve now realised that the info I’m capturing from the
SCSI_PASS_THROUGH_DIRECT structure isn’t correct. The numbers are almost
random every time for different devices, it was just that the original
devices I was testing with happened to throw out the correct numbers by
coincidence. Now that I’ve hooked up more devices I’ve found the PTL
info is not changing between devices, I think the numbers I’m seeing are
ones left on the stack from previous commands…
>
> Can someone help advise why these numbers are not being set correctly,
either in the initial IRP_MJ_DEVICE_CONTROL’s, or the completion routine
for these IRPs? Whilst I implemented the suggested fix of passing the
PTL info using the Context parameter of the IoSetCompletionRoutine call,
I have also tested for the correct PTL info being set in the completion
routine, but no luck.
>
>
> Thanks,
>
> Ben
>
> —
> 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</ben.simpson>

Yes I misspoke. You can send SPT to the HBA FDO for devices that are
not claimed by class drivers, and then you have to use the address
fields in the request. For claimed devices (for example disks) the SPT
requests have to go through the class driver. You can do anything you
want with the address fields - they are ignored and are instead filled
in by the port driver based on the PDO target. The point being that
the OP’s filter driver, as he has discovered, is going to have to deal
with garbage values for the address in the SPT request and will have
to use other mechanisms to determine what that address is.

Mark Roddy

On Wed, Sep 9, 2009 at 2:19 PM, Arora, Harish wrote:
> I may be stating the obvious but AFAIK spt requests can be directed to
> either disk(or other FDOs) or port instances. If directed to disk, you
> don’t need to pass in PTL because disk class driver already knows PTL.
> If directed to port, you need to supply the PTL thereby telling the port
> as to which lun do you want to send the command.
>
> Harish
>
> -----Original Message-----
> From: Mark Roddy [mailto:xxxxx@hollistech.com]
> Sent: Wednesday, September 09, 2009 10:06 AM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] SCSI passthrough target/path/lun data
>
> Offhand PTL is inferred from the target device object. If I recall
> correctly, a long time ago SPT used to go to the HBA FDO and the
> caller had to specify the device address in the request. Then it got
> changed to go directly to the device FDO and in the process PTL in the
> request became irrelevant.
>
> You can ask the device FDO what its PTL is.
>
> "This structure includes a SCSI CDB, which must be initialized by the
> caller except for the path, target ID, and LUN, which are filled in by
> the port driver. " some version or other of the WDK docs, the sample
> of course ignores this advice just to confuse the innocent.
>
> Mark Roddy
>
>
>
> On Tue, Sep 8, 2009 at 12:00 PM, <ben.simpson> wrote:
>> Ok, thanks I’ve got that sorted now, using another completion routine
> for the IRP_MJ_SCSIs. Going back to the original problem I had with the
> PTL info, I’ve now realised that the info I’m capturing from the
> SCSI_PASS_THROUGH_DIRECT structure isn’t correct. The numbers are almost
> random every time for different devices, it was just that the original
> devices I was testing with happened to throw out the correct numbers by
> coincidence. Now that I’ve hooked up more devices I’ve found the PTL
> info is not changing between devices, I think the numbers I’m seeing are
> ones left on the stack from previous commands…
>>
>> Can someone help advise why these numbers are not being set correctly,
> either in the initial IRP_MJ_DEVICE_CONTROL’s, or the completion routine
> for these IRPs? Whilst I implemented the suggested fix of passing the
> PTL info using the Context parameter of the IoSetCompletionRoutine call,
> I have also tested for the correct PTL info being set in the completion
> routine, but no luck.
>>
>>
>> Thanks,
>>
>> Ben
>>
>> —
>> 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
>
> —
> 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
></ben.simpson>

Thanks for the replies guys. I don’t need to get the PTL info for driver functionality, but from a data analysis point of view I need to use the PTL info to differentiate between devices in the class. I’m surprised that the PTL is supplied correctly in the SRB structures associated with the IRP_MJ_SCSI’s, but not as part of the SPT data. Is there any other way that I can find the PTL info when receiving SPT data?

Mark, when you say that I can ask the device FDO what its PTL is, how would I go about doing that?

Thanks,

Ben

IOCTL_SCSI_GET_ADDRESS

Mark Roddy

On Thu, Sep 10, 2009 at 5:44 AM, <ben.simpson> wrote:
> Thanks for the replies guys. I don’t need to get the PTL info for driver functionality, but from a data analysis point of view I need to use the PTL info to differentiate between devices in the class. I’m surprised that the PTL is supplied correctly in the SRB structures associated with the IRP_MJ_SCSI’s, but not as part of the SPT data. Is there any other way that I can find the PTL info when receiving SPT data?
>
> Mark, when you say that I can ask the device FDO what its PTL is, how would I go about doing that?
>
> Thanks,
>
> Ben
>
> —
> 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
></ben.simpson>

Yea, I’m using that in a DeviceIoControl call from a Windows app to get the PTL data, but I need to access the PTL data in every SPT that is sent to my driver, not just the once from Windows app.

Is there another way to get PTL info within the driver?

Ben

IOCTL_SCSI_GET_ADDRESS works fine in a driver. I use this in a driver
to get the scsi address from scsi PDOs my driver is sitting on top of.
You do this once during device initialization (start device
completion) and cache the results in your device extension for that
device.

Mark Roddy

On Thu, Sep 10, 2009 at 6:56 AM, <ben.simpson> wrote:
> Yea, I’m using that in a DeviceIoControl call from a Windows app to get the PTL data, but I need to access the PTL data in every SPT that is sent to my driver, not just the once from Windows app.
>
> Is there another way to get PTL info within the driver?
>
> Ben
>
> —
> 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
></ben.simpson>

Ok, but my driver is a lower filter driver in the class, can I still do this for every device passed through my driver?

Ben

Yes. Send the IOCTL as part of your completion processing for
StartDevice (at PASSIVE_LEVEL) and store it for later reference.

Mark Roddy

On Fri, Sep 11, 2009 at 5:30 AM, <ben.simpson> wrote:
> Ok, but my driver is a lower filter driver in the class, can I still do this for every device passed through my driver?
>
> Ben
>
> —
> 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
></ben.simpson>

> Is there another way to get PTL info within the driver?

Attach a filter to the LUN PDO.

In its post-MN_START_DEVICE path, send IOCTL_SCSI_GET_ADDRESS and save the address to the devext.

Then, for each and every SRB and SPT sent to this filter DO, you can assume the saved address.

This is what the storage port does internally.

Proper filling of PTL at the upper edge of the storage port is NOT a must, neither for SPT nor for SRBs. It is only a must if the adapter FDO is the target, i.e. \.\Scsi0:

But, if the LUN PDO is the target, i.e. \.\e: for CD/DVD, or the PnP device interface name for CD/DVD, or \.\PhysicalDrive0 - then PTL fields from SPT or SRB are just plain junk or zeroes, and are substituted from the internals of the storage port.

Surely that, at ScsiPort’s and StorPort’s lower egde, the PTL fields in the SRB are valid, but you cannot filter there.


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