Subject: Re: In-kernel support for Cabletron scsi ethernet adaptor
To: None <marcb@bms.itg.telstra.com.au>
From: Ian Dall <Ian.Dall@dsto.defence.gov.au>
List: port-pc532
Date: 01/30/1997 10:22:58
Marc Boschma <marcb@bms.itg.telstra.com.au> writes:

  > I think Jason outlined the intergration between the SCSI driver and the
  > network.

  > Phil Budne <budd@cs.bu.edu> wrote:

  >> I've wondered if it would be easier to write a real driver that
  >> depends on a user process for context (ie; a process which does an
  >> ioctl() which never returns) for the scsi I/O.

  > Phil, could you expand on this, as I think I'm missing the whole thrust of
  > this thought...


I've started looking at this seriously (instead of just theorising
which is all I did before).  I think that Phil's concern is valid and
Jasons code won't quite work, though the reason Jasons code won't
work is arguably due to a bug in the generic scsi code.

The problem is you want to use scsi_scsi_cmd() to read/write from the
device. scsi_scsi_cmd() (or something called by it) wants to put a
process to sleep until the scsi command completes *unless* it is
called with bp non zero when it assumes it is an internal kernel
operation. At interrupt time, there is no current process (or the
current process is random depending on how you look at it). Having a
process sitting around waiting for an ioctl which never completes is
one way of having a process which can be validly put to sleep. The
trouble is, that doesn't really fit with the way the interface code is
run I think.

As far as I can see, bp is not actually de-referenced anywhere until
the device layer xxx_done is called. So, I think you could set bf to
be non-null, supply your own xxx_done routine, call scsi_scsi_cmd()
and things would be OK. This seems a bit dodgy since someone (either
now or in the future) might assume the bf really points to a valid
struct buf.  A bit cleaner would be to add an extra flag to say "don't
sleep". There is actually a SCSI_NOSLEEP flag, which is asserted must
be true if bp is non null. However, that flag is not actually used to
decide whether to send a process to sleep! I think the thing to do is
fix it (I think it is called scsi_exec_xs()) so it does the moral
equivalent of:

  if(!(bp || flags & SCSI_NOSLEEP))
    while(! done)
     tsleep(...)

or perhaps don't test for bp at all since if bp is non null,
SCSI_NOSLEEP must be set.

Then I think the rest is not too bad. In fact, I would think it is easier
than a normal interface.

Ian