bug-hurd
[Top][All Lists]
Advanced

[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, 16 Oct 2011 12:50:24 +0200

Hi,

Samuel Thibault:
> I'm afraid I just can't afford spending time on taking part of the
> details. I see that you are understanding each other, so it should be
> fine.

So i present my current sketch mainly to Olaf for review and
hopefully for intermediate approval.

This proposal shall cover RPC definition and architecture impact. 
There is still some flesh to put on the bones. Especially the
userspace part is still riddling to me.

I have now dropped both, manual marshalling and function membership
in the interface struct device_emulation_ops.
(The latter could be re-introduced easily.)


(">>>" means that further investigation and sketching is needed.)

-----------------------------------------------------------------------
gnumach/include/device/device.defs

A new RPC is defined:

  routine device_transact_cd(
       in    device          : device_t;
       in    cmd             : ^ array[] of unsigned char;
       in    timeout         : unsigned int;
       in    flags           : unsigned int;
       in    data_size       : unsigned int;
       in    write_data      : ^ array[] of unsigned char;
       out   outcome         : unsigned int;
       out   read_data       : ^ array[] of unsigned char;
       out   sense_bytes     : ^ array[] of unsigned char;
       );

The parameter .timeout is not yet supported by the existing transaction
calls in gnumach. But it is so desirable that i would consider to
beef up the parameters of these existing calls. (Impact on other parts
of gnumach has not yet been explored.)

The parameters .flags and .outcome shall be used for behavior control
and resulting information about unusual events during the transaction.
>>> It has still to be decided which sg_io_hdr aspects will be mapped
>>> onto these parameters.

-----------------------------------------------------------------------

>>> Where to implement the userspace code ?

>>> The userspace function has to pick the supported parameters from
>>> Linux struct sg_io_hdr, do the RPC, put the supported result parameters
>>> into the struct and set the unsupported ones to default values.


-----------------------------------------------------------------------
gnumach/device/ds_routines.c

The RPC receiver in the kernel:

io_return_t
ds_device_transact_cd (device_t dev,
                       unsigned char *cmd, 
                       mach_msg_type_number_t cmd_len,
                       unsigned int timeout,
                       unsigned int flags,
                       unsigned int data_size,
                       unsigned char *write_data,
                       mach_msg_type_number_t write_data_len,
                       unsigned int *outcome,
                       unsigned char *read_data,
                       mach_msg_type_number_t read_data_len,
                       unsigned char *sense_bytes,
                       mach_msg_type_number_t sense_bytes_len)
{   
  /* Refuse if device is dead or not completely open.  */
  if (dev == DEVICE_NULL)
    return D_NO_SUCH_DEVICE;

  /* Call dispatcher in gnumach/linux/dev/glue/block.c
     which decides whether SCSI CD, ATAPI CD, or unsuitable device
  */
  return device_transact_cd (dev, cmd, cmd_len, timeout, flags, data_size,
                             write_data, write_data_len,
                             outcome, read_data, read_data_len,
                             sense_bytes, sense_bytes_len);
}

-----------------------------------------------------------------------
gnumach/linux/dev/glue/block.c

io_return_t
device_transact_cd (device_t dev,
                    unsigned char *cmd,
                    mach_msg_type_number_t cmd_len,
                    unsigned int timeout,
                    unsigned int flags,
                    unsigned int data_size,
                    unsigned char *write_data,
                    mach_msg_type_number_t write_data_len,
                    unsigned int *outcome,
                    unsigned char *read_data,
                    mach_msg_type_number_t read_data_len,
                    unsigned char *sense_bytes,
                    mach_msg_type_number_t sense_bytes_len)
{
  struct block_data *bd;

  bd = dev->emul_data;

  if (scsi_blk_major (MAJOR (bd->dev))
        {

          /* >>> scsi transport by call to scsi.c */;

        }
  else if (MAJOR (bd->dev) == IDE0_MAJOR ||
           MAJOR (bd->dev) == IDE1_MAJOR ||
           MAJOR (bd->dev) == IDE2_MAJOR ||
           MAJOR (bd->dev) == IDE3_MAJOR)
        {

          /* >>> ide transport by call to ide-cd.c */;

        }
  else
        return D_INVALID_OPERATION;

  /* >>> bring result into the output parameters */;

  return D_SUCCESS;
}

The calls for SCSI and ATAPI may decide to return D_INVALID_OPERATION
if the device is not a CD drive.

-----------------------------------------------------------------------
gnumach/linux/src/drivers/block/ide.c

To obtain (ide_drive_t *) from kdev_t, there exists:
  /*
   * get_info_ptr() returns the (ide_drive_t *) for a given device number.
   * It returns NULL if the given device number does not match any present
     drives.
   */
  static ide_drive_t *get_info_ptr (kdev_t i_rdev)


New function to check whether drive is a IDE ATAPI CDROM device
(ide_disk is not ATAPI. ide_tape is not block. I have no clue about them)
gnumach/linux/src/drivers/block/ide.h
    defines ide_media_t value ide_cdrom
    and ide_media_t ide_drive_t.media

static int
is_atapi_cd(ide_drive_t *drive)
{
  return (drive->media == ide_cdrom);
}

>>> Need a glue function which checks this. If appropriate. it sets up
>>> this struct which is defined in gnumach/linux/src/drivers/block/ide.h

  struct packet_command {
        unsigned char *buffer;
        int buflen;
        int stat;
        struct atapi_request_sense *sense_data;
        unsigned char c[12];
  };

>>> Then it calls the existing ATAPI CD transaction function from:
>>> gnumach/linux/src/drivers/block/ide-cd.c:

        static
        int cdrom_queue_packet_command (ide_drive_t *drive,
                                        struct packet_command *pc);

>>> and fills its reply parameters.


-----------------------------------------------------------------------
gnumach/linux/src/drivers/scsi/scsi.c

To obtain Scsi_Device from kdev_t there will be a new function

static Scsi_Device
*get_scsi_cdrom_device(kdev_t dev)
{
  if (MAJOR(dev) == SCSI_CDROM_MAJOR)
         return scsi_CDs[MINOR(dev)].device;
  return NULL;
}

>>> Need a glue function which checks this. If appropriate. it sets up
>>> this struct which is not really defined but only described in a
>>> comment in scsi_ioctl_send_command() about its (void *) parameter:

        /*
         * 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[];
         * };

>>> Then it calls the existing SCSI transaction function from:
>>> gnumach/linux/src/drivers/scsi/scsi.c

        int scsi_ioctl_send_command(Scsi_Device *dev, void *buffer)

>>> and fills its reply parameters.

-----------------------------------------------------------------------


Have a nice day :)

Thomas




reply via email to

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