summaryrefslogtreecommitdiff
path: root/static/netbsd/man9/scsipi.9
diff options
context:
space:
mode:
Diffstat (limited to 'static/netbsd/man9/scsipi.9')
-rw-r--r--static/netbsd/man9/scsipi.9622
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.