[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Interface for SCSI transactions ?

From: Thomas Schmitt
Subject: Re: Interface for SCSI transactions ?
Date: Sun, 09 Oct 2011 12:48:37 +0200


> Well, the problem is that if we decide on a solution you don't like, you
> won't be very motivated to follow it :-) That's why I'd prefer a
> solution in consensus between all involved parties, i.e. You, Samuel,
> and me.

In general, this mindfulness is surely helpful to gain co-workers.
But in this special case i would have accepted any existing solution
and be it ever so odd.
So i can live happily with any decision about the form of a newly
introduced solution.

My remorse is only about not creating an odd protrusion in the
system interface of Hurd.

About RPC definition:

> Furthermore considering that the kernel
> driver interface will be temporary anyways, I'm not really concerned
> about compromising the Hurd architecture...

Time is running slowly in the Hurd universe.
A temporary decicision can last for quite some time.

[about future widening of the parameter list] :
> we can just as well
> explicitly introduce a new RPC with different parameters, while keeping
> the original one unchanged. That's the proper way to provide
> client/server compatibility in the Hurd.

So the case of fanned-out parameters could start with a narrow set
of parameters which currently are served by the SCSI or ATAPI transaction
calls in gnumach.

> A more interesting question is: in what direction we keep compatibility?

In any case towards userspace.
So it would be wise to design a wide parameter set for userspace
even if most of it is already dropped at the RPC.

> I don't think it's necessary to arbitrarily allow mixing old/new servers
> and clients.

If it is ensured that both sides of RPC get updated in sync,
then we have much freedom with later changing the RPC definition.

> It's enough to know that we can
> easily keep compatibility at the RPC level whenever we want/need to --
> without any manual marshalling ugliness :-)

So we decide for fanned-out RPC with only those parameters which
currently can be served by the two existing transaction calls in

> Of course I still consider (a) or (b) the best options :-)

We are getting in sync. :)

(a) looks like the winner.

> I'm sure you actually mean "(unsigned int)-1" -- which is only
> equivalent to 0xffffffff on machines with 32 bit int :-)

This proposal took into respect the possibility of parameter transport
as byte array, where we would have to assume a particular word legth.

One can decide for each of both. 0xffffffff would mean more than a
month of execution time for a single transaction.
The only indispensible assumption here is: sizeof(int) >= 4.

The existing gnumach functions which i want to use:

For drives attached to SCSI controllers:

  int scsi_ioctl_send_command(Scsi_Device *dev, void *buffer)
with this comment about the meaning of buffer
     * The structure that we are passed should look like:
     * struct sdata {
     *  unsigned int inlen;
     *  unsigned int outlen;
     *  unsigned char  cmd[];  # However many bytes are used for cmd.
     *  unsigned char  data[];
     * };

For drives connected to IDE/ATAPI controllers:

  int cdrom_queue_packet_command (ide_drive_t *drive,
                                  struct packet_command *pc)
  struct packet_command {
        unsigned char *buffer;
        int buflen;
        int stat;
        struct atapi_request_sense *sense_data;
        unsigned char c[12];

sense_data is equivalent to sdata.data[0:17] in case of error reply.
  struct atapi_request_sense {
        unsigned char error_code : 7;
        unsigned char valid      : 1;
        byte reserved1;
        unsigned char sense_key  : 4;
        unsigned char reserved2  : 1;
        unsigned char ili        : 1;
        unsigned char reserved3  : 2;
        byte info[4];
        byte sense_len;
        byte command_info[4];
        byte asc;
        byte ascq;
        byte fru;
        byte sense_key_specific[3];
This corresponds to SCSI specs: SPC-3 4.5.3 Fixed format sense data, Table 26.
reserved3 is in SPC-3: FILEMARK, EOM with reference to SSC-2 (i.e. tapes).
SPC allows additional sense bytes after sense_key_specific.

packet_command.c[12] is equivalent to sdata.cmd[].
The restriction to a command length of 12 is covered by MMC-6. So no
16-byte commands should occur with a CD driver.

Both have the frightening habit to determine a command's length from
its function code. This is not completely covered by SCSI specs.
(SPC-3, Table 11, Group Code values, describes an opcode 0x7F with
 variable command length.)
Linux had reason to introduce a command length parameter in its
struct sg_io_hdr.

I still have to find out, how cdrom_queue_packet_command()
determines the transfer direction of payload (read or write ?).
My suspicion is that it allows the CD drive to decide.
In gnumach/linux/src/drivers/block/ide-cd.c:
  static void cdrom_pc_intr (ide_drive_t *drive)
        /* Read the interrupt reason and the transfer length. */
        ireason = IN_BYTE (IDE_NSECTOR_REG); 
        /* The drive wants to be written to. */
        if ((ireason & 3) == 0) {

        /* Same drill for reading. */
        else if ((ireason & 3) == 2) {
Linux had reason to introduce a caller defined transfer direction.
(Maybe because only the IDE driver is willing to let the drive decide.)

General design considerations:

[putting cars on transport vehicles]
> The Tunnel trains can transport passengers directly, but they can *also*
> cars. This is useful, as taking the car along can be convenient for the
> travelers before/after passing the Tunnel;

That's what i deem appealing with the idea of a generic system call.
It would solve in general the problem of reaching gnumach from hurd.

But this is actually far outside the scope of my work.
So i submit myself to what experienced Hurd developers think is best
in the current situation.

struct device_emulation_ops or not:

> Well, obviously it's not a generic device_transact() call if we use
> SG-specific parameters

That's my remorse.

> This is
> indeed a case polymorphism -- and for the reasons explained above, it's
> not useful here :-)

So we get in sync once more.
A fanned-out RPC has no place in struct device_emulation_ops.
Especially if we explicitly plan it to be accompanied by improved
versions in future.

(I would also question the reason for the existence of
 if it really only serves for networking.)

> Now bypassing the device_emulation interface for just one new device
> call, would be really inconsistent and confusing;

I would see it as breaking a bad tradition.

> so passing it through
> the device_emulation layer instead is probably preferable.

I would see this as further cementing a bad tradition.

> However, as
> this call is not going to be used for anything else, it really doesn't
> matter whether it's explicitly specific, or pretends to be generic

This should be reason enough to make it non-generic.

Linux compatibility aspects:

> I somehow managed to temporarily forget the most important reason why it
> makes sense to stick to whatever the Linux interface does: as the actual
> driver we will use in the future will most likely come directly from
> Linux, using any substantially different interface would be extra
> effort ... So better keep close to Linux, unless there is a really really
> good reason not to.

If we use the Linux struct sg_io_hdr in userspace, then we are halfways
prepared for that. A few extensions learned from FreeBSD and Solaris
would do no harm.
When ioctl(SG_IO) gets implemented on the kernel side, then one will
have to define a fat RPC to connect it to the userspace struct which
then will be re-composed to struct sg_io_hdr on the kernel side.

So, if the decision is for fanned-out parameters, then i would
re-unify my proposed in- and out-structs to a single struct which
begins by the same members as Linux struct sg_io_hdr.

This would at least ease porting of CD userspace drivers from Linux
to Hurd.


Have a nice day :)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]