Unix/Linux Go Back    

NetBSD 6.1.5 - man page for scsipi (netbsd section 9)

Linux & Unix Commands - Search Man Pages
Man Page or Keyword Search:   man
Select Man Page Set:       apropos Keyword Search (sections above)

SCSIPI(9)			  BSD Kernel Developer's Manual 			SCSIPI(9)

     scsipi -- SCSI/ATAPI middle-layer interface

     #include <dev/scsipi/atapiconf.h>
     #include <dev/scsipi/scsiconf.h>

     scsipi_async_event(struct scsipi_channel *chan, scsipi_async_event_t event, void *arg);

     scsipi_channel_freeze(struct scsipi_channel *chan, int count);

     scsipi_channel_thaw(struct scsipi_channel *chan, int count);

     scsipi_channel_timed_thaw(void *arg);

     scsipi_periph_freeze(struct scsipi_periph *periph, int count);

     scsipi_periph_thaw(struct scsipi_periph *periph, int count);

     scsipi_periph_timed_thaw(void *arg);

     scsipi_done(struct scsipi_xfer *xs);

     scsipi_printaddr(struct scsipi_periph *periph);

     scsipi_target_detach(struct scsipi_channel *chan, int target, int lun, int flags);

     scsipi_thread_call_callback(struct scsipi_channel *chan,
	 void (*callback)(struct scsipi_channel *, void *), void *arg);

     The 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

     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

     The mid-layer can also handle QUEUE FULL and CHECK CONDITION events.

     An HBA driver has to allocate and initialize to 0 a struct scsipi_adapter and fill in the
     following members:
	   struct device *adapt_dev  pointer to the HBA's struct device
	   int adapt_nchannels	     number of channels (or busses) of the adapter
	   int adapt_openings	     total number of commands the adapter can handle (may be
				     replaced by chan_openings, see below)
	   int adapt_max_periph      number of commands the adapter can handle per device

     The following callbacks should be provided through the struct scsipi_adapter:
	   void (*adapt_request)(struct scsipi_channel *, scsipi_adapter_req_t, void *)
	   void (*adapt_minphys)(struct buf *)
	   int (*adapt_ioctl)(struct scsipi_channel *, u_long, void *, int, struct lwp *)
	   int (*adapt_enable)(struct device *, int)
			     optional, set to NULL if not used
	   int (*adapt_getgeom)(struct scsipi_periph *, struct disk_parms *, u_long)
			     optional, set to NULL if not used
	   int (*adapt_accesschk)(struct scsipi_periph *, struct scsipi_inquiry_pattern *)
			     optional, set to NULL if not used

     The HBA driver has to allocate and initialize to 0 one struct scsipi_channel per channel and
     fill in the following members:
	   struct scsipi_adapter *chan_adapter
				  Pointer to the HBA's struct scsipi_adapter
	   struct scsipi_bustype *chan_bustype
				  should be initialized to either bus_atapi or bus_scsi, both
				  defined in the scsipi code.
	   int chan_channel	  channel number (starting at 0)
	   int chan_flags	  channel flags:
				  SCSIPI_CHAN_OPENINGS	Use per-channel max number of commands
							chan_openings instead of per-adapter
				  SCSIPI_CHAN_CANGROW	This channel can grow its chan_openings
							or adapt_openings on request (via the
							adapt_request() callback)
				  SCSIPI_CHAN_NOSETTLE	Do not wait SCSI_DELAY seconds for
							devices to settle before probing (usually
							used by adapters that provide an
							"abstracted" view of the bus).
	   int chan_openings	  total number of commands the adapter can handle for this chan-
				  nel (used only if the SCSIPI_CHAN_OPENINGS flag is set)
	   chan_max_periph	  number of commands per device the adapter can handle on this
				  channel (used only if the SCSIPI_CHAN_OPENINGS flag is set)
	   int chan_ntargets	  number of targets
	   int chan_nluns	  number of LUNs per target
	   int chan_id		  adapter's ID on this channel
	   int chan_defquirks	  default device quirks.  Quirks are defined 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.

     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().

     When scanning the bus, the scsipi system allocates a struct scsipi_periph for each device
     probed.  The interesting fields are:
	   struct device *periph_dev
				pointer to the device's struct device
	   struct scsipi_channel *periph_channel
				pointer to the channel the device is connected to
	   int periph_quirks	device quirks, defined in <dev/scsipi/scsipiconf.h>
	   int periph_target	target ID, or drive number on ATAPI
	   int periph_lun	LUN (currently not used on ATAPI)

     A SCSI or ATAPI request is passed to the HBA through a struct scsipi_xfer.  The HBA driver
     has access to the following data:
	   struct callout xs_callout
			   callout for adapter use, usually for command timeout
	   int xs_control  control flags (only flags of interest for HBA drivers are described):
			   XS_CTL_POLL	     poll in the HBA driver for request completion (most
					     likely because interrupts are disabled)
			   XS_CTL_RESET      reset the device
			   XS_CTL_DATA_UIO   xs_data points to a struct uio buffer
			   XS_CTL_DATA_IN    data is transferred from HBA to memory
			   XS_CTL_DATA_OUT   data is transferred from memory to HBA
			   XS_CTL_DISCOVERY  this xfer is part of a device discovery done by the
					     middle layer
			   XS_CTL_REQSENSE   xfer is a request sense

	   int xs_status   status flags:
			   XS_STS_DONE	   xfer is done (set by scsipi_done())
			   XS_STS_PRIVATE  mask of flags reserved for HBA's use (0xf0000000)

	   struct scsipi_periph *xs_periph
			   periph doing the xfer
	   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 hap-
			   pens, the HBA shall terminate the command through scsipi_done() with a
			   XS_TIMEOUT error
	   struct scsipi_generic *cmd
			   scsipi command to execute
	   int cmdlen	   len (in bytes) of the cmd buffer
	   u_char *data    data buffer (this is either a DMA or uio address)
	   int datalen	   data length (in bytes, zero if uio)
	   int resid	   difference between datalen and how much data was really transferred
	   scsipi_xfer_result_t error
			   error value returned by the HBA driver to mid-layer.  See description
			   of scsipi_done() for valid values
	   union {struct scsipi_sense_data scsi_sense; uint32_t atapi_sense;} sense
			   where to store sense info if error is XS_SENSE or XS_SHORTSENSE
	   uint8_t status  SCSI status; checked by middle layer when error is XS_BUSY (the middle
			   layer handles SCSI_CHECK and SCSI_QUEUE_FULL)
	   uint8_t xs_tag_type
			   SCSI tag type, set to 0 if untagged command
	   uint8_t xs_tag_id
			   tag ID, used for tagged commands

     (*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.  req can be one of:
			 request the adapter to send a command to the device.  arg is a pointer
			 to the struct scsipi_xfer.  Once the xfer is complete the HBA driver
			 shall call scsipi_done() with updated status and error information.
			 ask the adapter to increase resources of the channel (grow
			 adapt_openings or chan_openings) if possible.	Support of this feature
			 is optional.  This request is called from the kernel completion thread.
			 arg must be ignored.
			 set the xfer mode for a for I_T Nexus.  This will be called once all
			 LUNs of a target have been probed.  arg points to a struct
			 scsipi_xfer_mode defined as follows:
			 int xm_target	target for I_T Nexus
			 int xm_mode	bitmask of device capabilities
			 int xm_period	sync period
			 int xm_offset	sync offset

			 xm_period and xm_offset shall be ignored for ADAPTER_REQ_SET_XFER_MODE.
			 xm_mode holds the following bits:
				   ST synchronous transfers
				   ST 16 bit wide transfers
				   ST 32 bit wide transfers
				   DT transfers
				   tagged queuing
			 Whenever the xfer mode changes, the driver should call
			 scsipi_async_event() to notify the mid-layer.

	       adapt_request() may be called from interrupt context.
	       pointer to the driver's minphys function.  If the driver can handle transfers of
	       size MAXPHYS, this can point to minphys().
	       ioctl function for the channel.	The only ioctl supported at this level is
	       SCBUSIORESET for which the HBA driver shall issue a SCSI reset on the channel.
     int adapt_enable(struct device *dev, int enable)
	       Disable the adapter if enable is zero, or enable it if non-zero.  Returns 0 if
	       operation is successful, or error from <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.
     int 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.
     int 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 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)
	       Asynchronous event notification for the mid-layer.  event can be one of:
			 set max openings for a periph.  Argument is a struct scsipi_max_openings
			 with at least the following members:
			 int mo_target
			 int mo_lun
			 int mo_openings

			 Not all periphs may allow openings to increase; if not allowed the
			 request is silently ignored.
			 update the xfer mode for an I_T nexus.  Argument is a struct
			 scsipi_xfer_mode properly filled in.  An ASYNC_EVENT_XFER_MODE call with
			 PERIPH_CAP_TQING set in xm_mode is mandatory to activate tagged queuing.
			 channel has been reset.  No argument.	HBA drivers have to issue
			 ASYNC_EVENT_RESET events if they rely on the mid-layer for SCSI CHECK
			 CONDITION handling.

     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.  error in the scsipi_xfer shall be set to one of the
			 xfer completed without error.
	       XS_SENSE  Check the returned SCSI sense for the error.
			 Check the ATAPI sense for the error.
			 Driver failed to perform operation.
			 Adapter resource shortage.  The mid-layer will retry the command after
			 some delay.
			 The device timed out while trying to send the command
			 The command was accepted by the device, but it didn't complete in
			 allowed time.
	       XS_BUSY	 The mid-layer will check status for additional details:
			 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).
			 SCSI_QUEUE_FULL  The mid layer will adjust the periph's openings and
					  requeue the command.
			 SCSI_BUSY	  The mid-layer will requeue the xfer after delay.
	       XS_RESET  xfer destroyed by a reset; the mid-layer will requeue it.
			 Ask the mid-layer to requeue this command immediately.

	       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)
	       print a kernel message with the periph's name, in the form device(controller:chan-
     scsipi_channel_freeze(struct scsipi_channel *chan, int count)
	       Freeze the specified channel (requests are queued but not sent to HBA).	The chan-
	       nel's freeze counter is increased by count.
     scsipi_channel_thaw(struct scsipi_channel *chan, int count)
	       Decrement the channel's freeze counter by count and process the queue if the
	       counter goes to 0.  In order to preserve command ordering, HBA drivers should not
	       call 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)
	       Call 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)
	       Same as the channel counterparts, but only for one specific peripheral.
     scsipi_target_detach(struct scsipi_channel *chan, int target, int lun, int flags)
	       detach the periph associated with this I_T_L nexus.  Both target and lun may be
	       wildcarded using the magic value -1.  flags is passed to 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 comple-
	       tion thread.  The callback is run at splbio.  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.

     sys/dev/scsiconf.h   header file for use by SCSI HBA drivers

     sys/dev/atapiconf.h  header file for use by ATAPI HBA drivers

     Both header files include sys/dev/scsipiconf.h which contains most structure definitions,
     function prototypes and macros.

     The best examples are existing HBA drivers.  Most of them sit in the sys/dev/ic directory.

     The scsipi interface appeared in NetBSD 1.6.

     The scsipi interface was designed and implemented by Jason R. Thorpe.  Manuel Bouyer con-
     verted most drivers to the new interface.

BSD					December 20, 2005				      BSD
Unix & Linux Commands & Man Pages : ©2000 - 2018 Unix and Linux Forums

All times are GMT -4. The time now is 07:55 PM.