I mis-stated the SCSI-2 standard number.  It is X3.131-1994.  It can be 
downloaded in PDF from this URL:

http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf

Hopefully it wasn't confusing to anyone.  If it was, I apologize.

    -- Garrett

Garrett D'Amore - sun microsystems wrote:
> I'm submitting following fast-track on my own behalf.  This may be straddling
> the boundary of what can pass for a fast-track.  If members feel that this
> is deserving of a full review, please don't hesitate to derail it.  (I won't
> take it personally. :-)
>
> Template Version: @(#)sac_nextcase 1.64 07/13/07 SMI
> This information is Copyright 2007 Sun Microsystems
> 1. Introduction
>     1.1. Project/Component Working Name:
>        blk2scsa
>     1.2. Name of Document Author/Supplier:
>        Author:  Garrett D'Amore
>     1.3  Date of This Document:
>       14 November, 2007
> 4. Technical Description
>
> Generic Block Device to SCSA Translation Layer
> Functional Specification
>
> Garrett D'Amore (gdamore at sun.com)
> Nov 13, 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_hba b2s_hba_t;
>
>   The b2s_hba_t structure is an opaque structure that is used as a handle
>   to the emulated host bus adapter.
>
> typedef struct b2s_target b2s_target_t;
>
>   The b2s_target_t structure is a handle to an emulated SCSI disk.  It
>   has the following accessible members:
>
>       uint16_t          target_number;
>       void      *target_private;
>       const char  *target_vendor;
>       const char  *target_product;
>       const char  *target_revision;
>       const char  *target_serial;
>       uint32_t          target_flags;
>       boolean_t         (*target_request)(void *, struct b2s_request *);
>
>   The target_number field is the number to use for the emulated SCSI target.
>   (For example, if target_number == 1, then the emulated disk will be
>   addressed as cXt1d0.)  Each target on an emulated HBA must have a unique
>   number.
>
>   The target_private field is available for the device driver's own
>   use, and should point to per-target state.
>
>   The target_vendor, target_product, target_revision, and target_serial
>   fields are ASCIIZ strings used to identify the target.  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.)
>
>   The target_flags field can contain one of two flags:
>
>       B2S_TARGET_FLAG_REMOVABLE - indicates that the target supports removable
>       media
>
>       B2S_TARGET_FLAG_HOTPLUGGABLE - indicates that the target can be hot
>       plugged (including either removal or attachment.)
>
>   The target_request field is the entry point that the device driver 
> implements
>   to handle I/O requests.  It is passed target_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.
>
> 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;
>       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_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.
>
>
> Functions
> ---------
>
> int b2s_hba_init(struct modlinkage *);
> int b2s_hba_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_hba_t *b2s_alloc_hba(int version, dev_info_t *dip, ddi_dma_attr_t *attrp);
>
>   This allocates an initial emulated HBA structure.  The version field
>   shall be set to B2S_VERSION_0.  The dip should be the instance
>   structure for the device (the first argument to attach(9e).)  The
>   attrp is a pointer to DMA attributes for the IO requests to the
>   device.  If the device cannot support DMA, then it shall use the
>   value NULL for attrp.
>
> void b2s_free_hba(b2s_hba_t *);
>
>   This frees an allocated, unattached emulated HBA structure.  It will
>   also implicitly free any targets that are still registered with the HBA.
>
> b2s_target_t *b2s_alloc_target(void);
>
>   This allocates an empty target structure.  The driver is responsible
>   for populating the public members (see b2s_target_t in Types above),
>   before registering it.
>
> void b2s_free_target(b2s_target_t *);
>
>   This frees an unregistered target structure.
>
> int b2s_register_target(b2s_hba_t *hba, b2s_target_t *target);
>
>   This registers the target with the HBA.  If the HBA has been attached,
>   this will appear to the system as an emulated hotplug attach of the
>   disk.  It returns DDI_SUCCESS on success, DDI_FAILURE otherwise.
>
> int b2s_unregister_target(b2s_target_t *target);
>
>   This unregisters the target from the HBA.  If the HBA is attached,
>   then this will appear to the system as a hotplug removal of the disk.
>   It returns DDI_SUCCESS on success, DDI_FAILURE otherwise.
>
> 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_hba(b2s_hba_t *);
>
>   This attaches the HBA (and any registered targets) 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_hba(b2s_hba_t *);
>
>   This detaches the HBA from the system.  It returns DDI_SUCCESS on success,
>   DDI_FAILURE otherwise.
>
>
> Commands
> --------
>
> 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_target   Consolidation Private   target structure
>   struct b2s_hba      Consolidation Private   hba structure (opaque)
>   struct b2s_media    Consolidation Private   media description
>
>   b2s_alloc_hba()     Consolidation Private   HBA allocation
>   b2s_free_hba()      Consolidation Private   HBA deallocation
>   b2s_attach_hba()    Consolidation Private   HBA attachment
>   b2s_detach_hba()    Consolidation Private   HBA detachment
>
>   b2s_alloc_target()  Consolidation Private   target allocation
>   b2s_free_target()   Consolidation Private   target deallocation
>   b2s_target_register()       Consolidation Private   target registration
>   b2s_target_unregister()     Cons. Private   target unregistration
>
>   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_hba_init()      Consolidation Private   modlinkage initialization
>   b2s_hba_fini()      Condolidation Private   modlinkage de-initialization
>
> 6. Resources and Schedule
>     6.4. Steering Committee requested information
>       6.4.1. Consolidation C-team Name:
>               ON
>     6.5. ARC review type: FastTrack
>     6.6. ARC Exposure: open
>
>   


Reply via email to