Hi everyone,
I think everyone just hates this subject so let’s kill this beast once and
forever. I’m talking about virtual SCSI miniports that complete requests
w/o use of either HwTimer or call to ScsiPortNotification(
RequestTimerCall, … ).
I’ll tell the sequence of actions SCSI miniport driver will perform to
complete the request and you’ll tell me where it can (you think) block and
why. I still cannot get why it should block and cannot make it block as
well…
-
SCSI miniport registers itself within SCSIPORT with
MultipleRequestsPerLu set to TRUE in the HW_INITIALIZATION_DATA structure
it passes to the ScsiPortInitialize( … ). Will be described below why it
must be done. -
SCSI miniport is called at HwStartIo entry point with some SRB with some
SCSI opcode to execute (inquiry, read, write, mode sense etc).
SCSIPORT holds spinlocks…
- Routine for HwStartIo creates work item for this SRB (allocates memory,
sets back pointers to SRB and SCSI miniport itself etc) and asks SCSIPORT
for new request by the call to ScsiPortNotification( NextRequest, < target
address > ). And RETURNS from the HwStartIo with SRB_STATUS_PENDING
and ->SrbStatus set to SRB_STATUS_PENDING as well.
We’re not in SCSIPORT any more and SCSIPORT does not hold any spinlocks.
-
Work item callback now get’s called by the system at PASSIVE_LEVEL and
in the context of the system. It does all required manipulations
(calls Zw* code to read/write the files, calles the TDI clinet code to
send/receive data over the TCP connection etc) to process SCSI opcode in
SRB. Then in constructs new SRB with special vendor SCSI opcode (let it be
0xFE), set’s new SRB data buffer ptr with the address of old “real” SRB
(stored in the work item memory at step 3) and calls SCSI miniport
by it’s pointers stored in work item (step 3) as well. -
SCSI miniport is called at HwStartIo entry with this SRB constructed at
step 4 with opcode 0xFE and old SRB to complete at SRB’s data buffer ptr.
Miniport differs opcode 0xFE from the others and just calls
ScsiPortNotification( RequestComplete, … ) for this old SRB passed in
data buffer ptr, calls again ScsiPortNotification( RequestComplete, … )
for actual SRB it was called with (constructed at step 4 with 0xFE opcode)
and calls ScsiPortNotification( NextRequest, < target address > ) to ask
SCSIPORT for new requests.
Attention! That’s why we enabled multiple requests per logical unit at step
- If we would not do it we’ll deadlock at step 5 as SCSI miniport would
not be able to process the passed SRB until it did not
complete previous one. It just will not get it.
As the call to the SCSI miniport to complete the previous request was done
from the work item and not from the SCSI miniport context (when SCSIPORT
spinlocks are hold) I see no problem at all. SMP machine or MMP or
uniprocessor at all.
Maybe you’ll point me where problem is?
Again, there is no problem in completing multiple SRBs in HwStartIo as
we’ve set we can process multiple requests per LU and it’s our bussiness
how many we’ve enqueued inside the miniport.
Any comments, ideas and remarks welcomed!!!
P.S. No LU queue lenght comments, OK? There can be tons of workarounds as
well. Separate LU to complete requests per every LU. Nobady will touch your
private LU responding as “processor device” to SCSI inquiry except you in
your driver. No need to warry.
With respect,
Anton Kolomyeytsev
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