Mapbuffers entry

Hello!
I had a question regarding MapBuffers. The SCSI miniport driver, during
initialization must set this to true or false. The question is:

If, while creating the device object, we specify DO_DIRECT_IO, and set
MapBuffers to FALSE, what does the SRB Databuffer field signify. Its not
the kernel mapped address of the use buffer. Is it the user VA of the
buffer, or is it the Virtual address of the MDL?

From what I understand DO_DIRECT_IO sends an MDL down through the stack.
So does it mean that the DataBuffer address is an MDL?

Thanks!


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

I’m confused by the close association of “SCSI miniport driver” and
“creating the device object”. These two things are incompatible.

You set MapBuffers to TRUE in your miniport if you need to directly access
the contents of the databuffer, typically this is because your miniport is,
arghhhh, doing PIO rather than DMA.

If you set this to FALSE then Databuffer ought to indeed be the ‘user va’,
however other than curiosity and perhaps alignment, a user va in a scsi
miniport is not of any value. This field is not the MDL.

You could be a naughty hacker and poke around the memory at OriginalRequest,
which at least the w2k docs claimed:
“Points to the IRP for this request. This member is irrelevant to miniport
drivers”.

This phrase needs a little DDK-speak translation. The second sentence must
be read first, and then the first sentence must be read substituting “Does
not point” for “Points”. There then should follow a long list of other
kernel objects that OriginalRequest does not point to :slight_smile:

If you use scsikd in windbg you can discover that originalrequest generally
(but perhaps not always) points to an internal scsiport srb extension
object, which in turn has a pointer to the Irp, which has a pointer to the
MDL.

Of course the internal SRB structure used by scsiport is undocumented, which
is a very strong indicator that if you think you need the MDL for some
reason in your miniport driver you should re-cogitate.

-----Original Message-----
From: xxxxx@troikanetworks.com [mailto:xxxxx@troikanetworks.com]
Sent: Monday, November 05, 2001 9:19 AM
To: NT Developers Interest List
Subject: [ntdev] Mapbuffers entry

Hello!
I had a question regarding MapBuffers. The SCSI miniport driver, during
initialization must set this to true or false. The question is:

If, while creating the device object, we specify DO_DIRECT_IO, and set
MapBuffers to FALSE, what does the SRB Databuffer field signify. Its not
the kernel mapped address of the use buffer. Is it the user VA of the
buffer, or is it the Virtual address of the MDL?

From what I understand DO_DIRECT_IO sends an MDL down through the stack.
So does it mean that the DataBuffer address is an MDL?

Thanks!


You are currently subscribed to ntdev as: xxxxx@stratus.com To
unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> From what I understand DO_DIRECT_IO sends an MDL down through the stack.

So does it mean that the DataBuffer address is an MDL?

Forget about MDLs in a SCSI miniport, you will never see them.

If a miniport will require the CPU to touch the data transfer buffer, especially in an ISR, then it MUST use MapBuffers.

For a MapBuffers = TRUE miniport, Srb->DataBuffer points to a nonpaged system space address (OK for ISRs) for the transfer described
by this SRB. It can be a part of the original MDL since SCSIPORT can split requests.

For DMA miniports, use ScsiPortGetPhysicalAddress.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> If you use scsikd in windbg you can discover that originalrequest generally

(but perhaps not always) points to an internal scsiport srb extension
object, which in turn has a pointer to the Irp, which has a pointer to the
MDL.

Exactly so, but, in NT4, Srb->OriginalRequest really pointed to the IRP.

This is because NT4 SCSIPORT used global queue tag assignment engine, and thus they could find their internal extension from the SRB
by using the Srb->QueueTag to index the preallocated extension array. For SP_UNTAGGED request, the extension is a part of an
internal LUN descriptor structure.

w2k’s SCSIPORT has per-LUN queue tag assignment for better work, thus, they need the pointer in the SRB to their internal extension.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Max,
Thats for the reply!
I think I am actually confused on what actually happens when MapBuffers is
FALSE. Just out of curiosity, what do we get in DataBuffer when MapBuffers
is FALSE?

Thanks

-----Original Message-----
From: Maxim S. Shatskih [mailto:xxxxx@storagecraft.com]
Sent: Monday, November 05, 2001 2:10 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Mapbuffers entry

From what I understand DO_DIRECT_IO sends an MDL down through the stack.
So does it mean that the DataBuffer address is an MDL?

Forget about MDLs in a SCSI miniport, you will never see them.

If a miniport will require the CPU to touch the data transfer buffer,
especially in an ISR, then it MUST use MapBuffers.

For a MapBuffers = TRUE miniport, Srb->DataBuffer points to a nonpaged
system space address (OK for ISRs) for the transfer described
by this SRB. It can be a part of the original MDL since SCSIPORT can split
requests.

For DMA miniports, use ScsiPortGetPhysicalAddress.

Max


You are currently subscribed to ntdev as: xxxxx@troikanetworks.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Oops…I meant Thanks for the reply , not Thats for the reply in the previous
email!

-----Original Message-----
From: Mukul Kotwani [mailto:xxxxx@troikanetworks.com]
Sent: Monday, November 05, 2001 3:24 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Mapbuffers entry

Max,
Thats for the reply!
I think I am actually confused on what actually happens when MapBuffers is
FALSE. Just out of curiosity, what do we get in DataBuffer when MapBuffers
is FALSE?

Thanks

-----Original Message-----
From: Maxim S. Shatskih [mailto:xxxxx@storagecraft.com]
Sent: Monday, November 05, 2001 2:10 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Mapbuffers entry

From what I understand DO_DIRECT_IO sends an MDL down through the stack.
So does it mean that the DataBuffer address is an MDL?

Forget about MDLs in a SCSI miniport, you will never see them.

If a miniport will require the CPU to touch the data transfer buffer,
especially in an ISR, then it MUST use MapBuffers.

For a MapBuffers = TRUE miniport, Srb->DataBuffer points to a nonpaged
system space address (OK for ISRs) for the transfer described
by this SRB. It can be a part of the original MDL since SCSIPORT can split
requests.

For DMA miniports, use ScsiPortGetPhysicalAddress.

Max


You are currently subscribed to ntdev as: xxxxx@troikanetworks.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: xxxxx@troikanetworks.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> I think I am actually confused on what actually happens when MapBuffers is

FALSE. Just out of curiosity, what do we get in DataBuffer when MapBuffers
is FALSE?

Some Internal’s SCSIPORT Value not interesting to you.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Hi,

> From what I understand DO_DIRECT_IO sends an MDL down through the stack.
> So does it mean that the DataBuffer address is an MDL?

Forget about MDLs in a SCSI miniport, you will never see them.

If a miniport will require the CPU to touch the data transfer buffer,
especially in an ISR, then it MUST use MapBuffers.

For a MapBuffers = TRUE miniport, Srb->DataBuffer points to a nonpaged
system space address (OK for ISRs) for the transfer described
by this SRB. It can be a part of the original MDL since SCSIPORT can split
requests.

For DMA miniports, use ScsiPortGetPhysicalAddress.

I have a question (problem really) about this also ( I am discussing this
matter with a vendor and so far we have not come to a solution). If I
allocate memory in userspace and I want to store to bufferaddress in the
Srb, do I have to use MmGetMdlVirtualAddress() or do I use
mmGetSystemAddressForMdlSafe(). Btw, the first option is what I use but
causes problems because the driver from the other vendor is accessing memory
using that address but if use I the second option then my buffer is not
updated with the correct data ? So what is the theory behind DataBuffer ?

Thanks all.
Jos

PS: The User buffer is coming to me using a Device COntrol which uses the
NEITHER METHOD.


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> allocate memory in userspace and I want to store to bufferaddress in the

Srb, do I have to use MmGetMdlVirtualAddress() or do I use
mmGetSystemAddressForMdlSafe().

In order to send buffers to a miniport, one must send an IRP to SCSIPORT. SCSIPORT uses DO_DIRECT_IO and will process
Irp->MdlAddress correctly.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Hi,

> allocate memory in userspace and I want to store to bufferaddress in the
> Srb, do I have to use MmGetMdlVirtualAddress() or do I use
> mmGetSystemAddressForMdlSafe().

In order to send buffers to a miniport, one must send an IRP to SCSIPORT.
SCSIPORT uses DO_DIRECT_IO and will process
Irp->MdlAddress correctly.

Sorry but I am not sending an IRP (IRP_MJ_SCSI) to the SCSIPORT but to the
CDROM device. I create an SRB (SRB_FUNCTION_EXECUTE_SCSI) and think I also
have to initialize the SRB->DataBuffer field. Are you saying I am not
supposed to initialize this ? If think it should have the buffer address and
the question is what it should be (Virtual versus System). I am not sure how
this field is used and therefore I can’t detemine how to make this work with
the other vendors software (without it everything works fine)

Waiting anxiously :))

Jos.


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

I’m confused. If you are trying to read from the CD, just send an
IRP_MJ_READ to the Cdrom driver and let him deal with the problem of how to
build an SRB, that is what the class drivers are for. If instead you want to
control the scsi cd rom target directly, perhaps the SCSI passthrough IOCTLs
would be a better approach? See IOCTL_SCSI_PASS_THROUGH_DIRECT and
IOCTL_SCSI_PASS_THROUGH. All the samples are user mode, but I see no reason
why they cannot be done in kernel mode. Use IoBuildDeviceIoControlRequest to
construct the IRP. The Scsiport driver will take care of the mystery of how
to build an SRB for you in this case. By the way, the ddk has the source for
classpnp and disk - they build SRBs - so if you insist the answers are all
there.

-----Original Message-----
From: Jos Scherders [mailto:xxxxx@home.nl]
Sent: Wednesday, November 07, 2001 1:37 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Mapbuffers entry

Hi,

> allocate memory in userspace and I want to store to bufferaddress in
> the Srb, do I have to use MmGetMdlVirtualAddress() or do I use
> mmGetSystemAddressForMdlSafe().

In order to send buffers to a miniport, one must send an IRP to
SCSIPORT.
SCSIPORT uses DO_DIRECT_IO and will process
Irp->MdlAddress correctly.

Sorry but I am not sending an IRP (IRP_MJ_SCSI) to the SCSIPORT but to the
CDROM device. I create an SRB (SRB_FUNCTION_EXECUTE_SCSI) and think I also
have to initialize the SRB->DataBuffer field. Are you saying I am not
supposed to initialize this ? If think it should have the buffer address and
the question is what it should be (Virtual versus System). I am not sure how
this field is used and therefore I can’t detemine how to make this work with
the other vendors software (without it everything works fine)

Waiting anxiously :))

Jos.


You are currently subscribed to ntdev as: xxxxx@stratus.com To
unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Hi,

I’m confused. If you are trying to read from the CD, just send an
IRP_MJ_READ to the Cdrom driver and let him deal with the problem of how
to
build an SRB, that is what the class drivers are for. If instead you want
to
control the scsi cd rom target directly, perhaps the SCSI passthrough
IOCTLs
would be a better approach? See IOCTL_SCSI_PASS_THROUGH_DIRECT and
IOCTL_SCSI_PASS_THROUGH.

I am working on an existing driver which can’t be changed. It uses a private
IOCTL mechanism to send requests, I then build an IRP + the SRB to sent it
to the CDROM device.

All the samples are user mode, but I see no reason

why they cannot be done in kernel mode. Use IoBuildDeviceIoControlRequest
to
construct the IRP.

I do this yes.

The Scsiport driver will take care of the mystery of how

to build an SRB for you in this case. By the way, the ddk has the source
for
classpnp and disk - they build SRBs - so if you insist the answers are all
there.

Yes, I follow these examples and all works except I have a problem with the
filter driver from another vendor who uses the address in the
SRB->DataBuffer field to read data and that results in a blue screen. The
reason being that I store a Virtual Address (MmGetMdlVirtualAddress) in that
field (just like MS examples do). So now I don’t know if I am doing
something wrong or if one is not supposed to read from this address(but use
MmGetSystemAddressForMdlSafe on the MDL for example).

Jos


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

OK here is the thing, the class drivers do indeed set Srb.DataBuffer to the
user virtual address (MmGetMdlVirtualAddress.) The scsiport driver may, if
the miniport needs a system virtual address, replace this with a system
virtual address returned by MmGetSystemAddressForMdlSafe, but by the time
the request is completed it has reverted to its original contents
(MmGetMdlVirtualAddress).

I still do not understand why you are building SRBs directly, rather than
using the IOCTL_SCSI_PASS_THROUGH_DIRECT interface, but regardless, your
SRBs *should* have DataBuffer set to MmGetMdlVirtualAddress. NOBODY EXCEPT A
MINIPORT DRIVER SHOULD BE USING THIS ADDRESS TO ACCESS DATA, EVER. (Ever is
a bit harsh, but in this case it is fairly accurate.) This other filter
driver you mention is BROKEN. That probably doesn’t do you much good, as I
am guessing that broken or not you have to live with it. Did you try using
MmGetSystemAddressForMdlSafe? It might just work, it would at least produce
an address that your broken filter driver will not automatically crap out
on.

The user virtual address returned by MmGetMdlVirtualAddress is only valid in
the process context that originated the IO request. In any other process
context it is either going to cause an exception or produce garbage results.
Typically it is used only to understand the alignment of the original user
data request within a page.

-----Original Message-----
From: Jos Scherders [mailto:xxxxx@home.nl]
Sent: Wednesday, November 07, 2001 2:26 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Mapbuffers entry

Hi,

I’m confused. If you are trying to read from the CD, just send an
IRP_MJ_READ to the Cdrom driver and let him deal with the problem of
how
to
build an SRB, that is what the class drivers are for. If instead you
want
to
control the scsi cd rom target directly, perhaps the SCSI passthrough
IOCTLs
would be a better approach? See IOCTL_SCSI_PASS_THROUGH_DIRECT and
IOCTL_SCSI_PASS_THROUGH.

I am working on an existing driver which can’t be changed. It uses a private
IOCTL mechanism to send requests, I then build an IRP + the SRB to sent it
to the CDROM device.

All the samples are user mode, but I see no reason

why they cannot be done in kernel mode. Use
IoBuildDeviceIoControlRequest
to
construct the IRP.

I do this yes.

The Scsiport driver will take care of the mystery of how

to build an SRB for you in this case. By the way, the ddk has the
source
for
classpnp and disk - they build SRBs - so if you insist the answers are
all there.

Yes, I follow these examples and all works except I have a problem with the
filter driver from another vendor who uses the address in the
SRB->DataBuffer field to read data and that results in a blue screen.
SRB->The
reason being that I store a Virtual Address (MmGetMdlVirtualAddress) in that
field (just like MS examples do). So now I don’t know if I am doing
something wrong or if one is not supposed to read from this address(but use
MmGetSystemAddressForMdlSafe on the MDL for example).

Jos


You are currently subscribed to ntdev as: xxxxx@stratus.com To
unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Hi,

Thanks Roddy,

I still do not understand why you are building SRBs directly, rather than
using the IOCTL_SCSI_PASS_THROUGH_DIRECT interface, but regardless, your
SRBs *should* have DataBuffer set to MmGetMdlVirtualAddress.

This is from history but I guess I can change that as a workaround maybe.

NOBODY EXCEPT A

MINIPORT DRIVER SHOULD BE USING THIS ADDRESS TO ACCESS DATA, EVER. (Ever
is
a bit harsh, but in this case it is fairly accurate.) This other filter
driver you mention is BROKEN. That probably doesn’t do you much good, as I
am guessing that broken or not you have to live with it. Did you try using
MmGetSystemAddressForMdlSafe? It might just work, it would at least
produce
an address that your broken filter driver will not automatically crap out
on.

I did try MmGetSystemAddressForMdl (does the Safe variant work on NT 4.0
also, I couldnt find the protopye in header files if I recall correctly) and
the system doesnt crash now but I am not getting the data requested. I
havent figured out why that happens. Btw, the filter which is causes me
problem is, in fact, a SCSIPORT filter driver, e.g. it sits just on top of
SCSIPORT driver.

The user virtual address returned by MmGetMdlVirtualAddress is only valid
in
the process context that originated the IO request. In any other process
context it is either going to cause an exception or produce garbage
results.
Typically it is used only to understand the alignment of the original user
data request within a page.

Right, that is what I understood. Thanks for the confirmation.

Jos.


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com