I am developing a toolset that will exercise storage devices attached to
Windows XP and later systems, perhaps Windows 2000 also. Unlike most, mine
will (I think) manage to deliver arbitrary CDBs to a device at an arbitrary
queue depth. As most of you know, you can use Read/WriteFile to manage an
arbitrary queue depth of READ and WRITE. You can also send arbitrary CDBs
through SPTI, but SCSIPORT serializes them per device, or maybe LUN, so you
won’t see a queue of arbitrary CDBs on the device.
In order to get around these limitations, I am working with the following
architecture. Filter driver intercepts SCSI INQUIRY and changes the
PERIPHERAL DEVICE TYPE to something for which Windows doesn’t provide a
class driver. Custom class driver supports this new type, and app accesses
devices through custom class driver, by supplying a struct, in the user
buffer to Read/WriteFile, which includes the CDB, a pointer to user buffer,
and a pointer to sense buffer. I also have IOCTL available between app and
class driver.
I’m currently using an SRB as the user buffer passed into Read/Write, and
the class driver is responsible for looking at the pointers in the SRB for
the real data and sense data buffers, and locking them into memory. Gary
Little, this should look very familiar.
Before I go all the way down this road, I’m asking myself if I am painting
myself into a corner, or at least making life harder on myself than I need
to. Gary, and a few others, had some issues with this approach, which
appeared, based on my reading of the archive, to be due to the complexity of
the options available. (direct or buffered? Do you associate the secondary
MDLs with the Irp or not? Do you need to map the buffer?) I think I
understand what I need to do if I pursue this approach, but Mark Roddy
suggested if I have a top level driver, I should be able to avoid having
embedded data object pointers. In the archive articles I saw, Mark didn’t
elaborate in a way that I could wrap my limited brain around.
Since my devices aren’t disks to the system, I don’t have to worry about an
FS above me, and so I *think* my class driver qualifies as a top level
driver? If that’s so, how can I pass a buffer describing the CDB, plus a
pointer to user data buffer and another one for the sense buffer?
Backing up even a step further, do I gain anything by supporting Read/Write,
or should I just limit myself to IOCTLs, since the direction of dataflow is
determined by the contents of the CDB, and in some cases, isn’t even
defined? Is there a performance issue that I don’t know about, or would I
be able to get just as much concurrency if I were to limit the interface to
IOCTLs?
Thanks,
Phil
Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.
E-mail address is pointed at a domain squatter. Use reply-to instead.