diff options
Diffstat (limited to 'static/netbsd/man9/scsipi.9')
| -rw-r--r-- | static/netbsd/man9/scsipi.9 | 622 |
1 files changed, 622 insertions, 0 deletions
diff --git a/static/netbsd/man9/scsipi.9 b/static/netbsd/man9/scsipi.9 new file mode 100644 index 00000000..d8ef3739 --- /dev/null +++ b/static/netbsd/man9/scsipi.9 @@ -0,0 +1,622 @@ +.\" $NetBSD: scsipi.9,v 1.33 2024/10/29 15:45:58 nat Exp $ +.\" +.\" +.\" Copyright (c) 2001 Manuel Bouyer. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" +.Dd November 20, 2016 +.Dt SCSIPI 9 +.Os +.Sh NAME +.Nm scsipi +.Nd SCSI/ATAPI middle-layer interface +.Sh SYNOPSIS +.In dev/scsipi/atapiconf.h +.In dev/scsipi/scsiconf.h +.Ft void +.Fn scsipi_async_event "struct scsipi_channel *chan" "scsipi_async_event_t event" "void *arg" +.Ft void +.Fn scsipi_channel_freeze "struct scsipi_channel *chan" "int count" +.Ft void +.Fn scsipi_channel_thaw "struct scsipi_channel *chan" "int count" +.Ft void +.Fn scsipi_channel_timed_thaw "void *arg" +.Ft void +.Fn scsipi_periph_freeze "struct scsipi_periph *periph" "int count" +.Ft void +.Fn scsipi_periph_thaw "struct scsipi_periph *periph" "int count" +.Ft void +.Fn scsipi_periph_timed_thaw "void *arg" +.Ft void +.Fn scsipi_done "struct scsipi_xfer *xs" +.Ft void +.Fn scsipi_printaddr "struct scsipi_periph *periph" +.Ft int +.Fn scsipi_target_detach "struct scsipi_channel *chan" "int target" "int lun" "int flags" +.Ft int +.Fn scsipi_thread_call_callback "struct scsipi_channel *chan" "void (*callback)(struct scsipi_channel *, void *)" "void *arg" +.Ft int +.Fn scsipi_adapter_addref "struct scsipi_adapter *adapt" +.Ft void +.Fn scsipi_adapter_delref "struct scsipi_adapter *adapt" +.Sh DESCRIPTION +The +.Nm +system is the middle layer interface between SCSI/ATAPI host bus +adapters (HBA) and high-level SCSI/ATAPI drivers. +This document describes the interfaces provided by the +.Nm +layer towards the HBA layer. +An HBA has to provide a pointer to a +.Va struct scsipi_adapter +and one pointer per channel to a +.Va struct scsipi_channel . +Once the SCSI or ATAPI bus is attached, the +.Nm +system will scan the bus and allocate a +.Va struct scsipi_periph +for each device found on the bus. +A high-level command (command sent from the high-level SCSI/ATAPI +layer to the low-level HBA layer) is described by a +.Va struct scsipi_xfer . +.Pp +A request is sent to the HBA driver through the +.Fn adapt_request +callback. +The HBA driver signals completion (with or without errors) of the +request through +.Fn scsipi_done . +.Nm +knows the resource's limits of the HBA (max number of concurrent requests per +adapter of channel, and per periph), and will make sure the HBA won't receive +more requests than it can handle. +.Pp +The mid-layer can also handle +.Dv QUEUE FULL +and +.Dv CHECK CONDITION +events. +.Ss INITIALISATION +An HBA driver has to allocate and initialize to 0 a +.Va struct scsipi_adapter +and fill in the following members: +.Bl -tag -width "struct_device *adapt_dev" -compact -offset indent +.It Va struct device *adapt_dev +pointer to the HBA's +.Va struct device +.It Va int adapt_nchannels +number of channels (or busses) of the adapter +.It Va int adapt_openings +total number of commands the adapter can handle (may be replaced by +.Va chan_openings , +see below) +.It Va int adapt_max_periph +number of commands the adapter can handle per device +.It Va int adapt_flags +adapter properties +.Bl -tag -width SCSIPI_ADAPT_POLL_ONLY -compact +.It Dv SCSIPI_ADAPT_POLL_ONLY +the HBA can't do interrupts +.It Dv SCSIPI_ADAPT_MPSAFE +don't acquire the kernel lock when doing HBA callbacks +.El +.El +.Pp +The following callbacks should be provided through the +.Va struct scsipi_adapter : +.Bl -tag -width someverylongword -compact -offset indent +.It void Fn (*adapt_request) "struct scsipi_channel *" "scsipi_adapter_req_t" "void *" +mandatory +.It void Fn (*adapt_minphys) "struct buf *" +mandatory +.It int Fn (*adapt_ioctl) "struct scsipi_channel *" "u_long" "void *" "int" "struct lwp *" +optional +.It int Fn (*adapt_enable) "struct device *" "int" +optional, set to +.Dv NULL +if not used +.It int Fn (*adapt_getgeom) "struct scsipi_periph *" "struct disk_parms *" "u_long" +optional, set to +.Dv NULL +if not used +.It int Fn (*adapt_accesschk) "struct scsipi_periph *" "struct scsipi_inquiry_pattern *" +optional, set to +.Dv NULL +if not used +.El +.Pp +The HBA driver has to allocate and initialize to 0 one +.Va struct scsipi_channel +per channel and fill in the following members: +.Bl -tag -width struct_scsipi_adapter -compact -offset indent +.It Va struct scsipi_adapter *chan_adapter +Pointer to the HBA's +.Fa struct scsipi_adapter +.It Va struct scsipi_bustype *chan_bustype +should be initialized to either +.Va bus_atapi +or +.Va bus_scsi , +both defined in the +.Nm +code. +.It Va int chan_channel +channel number (starting at 0) +.It Va int chan_flags +channel flags: +.Bl -tag -width SCSIPI_CHAN_OPENINGS -compact +.It Dv SCSIPI_CHAN_OPENINGS +Use per-channel max number of commands +.Va chan_openings +instead of per-adapter +.Va adapt_openings +.It Dv SCSIPI_CHAN_CANGROW +This channel can grow its +.Va chan_openings +or +.Va adapt_openings +on request (via the +.Fn adapt_request +callback) +.It Dv SCSIPI_CHAN_NOSETTLE +Do not wait SCSI_DELAY seconds for devices to settle before probing (usually +used by adapters that provide an \*qabstracted\*q view of the bus). +.El +.It Va int chan_openings +total number of commands the adapter can handle for this channel (used only +if the +.Dv SCSIPI_CHAN_OPENINGS +flag is set) +.It Va chan_max_periph +number of commands per device the adapter can handle on this +channel (used only if the +.Va SCSIPI_CHAN_OPENINGS +flag is set) +.It Va int chan_ntargets +number of targets +.It Va int chan_nluns +number of LUNs per target +.It Va int chan_id +adapter's ID on this channel +.It Va int chan_defquirks +default device quirks. +Quirks are defined in +.In dev/scsipi/scsipiconf.h +and are usually set in the middle layer based on the device's inquiry +data. +For some kinds of adapters it may be convenient to have a set of +quirks applied to all devices, regardless of the inquiry data. +.El +.Pp +The HBA driver attaches the SCSI or ATAPI bus (depending on the setting of +.Va chan_bustype ) +by passing a pointer to the +.Va struct scsipi_channel +to the +.Xr autoconf 9 +machinery. +The print function shall be either +.Fn scsiprint +or +.Fn atapiprint . +.Ss OTHER DATA STRUCTURES +When scanning the bus, the +.Nm +system allocates a +.Va struct scsipi_periph +for each device probed. +The interesting fields are: +.Bl -tag -width int_periph_openings -compact -offset indent +.It Va struct device *periph_dev +pointer to the device's +.Va struct device +.It Va struct scsipi_channel *periph_channel +pointer to the channel the device is connected to +.It Va int periph_quirks +device quirks, defined in +.In dev/scsipi/scsipiconf.h +.It Va int periph_target +target ID, or drive number on ATAPI +.It Va int periph_lun +LUN (currently not used on ATAPI) +.El +.Pp +A SCSI or ATAPI request is passed to the HBA through a +.Va struct scsipi_xfer . +The HBA driver has access to the following data: +.Bl -tag -width "int xs_callout" -compact -offset indent +.It Va struct callout xs_callout +callout for adapter use, usually for command timeout +.It Va int xs_control +control flags (only flags of interest for HBA drivers are described): +.Bl -tag -width XS_CTL_DISCOVERY -compact +.It Dv XS_CTL_POLL +poll in the HBA driver for request completion (most likely because interrupts +are disabled) +.It Dv XS_CTL_RESET +reset the device +.It Dv XS_CTL_DATA_UIO +xs_data points to a +.Fa struct uio +buffer +.It Dv XS_CTL_DATA_IN +data is transferred from HBA to memory +.It Dv XS_CTL_DATA_OUT +data is transferred from memory to HBA +.It Dv XS_CTL_DISCOVERY +this xfer is part of a device discovery done by the middle layer +.It Dv XS_CTL_REQSENSE +xfer is a request sense +.El +.Pp +.It Va int xs_status +status flags: +.Bl -tag -width XS_STS_PRIVATE -compact +.It Va XS_STS_DONE +xfer is done (set by +.Fn scsipi_done ) +.It Va XS_STS_PRIVATE +mask of flags reserved for HBA's use (0xf0000000) +.El +.Pp +.It Va struct scsipi_periph *xs_periph +periph doing the xfer +.It Va int timeout +command timeout, in milliseconds. +The HBA should start the timeout at the time the command is accepted +by the device. +If the timeout happens, the HBA shall terminate the command through +.Fn scsipi_done +with a XS_TIMEOUT error +.It Va struct scsipi_generic *cmd +scsipi command to execute +.It Va int cmdlen +len (in bytes) of the cmd buffer +.It Va u_char *data +data buffer (this is either a DMA or uio address) +.It Va int datalen +data length (in bytes, zero if uio) +.It Va int resid +difference between +.Fa datalen +and how much data was really transferred +.It Va scsipi_xfer_result_t error +error value returned by the HBA driver to mid-layer. +See description of +.Fn scsipi_done +for valid values +.It Va union {struct scsipi_sense_data scsi_sense; uint32_t atapi_sense;} sense +where to store sense info if +.Fa error +is +.Dv XS_SENSE +or +.Dv XS_SHORTSENSE +.It Va uint8_t status +SCSI status; checked by middle layer when +.Fa error is +.Dv XS_BUSY +(the middle layer handles +.Dv SCSI_CHECK +and +.Dv SCSI_QUEUE_FULL ) +.It Va uint8_t xs_tag_type +SCSI tag type, set to 0 if untagged command +.It Va uint8_t xs_tag_id +tag ID, used for tagged commands +.El +.Ss FUNCTIONS AND CALLBACKS +.Bl -tag -width xxxxxxxx -compact +.It Fn (*adapt_request) "struct scsipi_channel *chan" "scsipi_adapter_req_t req" "void *arg" +Used by the mid-layer to transmit a request to the adapter. +.Va req +can be one of: +.Bl -tag -width xxxxxxxx -compact +.It Dv ADAPTER_REQ_RUN_XFER +request the adapter to send a command to the device. +.Fa arg +is a pointer to the +.Va struct scsipi_xfer . +Once the xfer is complete the HBA driver shall call +.Fn scsipi_done +with updated status and error information. +.It Dv ADAPTER_REQ_GROW_RESOURCES +ask the adapter to increase resources of the channel (grow +.Va adapt_openings +or +.Va chan_openings ) +if possible. +Support of this feature is optional. +This request is called from the kernel completion thread. +.Fa arg +must be ignored. +.It Dv ADAPTER_REQ_SET_XFER_MODE +set the xfer mode for a I_T Nexus. +This will be called once all LUNs of a target have been probed. +.Fa arg +points to a +.Va struct scsipi_xfer_mode +defined as follows: +.Bl -tag -width int_xm_target -compact +.It Va int xm_target +target for I_T Nexus +.It Va int xm_mode +bitmask of device capabilities +.It Va int xm_period +sync period +.It Va int xm_offset +sync offset +.El +.Pp +.Va xm_period +and +.Va xm_offset +shall be ignored for +.Dv ADAPTER_REQ_SET_XFER_MODE . +.Va xm_mode +holds the following bits: +.Bl -tag -width xxxxxxxx -compact +.It Dv PERIPH_CAP_SYNC +ST synchronous transfers +.It Dv PERIPH_CAP_WIDE16 +ST 16 bit wide transfers +.It Dv PERIPH_CAP_WIDE32 +ST 32 bit wide transfers +.It Dv PERIPH_CAP_DT +DT transfers +.It Dv PERIPH_CAP_TQING +tagged queuing +.El +Whenever the xfer mode changes, the driver should call +.Fn scsipi_async_event +to notify the mid-layer. +.El +.Pp +.Fn adapt_request +may be called from interrupt context. +.It Fn adapt_minphys +pointer to the driver's minphys function. +If the driver can handle transfers of size +.Dv MAXPHYS , +this can point to +.Fn minphys . +.It Fn adapt_ioctl +ioctl function for the channel. +The only ioctl supported at this level is +.Dv SCBUSIORESET +for which the HBA driver shall issue a SCSI reset on the channel. +.It int Fn adapt_enable "struct device *dev" "int enable" +Disable the adapter if +.Va enable +is zero, or enable it if non-zero. +Returns 0 if operation is successful, or error from +.Pa <sys/errno.h> . +This callback is optional, and is useful mostly for hot-plug devices. +For example, this callback would power on or off +the relevant PCMCIA socket for a PCMCIA controller. +.Fn scsipi_adapter_addref +and +.Fn scsipi_adapter_delref +maintain a reference count, the enable callback is called appropriately +for the first reference and the last reference. +.It int Fn adapt_getgeom "struct scsipi_periph *periph" "struct disk_parms *params" "u_long sectors" +Optional callback, used by high-level drivers to get the fictitious geometry +used by the controller's firmware for the specified periph. +Returns 0 if successful. +See Adaptec drivers for details. +.It int Fn adapt_accesschk "struct scsipi_periph *periph" "struct scsipi_inquiry_pattern *inqbuf" +Optional callback; if present the mid-layer uses it to check if it can +attach a driver to the specified periph. +If the callback returns a non-zero value, the periph is ignored by the +.Nm +code. +This callback is used by adapters which want to drive some devices +themselves, for example hardware RAID controllers. +.It Fn scsipi_async_event "struct scsipi_channel *chan" "scsipi_async_event_t event" "void *arg" +Asynchronous event notification for the mid-layer. +.Fa event +can be one of: +.Bl -tag -width xxxxxxxx -compact +.It Dv ASYNC_EVENT_MAX_OPENINGS +set max openings for a periph. +Argument is a +.Va struct scsipi_max_openings +with at least the following members: +.Bl -tag -width xxxxxxxx -compact +.It Va int mo_target +.It Va int mo_lun +.It Va int mo_openings +.El +.Pp +Not all periphs may allow openings to increase; if not allowed the request is +silently ignored. +.It Dv ASYNC_EVENT_XFER_MODE +update the xfer mode for an I_T nexus. +Argument is a +.Va struct scsipi_xfer_mode +properly filled in. +An +.Dv ASYNC_EVENT_XFER_MODE +call with +.Dv PERIPH_CAP_TQING +set in +.Va xm_mode +is mandatory to activate tagged queuing. +.It Dv ASYNC_EVENT_RESET +channel has been reset. +No argument. +HBA drivers have to issue +.Dv ASYNC_EVENT_RESET events if they rely on the +mid-layer for SCSI CHECK CONDITION handling. +.El +.Pp +.It Fn scsipi_done "struct scsipi_xfer *xs" +shall be called by the HBA when the xfer is complete, or when it needs to +be requeued by the mid-layer. +.Va error +in the scsipi_xfer shall be set to one of the following: +.Bl -tag -width xxxxxxxx -compact +.It Dv XS_NOERROR +xfer completed without error. +.It Dv XS_SENSE +Check the returned SCSI sense for the error. +.It Dv XS_SHORTSENSE +Check the ATAPI sense for the error. +.It Dv XS_DRIVER_STUFFUP +Driver failed to perform operation. +.It Dv XS_RESOURCE_SHORTAGE +Adapter resource shortage. +The mid-layer will retry the command after some delay. +.It Dv XS_SELTIMEOUT +The device timed out while trying to send the command +.It Dv XS_TIMEOUT +The command was accepted by the device, but it didn't complete in allowed time. +.It Dv XS_BUSY +The mid-layer will check +.Va status +for additional details: +.Bl -tag -width SCSI_QUEUE_FULL -compact +.It Dv SCSI_CHECK +SCSI check condition. +The mid-layer will freeze the periph queue and issue a REQUEST SENSE command. +If the HBA supports tagged queuing, it shall remove and requeue any command +not yet accepted by the HBA (or at last make sure no more commands will +be sent to the device before the REQUEST SENSE is complete). +.It Dv SCSI_QUEUE_FULL +The mid layer will adjust the periph's openings and requeue the command. +.It Dv SCSI_BUSY +The mid-layer will requeue the xfer after delay. +.El +.It Dv XS_RESET +xfer destroyed by a reset; the mid-layer will requeue it. +.It Dv XS_REQUEUE +Ask the mid-layer to requeue this command immediately. +.El +.Pp +The adapter should not reference an +.Fa xfer +once +.Fn scsipi_done "xfer" +has been called, unless the +.Fa xfer +had +.Dv XS_CTL_POLL +set. +.Pp +.Fn scsipi_done +will call the +.Fn adapt_request +callback again only if called with +.Fa xs->error +set to +.Dv XS_NOERROR , +and +.Fa xfer +doesn't have +.Dv XS_CTL_POLL +set. +All other error conditions are handled by a kernel thread +(once the HBA's interrupt handler has returned). +.It Fn scsipi_printaddr "struct scsipi_periph *periph" +print a kernel message with the periph's name, in the form +device(controller:channel:target:lun). +.It Fn scsipi_channel_freeze "struct scsipi_channel *chan" "int count" +Freeze the specified channel (requests are queued but not sent to HBA). +The channel's freeze counter is increased by +.Fa count . +.It Fn scsipi_channel_thaw "struct scsipi_channel *chan" "int count" +Decrement the channel's freeze counter by +.Fa count +and process the queue if the counter goes to 0. +In order to preserve command ordering, HBA drivers should not call +.Fn scsipi_channel_thaw +before calling +.Fn scsipi_done +for all commands in the HBA's queue which need to be requeued. +.It Fn scsipi_periph_timed_thaw "void *arg" +Call +.Fn scsipi_channel_thaw "arg" "1" . +Intended to be used as +.Xr callout 9 +callback. +.It Fn scsipi_periph_freeze "struct scsipi_periph *periph" "int count" +.It Fn scsipi_periph_thaw "struct scsipi_periph *periph" +.It Fn scsipi_periph_timed_thaw "void *arg" +Same as the channel counterparts, but only for one specific peripheral. +.It Fn scsipi_target_detach "struct scsipi_channel *chan" "int target" "int lun" "int flags" +detach the periph associated with this I_T_L nexus. +Both +.Fa target +and +.Fa lun +may be wildcarded using the magic value -1. +.Fa flags +is passed to +.Fn config_detach "" +\&. +Returns 0 if successful, or error code if a device couldn't be removed. +.It Fn scsipi_thread_call_callback "struct scsipi_channel *chan" "void (*callback)(struct scsipi_channel *, void *)" "void *arg" +.Fn callback +will be called with +.Fa chan +and +.Fa arg +as arguments, from the channel completion thread. +The callback is run at +.Dv IPL_BIO +with the channel lock held. +.Fn scsipi_thread_call_callback +will freeze the channel by one, it's up to the caller to thaw it when +appropriate. +Returns 0 if the callback was properly recorded, or EBUSY if the +channel has already a callback pending. +.El +.Sh FILES +.Bl -tag -width sys/dev/atapiconf.h +.It Pa sys/dev/scsiconf.h +header file for use by SCSI HBA drivers +.It Pa sys/dev/atapiconf.h +header file for use by ATAPI HBA drivers +.El +.Pp +Both header files include +.Pa sys/dev/scsipiconf.h +which contains most structure definitions, function prototypes and macros. +.Sh EXAMPLES +The best examples are existing HBA drivers. +Most of them sit in the +.Pa sys/dev/ic +directory. +.Sh HISTORY +The +.Nm +interface appeared in +.Nx 1.6 . +.Sh AUTHORS +.An -nosplit +The +.Nm +interface was designed and implemented by +.An Jason R. Thorpe . +.An Manuel Bouyer +converted most drivers to the new interface. |
