Initial doc's commit
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 12 Oct 2006 14:02:57 +0000 (14:02 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 12 Oct 2006 14:02:57 +0000 (14:02 +0000)
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@2 d57e44dd-8a1f-0410-8b47-8ef2f437770f

doc/Makefile [new file with mode: 0644]
doc/fig1.png [new file with mode: 0644]
doc/fig2.png [new file with mode: 0644]
doc/fig3.png [new file with mode: 0644]
doc/fig4.png [new file with mode: 0644]
doc/scst_pg.sgml [new file with mode: 0644]

diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644 (file)
index 0000000..3fc8dd4
--- /dev/null
@@ -0,0 +1,61 @@
+COMMAND=linuxdoc --backend=
+
+SOURCE_NAME=scst_pg
+
+SOURCE=$(SOURCE_NAME).sgml
+
+default: html txt pdf
+
+all: html txt pdf tex dvi ps info lyx rtf
+
+txt: $(SOURCE_NAME).txt
+
+html: $(SOURCE_NAME).html
+
+tex: $(SOURCE_NAME).tex
+
+dvi: $(SOURCE_NAME).dvi
+
+ps: $(SOURCE_NAME).ps
+
+pdf: $(SOURCE_NAME).pdf
+
+info: $(SOURCE_NAME).info
+
+lyx: $(SOURCE_NAME).lyx
+
+rtf: $(SOURCE_NAME).rtf
+
+$(SOURCE_NAME).txt: $(SOURCE)
+       $(COMMAND)txt $(SOURCE)
+
+$(SOURCE_NAME).html: $(SOURCE)
+       $(COMMAND)html --split=0 $(SOURCE)
+
+$(SOURCE_NAME).tex: $(SOURCE)
+       $(COMMAND)latex -o tex $(SOURCE)
+
+$(SOURCE_NAME).dvi: $(SOURCE)
+       $(COMMAND)latex -o dvi $(SOURCE)
+
+$(SOURCE_NAME).ps: $(SOURCE)
+       $(COMMAND)latex -o ps $(SOURCE)
+
+$(SOURCE_NAME).pdf: $(SOURCE)
+       $(COMMAND)latex -o pdf $(SOURCE)
+
+$(SOURCE_NAME).info: $(SOURCE)
+       $(COMMAND)info $(SOURCE)
+
+$(SOURCE_NAME).lyx: $(SOURCE)
+       $(COMMAND)lyx $(SOURCE)
+
+$(SOURCE_NAME).rtf: $(SOURCE)
+       $(COMMAND)rtf $(SOURCE)
+
+clean:
+       rm -f *.txt *.html *.tex *.dvi *.ps *.pdf *.info *.lyx *.rtf
+
+extraclean: clean
+
+.PHONY: all default html txt pdf tex dvi ps info lyx rtf clean extraclean
diff --git a/doc/fig1.png b/doc/fig1.png
new file mode 100644 (file)
index 0000000..94b9fa0
Binary files /dev/null and b/doc/fig1.png differ
diff --git a/doc/fig2.png b/doc/fig2.png
new file mode 100644 (file)
index 0000000..3bdf882
Binary files /dev/null and b/doc/fig2.png differ
diff --git a/doc/fig3.png b/doc/fig3.png
new file mode 100644 (file)
index 0000000..e502f2d
Binary files /dev/null and b/doc/fig3.png differ
diff --git a/doc/fig4.png b/doc/fig4.png
new file mode 100644 (file)
index 0000000..667e412
Binary files /dev/null and b/doc/fig4.png differ
diff --git a/doc/scst_pg.sgml b/doc/scst_pg.sgml
new file mode 100644 (file)
index 0000000..95d7e1f
--- /dev/null
@@ -0,0 +1,2278 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<title>Generic SCSI Target Middle Level for Linux</title>
+
+<author>
+       <name>Vladislav Bolkhovitin &lt;<tt/vst @at@ vlnb .dot. net/&gt;</name>
+</author>
+
+<date>Version 0.9.3-pre4 2006/02/07, actual for SCST 0.9.3-pre4 and later</date>
+
+<abstract>
+This document describes SCSI target mid-level for Linux (SCST), its
+architecture and drivers from the driver writer's point of view. 
+</abstract>
+
+<toc>
+
+<sect>Introduction
+
+<p>
+SCST is a SCSI target mid-level subsystem for Linux. It is designed to
+provide unified, consistent interface between SCSI target drivers and
+Linux kernel and simplify target drivers development as much as
+possible. It has the following features:
+
+<itemize> 
+
+<item> Very low overhead, fine-grained locks and simplest commands
+processing path, which allow to reach maximum possible performance and
+scalability that close to theoretical limit.
+
+<item> Incoming requests can be processed in the caller's context or in
+one of the internal SCST's tasklets, therefore no extra context switches
+required. 
+
+<item> Complete SMP support.
+
+<item> Undertakes most problems, related to execution contexts, thus
+practically eliminating one of the most complicated problem in the
+kernel drivers development. For example, a target driver for Qlogic
+2200/2300 cards, which has all necessary features, is about 2000
+lines of code long, that is at least in several times less, than the
+initiator one.
+
+<item> Performs all required pre- and post- processing of incoming
+requests and all necessary error recovery functionality. 
+
+<item> Emulates necessary functionality of SCSI host adapter, because
+from a remote initiator's point of view SCST acts as a SCSI host with
+its own devices. Some of the emulated functions are the following:
+
+       <itemize>
+       
+       <item> Generation of necessary UNIT ATTENTIONs, their storage and
+       delivery to all connected remote initiators (sessions).
+
+       <item> RESERVE/RELEASE functionality. 
+
+       <item> CA/ACA conditions.
+       
+       <item> All types of RESETs and other task management functions.
+       
+       <item> REPORT LUNS command as well as SCSI address space management
+       in order to have consistent address space on all remote initiators,
+       since local SCSI devices could not know about each other to report
+       via REPORT LUNS command. Additionally, SCST responds with error on
+       all commands to non-existing devices and provides access control
+       (not implemented yet), so different remote initiators could see
+       different set of devices.
+
+       <item> Other necessary functionality (task attributes, etc.) as
+       specified in SAM-2, SPC-2, SAM-3, SPC-3 and other SCSI standards.
+       
+       </itemize>
+<item> Device handlers architecture provides extra reliability and
+security via verifying all incoming requests and allows to make any
+additional requests processing, which is completely independent from
+target drivers, for example, data caching or device dependent
+exceptional conditions treatment.
+
+</itemize>
+
+Interoperability between SCST and local SCSI initiators (like sd, st) is
+the additional issue that SCST is going to address (it is not
+implemented yet). It is necessary, because local SCSI initiators can
+change the state of the device, for example RESERVE the device, or some
+of its parameters and that would be done behind SCST, which could lead
+to various problems. Thus, RESERVE/RELEASE commands, locally generated
+UNIT ATTENTIONs, etc. should be intercepted and processed as if local
+SCSI initiators act as remote SCSI initiators connected to SCST. This
+feature requires some the kernel modification. Since in the current
+version it is not implemented, SCST and the target drivers are able to
+work with any unpatched 2.4 kernel version.
+
+Interface between SCST and the target drivers is based on work, done by
+University of New Hampshire Interoperability Labs (UNH IOL).
+
+All described below data structures and function could be found in
+<bf/scsi_tgt.h/. The SCST's Internet page is
+<url url="http://scst.sourceforge.net">.
+
+<sect>Terms and Definitions
+
+<p><bf/SCSI initiator device/
+
+A SCSI device that originates service and task management requests to be
+processed by a SCSI target device and receives device service and task
+management responses from SCSI target devices.
+
+<bf/SCSI target device/
+
+A SCSI device that receives device service and task management requests
+for processing and sends device service and task management responses
+to SCSI initiator devices or drivers. 
+
+<bf/SCST session/
+
+SCST session is the object that describes relationship between a remote
+initiator and SCST via a target driver. All the commands from the remote
+initiator is passed to SCST in the session. For example, for connection
+oriented protocols, like iSCSI, SCST session could be mapped to the TCP
+connection. SCST session is the close equivalent of I_T nexus object.
+
+<bf/Local SCSI initiator/
+
+A SCSI initiator that is located on the same host as SCST subsystem.
+Examples are sg and st drivers.
+
+<bf/Remote SCSI initiator/
+
+A SCSI initiator that is located on the remote host for SCST subsystem
+and makes client connections to SCST via SCSI target drivers.
+
+<bf/SCSI target driver/
+
+A Linux hardware or logical driver that acts as a SCSI target for remote
+SCSI initiators, i.e. accepts remote connections, passes incoming SCSI
+requests to SCST and sends SCSI responses from SCST back to their
+originators.
+
+<bf/Device handler driver/
+
+Also known as "device type specific driver" or "dev handler", is plugin
+for SCST, which helps SCST to analyze incoming requests and determine
+parameters, specific to various types of devices as well as perform some
+processing. See appropriate section for details.
+
+<sect>SCST Architecture
+
+<p> 
+SCST accepts commands and passes them to SCSI mid-level at the same
+way as SCSI high-level drivers (sg, sd, st) do. Figure 1 shows
+interaction between SCST, its drivers and Linux SCSI subsystem.
+
+<figure>
+<eps file="fig1.png">
+<img src="fig1.png">
+<caption>
+ <newline> Interaction between SCST, its drivers and Linux SCSI subsystem.
+</caption>
+</figure>
+
+<sect>Target driver registration
+
+<p>
+To work with SCST a target driver must register its template in SCST by
+calling scst_register_target_template(). The template lets SCST know the
+target driver's entry points. It is defined as the following:
+
+<sect1>Structure scst_tgt_template
+
+<p>
+<verb>
+struct scst_tgt_template 
+{
+       int sg_tablesize;
+       const char name[15];
+
+       unsigned unchecked_isa_dma:1;
+       unsigned use_clustering:1;
+
+       unsigned xmit_response_atomic:1; 
+       unsigned rdy_to_xfer_atomic:1;
+       unsigned report_aen_atomic:1;
+
+       int (* detect) (struct scst_tgt_template *tgt_template);
+       int (* release)(struct scst_tgt *tgt);
+
+       int (* xmit_response)(struct scst_cmd *cmd);
+       int (* rdy_to_xfer)(struct scst_cmd *cmd);
+       
+       void (*on_free_cmd) (struct scst_cmd *cmd);
+
+       void (* task_mgmt_fn_done)(struct scst_mgmt_cmd *mgmt_cmd);
+       void (* report_aen)(int mgmt_fn, const uint8_t *lun, int lun_len);
+       
+       int (*proc_info) (char *buffer, char **start, off_t offset,
+               int length, int *eof, struct scst_tgt *tgt, int inout);
+}
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/sg_tablesize/ - allows checking whether scatter/gather can be
+used or not and, if yes, sets the maximum supported count of
+scatter/gather entries
+
+<item><bf/name/ - the name of the template. Must be unique to identify
+the template. Must be defined.
+
+<item><bf/unchecked_isa_dma/ - true, if this target adapter uses
+unchecked DMA onto an ISA bus.
+
+<item><bf/use_clustering/ - true, if this target adapter wants to use
+clustering (i.e. smaller number of segments).
+
+<item><bf/xmit_response_atomic/, <bf/rdy_to_xfer_atomic/ - true, if the
+corresponding function supports execution in the atomic (non-sleeping)
+context.
+
+<item><bf/int (* detect) (struct scst_tgt_template *tgt_template)/ - this
+function is intended to detect the target adapters that are present in
+the system. Each found adapter should be registered by calling
+<bf/scst_register()/. The function should return a value >= 0 to signify
+the number of detected target adapters. A negative value should be
+returned whenever there is an error. Must be defined.
+
+<item><bf/int (* release)(struct scst_tgt *tgt)/ - this function is
+intended to free up the resources allocated to the device. The function
+should return 0 to indicate successful release or a negative value if
+there are some issues with the release. In the current version of SCST
+the return value is ignored. Must be defined.
+
+<item><bf/int (* xmit_response)(struct scst_cmd *cmd)/ - this
+function is equivalent to the SCSI queuecommand(). The target should
+transmit the response data and the status in the struct scst_cmd. See
+below for details. Must be defined.
+
+<item><bf/int (* rdy_to_xfer)(struct scst_cmd *cmd)/ - this function
+informs the driver that data buffer corresponding to the said command
+have now been allocated and it is OK to receive data for this command.
+This function is necessary because a SCSI target does not have any
+control over the commands it receives. Most lower-level protocols have a
+corresponding function which informs the initiator that buffers have
+been allocated e.g., XFER_RDY in Fibre Channel. After the data is
+actually received the low-level driver should call <bf/scst_rx_data()/
+in order to continue processing this command. Returns one of the 
+<bf/SCST_TGT_RES_*/ constants, described below. Pay attention to
+"atomic" attribute of the command, which can be get via
+<bf/scst_cmd_atomic()/: it is true if the function called in the atomic
+(non-sleeping) context. Must be defined.
+
+<item><bf/void (*on_free_cmd)(struct scst_cmd *cmd)/ - this function
+called to notify the driver that the command is about to be freed.
+Necessary, because for aborted commands <bf/xmit_response()/ could not be
+called. Could be used on IRQ context. Must be defined.
+
+<item><bf/void (* task_mgmt_fn_done)(struct scst_mgmt_cmd *mgmt_cmd)/ -
+this function informs the driver that a received task management
+function has been completed. Completion status could be get via
+<bf/scst_mgmt_cmd_get_status()/. No return value expected. Must be
+defined, if the target supports task management functionality.
+
+<item><bf/int (* report_aen)(int mgmt_fn, const uint8_t *lun, int
+lun_len)/ - this function is used for Asynchronous Event Notification.
+It is the responsibility of the driver to notify any/all initiators
+about the Asynchronous Event reported. Returns one of the
+<bf/SCST_TGT_RES_*/ constants, described below. Must be defined, if
+low-level protocol supports AEN. This feature is not implemented yet.
+
+<item><bf/int (*proc_info) (char *buffer, char **start, off_t offset,
+int length, int *eof, struct scst_tgt *tgt, int inout)/ - this function
+can be used to export the driver's statistics and other information to
+the world outside the kernel. Parameters:
+
+       <enum>
+       
+       <item> <bf/buffer, start, offset, length, eof/ - have the same
+       meaning as for <bf/read_proc_t/ function of the kernel
+       
+       <item> <bf/tgt/ - pointer to the target, for which the function
+       is called
+       
+       <item> <bf/inout/ - read/write direction flag, 0 - for reads, other
+       value - for writes
+       
+       </enum>
+
+If the driver needs to create additional files in its /proc
+subdirectory, it can use <bf/scst_proc_get_tgt_root()/ function to get
+the root proc_dir_entry.
+
+</itemize>
+
+Functions <bf/xmit_response()/, <bf/rdy_to_xfer()/ are expected to be
+non-blocking, i.e. return immediately and don't wait for actual data 
+transfer to finish. Blocking in such command could negatively impact on
+overall system performance. If blocking is necessary, it is worth to
+consider creating dedicated thread(s) in target driver, to which the
+commands would be passed and which would perform blocking operations
+instead of SCST. If the function allowed to sleep or not is defined by
+"atomic" attribute of the cmd that can be get via
+<bf/scst_cmd_atomic()/, which is true, if sleeping is not allowed. In
+this case, if the function requires sleeping, it can return
+<bf/SCST_TGT_RES_NEED_THREAD_CTX/ in order to be recalled in the thread
+context, where sleeping is allowed.
+
+Functions <bf/task_mgmt_fn_done()/ and <bf/report_aen()/ are recommended
+to be non-blocking as well. Blocking there will stop all management
+processing for all target drivers in the system (there is only one
+management thread in the system).
+
+Functions <bf/xmit_response()/, <bf/rdy_to_xfer()/ and <bf/report_aen()/
+can return the following error codes:
+
+<itemize>
+
+<item><bf/SCST_TGT_RES_SUCCESS/ - success.
+
+<item><bf/SCST_TGT_RES_QUEUE_FULL/ - internal device queue is full, retry
+again later.
+
+<item><bf/SCST_TGT_RES_NEED_THREAD_CTX/ - it is impossible to complete 
+requested task in atomic context. The command should be restarted in the
+thread context as described above.
+
+<item><bf/SCST_TGT_RES_FATAL_ERROR/ - fatal error, i.e. it is unable to
+perform requested operation. If returned by <bf/xmit_response()/ the
+command will be destroyed, if by <bf/rdy_to_xfer()/,
+<bf/xmit_response()/ will be called with <bf/HARDWARE ERROR/ sense data.
+
+</itemize>
+
+<sect2>More about <bf/xmit_response()/
+
+<p> 
+As already written above, function <bf/xmit_response()/ should transmit
+the response data and the status from the cmd parameter. Either it
+should transmit the data or the status is defined by bits of the value,
+returned by <bf/scst_cmd_get_tgt_resp_flags()/. They are:
+
+<itemize>
+
+<item><bf/SCST_TSC_FLAG_DATA/ - set if there are data to be sent
+
+<item><bf/SCST_TSC_FLAG_STATUS/ - set if the command is finished and
+there is status/sense to be sent
+
+</itemize>
+
+If <bf/SCST_TSC_FLAG_DATA/ is set, the data contained in the buffer,
+returned by <bf/scst_cmd_get_buffer()/ (pay attention to
+<bf/scst_cmd_get_use_sg()/ for scatter/gather) with length, returned by
+<bf/scst_cmd_get_resp_data_len()/. It is recommended to use
+<bf/scst_get_buf_*()/scst_put_buf()/ family of function instead of
+direct access to the data buffers, because they hide all HIGHMEM and
+SG/plain buffer issues.
+
+If <bf/SCST_TSC_FLAG_STATUS/ is set the status could be received by the
+appropriate <bf/scst_cmd_get_*_status()/ functions (see below).
+
+The sense, if any, is contained in the buffer, returned by
+<bf/scst_cmd_get_sense_buffer()/, with length, returned by
+<bf/scst_cmd_get_sense_buffer_len()/. SCST always works in
+<bf/autosense/ mode. If a low-level SCSI driver/device doesn't support
+autosense mode, SCST will issue REQUEST SENSE command, if necessary.
+Thus, if CHECK CONDITION established, target driver will always see
+sense in the sense buffer and isn't required to request the sense
+manually.
+
+It is possible, that <bf/SCST_TSC_FLAG_DATA/ is set, but
+<bf/SCST_TSC_FLAG_STATUS/ is not set. In this case the driver should
+only transmit the data, but not finish the command and transmit the
+status. Function <bf/xmit_response()/ will be called again either to
+transmit the status or data once more.
+
+After the response is completely sent, the target should call
+<bf/scst_tgt_cmd_done()/ function in order to allow SCST to free the
+command. 
+
+Function <bf/xmit_response()/ returns one of the <bf/SCST_TGT_RES_*/
+constants, described above. Pay attention to "atomic" attribute of the
+cmd, which can be get via <bf/scst_cmd_atomic()/: it is true if the
+function called in the atomic (non-sleeping) context.
+
+<sect1>Target driver registration functions
+
+<sect2>scst_register_target_template()
+
+<p>
+Function <bf/scst_register_target_template()/ is defined as the following:
+
+<verb>
+int scst_register_target_template(
+       struct scst_tgt_template *vtt)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/vtt/ - pointer to the target driver template
+</itemize>
+
+Returns 0 on success or appropriate error code otherwise.
+
+<sect2>scst_register()
+
+<p>
+Function <bf/scst_register()/ is defined as the following:
+
+<verb>
+struct scst_tgt *scst_register(
+       struct scst_tgt_template *vtt)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/vtt/ - pointer to the target driver template
+</itemize>
+
+Returns target structure based on template vtt or NULL in case of error.
+
+<sect>Target driver unregistration
+
+<p>
+In order to unregister itself target driver should at first call
+<bf/scst_unregister()/ for all its adapters and then call
+<bf/scst_unregister_target_template()/ for its template.
+
+<sect1>scst_unregister()
+
+<p>
+Function <bf/scst_unregister()/ is defined as the following:
+
+<verb>
+void scst_unregister(
+       struct scst_tgt *tgt)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/tgt/ - pointer to the target driver structure
+</itemize>
+
+<sect1>scst_unregister_target_template()
+
+<p>
+Function <bf/scst_unregister_target_template()/ is defined as the following:
+
+<verb>
+void scst_unregister_target_template(
+       struct scst_tgt_template *vtt)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/vtt/ - pointer to the target driver template
+</itemize>
+
+<sect>SCST session registration
+
+<p>
+When target driver determines that it needs to create new SCST session
+(for example, by receiving new TCP connection), it should call
+<bf/scst_register_session()/, that is defined as the following:
+
+<verb>
+struct scst_session *scst_register_session(
+       struct scst_tgt *tgt,
+       int atomic,
+       const char *initiator_name,
+       void *data,
+       void (*result_fn) (
+               struct scst_session *sess,
+               void *data, 
+               int result));
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/tgt/ - target
+
+<item><bf/atomic/ - true, if the function called in the atomic context 
+
+<item><bf/initiator_name/ - remote initiator's name, any NULL-terminated
+string, e.g. iSCSI name, which used as the key to found appropriate
+access control group. Could be NULL, then "default" group is used.  The
+groups are set up via /proc interface.
+
+<item><bf/data/ - data that will be used as the second
+parameter for <bf/bf/result_fn/()/ function
+
+<item><bf/result_fn/ - pointer to the function that will be
+asynchronously called when session initialization finishes. Can be NULL.
+Parameters:
+
+       <itemize>
+
+       <item><bf/sess/ - session
+
+       <item><bf/data/ - target driver supplied to
+       <bf/scst_register_session()/ data
+
+       <item><bf/result/ - session initialization result, 0 on success or
+       appropriate error code otherwise
+
+       </itemize>
+
+</itemize>
+
+A session creation and initialization is a complex task, which requires
+sleeping state, so it can't be fully done in interrupt context.
+Therefore the "bottom half" of it, if <bf/scst_register_session()/ is
+called from atomic context, will be done in SCST thread context. In this
+case <bf/scst_register_session()/ will return not completely initialized
+session, but the target driver can supply commands to this session via
+<bf/scst_rx_cmd()/. Those commands processing will be delayed inside
+SCST until the session initialization is finished, then their processing
+will be restarted. The target driver will be notified about finish of
+the session initialization by function <bf/result_fn()/. On success the
+target driver could do nothing, but if the initialization fails, the
+target driver must ensure that no more new commands being sent or will
+be sent to SCST after <bf/result_fn()/ returns. All already sent to SCST
+commands for failed session will be returned in <bf/xmit_response()/
+with BUSY status. In case of failure the driver shall call
+<bf/scst_unregister_session()/ inside <bf/result_fn()/, it will NOT be
+called automatically. Thus, <bf/scst_register_session()/ can be called
+even on IRQ context. 
+
+Session registration is illustrated on Figure 2 and Figure 3.
+
+<figure>
+<eps file="fig2.png">
+<img src="fig2.png">
+<caption>
+ <newline> Session registration when <bf/atomic/ parameter is false
+</caption>
+</figure>
+
+<figure>
+<eps file="fig3.png">
+<img src="fig3.png">
+<caption>
+ <newline> Session registration when <bf/atomic/ parameter is true 
+</caption>
+</figure>
+
+<sect>SCST session unregistration
+
+<p>
+SCST session unregistration basically is the same, except that instead of
+atomic parameter there is <bf/wait/ one.
+
+<verb>
+void scst_unregister_session(
+       struct scst_session *sess, 
+       int wait,
+       void (* unreg_done_fn)(
+               struct scst_session *sess))
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/sess/ - session to be unregistered
+
+<item><bf/wait/ - if true, instructs to wait until all commands, which
+currently executing and belonged to the session, finished. Otherwise,
+target driver should be prepared to receive <bf/xmit_response()/ for
+the session after <bf/scst_unregister_session()/ returns.
+
+<item><bf/unreg_done_fn/ - pointer to the function that will be
+asynchronously called when the last session's command finishes and the
+session is about to be completely freed. Can be NULL. Parameter:
+
+       <itemize>
+
+       <item><bf/sess/ - session
+
+       </itemize>
+       
+</itemize>
+
+All outstanding commands will be finished regularly. After
+<bf/scst_unregister_session()/ returned no new commands must be sent to
+SCST via <bf/scst_rx_cmd()/. Also, the caller must ensure that no
+<bf/scst_rx_cmd()/ or <bf/scst_rx_mgmt_fn_*()/ is called in paralell
+with <bf/scst_unregister_session()/. 
+
+Function <bf/scst_unregister_session()/ can be called before
+<bf/result_fn()/ of <bf/scst_register_session()/ called, i.e. during the
+session registration/initialization.
+
+<sect>The commands processing and interaction between SCST and its drivers
+
+<p>
+The commands processing by SCST started when target driver calls
+<bf/scst_rx_cmd()/. This function returns SCST's command. Then the target
+driver finishes the command's initialization, if necessary, for
+example, storing necessary target driver specific data there, and calls
+<bf/scst_cmd_init_done()/ telling SCST that it can start the processing.
+Then SCST translates the command's LUN to local device, determines the
+command's data direction and required data buffer size by calling
+appropriate device handler's <bf/parse()/ function. Then:
+
+<itemize>
+
+<item>If the command required no data transfer, it will be passed to
+SCSI mid-level directly or via device handler's <bf/exec()/ call.
+
+<item>If the command is <bf/READ/ command (data to the target),
+necessary space will be allocated and then the command will be passed
+to SCSI mid-level directly or via device handler's <bf/exec()/ call.
+
+<item>If the command is <bf/WRITE/ command (data from the target),
+necessary space will be allocated, then the target's <bf/rdy_to_xfer()/
+function will be called, telling the target that the space is ready and
+it can start data transferring. When all the data are read from the
+target, it will call <bf/scst_rx_data()/, and the command will be passed
+to SCSI mid-level directly or via device handler's <bf/exec()/ call.
+
+</itemize>
+
+When the command is finished by SCSI mid-level, device handler's
+<bf/dev_done()/ is called to notify it about the command's
+completion. Then in order to send the response the target's
+<bf/xmit_response()/ is called. When the response, including data, if
+any, is transmitted, the target will call <bf/scst_tgt_cmd_done()/
+telling SCST that it can free the command and its data buffer.
+
+Then during the command's deallocation device handler's and the target's
+<bf/on_free_cmd()/ will be called in this order, if set.
+
+This sequence is illustrated on Figure 4. To simplify the picture, sign
+"..." means SCST's waiting state for the corresponding command to
+complete. During this state SCST and its drivers continue processing of
+other commands, if there are any. One way arrow, for example to
+<bf/xmit_response()/, means that after this function returns, nothing
+valuable for the current command will be done and SCST goes sleeping or
+to the next command processing until corresponding event happens.
+<figure>
+<eps file="fig4.png">
+<img src="fig4.png">
+<caption>
+ <newline> The commands processing flow
+</caption>
+</figure>
+
+Additionally, before calling <bf/scst_cmd_init_done()/ the target driver can
+set the following the command's flags or parameters:
+
+<itemize>
+
+<item> <bf/DATA_BUF_ALLOCED/ - set if the data buffer is already 
+allocated. The flag is set via <bf/scst_cmd_set_data_buff_alloced()/ and
+get via <bf/scst_cmd_get_data_buff_alloced()/. Useful, for instance, for
+iSCSI unsolicited data. 
+
+<item> Expected transfer length and direction via
+<bf/scst_cmd_set_expected()/ as supplied by remote initiator, if any.
+This values will be used only if the command's opcode is unknown for
+SCST, for example for vendor-specific commands. If these values not set
+and opcode isn't known, the command will be completed by SCST in
+preprocessing phase with <bf/INVALID OPCODE/ sense.
+
+</itemize>
+
+<sect1>The commands processing functions
+
+<sect2>scst_rx_cmd()
+
+<p>
+Function <bf/scst_rx_cmd()/ creates and sends new command to SCST. Returns
+the command on success or NULL otherwise. It is defined as the
+following:
+
+<verb>
+struct scst_cmd *scst_rx_cmd(
+       struct scst_session *sess, 
+       const uint8_t *lun, 
+       int lun_len,
+       const uint8_t *cdb, 
+       int cdb_len, 
+       int atomic)
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/sess/ - SCST's session
+
+<item><bf/lun/ - pointer to device's LUN as specified in SCSI
+Architecture Model 2/3 without any byte order translation. Extended
+addressing method is not supported.
+
+<item><bf/lun_len/ - LUN's length
+
+<item><bf/cdb/ - SCSI CDB
+
+<item><bf/cdb_len/ - CDB's length
+
+<item><bf/atomic/ - if true, the command will be allocated with
+GFP_ATOMIC flag, otherwise GFP_KERNEL will be used
+
+</itemize>
+
+<sect2>scst_cmd_init_done()
+
+<p>
+Function <bf/scst_cmd_init_done()/ notifies SCST that the driver finished
+its part of the command initialization, and the command is ready for
+execution. It is defined as the following:
+
+<verb>
+void scst_cmd_init_done(
+       struct scst_cmd *cmd, 
+       int pref_context)
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/cmd/ - the command
+
+<item><bf/pref_context/ - preferred command execution context. See
+<bf/SCST_CONTEXT_*/ constants below for details.
+
+</itemize>
+
+<sect2>scst_rx_data()
+
+<p>
+Function <bf/scst_rx_data()/ notifies SCST that the driver received all
+the necessary data and the command is ready for further processing. It
+is defined as the following:
+
+<verb>
+void scst_rx_data(
+       struct scst_cmd *cmd, 
+       int status,
+       int pref_context)
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/cmd/ - the command
+
+<item><bf/status/ - completion status, see below.
+
+<item><bf/pref_context/ - preferred command execution context. See
+<bf/SCST_CONTEXT_*/ constants below for details.
+
+</itemize>
+
+Parameter <bf/status/ can have one of the following values:
+
+<itemize>
+
+<item><bf/SCST_RX_STATUS_SUCCESS/ - success
+
+<item><bf/SCST_RX_STATUS_ERROR/ - data receiving finished with error, so
+SCST should set the sense and finish the command by calling
+<bf/xmit_response()/
+
+<item><bf/SCST_RX_STATUS_ERROR_SENSE_SET/ - data receiving finished with 
+error and the sense is set, so SCST should finish the command by calling 
+<bf/xmit_response()/
+
+<item><bf/SCST_RX_STATUS_ERROR_FATAL/ - data receiving finished with
+fatal error, so SCST should finish the command, but don't call
+<bf/xmit_response()/. In this case the driver must free all associated
+with the command data before calling <bf/scst_rx_data()/.
+
+</itemize>
+
+<sect2>scst_tgt_cmd_done()
+
+<p>
+Function <bf/scst_tgt_cmd_done()/ notifies SCST that the driver sent the
+data and/or response. It must not been called if there are an error and
+<bf/xmit_response()/ returned something other, than
+<bf/SCST_TGT_RES_SUCCESS/. It is defined as the following:
+
+<verb>
+void scst_tgt_cmd_done(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+<itemize>
+<item><bf/cmd/ - the command
+</itemize>
+
+<sect1>The commands processing context
+
+<p>
+Execution context often is a major problem in the kernel drivers
+development, because many contexts, like IRQ one, greatly limit
+available functionality, therefore require additional complex code in
+order to pass processing to more simple context. SCST does its best to
+undertake most of the context handling. 
+
+On the initialization time SCST creates for internal command processing
+as many threads as there are processors in the system or specified by
+user via <bf/scst_threads/ module parameter. Similarly, as many tasklets
+created as there are processors in the system.
+
+Each command can be processed in one of four contexts:
+
+<enum>
+<item>Directly, i.e. in the caller's context, without limitations
+<item>Directly atomically, i.e. with sleeping forbidden
+<item>In the SCST's internal per processor or per session thread
+<item>In the SCST's per processor tasklet
+</enum>
+
+The target driver sets this context as pref_context parameter for 
+<bf/scst_cmd_init_done()/ and <bf/scst_rx_data()/. Additionally, target's
+template's <bf/xmit_response_atomic/ and <bf/rdy_to_xfer_atomic/ flags
+have direct influence on the context. If one of them is false, the
+corresponding function will never be called in the atomic context and,
+if necessary, the command will be rescheduled to one of the SCST's 
+threads.
+
+SCST in some circumstances can change preferred context to less
+restrictive one, for example, for large data buffer allocation, if
+there is not enough GFP_ATOMIC memory. 
+
+<sect2>Preferred context constants
+
+<p>
+There are the following preferred context constants: 
+
+<itemize>
+
+<item><bf/SCST_CONTEXT_DIRECT/ - sets direct command processing (i.e.
+regular function calls in the current context) sleeping is allowed, no
+context restrictions. Supposed to be used when calling from thread
+context where no locks are held and the driver's architecture allows
+sleeping without performance degradation or anything like that.
+
+<item><bf/SCST_CONTEXT_DIRECT_ATOMIC/ - sets direct command processing 
+(i.e. regular function calls in the current context), sleeping is not
+allowed. Supposed to be used when calling on thread context where there
+are locks held, when calling on softirq context or the driver's
+architecture does not allow sleeping without performance degradation or
+anything like that.
+
+<item><bf/SCST_CONTEXT_TASKLET/ - tasklet or thread context required for 
+the command processing. Supposed to be used when calling from IRQ
+context.
+
+<item><bf/SCST_CONTEXT_THREAD/ - thread context required for the
+command processing. Supposed to be used if the driver's architecture
+does not allow using any of above.
+
+</itemize>
+
+<sect>Task management functions
+
+<p>
+There are the following task management functions supported:
+
+<itemize>
+
+<item> <bf/SCST_ABORT_TASK/ - <bf/ABORT_TASK/ task management function,
+aborts the specified task (command). Returns completion status via
+<bf/task_mgmt_fn_done()/ when the command (task) is actually aborted.
+
+<item> <bf/SCST_ABORT_TASK_SET/ - <bf/ABORT_TASK_SET/ task management
+function, aborts all tasks (commands) on the specified device. Returns
+the success via <bf/task_mgmt_fn_done()/ immediately, not waiting for
+the commands being actually aborted.
+
+<item> <bf/SCST_CLEAR_ACA/ - <bf/CLEAR_ACA/ task management function,
+currently does nothing.
+
+<item> <bf/SCST_CLEAR_TASK_SET/ - <bf/CLEAR_TASK_SET/ task management
+function, the same as <bf/SCST_ABORT_TASK_SET/.
+
+<item> <bf/SCST_LUN_RESET/ - <bf/LUN_RESET/ task management function,
+implemented via <bf/scsi_reset_provider()/ call for the specified device
+with <bf/SCSI_TRY_RESET_DEVICE/ parameter.
+
+<item> <bf/SCST_TARGET_RESET/ - <bf/TARGET_RESET/ task management
+function, implemented via <bf/scsi_reset_provider()/ call for all the
+hosts in the system (one device per each host) with
+<bf/SCSI_TRY_RESET_BUS/ parameter at first and then, if failed, with
+<bf/SCSI_TRY_RESET_HOST/.
+
+</itemize>
+
+<sect1>scst_rx_mgmt_fn_tag()
+
+<p>
+Function <bf/scst_rx_mgmt_fn_tag()/ tells SCST to perform the specified
+task management function, based on the command's tag. Can be used only
+for <bf/SCST_ABORT_TASK/.
+
+It is defined as the following:
+
+<verb>
+int scst_rx_mgmt_fn_tag(
+       struct scst_session *sess, 
+       int fn, 
+       uint32_t tag,
+       int atomic, 
+       void *tgt_specific)
+</verb>
+
+Where:
+
+<itemize>
+
+<item> <bf/sess/ - the session, on which the command should be performed.
+
+<item> <bf/fn/ - task management function, one of the constants above.
+
+<item> <bf/tag/ - the command's tag.
+
+<item> <bf/atomic/ - true, if the function called in the atomic context.
+
+<item> <bf/tgt_specific/ - pointer to the target driver specific data,
+can be retrieved in <bf/task_mgmt_fn_done()/ via
+<bf/scst_mgmt_cmd_get_status()/ function.
+
+</itemize>
+
+Returns 0 if the command was successfully created and scheduled for
+execution, error code otherwise. On success, the completion status of
+the command will be reported asynchronously via <bf/task_mgmt_fn_done()/
+driver's callback.
+
+<sect1>scst_rx_mgmt_fn_lun()
+
+<p>
+Function <bf/scst_rx_mgmt_fn_lun()/ tells SCST to perform the specified
+task management function, based on the LUN. Currently it can be used for
+any function, except <bf/SCST_ABORT_TASK/.
+
+It is defined as the following:
+
+<verb>
+int scst_rx_mgmt_fn_lun(
+       struct scst_session *sess, 
+       int fn,
+       const uint8_t *lun, 
+       int lun_len,
+       int atomic, 
+       void *tgt_specific);
+</verb>
+
+Where:
+
+<itemize>
+
+<item> <bf/sess/ - the session, on which the command should be performed.
+
+<item> <bf/fn/ - task management function, one of the constants above.
+
+<item> <bf/lun/ - LUN, the format is the same as for <bf/scst_rx_cmd()/.
+
+<item> <bf/lun_len/ - LUN's length.
+
+<item> <bf/atomic/ - true, if the function called in the atomic context.
+
+<item> <bf/tgt_specific/ - pointer to the target driver specific data,
+can be retrieved in <bf/task_mgmt_fn_done()/ via
+<bf/scst_mgmt_cmd_get_status()/ function.
+
+</itemize>
+
+Returns 0 if the command was successfully created and scheduled for
+execution, error code otherwise. On success, the completion status of
+the command will be reported asynchronously via <bf/task_mgmt_fn_done()/
+driver's callback.
+
+<sect>Device specific drivers (device handlers)
+
+<p>
+Device specific drivers are plugins for SCST, which help SCST to analyze
+incoming requests and determine parameters, specific to various types
+of devices. Device handlers are intended for the following:
+
+<itemize>
+
+<item>To get data transfer length and direction directly from CDB and
+current device's configuration exactly as an end-target SCSI device
+does. This serves two purposes:
+
+       <itemize>
+       
+       <item> Improves security and reliability by not trusting the data
+       supplied by remote initiator via SCSI low-level protocol.
+       
+       <item> Some low-level SCSI protocols don't provide data transfer
+       length and direction, so that information can be get only
+       directly from CDB and current device's configuration. For
+       example, for tape devices to get data transfer size it might be
+       necessary to know block size setting.
+       
+       </itemize>
+
+<item>To process some exceptional conditions, like ILI on tape devices.
+
+<item>To initialize incoming commands with some device-specific
+parameters, like timeout value.
+
+<item>To allow some additional device-specific commands pre-, post- 
+processing or alternative execution, like copying data from system
+cache, and do that completely independently from target drivers.
+
+</itemize>
+
+Device handlers performs very lightweight processing and therefore
+should not considerably affect performance or CPU load. They are
+considered to be part of SCST, so they could directly access any fields
+in SCST's structures as well as use the corresponding functions.
+
+Without appropriate device handler SCST hides devices of this type from
+remote initiators and returns <bf/HARDWARE ERROR/ sense data to any
+requests to them.
+
+<sect1>Device specific driver registration
+
+<sect2>scst_register_dev_driver()
+
+<p>
+To work with SCST a device specific driver must register itself in SCST by
+calling <bf/scst_register_dev_driver()/. It is defined as the following:
+
+<verb>
+int scst_register_dev_driver(
+       struct scst_dev_type *dev_type)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/dev_type/ - device specific driver's description structure
+</itemize>
+
+The function returns 0 on success or appropriate error code otherwise.
+
+<sect2>Structure <bf/scst_dev_type/
+
+<p>
+Structure <bf/scst_dev_type/ is defined as the following:
+
+<verb>
+struct scst_dev_type
+{
+       char name[15];
+       int type;
+       unsigned parse_atomic:1;
+       unsigned exec_atomic:1;
+       unsigned dev_done_atomic:1;
+       
+       int (*init) (struct scst_dev_type *dev_type);
+       void (*release) (struct scst_dev_type *dev_type);
+       int (*attach) (struct scst_device *dev);
+       void (*detach) (struct scst_device *dev);
+       int (*attach_tgt) (struct scst_tgt_device *tgt_dev);
+       void (*detach_tgt) (struct scst_tgt_device *tgt_dev);
+       int (*parse) (struct scst_cmd *cmd);
+       int (*exec) (struct scst_cmd *cmd, 
+               void (*scst_cmd_done)(struct scsi_cmnd *cmd, int next_state));
+       int (*dev_done) (struct scst_cmd *cmd);
+       int (*task_mgmt_fn) (struct scst_mgmt_cmd *mgmt_cmd, 
+               struct scst_tgt_dev *tgt_dev, struct scst_cmd *cmd_to_abort);
+       int (*on_free_cmd) (struct scst_cmd *cmd);
+       
+       int (*proc_info) (char *buffer, char **start, off_t offset,
+               int length, int *eof, struct scst_dev_type *dev_type,
+               int inout)
+       struct module *module;
+}
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/name/ - the name of the device handler. Must be defined and
+unique
+
+<item><bf/type/ - SCSI type of the supported device. Must be defined.
+
+<item><bf/parse_atomic/, <bf/exec_atomic/, <bf/dev_done_atomic/ - true,
+if corresponding function supports execution in the atomic
+(non-sleeping) context
+
+<item><bf/int (*init) (struct scst_dev_type *dev_type)/ - called on the
+device handler load, before the first attach(). Returns 0 on success,
+error code otherwise.
+
+<item><bf/void (*release) (struct scst_dev_type *dev_type)/ - called on
+the device handler unload, after final detach()
+
+<item><bf/int (*attach) (struct scst_device *dev)/ - called when new
+device is attaching to the device handler
+
+<item><bf/void (*detach) (struct scst_device *dev)/ - called when new
+device is detaching from the device handler
+
+<item><bf/int (*attach_tgt) (struct scst_tgt_device *tgt_dev)/ - called
+when new tgt_device (session) is attaching to the device handler
+
+<item><bf/void (*detach_tgt) (struct scst_tgt_device *tgt_dev)/ - called
+when tgt_device (session) is detaching from the device handler
+
+<item><bf/int (*parse) (struct scst_cmd *cmd, const struct scst_info_cdb
+*cdb_info)/ - called to parse CDB from the command. It should initialize
+<bf/cmd->bufflen/ and <bf/cmd->data_direction/ (see below
+<bf/SCST_DATA_*/ constants) if necessary, otherwise defaults based on
+<bf/cdb_info/ will be used. Parameter <bf/cdb_info/ provides some info
+about the CDB (see below). Pay attention to "atomic" attribute of the
+cmd, which can be via by <bf/scst_cmd_atomic()/: it is true if the
+function called in the atomic (non-sleeping) context. Returns the 
+command's next state or <bf/SCST_CMD_STATE_DEFAULT/, if the next default 
+state should be used, or <bf/SCST_CMD_STATE_NEED_THREAD_CTX/ if the 
+function called in atomic context, but requires sleeping. In the last
+case, the function will be recalled in the thread context, where
+sleeping is allowed. Additionally, <bf/SCST_CMD_DATA_BUF_ALLOCED/ flag
+can be set by <bf/parse()/ (see above). Must be defined.
+
+<item><bf/int (*exec) (struct scst_cmd *cmd, void (*scst_cmd_done)( struct
+scst_cmd *cmd, int next_state))/ - called to execute CDB. The result of
+the CDB execution is reported via <bf/scst_cmd_done()/ callback. Pay
+attention to "atomic" attribute of the command, which can be get via
+<bf/scst_cmd_atomic()/: it is true if the function called in the
+atomic (non-sleeping) context. For <bf/scst_cmd_done()/ parameter
+<bf/next_state/ is the command's next state or
+<bf/SCST_CMD_STATE_DEFAULT/, if the next default state should be used.
+Using this function modules <bf/devdisk_perf/ and <bf/devtape_perf/ were
+implemented. These modules in their <bf/exec()/ method skip (pretend to
+execute) all READ and WRITE operations and thus allow direct link
+performance measurements without overhead of actual data transferring
+from/to underlying SCSI device. See also <bf/scst_is_cmd_local()/ below.
+Returns:
+
+       <itemize>
+
+       <item><bf/SCST_EXEC_COMPLETED/ - the command is done, go to
+       other ones
+
+       <item><bf/SCST_EXEC_NEED_THREAD/ - thread context is required to
+       execute the command. <bf/Exec()/ will be called again in the
+       thread context.
+
+       <item><bf/SCST_EXEC_NOT_COMPLETED/ - the command should be sent
+       to SCSI mid-level.
+       
+       </itemize>
+
+<item><bf/int (*dev_done) (struct scst_cmd *cmd)/ - called to notify
+device handler about the result of the command's execution and perform
+some post processing. If <bf/parse()/ function is called,
+<bf/dev_done()/ is guaranteed to be called as well. The command's fields
+<bf/tgt_resp_flags/ and <bf/resp_data_len/ should be set by this
+function, but SCST offers good defaults. Pay attention to "atomic"
+attribute of the command, which can be get via
+<bf/scst_cmd_atomic()/: it is true if the function called in the
+atomic (non-sleeping) context. Returns the command's next state or
+<bf/SCST_CMD_STATE_DEFAULT/, if the next default state should be used,
+or <bf/SCST_CMD_STATE_NEED_THREAD_CTX/ if the function called in atomic
+context, but requires sleeping. In the last case, the function will be
+recalled in the thread context, where sleeping is allowed.
+
+<item><bf/int (*task_mgmt_fn) (struct scst_mgmt_cmd *mgmt_cmd,  struct
+scst_tgt_dev *tgt_dev, struct scst_cmd *cmd_to_abort)/ - called to
+execute a task management command. Returns: 
+
+       <itemize>
+
+       <item><bf/SCST_DEV_TM_COMPLETED_SUCCESS/ - the command is done
+       with success, no firther actions required
+
+       <item><bf/SCST_DEV_TM_COMPLETED_FAILED/ - the command is failed, 
+       no firther actions required
+
+       <item><bf/SCST_DEV_TM_NOT_COMPLETED/ - regular standard actions
+       for the command should be done
+
+       </itemize>
+
+<bf/NOTE/: for <bf/SCST_ABORT_TASK/ called under spinlock
+
+<item><bf/void (*on_free_cmd) (struct scst_cmd *cmd)/ - called to notify
+device handler that the command is about to be freed. Could be called on
+IRQ context.
+
+<item><bf/int (*proc_info) (char *buffer, char **start, off_t offset,
+int length, int *eof, struct scst_dev_type *dev_type, int inout)/ - this
+function can be used to export the handler's statistics and other
+information to the world outside the kernel. Parameters:
+
+       <enum>
+       
+       <item> <bf/buffer, start, offset, length, eof/ - have the same
+       meaning as for <bf/read_proc_t/ function of the kernel
+       
+       <item> <bf/dev_type/ - pointer to the device handler, for which
+       the function is called
+       
+       <item> <bf/inout/ - read/write direction flag, 0 - for reads, other
+       value - for writes
+       
+       </enum>
+
+If the driver needs to create additional files in its /proc
+subdirectory, it can use <bf/scst_proc_get_dev_type_root()/ function to get
+the root proc_dir_entry.
+
+<item><bf/struct module *module/ - pointer to device handler's module
+
+</itemize>
+
+Structure <bf/scst_info_cdb/ is defined as the following:
+
+<verb>
+struct scst_info_cdb
+{
+       enum scst_cdb_flags flags;
+       scst_data_direction direction;
+       unsigned int transfer_len;
+       unsigned short cdb_len;
+       const char *op_name;
+}
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/flags/ - CDB's flags can be (OR'ed):
+
+       <itemize>
+
+       <item><bf/SCST_TRANSFER_LEN_TYPE_FIXED/ - set if data length in
+       CDB set in blocks
+
+       <item><bf/SCST_SMALL_TIMEOUT/ - set if CDB requires small timeout
+
+       <item><bf/SCST_LONG_TIMEOUT/ - set if CDB requires long timeout
+       
+       </itemize>
+
+<item><bf/direction/ - one of the <bf/SCST_DATA_*/ constants (see below)
+
+<item><bf/transfer_len/ - CDB's data length as set in CDB
+
+<item><bf/cdb_len/ - CDB's length
+
+<item><bf/op_name/ - the name of the command
+
+</itemize>
+
+Field <bf/cmd->data_direction/, set by <bf/parse()/, can have one of the
+following values:
+
+<itemize>
+
+<item><bf/SCST_DATA_UNKNOWN/ - data flow direction is unknown
+
+<item><bf/SCST_DATA_WRITE/ - data flow direction is <bf/WRITE/ (from
+target to initiator)
+
+<item><bf/SCST_DATA_READ/ - data flow direction is <bf/READ/ (from
+initiator to target)
+
+<item><bf/SCST_DATA_NONE/ - there is no data transfer
+
+</itemize>
+
+<sect1>Device specific driver unregistration
+
+<p>
+Device specific driver is unregistered by calling
+<bf/scst_unregister_dev_driver()/. It is defined as the following:
+
+<verb>
+void scst_unregister_dev_driver(
+       struct scst_dev_type *dev_type)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/dev_type/ - device specific driver's description structure
+</itemize>
+
+<sect>SCST commands' states
+
+<p> 
+There are the following states, which a SCST command passes through
+during execution and which could be returned by device handler's
+<bf/parse()/ and <bf/dev_done()/ (but not all states are allowed to be
+returned): 
+
+<itemize>
+
+<item><bf/SCST_CMD_STATE_INIT_WAIT/ - the command is created, but 
+<bf/scst_cmd_init_done()/ not called
+
+<item><bf/SCST_CMD_STATE_INIT/ - LUN translation (i.e. <bf/cmd->tgt_dev/
+assignment) state
+
+<item><bf/SCST_CMD_STATE_REINIT/ - again LUN translation, used if device
+handler wants to restart the command on another LUN
+
+<item><bf/SCST_CMD_STATE_DEV_PARSE/ - device handler's <bf/parse()/ is going
+to be called
+
+<item><bf/SCST_CMD_STATE_PREPARE_SPACE/ - allocation of the command's
+data buffer
+
+<item><bf/SCST_CMD_STATE_RDY_TO_XFER/ - target driver's
+<bf/rdy_to_xfer()/ is going to be called
+
+<item><bf/SCST_CMD_STATE_DATA_WAIT/ - waiting for data from the initiator
+(until <bf/scst_rx_data()/ called)
+
+<item><bf/SCST_CMD_STATE_SEND_TO_MIDLEV/ - the command is going to be
+sent to SCSI mid-level for execution
+
+<item><bf/SCST_CMD_STATE_EXECUTING/ - waiting for the command's execution 
+finish
+
+<item><bf/SCST_CMD_STATE_DEV_DONE/ - device handler's <bf/dev_done()/ is
+going to be called
+
+<item><bf/SCST_CMD_STATE_XMIT_RESP/ - target driver's
+<bf/xmit_response()/ is going to be called
+
+<item><bf/SCST_CMD_STATE_XMIT_WAIT/ - waiting for data/response's
+transmission finish (until <bf/scst_tgt_cmd_done()/ called)
+
+<item><bf/SCST_CMD_STATE_FINISHED/ - the command finished and going to be 
+freed
+
+</itemize>
+
+<sect>SCST's structures manipulation functions
+
+<p>
+Target drivers must not directly access any fields in SCST's structures,
+they must use only described below functions.
+
+<sect1>SCST target driver manipulation functions
+
+<sect2>scst_tgt_get_tgt_specific() and scst_tgt_set_tgt_specific()
+
+<p> 
+Function <bf/scst_tgt_get_tgt_specific()/ returns pointer to the target
+driver specific data, set by <bf/scst_tgt_set_tgt_specific()/. It is
+defined as the following:
+
+<verb>
+void *scst_tgt_get_tgt_specific(
+       struct scst_tgt *tgt)
+</verb>
+
+Function <bf/scst_tgt_set_tgt_specific()/ stores the target driver
+specific data that could be retrieved later by
+by<bf/scst_tgt_get_tgt_specific()/. It is defined as the following:
+
+<verb>
+void scst_tgt_set_tgt_specific(
+       struct scst_tgt *tgt,
+       void *val)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/tgt/ - pointer to the SCST target structure
+<item><bf/val/ - pointer to the target driver specific data
+</itemize>
+
+<sect1>SCST session manipulation functions
+
+<sect2>scst_sess_get_tgt_specific() and scst_sess_set_tgt_specific()
+
+<p>
+Function <bf/scst_sess_get_tgt_specific()/ returns pointer to the target
+driver specific data, set by <bf/scst_sess_set_tgt_specific()/. It is
+defined as the following:
+
+<verb>
+void *scst_sess_get_tgt_specific(
+       struct scst_session *sess)
+</verb>
+
+Function <bf/scst_sess_set_tgt_specific()/ stores the target driver
+specific data that could be retrieved later by
+by<bf/scst_sess_get_tgt_specific()/. It is defined as the following:
+
+<verb>
+void scst_sess_set_tgt_specific(
+       struct scst_session *sess,
+       void *val)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/sess/ - pointer to the SCST session structure
+<item><bf/val/ - pointer to the target driver specific data
+</itemize>
+
+<sect1>SCST command manipulation functions
+
+<sect2>scst_cmd_atomic()
+
+<p>
+Function <bf/scst_cmd_atomic()/ returns true if the command is
+being executed in the atomic context or false otherwise. It is defined
+as the following:
+
+<verb>
+int scst_cmd_atomic(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command to check
+</itemize>
+
+<sect2>scst_cmd_get_session()
+
+<p>
+Function <bf/scst_cmd_get_session()/ returns the command's session. It
+is defined as the following:
+
+<verb>
+struct scst_session *scst_cmd_get_session(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_resp_data_len()
+
+<p>
+Function <bf/scst_cmd_get_resp_data_len()/ returns the command's
+response data length. It is defined as the following:
+
+<verb>
+unsigned int scst_cmd_get_resp_data_len(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_tgt_resp_flags()
+
+<p>
+Function <bf/scst_cmd_get_tgt_resp_flags()/ returns the command's
+response data response flags (SCST_TSC_FLAG_* constants). It is defined
+as the following:
+
+<verb>
+int scst_cmd_get_tgt_resp_flags(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_buffer()
+
+<p>
+Function <bf/scst_cmd_get_buffer()/ returns the command's data buffer.
+It is defined as the following:
+
+<verb>
+void *scst_cmd_get_buffer(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+It is recommended to use <bf/scst_get_buf_*()/scst_put_buf()/ family of
+function instead of direct access to the data buffers, because they hide
+all HIGHMEM and SG/plain buffer issues.
+
+<sect2>scst_cmd_get_bufflen()
+
+<p>
+Function <bf/scst_cmd_get_bufflen()/ returns the command's data buffer
+length. It is defined as the following:
+
+<verb>
+unsigned int scst_cmd_get_bufflen(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+It is recommended to use <bf/scst_get_buf_*()/scst_put_buf()/ family of
+function instead of direct access to the data buffers, because they hide
+all HIGHMEM and SG/plain buffer issues.
+
+<sect2>scst_cmd_get_use_sg()
+
+<p>
+Function <bf/scst_cmd_get_use_sg()/ returns the command's <bf/use_sg/
+value. Its meaning is the same as for <bf/scsi_cmnd/. The function is
+defined as the following:
+
+<verb>
+unsigned short scst_cmd_get_use_sg(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+It is recommended to use <bf/scst_get_buf_*()/scst_put_buf()/ family of
+function instead of direct access to the data buffers, because they hide
+all HIGHMEM and SG/plain buffer issues.
+
+<sect2>scst_cmd_get_data_direction()
+
+<p>
+Function <bf/scst_cmd_get_data_direction()/ returns the command's data
+direction (SCST_DATA_* constants). It is defined as the following:
+
+<verb>
+scst_data_direction scst_cmd_get_data_direction(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_status()
+
+<p>
+Functions <bf/scst_cmd_get_status()/ returns the status byte from
+host device. It is defined as the following:
+
+<verb>
+uint8_t scst_cmd_get_status(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_masked_status()
+
+<p>
+Functions <bf/scst_cmd_get_masked_status()/ returns the status byte set
+from host device by status_byte(). It is defined as the following:
+
+<verb>
+uint8_t scst_cmd_get_masked_status(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_msg_status()
+
+<p>
+Functions <bf/scst_cmd_get_msg_status()/ returns the status from host
+adapter itself. It is defined as the following:
+
+<verb>
+uint8_t scst_cmd_get_msg_status(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_host_status()
+
+<p>
+Functions <bf/scst_cmd_get_host_status()/ returns the status set by
+low-level driver to indicate its status. It is defined as the following:
+
+<verb>
+uint16_t scst_cmd_get_host_status(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_driver_status()
+
+<p>
+Functions <bf/scst_cmd_get_driver_status()/ returns the status set by
+SCSI mid-level. It is defined as the following:
+
+<verb>
+uint16_t scst_cmd_get_driver_status(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_sense_buffer()
+
+<p>
+Functions <bf/scst_cmd_get_sense_buffer()/ returns pointer to the sense
+buffer. It is defined as the following:
+
+<verb>
+uint8_t *scst_cmd_get_sense_buffer(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_sense_buffer_len()
+
+<p>
+Functions <bf/scst_cmd_get_sense_buffer_len()/ returns the sense buffer
+length. It is defined as the following:
+
+<verb>
+int scst_cmd_get_sense_buffer_len(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_get_tag() and scst_cmd_set_tag()
+
+<p> Function <bf/scst_cmd_get_tag()/ returns the command's tag, set by
+<bf/scst_cmd_set_tag()/. It is defined as the following:
+
+<verb>
+uint32_t scst_cmd_get_tag(
+       struct scst_cmd *cmd)
+</verb>
+
+Function <bf/scst_cmd_set_tag()/ sets command's tag that could be
+retrieved later by <bf/scst_cmd_get_tag()/. It is defined as the
+following:
+
+<verb>
+void scst_cmd_set_tag(
+       struct scst_cmd *cmd,
+       uint32_t tag)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+<item><bf/tag/ - the tag
+</itemize>
+
+<sect2>scst_cmd_get_tgt_specific() and scst_cmd_get_tgt_specific_lock()
+
+<p>
+Functions <bf/scst_cmd_get_tgt_specific()/ and
+<bf/scst_cmd_get_tgt_specific_lock()/ return pointer to the target
+driver specific data, set by <bf/scst_cmd_set_tgt_specific()/ or
+<bf/scst_cmd_set_tgt_specific_lock()/. Both function are basically the
+same, but the later one additionally takes lock, which helps to prevent
+some races. See <bf/scst_find_cmd()/ below for details.
+
+They are defined as the following:
+
+<verb>
+void *scst_cmd_get_tgt_specific(
+       struct scst_cmd *cmd)
+</verb>
+
+<verb>
+void *scst_cmd_get_tgt_specific_lock(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_set_tgt_specific() and scst_cmd_set_tgt_specific_lock()
+
+<p>
+Functions <bf/scst_cmd_set_tgt_specific()/ and
+<bf/scst_cmd_set_tgt_specific_lock()/ store the target driver specific
+data,  that could be retrieved later by <bf/scst_cmd_get_tgt_specific()/
+or <bf/scst_cmd_get_tgt_specific_lock()/. Both function are basically
+the same, but the later one additionally takes lock, which helps to
+prevent some races. See <bf/scst_find_cmd()/ below for details.
+
+They are defined as the following:
+
+<verb>
+void *scst_cmd_set_tgt_specific(
+       struct scst_cmd *cmd,
+       void *val)
+</verb>
+
+<verb>
+void *scst_cmd_set_tgt_specific_lock(
+       struct scst_cmd *cmd,
+       void *val)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+<item><bf/val/ - pointer to the target driver specific data
+</itemize>
+
+<sect2>scst_cmd_get_data_buff_alloced() and scst_cmd_set_data_buff_alloced()
+
+<p>
+Function <bf/scst_cmd_get_data_buff_alloced()/ returns the state of the
+<bf/SCST_CMD_DATA_BUF_ALLOCED/ flag. It is defined as the following:
+
+<verb>
+int scst_cmd_get_data_buff_alloced(
+       struct scst_cmd *cmd)
+</verb>
+
+Function <bf/scst_cmd_set_data_buff_alloced()/ tells SCST that the data
+buffer is alloced by target driver or device handler by setting the
+<bf/SCST_CMD_DATA_BUF_ALLOCED/ flag on. Could be useful, for instance,
+for iSCSI unsolicited data. It is defined as the following:
+
+<verb>
+void scst_cmd_set_data_buff_alloced(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect2>scst_cmd_set_expected(), scst_cmd_is_expected_set(),
+scst_cmd_get_expected_data_direction() and
+scst_cmd_get_expected_transfer_len()
+
+<p>
+Function <bf/scst_cmd_set_expected()/ tells SCST expected data transfer
+direction and its length, as supplied by remote initiator. It is defined
+as the following:
+
+<verb>
+void scst_cmd_set_expected(
+       struct scst_cmd *cmd,
+       scst_data_direction expected_data_direction,
+       unsigned int expected_transfer_len)
+</verb>
+
+Function <bf/scst_cmd_is_expected_set()/ returns true, if the expected
+values were set by target driver and false otherwise. It is defined as
+the following:
+
+<verb>
+int scst_cmd_is_expected_set(
+       struct scst_cmd *cmd)
+</verb>
+
+Function <bf/scst_cmd_get_expected_data_direction()/ returns expected
+data direction set by target driver, if any. If this value was not set,
+the return value is undefined. It is defined as the following:
+
+<verb>
+scst_data_direction scst_cmd_get_expected_data_direction(
+       struct scst_cmd *cmd)
+</verb>
+
+Function <bf/scst_cmd_get_expected_transfer_len()/ returns expected
+transfer length set by target driver, if any. If this value was not set,
+the return value is undefined. It is defined as the following:
+
+<verb>
+unsigned int scst_cmd_get_expected_transfer_len(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+<item><bf/expected_data_direction/ - expected data direction
+<item><bf/expected_transfer_len/ - expected transfer length
+</itemize>
+
+<sect2>scst_get_buf_first(), scst_get_buf_next(),
+scst_put_buf() and scst_get_buf_count()
+
+<p>
+These functions are designed to simplify and unify access to the
+commands data (SG vector or plain data buffer) in all possible
+conditions, including HIGHMEM environment, and should be used instead of
+direct access.
+
+Function <bf/scst_get_buf_first()/ starts access to the data. It is defined
+as the following:
+
+<verb>
+int scst_get_buf_first(
+       struct scst_cmd *cmd, 
+       uint8_t **buf)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+<item><bf/buf/ - pointer, where pointer to the first data chunk will be put
+</itemize>
+
+Returns the length of the chunk of data for success, 0 for the end of
+data, negative error code otherwise. 
+
+Function <bf/scst_get_buf_next()/ continues access to the data. It is defined
+as the following:
+
+<verb>
+int scst_get_buf_next(
+       struct scst_cmd *cmd, 
+       uint8_t **buf)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+<item><bf/buf/ - pointer, where pointer to the next data chunk will be put
+</itemize>
+
+Returns the length of the chunk of data for success, 0 for the end of
+data, negative error code otherwise. 
+
+Function <bf/scst_put_buf()/ tells SCST that the user of the chunk of
+data, returned by <bf/scst_get_buf_first()/ or <bf/scst_get_buf_next()/,
+finished accessing the data. This function must be called for all chunks
+of data, returned by <bf/scst_get_buf_first()/ or
+<bf/scst_get_buf_next()/. It is defined as the following:
+
+<verb>
+void scst_put_buf(
+       struct scst_cmd *cmd, 
+       uint8_t *buf)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+<item><bf/buf/ - pointer to the data chunk
+</itemize>
+
+Function <bf/scst_get_buf_count()/ returns the approximate higher
+rounded count of data chunks that <bf/scst_get_buf_[first|next]()/ will
+return. It is defined as the following:
+
+<verb>
+int scst_get_buf_count(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - pointer to the command
+</itemize>
+
+<sect1>SCST task management commands manipulation functions
+
+<sect2>scst_mgmt_cmd_get_tgt_specific()
+
+<p>
+Function <bf/scst_mgmt_cmd_get_tgt_specific()/ returns pointer to the
+target driver specific data, set on call of <bf/scst_rx_mgmt_fn_tag()/
+or <bf/scst_rx_mgmt_fn_lun()/. It is defined as the following:
+
+<verb>
+void *scst_mgmt_cmd_get_tgt_specific(
+       struct scst_mgmt_cmd *mcmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/mcmd/ - pointer to the task management command
+</itemize>
+
+<sect2>scst_mgmt_cmd_get_status()
+
+<p>
+Functions <bf/scst_mgmt_cmd_get_status()/ returns task management
+command's completion status. It is defined as the following:
+
+<verb>
+void *scst_mgmt_cmd_get_status(
+       struct scst_mgmt_cmd *mcmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/mcmd/ - pointer to the task management command
+</itemize>
+
+The following status values are possible:
+
+<itemize>
+
+<item> SCST_MGMT_STATUS_SUCCESS - the task management command completed
+successfully
+
+<item> SCST_MGMT_STATUS_FAILED - the task management command failed.
+
+</itemize>
+
+<sect>Miscellaneous functions
+
+<sect1>scst_find_cmd_by_tag()
+
+<p>
+Function <bf/scst_find_cmd_by_tag()/ is designed to find SCST's command
+based on the supplied tag comparing it with one that previously set by
+<bf/scst_cmd_set_tag()/. This value should be set by the target driver
+on the command's initialization time.
+
+It is defined as the following:
+
+<verb>
+struct scst_cmd *scst_find_cmd_by_tag(
+       struct scst_session *sess, 
+       uint32_t tag)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/sess/ - session to which the command belongs
+<item><bf/tag/ - the tag
+</itemize>
+
+Returns found command or NULL otherwise.
+
+<sect1>scst_find_cmd()
+
+<p>
+Function <bf/scst_find_cmd()/ is designed to find SCST's command. For example,
+it can be used to find the command by internal serial number that was
+supplied by a remote target's response.
+
+It is defined as the following:
+
+<verb>
+struct scst_cmd *scst_find_cmd(
+       struct scst_session *sess, 
+       void *data, 
+       int (*cmp_fn)(struct scst_cmd *cmd, void *data))
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/sess/ - session to which the command belongs
+
+<item><bf/data/ - comparison data that will be passed to <bf/cmp_fn()/
+as is
+
+<item><bf/cmp_fn/ - comparison callback function that will be called for
+each the session's command. Should return true if the command is found,
+false otherwise. Parameters:
+
+       <itemize>
+       <item><bf/cmd/ - the command to compare
+       <item><bf/data/ - comparison data.
+       </itemize>
+
+</itemize>
+
+Returns found command or NULL otherwise.
+
+<bf/IMPORTANT/
+
+SCST is designed in a such way that any command is always processed only
+by one thread at any time, so no locking is necessary. But there is one
+exception from that rule, it is <bf/scst_find_cmd()/ function. Since it
+calls the callback over all commands of the session in the internal
+lists, despite of the command's current state, there is a race
+possibility accessing to target specific data pointer between
+<bf/scst_cmd_set_tgt_specific()/ caller and <bf/cmp_fn()/, which usually
+calls <bf/scst_cmd_get_tgt_specific()/ from the different context. The
+only place, where it is safe to call <bf/scst_cmd_set_tgt_specific()/
+without the race probability, is between <bf/scst_rx_cmd()/ and
+<bf/scst_cmd_init_done()/. Thus, if you call
+<bf/scst_cmd_set_tgt_specific()/ only there, there is nothing to worry,
+always use the functions without "lock" suffix. Otherwise, be careful
+and, if necessary, use "lock" functions. In addition, <bf/cmp_fn()/ is
+allowed to use only target specific data and forbidden to call any
+SCST's functions.
+
+<sect1>scst_get_cdb_info()
+
+<p>
+Function <bf/scst_get_cdb_info()/ provides various CDB info. It is
+defined as the following:
+
+<verb>
+int scst_get_cdb_info(
+       const uint8_t *cdb_p, 
+       int dev_type, 
+       struct scst_info_cdb *info_p)
+</verb>
+
+Where:
+
+<itemize>
+
+<item><bf/cdb_p/ - pointer to CDB
+
+<item><bf/dev_type/ - SCSI device type
+
+<item><bf/info_p/ - the result structure, see description in device
+handler's <bf/parse()/ chapter
+
+</itemize>
+
+Returns 0 on success, -1 otherwise.
+
+<sect1>scst_to_dma_dir()
+
+<p>
+Function <bf/scst_to_dma_dir()/ translates SCST's data direction to
+DMA one. It is defined as the following:
+
+<verb>
+int scst_to_dma_dir(
+       int scst_dir)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/scst_dir/ - one of the <bf/SCST_DATA_*/ constants
+</itemize>
+
+Returns the corresponding <bf/PCI_DMA_*/ constant.
+
+<sect1>scst_is_cmd_local()
+
+<p>
+Function <bf/scst_is_cmd_local()/ checks if the command is handled
+by SCST (i.e. locally, as, e.g., REPORT LUNS command). Intended to be
+used in device handler's <bf/exec()/, when the device handler wants to
+perform all the commands, except ones that should be done by SCST
+itself. 
+
+It is defined as the following:
+
+<verb>
+int scst_is_cmd_local(
+       struct scst_cmd *cmd)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/cmd/ - the command, which CDB should be checked
+</itemize>
+
+Returns 1, if the command's CDB is locally handled by SCST or 0
+otherwise
+
+<sect1>scst_register_virtual_device() and scst_unregister_virtual_device()
+
+<p>
+These functions provide a way for device handlers to register a virtual
+(emulated) device, which will be visible only by remote initiators. For
+example, FILEIO device handler uses files on file system to makes from
+them virtual remotely available SCSI disks.
+
+Function <bf/scst_register_virtual_device()/ registers a virtual device.
+During the registration the device handlers functions <bf/init()/ and
+<bf/attach()/ will be called, if defined. The function is defined as the
+following:
+
+<verb>
+int scst_register_virtual_device(
+       struct scst_dev_type *dev_handler)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/dev_handler/ - device handler's descriptor
+</itemize>
+
+Returns assigned to the device ID on success, or negative value otherwise.
+
+Function <bf/scst_unregister_virtual_device()/ unregisters a virtual
+device. During the unregistration the device handlers functions
+<bf/detach()/ and <bf/release()/ will be called, if defined. The
+function is defined as the following:
+
+<verb>
+void scst_unregister_virtual_device(
+       int id)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/id/ - the device's ID, returned by 
+<bf/scst_register_virtual_device()/
+</itemize>
+
+<sect1>scst_add_threads() and scst_del_threads()
+
+<p>
+These functions allows to add or delete some SCST threads. For example,
+if <bf/exec()/ function in your device handler works synchronously, i.e.
+wait for job's completition, in order to prevent performance loss you
+can add for SCST as many threads as there are devices serviced by your
+device handler.
+
+Function <bf/scst_add_threads()/ starts requested number of threads. It
+is defined as the following:
+
+<verb>
+int scst_add_threads(
+       int num)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/num/ - number of the threads to start
+</itemize>
+
+Returns 0 on success, error code otherwise.
+
+Function <bf/scst_del_threads()/ stops requested number of threads. It
+is defined as the following:
+
+<verb>
+void scst_del_threads(
+       int num)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/num/ - number of the threads to stop
+</itemize>
+
+<sect1>scst_proc_get_tgt_root()
+
+<p>
+Function <bf/scst_proc_get_tgt_root()/ returns target driver's root
+entry in SCST's /proc hierarchy. The driver can create own
+files/directories here, which should be deleted in the driver's
+release(). It is defined as the following:
+
+<verb>
+struct proc_dir_entry *scst_proc_get_tgt_root(
+       struct scst_tgt_template *vtt)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/vtt/ - pointer to the driver's template
+</itemize>
+
+Returns proc_dir_entry on success, NULL otherwise.
+
+<sect1>scst_proc_get_dev_type_root()
+
+<p>
+Function <bf/scst_proc_get_dev_type_root()/ returns device handler's
+root entry in SCST's /proc hierarchy. The driver can create own
+files/directories here, which should be deleted in the driver's
+detach() or release(). It is defined as the following:
+
+<verb>
+struct proc_dir_entry *scst_proc_get_dev_type_root(
+       struct scst_dev_type *dtt)
+</verb>
+
+Where:
+
+<itemize>
+<item><bf/dtt/ - pointer to the handler's description structure
+</itemize>
+
+Returns proc_dir_entry on success, NULL otherwise.
+
+</article>