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 > >
