ScsiPortNotification(RequestComplete,...)

I have a rather unique SCSI miniport implementation I’m trying to get
working.

The actual device is a drive that connects to the PC via the serial port
(yes, it’s not exactly fast, but that’s not the point here). The drive
has it’s own communication protocol, but needs to look to the system as
if it’s a SCSI drive on a SCSI HBA.

Note that this only needs to work for Windows 2000 and XP (and beyond?).
No need to be compatible with Windoze 95/98/ME. So, I’ve broken the
rules regarding miniports and used some of the standard Windows 2000/XP
kernel driver APIs, and linked to the additional libraries in my sources
file. I know that this is, shall we say, “not recommended”, but since I
have to call another driver (in this case, the serial port driver), I
need to be able to call IoCallDriver() (amoungst other APIs), so I have
to do it this way.

Since the device is actually on the serial port, I’ve used
IoGetDeviceObjectPointer() to get a pointer to the serial port’s device
object so that I can then create my own IRPs to send to it to do the low
level reads and writes to/from the hardware. Of course, since those
IRPs may complete asynchronously, I need to be able to wait until they
are completed as I send each IRP. This requires running in a thread at
PASSIVE_LEVEL so that I can perform the wait, which means I must have an
independent thread running outside of the context of the miniport
routines, since the miniport StartIo and Timer routines all run at
raised IRQL under locks. And since the miniport does not handle the
serial interrupt itself, I can’t use a miniport interrupt routine for
notification of the completion of each IRP sent to the serial port. So
I’ve created an independent processing thread to do all of the actual
I/O processing of each SRB which uses IoBuildSynchronousFsdRequest() to
create IRPs to send the the serial port and then waits on an event for
completion.

The problem is that since this thread runs outside of the miniport
context, I have no means to call
ScsiPortNotification(RequestComplete,…) once all of the data transfer
between the PC and the drive is complete. As has been discussed on this
list in the past, calls to ScsiPortXXX functions outside of the context
of the miniport context are seemingly ignored, and thus the SRBs end up
timing out instead of being completed.

Does anybody know of a solution around this that I can make work? Other
than the SRBs timing out because I can’t complete them when I’m done,
pretty much everything else about my implementation is now working. But
I desparately need a means for somehow calling ScsiPortNotification()
(or a means to get a callback function called in miniport context) when
I complete each request.

Note that a solution bypassing the serial port driver is not desirable.
Ignoring the conflict issues, the general architecture of this driver
has to be able to support talking to other variations of my client’s
hardware that can connect to the PC by other means (parallel, add-in
card, etc.). Thus, if at all possible, a solution like I have
implemented where I am calling an underlying driver to do the actual
low-level communications with the device is desired since it is easily
modified for other underlying hardware implementations.

Any and all ideas would be greatly appreciated.

Thanks,

  • Jay

Jay Talbott
Principal Consulting Engineer
SysPro Consulting, LLC
3519 E. South Fork Drive
Suite 201
Phoenix, AZ 85044
(480) 704-8045
xxxxx@sysproconsulting.com
http://www.sysproconsulting.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 just recently ran into the exact same quirk, and here’s my solution (at
least for the time being)…

In my “foreign” thread I still call ScsiPortNotification(RequestComplete
…) because that function only sets a flag in the SRB saying it needs to
be completed, then it returns. It does this same behavior in or out of
SCSIPORT context, and at any IRQL. It doesn’t actually process the
completion, as far as I can tell. Then, I have a 20ms timer (tuned
more-or-less to the device’s interrupt timing to prevent overkill),
scheduled in StartIo via …(RequestTimerCall …), that simply reschedules
itself if needed (if my queue is not empty). Now for the voodoo… My
HwScsiTimer is called by SCSIPORT, and when my function returns (or at some
time in the process of invoking my timer) SCSIPORT then officially
completes all SRBs with the above mentioned flag set.

As has been suggested many times on this list, you could just do a
RequestComplete from within the timer. But, in my driver I have more
direct access to the data structures in the thread. Also, if one were to
look through my source and ignore the timer for the moment, everything is
structured as I think it should be. It’s more intuitive to do a
RequestComplete right when you have completed the request, not at some
arbitrary time later in a timer. Second to last, I believe it “cleans the
SRBs” around other callbacks than just HwScsiTimer, including StartIo. My
final excuse is that the DDK docs never warn against calling
ScsiPortNotification outside of SCSIPORT context. As a matter of fact, the
documentation seems to know nothing about any of the SCSIPORT limitations
I’ve been fighting with over the last couple weeks…

Jason

On 01/09/02, ““Jay Talbott” ” wrote:
> I have a rather unique SCSI miniport implementation I’m trying to get
> working.
>
> The actual device is a drive that connects to the PC via the serial port
> (yes, it’s not exactly fast, but that’s not the point here). The drive
> has it’s own communication protocol, but needs to look to the system as
> if it’s a SCSI drive on a SCSI HBA.
>
> Note that this only needs to work for Windows 2000 and XP (and beyond?).
> No need to be compatible with Windoze 95/98/ME. So, I’ve broken the
> rules regarding miniports and used some of the standard Windows 2000/XP
> kernel driver APIs, and linked to the additional libraries in my sources
> file. I know that this is, shall we say, “not recommended”, but since I
> have to call another driver (in this case, the serial port driver), I
> need to be able to call IoCallDriver() (amoungst other APIs), so I have
> to do it this way.
>
> Since the device is actually on the serial port, I’ve used
> IoGetDeviceObjectPointer() to get a pointer to the serial port’s device
> object so that I can then create my own IRPs to send to it to do the low
> level reads and writes to/from the hardware. Of course, since those
> IRPs may complete asynchronously, I need to be able to wait until they
> are completed as I send each IRP. This requires running in a thread at
> PASSIVE_LEVEL so that I can perform the wait, which means I must have an
> independent thread running outside of the context of the miniport
> routines, since the miniport StartIo and Timer routines all run at
> raised IRQL under locks. And since the miniport does not handle the
> serial interrupt itself, I can’t use a miniport interrupt routine for
> notification of the completion of each IRP sent to the serial port. So
> I’ve created an independent processing thread to do all of the actual
> I/O processing of each SRB which uses IoBuildSynchronousFsdRequest() to
> create IRPs to send the the serial port and then waits on an event for
> completion.
>
> The problem is that since this thread runs outside of the miniport
> context, I have no means to call
> ScsiPortNotification(RequestComplete,…) once all of the data transfer
> between the PC and the drive is complete. As has been discussed on this
> list in the past, calls to ScsiPortXXX functions outside of the context
> of the miniport context are seemingly ignored, and thus the SRBs end up
> timing out instead of being completed.
>
> Does anybody know of a solution around this that I can make work? Other
> than the SRBs timing out because I can’t complete them when I’m done,
> pretty much everything else about my implementation is now working. But
> I desparately need a means for somehow calling ScsiPortNotification()
> (or a means to get a callback function called in miniport context) when
> I complete each request.
>
> Note that a solution bypassing the serial port driver is not desirable.
> Ignoring the conflict issues, the general architecture of this driver
> has to be able to support talking to other variations of my client’s
> hardware that can connect to the PC by other means (parallel, add-in
> card, etc.). Thus, if at all possible, a solution like I have
> implemented where I am calling an underlying driver to do the actual
> low-level communications with the device is desired since it is easily
> modified for other underlying hardware implementations.
>
> Any and all ideas would be greatly appreciated.
>
> Thanks,
>
> - Jay
>
> Jay Talbott
> Principal Consulting Engineer
> SysPro Consulting, LLC
> 3519 E. South Fork Drive
> Suite 201
> Phoenix, AZ 85044
> (480) 704-8045
> xxxxx@sysproconsulting.com
> http://www.sysproconsulting.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


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,

Gimme a day or two and I’ll issue you with a code sample how to complete
SRBs in the SCSI miniport. Or you can start implementing monolithic SCSI
port driver.
No restrictions what API to call inside it -)

Anton

On 01/09/02, ““Jay Talbott” ” wrote:
> I have a rather unique SCSI miniport implementation I’m trying to get
> working.
>
> The actual device is a drive that connects to the PC via the serial port
> (yes, it’s not exactly fast, but that’s not the point here). The drive
> has it’s own communication protocol, but needs to look to the system as
> if it’s a SCSI drive on a SCSI HBA.
>
> Note that this only needs to work for Windows 2000 and XP (and beyond?).
> No need to be compatible with Windoze 95/98/ME. So, I’ve broken the
> rules regarding miniports and used some of the standard Windows 2000/XP
> kernel driver APIs, and linked to the additional libraries in my sources
> file. I know that this is, shall we say, “not recommended”, but since I
> have to call another driver (in this case, the serial port driver), I
> need to be able to call IoCallDriver() (amoungst other APIs), so I have
> to do it this way.
>
> Since the device is actually on the serial port, I’ve used
> IoGetDeviceObjectPointer() to get a pointer to the serial port’s device
> object so that I can then create my own IRPs to send to it to do the low
> level reads and writes to/from the hardware. Of course, since those
> IRPs may complete asynchronously, I need to be able to wait until they
> are completed as I send each IRP. This requires running in a thread at
> PASSIVE_LEVEL so that I can perform the wait, which means I must have an
> independent thread running outside of the context of the miniport
> routines, since the miniport StartIo and Timer routines all run at
> raised IRQL under locks. And since the miniport does not handle the
> serial interrupt itself, I can’t use a miniport interrupt routine for
> notification of the completion of each IRP sent to the serial port. So
> I’ve created an independent processing thread to do all of the actual
> I/O processing of each SRB which uses IoBuildSynchronousFsdRequest() to
> create IRPs to send the the serial port and then waits on an event for
> completion.
>
> The problem is that since this thread runs outside of the miniport
> context, I have no means to call
> ScsiPortNotification(RequestComplete,…) once all of the data transfer
> between the PC and the drive is complete. As has been discussed on this
> list in the past, calls to ScsiPortXXX functions outside of the context
> of the miniport context are seemingly ignored, and thus the SRBs end up
> timing out instead of being completed.
>
> Does anybody know of a solution around this that I can make work? Other
> than the SRBs timing out because I can’t complete them when I’m done,
> pretty much everything else about my implementation is now working. But
> I desparately need a means for somehow calling ScsiPortNotification()
> (or a means to get a callback function called in miniport context) when
> I complete each request.
>
> Note that a solution bypassing the serial port driver is not desirable.
> Ignoring the conflict issues, the general architecture of this driver
> has to be able to support talking to other variations of my client’s
> hardware that can connect to the PC by other means (parallel, add-in
> card, etc.). Thus, if at all possible, a solution like I have
> implemented where I am calling an underlying driver to do the actual
> low-level communications with the device is desired since it is easily
> modified for other underlying hardware implementations.
>
> Any and all ideas would be greatly appreciated.
>
> Thanks,
>
> - Jay
>
> Jay Talbott
> Principal Consulting Engineer
> SysPro Consulting, LLC
> 3519 E. South Fork Drive
> Suite 201
> Phoenix, AZ 85044
> (480) 704-8045
> xxxxx@sysproconsulting.com
> http://www.sysproconsulting.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


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

>>Does anybody know of a solution around this that I can make work?
Other than the SRBs timing out because I can’t complete them when I’m
done, pretty much everything else about my implementation is now
working. But I desparately need a means for somehow calling
ScsiPortNotification() (or a means to get a callback function called in
miniport context) when I complete each request.<<

You can use our Virtual SCSI port driver (VSPORT). I removes the context
limitations. It was designed specifically to allow you to call
IoCallDriver() and other DDK functions from a VSPORT miniport. We
include a sample virtual disk that reads it data from a file.

Jamey Kirby
StorageCraft
www.storagecraf.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

A way to do this is to have your thread open the SCSI port, and send an proprietary IOCTL that will actually notify the object.
In this way, the SCSIPort driver will get all the right locks for your miniport to complete the I/O.

The only concern that I’d have with this is that SCSIPort might block the IOCTL because it had too many other requests
outstanding.
Alternatively, you could have a queue of completions back to the your miniport, and use both the IOCTL and the timer Jason
suggested.
The IOCTL for immediate response, and the timer to break the deadlock.
-DH
----- Original Message -----
From: “Jay Talbott”
To: “NT Developers Interest List”
Sent: Tuesday, January 08, 2002 6:30 PM
Subject: [ntdev] ScsiPortNotification(RequestComplete,…)

> I have a rather unique SCSI miniport implementation I’m trying to get
> working.
>
> The actual device is a drive that connects to the PC via the serial port
> (yes, it’s not exactly fast, but that’s not the point here). The drive
> has it’s own communication protocol, but needs to look to the system as
> if it’s a SCSI drive on a SCSI HBA.
>
> Note that this only needs to work for Windows 2000 and XP (and beyond?).
> No need to be compatible with Windoze 95/98/ME. So, I’ve broken the
> rules regarding miniports and used some of the standard Windows 2000/XP
> kernel driver APIs, and linked to the additional libraries in my sources
> file. I know that this is, shall we say, “not recommended”, but since I
> have to call another driver (in this case, the serial port driver), I
> need to be able to call IoCallDriver() (amoungst other APIs), so I have
> to do it this way.
>
> Since the device is actually on the serial port, I’ve used
> IoGetDeviceObjectPointer() to get a pointer to the serial port’s device
> object so that I can then create my own IRPs to send to it to do the low
> level reads and writes to/from the hardware. Of course, since those
> IRPs may complete asynchronously, I need to be able to wait until they
> are completed as I send each IRP. This requires running in a thread at
> PASSIVE_LEVEL so that I can perform the wait, which means I must have an
> independent thread running outside of the context of the miniport
> routines, since the miniport StartIo and Timer routines all run at
> raised IRQL under locks. And since the miniport does not handle the
> serial interrupt itself, I can’t use a miniport interrupt routine for
> notification of the completion of each IRP sent to the serial port. So
> I’ve created an independent processing thread to do all of the actual
> I/O processing of each SRB which uses IoBuildSynchronousFsdRequest() to
> create IRPs to send the the serial port and then waits on an event for
> completion.
>
> The problem is that since this thread runs outside of the miniport
> context, I have no means to call
> ScsiPortNotification(RequestComplete,…) once all of the data transfer
> between the PC and the drive is complete. As has been discussed on this
> list in the past, calls to ScsiPortXXX functions outside of the context
> of the miniport context are seemingly ignored, and thus the SRBs end up
> timing out instead of being completed.
>
> Does anybody know of a solution around this that I can make work? Other
> than the SRBs timing out because I can’t complete them when I’m done,
> pretty much everything else about my implementation is now working. But
> I desparately need a means for somehow calling ScsiPortNotification()
> (or a means to get a callback function called in miniport context) when
> I complete each request.
>
> Note that a solution bypassing the serial port driver is not desirable.
> Ignoring the conflict issues, the general architecture of this driver
> has to be able to support talking to other variations of my client’s
> hardware that can connect to the PC by other means (parallel, add-in
> card, etc.). Thus, if at all possible, a solution like I have
> implemented where I am calling an underlying driver to do the actual
> low-level communications with the device is desired since it is easily
> modified for other underlying hardware implementations.
>
> Any and all ideas would be greatly appreciated.
>
> Thanks,
>
> - Jay
>
> Jay Talbott
> Principal Consulting Engineer
> SysPro Consulting, LLC
> 3519 E. South Fork Drive
> Suite 201
> Phoenix, AZ 85044
> (480) 704-8045
> xxxxx@sysproconsulting.com
> http://www.sysproconsulting.com
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@syssoftsol.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

Jay,

I’m exploring using an SRB queue, and a DDK edge to the mini-port that uses
a PASSIVE_LEVEL thread to send an IRP with IOCTL_SCSI_MINIPORT (???) to
SCSIPORT with a command to purge the queue. However, the trick is getting
the little beastie to load, and call the FindAdapter routine. That is almost
impossible as a WDM driver that has no resources, or any documentation as to
how the bus driver that enumerated the SCSI driver should respond to WDM
IRPs. Right now I am loading as a legacy driver with no interrupts on a
PCIBus.

Things would be so simple if SCSIPORT and or STORPORT did not have that
STUPID clan/family concept. The design of those two subsystems encourages
developers to violate the rules to provide virtual SCSI mini-ports for bus’s
that do not fit the standard mold.

Gary G. Little
Broadband Storage, Inc.
xxxxx@broadstor.com
xxxxx@inland.net
(949) 7372731

-----Original Message-----
From: Jay Talbott [mailto:xxxxx@sysproconsulting.com]
Sent: Tuesday, January 08, 2002 3:30 PM
To: NT Developers Interest List
Subject: [ntdev] ScsiPortNotification(RequestComplete,…)

I have a rather unique SCSI miniport implementation I’m trying to get
working.

The actual device is a drive that connects to the PC via the serial port
(yes, it’s not exactly fast, but that’s not the point here). The drive
has it’s own communication protocol, but needs to look to the system as
if it’s a SCSI drive on a SCSI HBA.

Note that this only needs to work for Windows 2000 and XP (and beyond?).
No need to be compatible with Windoze 95/98/ME. So, I’ve broken the
rules regarding miniports and used some of the standard Windows 2000/XP
kernel driver APIs, and linked to the additional libraries in my sources
file. I know that this is, shall we say, “not recommended”, but since I
have to call another driver (in this case, the serial port driver), I
need to be able to call IoCallDriver() (amoungst other APIs), so I have
to do it this way.

Since the device is actually on the serial port, I’ve used
IoGetDeviceObjectPointer() to get a pointer to the serial port’s device
object so that I can then create my own IRPs to send to it to do the low
level reads and writes to/from the hardware. Of course, since those
IRPs may complete asynchronously, I need to be able to wait until they
are completed as I send each IRP. This requires running in a thread at
PASSIVE_LEVEL so that I can perform the wait, which means I must have an
independent thread running outside of the context of the miniport
routines, since the miniport StartIo and Timer routines all run at
raised IRQL under locks. And since the miniport does not handle the
serial interrupt itself, I can’t use a miniport interrupt routine for
notification of the completion of each IRP sent to the serial port. So
I’ve created an independent processing thread to do all of the actual
I/O processing of each SRB which uses IoBuildSynchronousFsdRequest() to
create IRPs to send the the serial port and then waits on an event for
completion.

The problem is that since this thread runs outside of the miniport
context, I have no means to call
ScsiPortNotification(RequestComplete,…) once all of the data transfer
between the PC and the drive is complete. As has been discussed on this
list in the past, calls to ScsiPortXXX functions outside of the context
of the miniport context are seemingly ignored, and thus the SRBs end up
timing out instead of being completed.

Does anybody know of a solution around this that I can make work? Other
than the SRBs timing out because I can’t complete them when I’m done,
pretty much everything else about my implementation is now working. But
I desparately need a means for somehow calling ScsiPortNotification()
(or a means to get a callback function called in miniport context) when
I complete each request.

Note that a solution bypassing the serial port driver is not desirable.
Ignoring the conflict issues, the general architecture of this driver
has to be able to support talking to other variations of my client’s
hardware that can connect to the PC by other means (parallel, add-in
card, etc.). Thus, if at all possible, a solution like I have
implemented where I am calling an underlying driver to do the actual
low-level communications with the device is desired since it is easily
modified for other underlying hardware implementations.

Any and all ideas would be greatly appreciated.

Thanks,

  • Jay

Jay Talbott
Principal Consulting Engineer
SysPro Consulting, LLC
3519 E. South Fork Drive
Suite 201
Phoenix, AZ 85044
(480) 704-8045
xxxxx@sysproconsulting.com
http://www.sysproconsulting.com


You are currently subscribed to ntdev as: xxxxx@broadstor.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

>In my “foreign” thread I still call ScsiPortNotification(RequestComplete

…) because that function only sets a flag in the SRB saying it needs to
be completed, then it returns. It does this same behavior in or out of
SCSIPORT context, and at any IRQL. It doesn’t actually process the
completion, as far as I can tell. Then, I have a 20ms timer (tuned
more-or-less to the device’s interrupt timing to prevent overkill),
scheduled in StartIo via …(RequestTimerCall …), that simply reschedules
itself if needed (if my queue is not empty). Now for the voodoo… My
HwScsiTimer is called by SCSIPORT, and when my function returns (or at some
time in the process of invoking my timer) SCSIPORT then officially
completes all SRBs with the above mentioned flag set.

That’s VERY interesting. It sounds like if we could just find ANY request
type that will always passes into the driver, bypassing any queues, we
would have a way to always trigger completion without a delay.

It seems like something like an abort request or WMI request might fit
this. Wasn’t there something about Microsoft saying they were going to
allow developers to come and look at parts of the OS source code, as part
of their desire to settle their legal issues?

I was thinking what a good opportunity this would be for Microsoft to
improve their relationship with kernel developers. They have the SCSIPORT
source code, and could officially tell us a way to make completion of srb’s
outside the “normal” context work. An approved method for the different OS
flavors (WinNT/W2K/WinXP) would be best. The alternative is we will be VERY
creative at finding ways that work 99% of the time (some may work 100% of
the time). It’s in Microsoft’s power to reduce a whole class of bugs here
(some of which may bring down the OS). It might be as simple as a
programmer looking at some source code and writing a little document, or it
might be as complex as adding a IOCTL to SCSIPORT that always just passes a
datablock into the driver, bypassing any queues, letting you call normal
miniport functions. Requiring a customer to use a certain service pack
level (which happens to have a slight change to SCSIPORT) is not so
unreasonable.

  • Jan

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

> Does anybody know of a solution around this that I can make work? Other

than the SRBs timing out because I can’t complete them when I’m done,
pretty much everything else about my implementation is now working. But
I desparately need a means for somehow calling ScsiPortNotification()
(or a means to get a callback function called in miniport context) when
I complete each request.

There are libraries on the market which replace SCSIPORT.
Under MS’s SCSIPORT, this is unsolvable without nasty hacks, whose speed and reliability is in question.

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

Except that you can not call DDK functions using the straight MS model.
This should be a clue.

Jamey

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@systran.com
Sent: Wednesday, January 09, 2002 2:17 PM
To: NT Developers Interest List
Subject: [ntdev] Re: ScsiPortNotification(RequestComplete,…)

I just recently ran into the exact same quirk, and here’s my solution
(at
least for the time being)…

In my “foreign” thread I still call ScsiPortNotification(RequestComplete

…) because that function only sets a flag in the SRB saying it needs
to
be completed, then it returns. It does this same behavior in or out of
SCSIPORT context, and at any IRQL. It doesn’t actually process the
completion, as far as I can tell. Then, I have a 20ms timer (tuned
more-or-less to the device’s interrupt timing to prevent overkill),
scheduled in StartIo via …(RequestTimerCall …), that simply
reschedules
itself if needed (if my queue is not empty). Now for the voodoo… My
HwScsiTimer is called by SCSIPORT, and when my function returns (or at
some
time in the process of invoking my timer) SCSIPORT then officially
completes all SRBs with the above mentioned flag set.

As has been suggested many times on this list, you could just do a
RequestComplete from within the timer. But, in my driver I have more
direct access to the data structures in the thread. Also, if one were
to
look through my source and ignore the timer for the moment, everything
is
structured as I think it should be. It’s more intuitive to do a
RequestComplete right when you have completed the request, not at some
arbitrary time later in a timer. Second to last, I believe it “cleans
the
SRBs” around other callbacks than just HwScsiTimer, including StartIo.
My
final excuse is that the DDK docs never warn against calling
ScsiPortNotification outside of SCSIPORT context. As a matter of fact,
the
documentation seems to know nothing about any of the SCSIPORT
limitations
I’ve been fighting with over the last couple weeks…

Jason

On 01/09/02, ““Jay Talbott” ” wrote:
> I have a rather unique SCSI miniport implementation I’m trying to get
> working.
>
> The actual device is a drive that connects to the PC via the serial
> port (yes, it’s not exactly fast, but that’s not the point here). The

> drive has it’s own communication protocol, but needs to look to the
> system as if it’s a SCSI drive on a SCSI HBA.
>
> Note that this only needs to work for Windows 2000 and XP (and
> beyond?). No need to be compatible with Windoze 95/98/ME. So, I’ve
> broken the rules regarding miniports and used some of the standard
> Windows 2000/XP kernel driver APIs, and linked to the additional
> libraries in my sources file. I know that this is, shall we say, “not

> recommended”, but since I have to call another driver (in this case,
> the serial port driver), I need to be able to call IoCallDriver()
> (amoungst other APIs), so I have to do it this way.
>
> Since the device is actually on the serial port, I’ve used
> IoGetDeviceObjectPointer() to get a pointer to the serial port’s
> device object so that I can then create my own IRPs to send to it to
> do the low level reads and writes to/from the hardware. Of course,
> since those IRPs may complete asynchronously, I need to be able to
> wait until they are completed as I send each IRP. This requires
> running in a thread at PASSIVE_LEVEL so that I can perform the wait,
> which means I must have an independent thread running outside of the
> context of the miniport routines, since the miniport StartIo and Timer

> routines all run at raised IRQL under locks. And since the miniport
> does not handle the serial interrupt itself, I can’t use a miniport
> interrupt routine for notification of the completion of each IRP sent
> to the serial port. So I’ve created an independent processing thread
> to do all of the actual I/O processing of each SRB which uses
> IoBuildSynchronousFsdRequest() to create IRPs to send the the serial
> port and then waits on an event for completion.
>
> The problem is that since this thread runs outside of the miniport
> context, I have no means to call
> ScsiPortNotification(RequestComplete,…) once all of the data
> transfer between the PC and the drive is complete. As has been
> discussed on this list in the past, calls to ScsiPortXXX functions
> outside of the context of the miniport context are seemingly ignored,
> and thus the SRBs end up timing out instead of being completed.
>
> Does anybody know of a solution around this that I can make work?
> Other than the SRBs timing out because I can’t complete them when I’m
> done, pretty much everything else about my implementation is now
> working. But I desparately need a means for somehow calling
> ScsiPortNotification() (or a means to get a callback function called
> in miniport context) when I complete each request.
>
> Note that a solution bypassing the serial port driver is not
> desirable. Ignoring the conflict issues, the general architecture of
> this driver has to be able to support talking to other variations of
> my client’s hardware that can connect to the PC by other means
> (parallel, add-in card, etc.). Thus, if at all possible, a solution
> like I have implemented where I am calling an underlying driver to do
> the actual low-level communications with the device is desired since
> it is easily modified for other underlying hardware implementations.
>
> Any and all ideas would be greatly appreciated.
>
> Thanks,
>
> - Jay
>
> Jay Talbott
> Principal Consulting Engineer
> SysPro Consulting, LLC
> 3519 E. South Fork Drive
> Suite 201
> Phoenix, AZ 85044
> (480) 704-8045
> xxxxx@sysproconsulting.com http://www.sysproconsulting.com
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com To
> unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: xxxxx@storagecraft.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

> In my “foreign” thread I still call ScsiPortNotification(RequestComplete

…) because that function only sets a flag in the SRB saying it needs to
be completed, then it returns.

Wrong. It puts the SRB to SCSIPORT’s internal list, guarded by “miniport context lock”.
ScsiPortNotification does not grab any locks, thus it is assumed to be called from the miniport context.
Real completion is done on quitting the miniport context.
If this list is not empty, ScsiPortCompletionDpc is scheduled, which processes request completions out of the miniport context.

It does this same behavior in or out of
SCSIPORT context, and at any IRQL.

No, calling this out of the miniport context can possibly damage the list and cause BSOD.

As has been suggested many times on this list, you could just do a
RequestComplete from within the timer.

Yes, HwTimer is called in the miniport context.

final excuse is that the DDK docs never warn against calling
ScsiPortNotification outside of SCSIPORT context.

This is very, very strange.

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

> Things would be so simple if SCSIPORT and or STORPORT did not have that

STUPID clan/family concept.

I also consider these “interface types” in HwFindAdapter as a stupid thing.
That’s why our SCSIPORT replacement does not use them, it provides full access to the underlying PDO and lower DO instead.
The miniport will be able to call any PnP functions or send PnP IRPs to check all bus-specific stuff.

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

Note: IOCTL_SCSI_MINIPORT can only be sent at PASSIVE_LEVEL. BSOD if you submit it at DISPATCH_LEVEL.
-DH
----- Original Message -----
From: “Gary Little”
To: “NT Developers Interest List”
Sent: Thursday, January 10, 2002 11:08 AM
Subject: [ntdev] RE: ScsiPortNotification(RequestComplete,…)

> Jay,
>
> I’m exploring using an SRB queue, and a DDK edge to the mini-port that uses
> a PASSIVE_LEVEL thread to send an IRP with IOCTL_SCSI_MINIPORT (???) to
> SCSIPORT with a command to purge the queue. However, the trick is getting
> the little beastie to load, and call the FindAdapter routine. That is almost
> impossible as a WDM driver that has no resources, or any documentation as to
> how the bus driver that enumerated the SCSI driver should respond to WDM
> IRPs. Right now I am loading as a legacy driver with no interrupts on a
> PCIBus.
>
> Things would be so simple if SCSIPORT and or STORPORT did not have that
> STUPID clan/family concept. The design of those two subsystems encourages
> developers to violate the rules to provide virtual SCSI mini-ports for bus’s
> that do not fit the standard mold.
>
> Gary G. Little
> Broadband Storage, Inc.
> xxxxx@broadstor.com
> xxxxx@inland.net
> (949) 7372731
>
> -----Original Message-----
> From: Jay Talbott [mailto:xxxxx@sysproconsulting.com]
> Sent: Tuesday, January 08, 2002 3:30 PM
> To: NT Developers Interest List
> Subject: [ntdev] ScsiPortNotification(RequestComplete,…)
>
> I have a rather unique SCSI miniport implementation I’m trying to get
> working.
>
> The actual device is a drive that connects to the PC via the serial port
> (yes, it’s not exactly fast, but that’s not the point here). The drive
> has it’s own communication protocol, but needs to look to the system as
> if it’s a SCSI drive on a SCSI HBA.
>
> Note that this only needs to work for Windows 2000 and XP (and beyond?).
> No need to be compatible with Windoze 95/98/ME. So, I’ve broken the
> rules regarding miniports and used some of the standard Windows 2000/XP
> kernel driver APIs, and linked to the additional libraries in my sources
> file. I know that this is, shall we say, “not recommended”, but since I
> have to call another driver (in this case, the serial port driver), I
> need to be able to call IoCallDriver() (amoungst other APIs), so I have
> to do it this way.
>
> Since the device is actually on the serial port, I’ve used
> IoGetDeviceObjectPointer() to get a pointer to the serial port’s device
> object so that I can then create my own IRPs to send to it to do the low
> level reads and writes to/from the hardware. Of course, since those
> IRPs may complete asynchronously, I need to be able to wait until they
> are completed as I send each IRP. This requires running in a thread at
> PASSIVE_LEVEL so that I can perform the wait, which means I must have an
> independent thread running outside of the context of the miniport
> routines, since the miniport StartIo and Timer routines all run at
> raised IRQL under locks. And since the miniport does not handle the
> serial interrupt itself, I can’t use a miniport interrupt routine for
> notification of the completion of each IRP sent to the serial port. So
> I’ve created an independent processing thread to do all of the actual
> I/O processing of each SRB which uses IoBuildSynchronousFsdRequest() to
> create IRPs to send the the serial port and then waits on an event for
> completion.
>
> The problem is that since this thread runs outside of the miniport
> context, I have no means to call
> ScsiPortNotification(RequestComplete,…) once all of the data transfer
> between the PC and the drive is complete. As has been discussed on this
> list in the past, calls to ScsiPortXXX functions outside of the context
> of the miniport context are seemingly ignored, and thus the SRBs end up
> timing out instead of being completed.
>
> Does anybody know of a solution around this that I can make work? Other
> than the SRBs timing out because I can’t complete them when I’m done,
> pretty much everything else about my implementation is now working. But
> I desparately need a means for somehow calling ScsiPortNotification()
> (or a means to get a callback function called in miniport context) when
> I complete each request.
>
> Note that a solution bypassing the serial port driver is not desirable.
> Ignoring the conflict issues, the general architecture of this driver
> has to be able to support talking to other variations of my client’s
> hardware that can connect to the PC by other means (parallel, add-in
> card, etc.). Thus, if at all possible, a solution like I have
> implemented where I am calling an underlying driver to do the actual
> low-level communications with the device is desired since it is easily
> modified for other underlying hardware implementations.
>
> Any and all ideas would be greatly appreciated.
>
> Thanks,
>
> - Jay
>
> Jay Talbott
> Principal Consulting Engineer
> SysPro Consulting, LLC
> 3519 E. South Fork Drive
> Suite 201
> Phoenix, AZ 85044
> (480) 704-8045
> xxxxx@sysproconsulting.com
> http://www.sysproconsulting.com
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@broadstor.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
>
> —
> You are currently subscribed to ntdev as: xxxxx@syssoftsol.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

But you can trigger an event for which a PASSIVE_LEVEL thread is waiting.
The thread then does the management of the IRP and IoCallDriver.

Gary G. Little
Broadband Storage, Inc.
xxxxx@broadstor.com
xxxxx@inland.net
(949) 7372731

-----Original Message-----
From: Dave Harvey [mailto:xxxxx@syssoftsol.com]
Sent: Friday, January 11, 2002 6:21 AM
To: NT Developers Interest List
Subject: [ntdev] RE: ScsiPortNotification(RequestComplete,…)

Note: IOCTL_SCSI_MINIPORT can only be sent at PASSIVE_LEVEL. BSOD if you
submit it at DISPATCH_LEVEL.
-DH
----- Original Message -----
From: “Gary Little”
To: “NT Developers Interest List”
Sent: Thursday, January 10, 2002 11:08 AM
Subject: [ntdev] RE: ScsiPortNotification(RequestComplete,…)

> Jay,
>
> I’m exploring using an SRB queue, and a DDK edge to the mini-port that
uses
> a PASSIVE_LEVEL thread to send an IRP with IOCTL_SCSI_MINIPORT (???) to
> SCSIPORT with a command to purge the queue. However, the trick is getting
> the little beastie to load, and call the FindAdapter routine. That is
almost
> impossible as a WDM driver that has no resources, or any documentation as
to
> how the bus driver that enumerated the SCSI driver should respond to WDM
> IRPs. Right now I am loading as a legacy driver with no interrupts on a
> PCIBus.
>
> Things would be so simple if SCSIPORT and or STORPORT did not have that
> STUPID clan/family concept. The design of those two subsystems encourages
> developers to violate the rules to provide virtual SCSI mini-ports for
bus’s
> that do not fit the standard mold.
>
> Gary G. Little
> Broadband Storage, Inc.
> xxxxx@broadstor.com
> xxxxx@inland.net
> (949) 7372731
>
> -----Original Message-----
> From: Jay Talbott [mailto:xxxxx@sysproconsulting.com]
> Sent: Tuesday, January 08, 2002 3:30 PM
> To: NT Developers Interest List
> Subject: [ntdev] ScsiPortNotification(RequestComplete,…)
>
> I have a rather unique SCSI miniport implementation I’m trying to get
> working.
>
> The actual device is a drive that connects to the PC via the serial port
> (yes, it’s not exactly fast, but that’s not the point here). The drive
> has it’s own communication protocol, but needs to look to the system as
> if it’s a SCSI drive on a SCSI HBA.
>
> Note that this only needs to work for Windows 2000 and XP (and beyond?).
> No need to be compatible with Windoze 95/98/ME. So, I’ve broken the
> rules regarding miniports and used some of the standard Windows 2000/XP
> kernel driver APIs, and linked to the additional libraries in my sources
> file. I know that this is, shall we say, “not recommended”, but since I
> have to call another driver (in this case, the serial port driver), I
> need to be able to call IoCallDriver() (amoungst other APIs), so I have
> to do it this way.
>
> Since the device is actually on the serial port, I’ve used
> IoGetDeviceObjectPointer() to get a pointer to the serial port’s device
> object so that I can then create my own IRPs to send to it to do the low
> level reads and writes to/from the hardware. Of course, since those
> IRPs may complete asynchronously, I need to be able to wait until they
> are completed as I send each IRP. This requires running in a thread at
> PASSIVE_LEVEL so that I can perform the wait, which means I must have an
> independent thread running outside of the context of the miniport
> routines, since the miniport StartIo and Timer routines all run at
> raised IRQL under locks. And since the miniport does not handle the
> serial interrupt itself, I can’t use a miniport interrupt routine for
> notification of the completion of each IRP sent to the serial port. So
> I’ve created an independent processing thread to do all of the actual
> I/O processing of each SRB which uses IoBuildSynchronousFsdRequest() to
> create IRPs to send the the serial port and then waits on an event for
> completion.
>
> The problem is that since this thread runs outside of the miniport
> context, I have no means to call
> ScsiPortNotification(RequestComplete,…) once all of the data transfer
> between the PC and the drive is complete. As has been discussed on this
> list in the past, calls to ScsiPortXXX functions outside of the context
> of the miniport context are seemingly ignored, and thus the SRBs end up
> timing out instead of being completed.
>
> Does anybody know of a solution around this that I can make work? Other
> than the SRBs timing out because I can’t complete them when I’m done,
> pretty much everything else about my implementation is now working. But
> I desparately need a means for somehow calling ScsiPortNotification()
> (or a means to get a callback function called in miniport context) when
> I complete each request.
>
> Note that a solution bypassing the serial port driver is not desirable.
> Ignoring the conflict issues, the general architecture of this driver
> has to be able to support talking to other variations of my client’s
> hardware that can connect to the PC by other means (parallel, add-in
> card, etc.). Thus, if at all possible, a solution like I have
> implemented where I am calling an underlying driver to do the actual
> low-level communications with the device is desired since it is easily
> modified for other underlying hardware implementations.
>
> Any and all ideas would be greatly appreciated.
>
> Thanks,
>
> - Jay
>
> Jay Talbott
> Principal Consulting Engineer
> SysPro Consulting, LLC
> 3519 E. South Fork Drive
> Suite 201
> Phoenix, AZ 85044
> (480) 704-8045
> xxxxx@sysproconsulting.com
> http://www.sysproconsulting.com
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@broadstor.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
>
> —
> You are currently subscribed to ntdev as: xxxxx@syssoftsol.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: xxxxx@broadstor.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