SCSIPI(9) | Kernel Developer's Manual | SCSIPI(9) |
scsipi
—
#include
<dev/scsipi/atapiconf.h>
#include <dev/scsipi/scsiconf.h>
void
scsipi_async_event
(struct
scsipi_channel *chan,
scsipi_async_event_t
event, void
*arg);
void
scsipi_channel_freeze
(struct
scsipi_channel *chan, int
count);
void
scsipi_channel_thaw
(struct
scsipi_channel *chan, int
count);
void
scsipi_channel_timed_thaw
(void
*arg);
void
scsipi_periph_freeze
(struct
scsipi_periph *periph,
int count);
void
scsipi_periph_thaw
(struct
scsipi_periph *periph,
int count);
void
scsipi_periph_timed_thaw
(void
*arg);
void
scsipi_done
(struct
scsipi_xfer *xs);
void
scsipi_printaddr
(struct
scsipi_periph *periph);
int
scsipi_target_detach
(struct
scsipi_channel *chan, int
target, int lun,
int flags);
int
scsipi_thread_call_callback
(struct
scsipi_channel *chan,
void (*callback)(struct
scsipi_channel *, void *),
void *arg);
int
scsipi_adapter_addref
(struct
scsipi_adapter *adapt);
void
scsipi_adapter_delref
(struct
scsipi_adapter *adapt);
scsipi
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
scsipi
layer towards the HBA layer. An HBA has to
provide a pointer to a struct scsipi_adapter and one
pointer per channel to a struct scsipi_channel. Once the
SCSI or ATAPI bus is attached, the scsipi
system will
scan the bus and allocate a 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
struct scsipi_xfer.
A request is sent to the HBA driver through the
adapt_request
() callback. The HBA driver signals
completion (with or without errors) of the request through
scsipi_done
(). scsipi
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.
The mid-layer can also handle QUEUE FULL
and CHECK CONDITION
events.
SCSIPI_ADAPT_POLL_ONLY
SCSIPI_ADAPT_MPSAFE
The following callbacks should be provided through the struct scsipi_adapter:
(*adapt_request)
(struct
scsipi_channel *, scsipi_adapter_req_t,
void *)(*adapt_minphys)
(struct buf
*)(*adapt_ioctl)
(struct
scsipi_channel *, u_long, void
*, int, struct lwp *)(*adapt_enable)
(struct device
*, int)NULL
if not used(*adapt_getgeom)
(struct
scsipi_periph *, struct disk_parms *,
u_long)NULL
if not used(*adapt_accesschk)
(struct
scsipi_periph *, struct scsipi_inquiry_pattern
*)NULL
if not usedThe HBA driver has to allocate and initialize to 0 one struct scsipi_channel per channel and fill in the following members:
scsipi
code.SCSIPI_CHAN_OPENINGS
SCSIPI_CHAN_CANGROW
adapt_request
() callback)SCSIPI_CHAN_NOSETTLE
SCSIPI_CHAN_OPENINGS
flag is set)<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.The HBA driver attaches the SCSI or ATAPI bus (depending on the
setting of chan_bustype) by passing a pointer to the
struct scsipi_channel to the
autoconf(9) machinery. The
print function shall be either scsiprint
() or
atapiprint
().
scsipi
system allocates a
struct scsipi_periph for each device probed. The
interesting fields are:
<dev/scsipi/scsipiconf.h>
A SCSI or ATAPI request is passed to the HBA through a struct scsipi_xfer. The HBA driver has access to the following data:
XS_CTL_POLL
XS_CTL_RESET
XS_CTL_DATA_UIO
XS_CTL_DATA_IN
XS_CTL_DATA_OUT
XS_CTL_DISCOVERY
XS_CTL_REQSENSE
scsipi_done
())scsipi_done
() with a XS_TIMEOUT errorscsipi_done
() for valid valuesXS_SENSE
or
XS_SHORTSENSE
XS_BUSY
(the middle layer handles
SCSI_CHECK
and
SCSI_QUEUE_FULL
)(*adapt_request)
(struct
scsipi_channel *chan, scsipi_adapter_req_t req,
void *arg)ADAPTER_REQ_RUN_XFER
scsipi_done
() with updated status and error
information.ADAPTER_REQ_GROW_RESOURCES
ADAPTER_REQ_SET_XFER_MODE
xm_period and
xm_offset shall be ignored for
ADAPTER_REQ_SET_XFER_MODE
.
xm_mode holds the following bits:
PERIPH_CAP_SYNC
PERIPH_CAP_WIDE16
PERIPH_CAP_WIDE32
PERIPH_CAP_DT
PERIPH_CAP_TQING
scsipi_async_event
() to notify the
mid-layer.adapt_request
() may be called from
interrupt context.
adapt_minphys
()MAXPHYS
, this can point to
minphys
().adapt_ioctl
()SCBUSIORESET
for which the HBA driver shall issue
a SCSI reset on the channel.adapt_enable
(struct device
*dev, int enable)scsipi_adapter_addref
() and
scsipi_adapter_delref
() maintain a reference
count, the enable callback is called appropriately for the first reference
and the last reference.adapt_getgeom
(struct
scsipi_periph *periph, struct disk_parms
*params, u_long sectors)adapt_accesschk
(struct
scsipi_periph *periph, struct scsipi_inquiry_pattern
*inqbuf)scsipi
code. This callback is used by adapters
which want to drive some devices themselves, for example hardware RAID
controllers.scsipi_async_event
(struct
scsipi_channel *chan, scsipi_async_event_t
event, void *arg)ASYNC_EVENT_MAX_OPENINGS
Not all periphs may allow openings to increase; if not allowed the request is silently ignored.
ASYNC_EVENT_XFER_MODE
ASYNC_EVENT_XFER_MODE
call with
PERIPH_CAP_TQING
set in
xm_mode is mandatory to activate tagged
queuing.ASYNC_EVENT_RESET
ASYNC_EVENT_RESET events if they rely on the
mid-layer for SCSI CHECK CONDITION handling.scsipi_done
(struct scsipi_xfer
*xs)XS_NOERROR
XS_SENSE
XS_SHORTSENSE
XS_DRIVER_STUFFUP
XS_RESOURCE_SHORTAGE
XS_SELTIMEOUT
XS_TIMEOUT
XS_BUSY
SCSI_CHECK
SCSI_QUEUE_FULL
SCSI_BUSY
XS_RESET
XS_REQUEUE
The adapter should not reference an xfer
once scsipi_done
(xfer) has
been called, unless the xfer had
XS_CTL_POLL
set.
scsipi_done
() will call the
adapt_request
() callback again only if called
with xs->error set to
XS_NOERROR
, and xfer
doesn't have XS_CTL_POLL
set. All other error
conditions are handled by a kernel thread (once the HBA's interrupt
handler has returned).
scsipi_printaddr
(struct
scsipi_periph *periph)scsipi_channel_freeze
(struct
scsipi_channel *chan, int count)scsipi_channel_thaw
(struct
scsipi_channel *chan, int count)scsipi_channel_thaw
() before calling
scsipi_done
() for all commands in the HBA's queue
which need to be requeued.scsipi_periph_timed_thaw
(void
*arg)scsipi_channel_thaw
(arg,
1). Intended to be used as
callout(9) callback.scsipi_periph_freeze
(struct
scsipi_periph *periph, int count)scsipi_periph_thaw
(struct
scsipi_periph *periph)scsipi_periph_timed_thaw
(void
*arg)scsipi_target_detach
(struct
scsipi_channel *chan, int target,
int lun, int flags)config_detach
() . Returns
0 if successful, or error code if a device couldn't be removed.scsipi_thread_call_callback
(struct
scsipi_channel *chan, void (*callback)(struct
scsipi_channel *, void *), void *arg)callback
() will be called with
chan and arg as arguments,
from the channel completion thread. The callback is run at
IPL_BIO
with the channel lock held.
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.Both header files include sys/dev/scsipiconf.h which contains most structure definitions, function prototypes and macros.
scsipi
interface appeared in NetBSD
1.6.
scsipi
interface was designed and implemented by
Jason R. Thorpe. Manuel Bouyer
converted most drivers to the new interface.
November 20, 2016 | NetBSD 9.2 |