From: <vl...@us...> - 2006-10-12 14:03:25
|
Revision: 2 http://svn.sourceforge.net/scst/?rev=2&view=rev Author: vlnb Date: 2006-10-12 07:02:57 -0700 (Thu, 12 Oct 2006) Log Message: ----------- Initial doc's commit Added Paths: ----------- trunk/doc/ trunk/doc/Makefile trunk/doc/fig1.png trunk/doc/fig2.png trunk/doc/fig3.png trunk/doc/fig4.png trunk/doc/scst_pg.sgml Added: trunk/doc/Makefile =================================================================== --- trunk/doc/Makefile (rev 0) +++ trunk/doc/Makefile 2006-10-12 14:02:57 UTC (rev 2) @@ -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 Added: trunk/doc/fig1.png =================================================================== (Binary files differ) Property changes on: trunk/doc/fig1.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/doc/fig2.png =================================================================== (Binary files differ) Property changes on: trunk/doc/fig2.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/doc/fig3.png =================================================================== (Binary files differ) Property changes on: trunk/doc/fig3.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/doc/fig4.png =================================================================== (Binary files differ) Property changes on: trunk/doc/fig4.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/doc/scst_pg.sgml =================================================================== --- trunk/doc/scst_pg.sgml (rev 0) +++ trunk/doc/scst_pg.sgml 2006-10-12 14:02:57 UTC (rev 2) @@ -0,0 +1,2278 @@ +<!doctype linuxdoc system> + +<article> + +<title>Generic SCSI Target Middle Level for Linux</title> + +<author> + <name>Vladislav Bolkhovitin <<tt/vst @at@ vlnb .dot. net/></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 ot... [truncated message content] |