will the /devices/ paths for blk2scsa devices use generic names
or will the /devices paths contain driver names?

an example of a generic name (for a usb disk device) is:
        /devices/pci at 0,0/pci104d,81e6 at 1d,7/storage at 3/disk at 0,0:g

an example of a non-generic name (for an ata disk device) is:
        /devices/pci at 0,0/pci-ide at 1f,2/ide at 0/cmdk at 0,0:h

ed

On Tue, Nov 27, 2007 at 12:50:09AM -0800, Garrett D'Amore wrote:
> I've found in the course of trying to add support for hotplug properly
> to the blk2scsa driver, that some changes to the API were necessary.
> While here, I made some other aesthetic changes which are easy to do
> now, but would require more annoying casework later.
>
> A full updated spec is attached.
>
> The main differences here relative to the first spec are:
>
> * b2s_hba renamed to b2s_nexus
> * b2s_target renamed to b2s_leaf
> * structure passed for nexus allocation, instead of array of pointers
> * request entry point associated with nexus structure instead of leaf
> * addition of target and lun members to request structure
> * support for non-zero lun numbers (multiple luns per target)
> * inquiry data now handled via separate request command, rather than at
> registration
> * no separate allocation/deallocation for leaf structure, done by leaf
> attach/detach automatically (possibly deferred for hotplug safety).
>
> I'm extending the case timer another week to allow for the extra review
> required.  Sorry, for the late changes, but thanks!
>
>
> Generic Block Device to SCSA Translation Layer
> Functional Specification
>
> Garrett D'Amore (gdamore at sun.com)
> Nov 27, 2007
>
>
> CHAPTER 1:  Introduction
>
> There are an ever growing number of digital memory formats, as well as
> other kinds of storage media in the market today.  Historically, Solaris
> has had only limited support for most of them, when connected through a
> USB or IEEE 1394 media reader.
>
> Modern laptops and mobile computing devices are now shipping with slots
> for these readers that are not connected via USB interfaces.  Solaris needs
> needs to provide support for media in these slots in a manner similar to
> how they are presented via USB.
>
> Writing a full block device driver is one possible way, but, unfortunately,
> it also means implementing a number of components besides the block
> driver itself, as various userland components exist (such as libsmedia)
> which only know how to talk to certain block devices.
>
> The sd(7d) device driver is the most common mass storage block driver, and
> it is also how most removable media is presented to the system.  Therefore,
> it already has most of the hooks necessary to support userland volume
> management, format and VTOC management, etc.
>
> Unfortunately, sd(7d) expects to be able to talk to a SCSI disk.  Busses
> such as USB and IEEE1394 often present mass storage using some subset of
> the SCSI command set, so combined with thin translation layers such as
> scsa1394 or scsa2usb, it is possible to emulate a SCSI bus sufficiently
> that these mass storage devices are usable with sd(7d).
>
> Many of the intersting media formats, however, do not use any form of SCSI
> command set.  Sometimes the access method is quite different, even though
> the underlying media is still typically block-oriented.
>
>
> CHAPTER 2:  blk2scsa translation layer
>
> Our solution to this problem involves the creation of a new kernel/misc
> module, blk2scsa.  This module provides some straight-forward underlying
> APIs for block-oriented drivers to implement, and maps those APIs to an
> emulated SCSI bus and one or more emulated SCSI disk drives, so that these
> devices are now usable with sd(7d).
>
> This frees the block device driver from needing to implement most of the
> labeling, ioctl, or other complex portions of the block device and instead
> focus on just the core device access functionality.
>
> In a sample system, imagine a block device driver called "nvflash".  This
> device driver has two independent flash chips per instance, each of which
> is block oriented using 512 byte blocks, and can have a separate filesystem
> on it.  The plumbing might look like this:
>
>
> +----------+
> |  nvflash |
> |  driver  |
> |    +----------+      +----------------+        +--------------+
> +----+    blk2scsa |----> | (emulated bus) | -+---> | sd, target 0 |
>      +----------+      +----------------+  |     +--------------+
>                               |
>                        |     +--------------+
>                        +---> | sd, target 1 |
>                              +--------------+
>
> In the diagram above, the flash chips would be addressable as
> /dev/{rdsk,dsk}/cXt0d0 and /dev/{rdsk,dsk}/cXt1d0.
>
> Note that the actual flash chips could be removable (perhaps as if they
> were slots on a physical media reader), and the sd driver would handle
> them properly.  This would include automatic volume manager support
> by userland components, so that when a device is inserted it is
> automatically
> mounted and presented in a desktop GNOME session, for example.
>
> The emulated HBA will support auto-sense-request (cannot be disabled),
> and emulated targets will support the removable and hotpluggable properties
> if they were registered with them.
>
>
> CHAPTER 3:  Programming Interface
> =================================
>
> The following API is provided for target devices.
>
> Basic setup
> -----------
>
>  The device driver shall #include <sys/scsi/adapters/blk2scsa.h>
>
>  The device driver shall add -N misc/blk2scsa to its link line, so
>  that the run-time kernel loader can resolve the sybmols
>  appropriately.
>
>
> Types
> -----
>
> typedef struct b2s_nexus b2s_nexus_t;
>
>  The b2s_nexus_t structure is an opaque structure that is used as a handle
>  to the emulated host bus adapter.
>
> typedef struct b2s_leaf b2s_leaf_t;
>
>  The b2s_leaf_t structure is an opaque structure that is used as a handle
>  to the emulated disk device.
>
> typedef struct b2s_nexus_info b2s_nexus_info_t;
>
>  The b2s_nexus_info structure describes the nexus device that should be
>  allocated.  It has the following members:
>
>      int         nexus_version;
>      dev_info_t     *nexus_dip;
>      void           *nexus_private;
>      ddi_dma_attr_t *nexus_dma_attr;
>      boolean_t         (*nexus_request)(void *, struct b2s_request *);
>
>  The nexus_version field is used for versioning, and represents the version
>  of the API that the device driver is coded for.  It must be B2S_VERSION_0
>  in this specification.
>
>  The nexus_dip is the device node associated with the driver.
>
>  The nexus_private field is available for the device driver's own
>  use, and should point to nexus state.
>
>  The nexus_dma_attr is the DMA attributes describing the DMA
> capabilities of
>  the driver.  It may be NULL if the driver is incapable of DMA.
>
>  The nexus_request field is the entry point that the device driver
> implements
>  to handle I/O requests.  It is passed nexus_private as its first argument.
>  The second argument describes the request in further detail.  If the
> driver
>  handles the request (or queues it for handling), then it must return
>  B_TRUE.  If the driver is unwilling to accept the request, but a future
>  attempt might be successful, then it should return B_FALSE.  Please see
>  the description for b2s_request_t below.
>
> typedef b2s_leaf_info b2s_leaf_info_t;
>
>  The b2s_leaf_info structure describes a leaf device (emulated SCSI
>  disk) that should be attached to the system.  It has the following
>  members:
>
>      uint_t      leaf_target;
>      uint_t      leaf_lun;
>      uint32_t      leaf_flags;
>      const char  *leaf_unique_id;
>
>      uint32_t      target_flags;
>      boolean_t      (*target_request)(void *, struct b2s_request *);
>
>  The leaf_target and leaf_lun fields are target and lun numbers to
>  use for the emulated SCSI target.  (For example, the disk device node
>  /dev/dsk/cXtYdZs2, the leaf_target is represented by Y, and the leaf_lun
>  is represented by Z.)  The combination of these two fields must be unique
>  for a given leaf node.
>
>  The leaf_unique_id field is an ASCIIZ string containing a string that
>  uniquely identifies the device.  The system uses this to protect against
>  incorrect hotplug operations.  (I.e. insertion of a different leaf target
>  at the specified SCSI address, while the previous leaf was still open
>  by another consumer.)  It may be used in the formulation of device
>  identifiers and GUIDs as well.
>
>  The leaf_flags field can contain one of two flags:
>
>      B2S_LEAF_REMOVABLE - indicates that the leaf supports removable
>      media
>
>      B2S_LEAF_HOTPLUGGABLE - indicates that the leaf can be hot
>      plugged (including either removal or attachment.)
>
> typedef struct b2s_request b2s_request_t;
>
>  This structure is the fundamental handle used for tracking I/O requests
>  between the SCSA layer and the device driver.  It has the following
>  accessible members:
>
>      int        br_cmd;
>      uint64_t        br_lba;
>      uint64_t        br_nblks;
>      b2s_media_t    br_media;
>      b2s_inquiry_t    br_inquiry;
>      uint32_t        br_flags;
>
>  The br_cmd field is the command code for the operation.  See Commands
>  below for a full explanation.  This field is supplied by the blk2scsa.
>
>  The br_lba field is the logical block address associated with the request.
>  It will be supplied by the blk2scsa framework.  It is only valid when the
>  br_cmd field is B2S_CMD_READ or B2S_CMD_WRITE.
>
>  The br_nblks is the number of logical blocks for the request.  It will be
>  supplied by the blk2scsa framework.  It is only valid when the br_cmd
> field
>  is B2S_CMD_READ or B2S_CMD_WRITE.
>
>  The br_media field is a description of the media for the target.  It is
>  filled out by the driver in response to a B2S_CMD_GETMEDIA request.
>  See the description of b2s_media_t below.
>
>
>  The br_inquiry field contains inquiry data for the target, to be filled
>  out by the device driver in response to a B2S_CMD_INQUIRY request.
>  See the description of b2s_inquiry_t below.
>
>  The br_flags field is a bitfield of flags associated the request.  The
>  public flags, which are read-only supplied by the framework, are
>
>      B2S_REQUEST_FLAG_POLL - indicates that a synchronous request without
>      use of interrupts should be performed.  (Such as when sync()'ing
>      filesystems or performing a crash dump in response to a panic.)
>
>      B2S_REQUEST_FLAG_HEAD - indicates that the request should be placed at
>      the head of any queue, if possible.
>
>      B2S_REQUEST_FLAG_LOAD_EJECT - only valid with the B2S_CMD_STOP or
>      B2S_CMD_START commands, it indicates that the media should either be
>      loaded (B2S_CMD_START) or ejected (B2S_CMD_STOP) if possible.
>
>      B2S_REQUEST_FLAG_IMMED - if present, indicates that the driver should
>      not wait for the operation to complete on the device before returning
>      status with b2s_request_done().  It is only valid with the commands
>      B2S_CMD_FORMAT, B2S_CMD_START, and B2S_CMD_STOP commands.
>
> typedef struct b2s_media b2s_media_t;
>
>  This structure is used in response to B2S_CMD_GETMEDIA.  The device driver
>  shall supply information about the media  in the following fields:
>
>      uint64_t media_blksz;
>      uint64_t media_nblks;
>      uint64_t media_flags;
>
>  The media_blksz and media_nblks fields are used to report the size and
> total
>  number of logical blocks on the device.
>
>  The media_flags bit field can have the flag B2S_MEDIA_FLAG_READ_ONLY
> set to
>  indicate that the media loaded in the target is not writable.
>
> typedef struct b2s_inquiry b2s_inquiry_t;
>
>  This structure is used in rsponse to B2S_CMD_INQUIRY.  The device driver
>  shall set the following fields for data to include in a standard SCSI
>  inquiry:
>
>      const char *inq_vendor;
>      const char *inq_product;
>      const char *inq_revision;
>      const char *inq_serial;
>
>  The inq_vendor, inq_product, inq_revision, and inq_serial
>  fields are ASCIIZ strings used to identify the device.  Note that this
>  is for the target, and not for any removable media that may be present
>  in the target.  These strings are used to formulate the response to
>  SCSI inquiries, so if the device driver is able to, it should use
>  values that are suitable for SCSI-2.  (See ANSI X3.131-1994 for more
>  information.)  Note that the driver need not pad these strings with
> spaces.
>
>
> Functions
> ---------
>
> int b2s_mod_init(struct modlinkage *);
> int b2s_mod_fini(struct modlinkage *);
>
>  These routines are called at _init and _fini respectively, to set up
>  and clean up HBA related entries in the device driver's dev_ops field.
>  As a consquence, a blk2scsa dependent driver need not supply any cb_ops
>  or bus_ops structure on its own behalf.
>
> b2s_nexus_t *b2s_alloc_nexus(b2s_nexus_info_t *);
>
>  This allocates an initial emulated HBA structure, using the supplied
>  information.
>
> void b2s_free_nexus(b2s_nexus_t *);
>
>  This frees an unattached emulated HBA structure.
>
> b2s_leaf_t *b2s_attach_leaf(b2s_nexus_t *, b2s_leaf_info_t *);
>
>  This indicates that a leaf (disk) device has been physically
>  attached to the nexus (HBA).  Appropriate hotplug actions will be
>  performed to make the device accessible, if possible.  It returns
>  an opaque handle to the leaf on success, or NULL on failure.
>
> void b2s_detach_leaf(b2s_leaf_t *leaf);
>
>  This indicates that a leaf device has been physically detached from
>  the nexus, and exists solely to support hotplug operation.
>
> void b2s_request_mapin(b2s_request_t *req, caddr_t *addrp, size_t *lenp);
>
>  This ensures that the buffer associated with the request is mapped into
>  kernel address space, and returns the address and length of the buffer
>  associated with the request.
>
> void b2s_request_dma(b2s_request_t *req, uint_t *num, ddi_dma_cookie_t **c);
>
>  This returns the number of DMA cookies associated with the request, and
>  a pointer to an array of the actual cookies.  Note that requests are
>  pre-mapped by the framework if a suitable DMA attribute was supplied at
>  registration time.  Note also that the buffer will always be fully mapped.
>  That is, it will never be necessary for a driver to use ddi_dma_getwin().
>
> void b2s_request_done(b2s_request_t *req, int errno, size_t resid);
>
>  This is called by the driver when it has completed processing for a
> request.
>  The errno takes an error code (see Error Codes below), and the resid
>  indicates the number of residual bytes that were not transferred.
>
> int b2s_attach_nexus(b2s_nexus_t *);
>
>  This attaches the HBA (and any registered leaves) to the system.  The
>  target driver should call this as part of its attach(9e) processing.  It
>  return DDI_SUCCESS on success, DDI_FAILURE otherwise.
>
> int b2s_detach_nexus(b2s_nexus_t *);
>
>  This detaches the HBA from the system.  It returns DDI_SUCCESS on success,
>  DDI_FAILURE otherwise.
>
>
> Commands
> --------
>
> B2S_CMD_INQUIRY
>
>  This command is sent to the driver to retrieve a description of the
>  device in response to a SCSI inquiry.  The driver shall provide the
> details
>  in the br_inquiry field of the associated request.
>
> B2S_CMD_GETMEDIA
>
>  This command is sent to the driver to retrieve a description of the
>  media currently loaded.  The driver shall provide the details in the
>  br_media field of the associated request.
>
> B2S_CMD_START
>
>  This command is used to initialize the device for use.  If the
>  B2S_REQUEST_FLAG_LOAD_EJECT is also present, then the device shall
>  load any removable media, if possible.
>
> B2S_CMD_STOP
>
>  This command is used to cease use of the device. (At this point the
>  device may be powered down.)  If the B2S_REQUEST_FLAG_LOAD_EJECT is
>  present, then the device should attempt to eject any removable media.
>  This command also implictly includes the effects of B2S_CMD_SYNC.
>
> B2S_CMD_LOCK
> B2S_CMD_UNLOCK
>
>  These commands are used to engage or release any locking mechanism
>  preventing removal of the media.
>
> B2S_CMD_READ
> B2S_CMD_WRITE
>
>  These commands read or write blocks to/from the device.  The block address
>  to start at is indicated by the br_lba field of the request.  The number
>  of blocks to transfer is indicated by the br_nblks field.   The actual
>  data region can be determined using either the b2s_request_mapin() or
>  b2s_request_dma() functions (depending on whether or not DMA is to be
> used.)
>
> B2S_CMD_FORMAT
>
>  This command formats the media.  It shall not be possible to format media
>  while a reservation set with B2S_CMD_RESERVE is in effect.  No defect
>  list is supplied, so the driver is responsible to take whatever action
>  it deems appropriate.  If the B2S_REQUEST_FLAG_IMMED is set, then the
>  device should not wait for the format to complete before calling
>  b2s_request_done().
>
> B2S_CMD_SYNC
>
>  This command flushes any cached write data from the device to media.
>
>
> Errors
> ------
>
> The following error codes can be returned in response to a request using
> b2s_request_done().
>
> B2S_EOK
>
>  No error.  The operation completed successfully.
>
> B2S_ENOTSUP
>
>  The device does not support the requested operation.  (This should be
>  returned, if the device does not have a door lock, for example.)
>
> B2S_EFORMATTING
>
>  An attempt to access the device while it was formatting was made.
>
> B2S_ENOMEDIA
>
>  No media is present in a target with removable media.
>
> B2S_EMEDIACHG
>
>  The media may have changed since the last request was made.  This is
>  used to prevent accidental overwrites to changed media.
>
> B2S_ESTOPPED
>
>  The target has not been started with B2S_CMD_START yet.
>
> B2S_EHARDWARE
>
>  An unknown hardware error occurred.
>
> B2S_ENODEV
>
>  The target is not present or has been removed.
>
> B2S_EMEDIA
>
>  An error on the medium occurred.
>
> B2S_EDOORLOCK
>
>  The B2S_CMD_STOP failed to eject the media, because the doorlock was
>  engaged.
>
> B2S_EWPROTECT
>
>  The media could not be written to because it is not writable.
>
> B2S_EBLKADDR
>
>  The supplied LBA block address was invalid.
>
> B2S_ESTARTING
>
>  The target is still starting up.  Try agin later.
>
> B2S_EIO
>
>  Generic failure.
>
> B2S_ERSVD
>
>  Target reserved.  (Internal use only.)
>
> B2S_EPARM
>
>  Bad parameter occurred in the SCSI packet.  (Internal use only.)
>
> B2S_EBADMSG
>
>  Invalid SCSI message presented to driver.  (Internal use only.)
>
> B2S_EINVAL
>
>  An invalid parameter was present in the SCSI packet.  (Internal use only.)
>
>
> CHAPER 4:  Interface Table
> ==========================
>
>  Imported Interface    Level            Comments
>
>  SCSI-2        Committed        ANSI X1.131-1994
>  scsi_hba_tran        Committed        SCSI HBA API
>  scsi_pkt2bp()        Consolidation Private
>
>
>  Exported Interface    Level            Comments
>
>  sys/scsi/adapters/blk2scsa.h    Cons. Private    blk2scsa header
>
>  misc/blk2scsa        Consolidation Private    kernel module
>  B2S_CMD_*        Consolidation Private    request command codes
>  B2S_E*        Consolidation Private    request error codes
>  B2S_REQUEST_FLAG_*    Consolidation Private    request flags
>  B2S_VERSION_0      Consolidation Private    API versioning
>
>  struct b2s_request    Consolidation Private    request structure
>  struct b2s_leaf    Consolidation Private    leaf (disk) structure (opaque)
>  struct b2s_nexus    Consolidation Private    nexus (hba) structure
> (opaque)
>  struct b2s_leaf_info  Consolidation Private   leaf (disk) attach
> information
>  struct b2s_nexus_info Consolidation Private   nexus (hba) registration
>  struct b2s_media    Consolidation Private    media description
>  struct b2s_inquiry    Consolidation Private   SCSI inquiry data
>
>  b2s_alloc_nexus()    Consolidation Private    nexus (hba) allocation
>  b2s_free_nexus()    Consolidation Private    nexus (hba) deallocation
>  b2s_attach_nexus()    Consolidation Private    nexus (hba) attachment
>  b2s_detach_nexus()    Consolidation Private    nexus (hba) detachment
>
>  b2s_attach_leaf()    Consolidation Private    leaf (disk) connection
>  b2s_detach_leaf()    Consolidation Private    leaf (disk) disconnection
>
>  b2s_request_mapin()    Consolidation Private    request buffer PIO access
>  b2s_request_dma()    Consolidation Private    request buffer DMA access
>  b2s_request_done()    Consolidation Private    request buffer completion
>
>  b2s_mod_init()    Consolidation Private    modlinkage initialization
>  b2s_mod_fini()    Condolidation Private    modlinkage de-initialization

Reply via email to