Home | History | Annotate | Download | only in iscsitgtd
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef _T10_H
     28 #define	_T10_H
     29 
     30 /*
     31  * This header file describes the service level between the transport
     32  * layer and the emulation portion. These procedure calls can be thought
     33  * of as part of the T10 SAM-3 specification.
     34  */
     35 
     36 #ifdef __cplusplus
     37 extern "C" {
     38 #endif
     39 
     40 /*
     41  * Here are the header files which are required to define references found
     42  * in this file. No other header files are to be included.
     43  */
     44 #include <pthread.h>
     45 #include <sys/avl.h>
     46 #include <signal.h>
     47 #include <sys/scsi/generic/sense.h>
     48 
     49 #include "queue.h"
     50 
     51 #ifdef lint
     52 /*
     53  * lints sees aio_return64, but can't find it in the aio structure. To keep
     54  * lint happy this define is used.
     55  */
     56 #define	aio_return64 aio_return
     57 #endif
     58 
     59 typedef void *transport_t;
     60 typedef void *t10_targ_handle_t;
     61 
     62 typedef void *t10_lun_handle_t;
     63 
     64 typedef void *emul_handle_t;
     65 typedef void *emul_cmd_t;
     66 
     67 typedef	enum {
     68 	ClearSet,
     69 	ResetTarget,
     70 	ResetLun,
     71 	InventoryChange,
     72 	CapacityChange,
     73 	DeviceOnline,
     74 	DeviceOffline
     75 } TaskOp_t;
     76 
     77 /*
     78  * For an explanation of the t10_cmd_state_t and t10_cmd_event_t
     79  * see t10_sam.c:t10_cmd_state_machine()
     80  */
     81 typedef enum {
     82 	T10_Cmd_S1_Free		= 1,
     83 	T10_Cmd_S2_In,
     84 	T10_Cmd_S3_Trans,
     85 	T10_Cmd_S4_AIO,
     86 	T10_Cmd_S5_Wait,
     87 	T10_Cmd_S6_Freeing_In,
     88 	T10_Cmd_S7_Freeing_AIO
     89 } t10_cmd_state_t;
     90 
     91 typedef enum {
     92 	T10_Cmd_T1		= 1,
     93 	T10_Cmd_T2,
     94 	T10_Cmd_T3,
     95 	T10_Cmd_T4,
     96 	T10_Cmd_T5,
     97 	T10_Cmd_T6,		/* cancel */
     98 	T10_Cmd_T7,
     99 	T10_Cmd_T8		/* shutdown */
    100 } t10_cmd_event_t;
    101 
    102 typedef enum {
    103 	lu_online,
    104 	lu_offline,
    105 	lu_errored
    106 } t10_lu_state_t;
    107 
    108 /*
    109  * The t10_cmd_t structure bridges the gap between the transport and
    110  * emulation services. At certain times either the transport or emulation
    111  * service needs to access the data stored within this structure.
    112  * For now we'll just use macros which hide the reference, but in the
    113  * future when the transport and emulation services are loadable modules
    114  * these macros will become functions so that the structure can change
    115  * inside of the T10 space and not cause compatibility issues.
    116  */
    117 #define	T10_MAX_OUT(cmd)	(cmd->c_lu->l_targ->s_maxout)
    118 #define	T10_MMAP_AREA(cmd)	(cmd->c_lu->l_common->l_mmap)
    119 #define	T10_PARAMS_AREA(cmd)	trans_params_area(cmd)
    120 #define	T10_TRANS_ID(cmd)	(cmd->c_trans_id)
    121 #define	T10_DATA(cmd)		(cmd->c_data)
    122 #define	T10_DATA_LEN(cmd)	(cmd->c_data_len)
    123 #define	T10_DATA_OFFSET(cmd)	(cmd->c_offset)
    124 #define	T10_CMD_LAST(cmd)	(cmd->c_last)
    125 #define	T10_CMD_STATUS(cmd)	(cmd->c_cmd_status)
    126 #define	T10_CMD_RESID(cmd)	(cmd->c_resid)
    127 #define	T10_SENSE_LEN(cmd)	(cmd->c_cmd_sense_len)
    128 #define	T10_SENSE_DATA(cmd)	(cmd->c_cmd_sense)
    129 #define	T10_PGR_TNAME(cmd)	(cmd->c_lu->l_targ->s_targ_base)
    130 #define	T10_PGR_INAME(cmd)	(cmd->c_lu->l_targ->s_i_name)
    131 
    132 #define	T10_DEFAULT_TPG	1
    133 
    134 /*
    135  * []------------------------------------------------------------------[]
    136  * | SAM-3 revision 14, section 4.9 -- Logical Unit Numbers		|
    137  * | The specification allows for 64-bit LUNs, but at this point	|
    138  * | most OSes don't support that many. Section 4.9.7, table 9 gives	|
    139  * | the Flat Space Addressing Method which allows for 16,383 LUNs.	|
    140  * | This will be the imposed maximum even though the code can support	|
    141  * | more. Raise this number if needed.					|
    142  * []------------------------------------------------------------------[]
    143  */
    144 #define	T10_MAX_LUNS	16383
    145 
    146 /*
    147  * SPC-3 Revision 21c, Section 6.4.2 Table 85
    148  * Version Descriptor Values
    149  */
    150 #define	T10_TRANS_ISCSI		0x960 /* iSCSI (no version claimed) */
    151 #define	T10_TRANS_FC		0x8c0 /* FCP (no version claimed) */
    152 
    153 typedef struct t10_aio {
    154 	/*
    155 	 * This must be the first member of the structure. aioread/aiowrite
    156 	 * take as one of the arguments an pointer to a aio_result_t
    157 	 * structure. When the operation is complete the aio_return and
    158 	 * aio_errno of that structure are updated. When aiowait() is
    159 	 * called the address of that aio_result_t is returned. By having
    160 	 * this structure at the beginning we can pass in the data_ptr
    161 	 * structure address. The ste_aio_process thread will get everything
    162 	 * it needs from the aiowait to send a message to the correct
    163 	 * STE thread. Clear as mud?
    164 	 */
    165 	aio_result_t	a_aio;
    166 
    167 	void		(*a_aio_cmplt)(emul_cmd_t id);
    168 	emul_cmd_t	a_id;
    169 	struct t10_cmd	*a_cmd;
    170 } t10_aio_t;
    171 
    172 /*
    173  * Bidirectional structure used to track requests from the transport
    174  * and send reponse data from the emulation.
    175  *
    176  * The glue logic for t10_send_cmd will allocate this structure, fill in
    177  * in with the provided data and put it on the LUN queue. The LUN thread
    178  * will dequeue this request and call the appropriate LUN command interpreter.
    179  */
    180 typedef struct t10_cmd {
    181 	/*
    182 	 * Transport specific tracking value. If this value is non-zero it
    183 	 * means this command was part of a previous command that wasn't
    184 	 * completed. Currently this is only used for DATA_OUT (SCSI write op)
    185 	 * commands.
    186 	 */
    187 	transport_t		c_trans_id;
    188 
    189 	t10_cmd_state_t		c_state;
    190 
    191 	/*
    192 	 * Emulation specific tracking value.
    193 	 */
    194 	emul_cmd_t		c_emul_id;
    195 
    196 	/*
    197 	 * Per I_T_L structure used to determine which command
    198 	 * interpreter to call and which transport queue to send the response.
    199 	 */
    200 	struct t10_lu_impl	*c_lu;
    201 
    202 	/*
    203 	 * Pointer to command buffer. No interpretation of data is
    204 	 * done by the glue logic. Interpretation is done by the LUN
    205 	 * emulation code.
    206 	 */
    207 	uint8_t			*c_cdb;
    208 	size_t			c_cdb_len;
    209 
    210 	/*
    211 	 * Optional offset into the command. If more than one response
    212 	 * is required this value indicates where the data belongs.
    213 	 */
    214 	off_t			c_offset;
    215 
    216 	/*
    217 	 * Data for transfer.
    218 	 */
    219 	char			*c_data;
    220 	size_t			c_data_len;
    221 	size_t			c_resid;
    222 
    223 	/*
    224 	 * Indicates if this response is the last to be sent
    225 	 * and will be followed closely by a complete message. Enables
    226 	 * transports to phase collapse the final READ data PDU with
    227 	 * completion PDU if possible.
    228 	 */
    229 	Boolean_t		c_last;
    230 
    231 	/*
    232 	 * When the transport is finished sending the data it will
    233 	 * call t10_cmd_destroy() which will cause the SAM-3 layer to
    234 	 * call the emulation function stored here with this command
    235 	 * pointer. The emulation code is responsible for freeing any
    236 	 * memory it allocated.
    237 	 */
    238 	void			(*c_emul_complete)(emul_handle_t id);
    239 
    240 	/*
    241 	 * During transitions from T10 layer to transport one of three
    242 	 * messages are sent. The state machine needs access to these
    243 	 * values to pass things along so we keep it here.
    244 	 */
    245 	msg_type_t		c_msg;
    246 
    247 	/*
    248 	 * SCSI sense information.
    249 	 */
    250 	int			c_cmd_status;
    251 	char			*c_cmd_sense;
    252 	size_t			c_cmd_sense_len;
    253 
    254 	/*
    255 	 * List of active commands at the ITL level.
    256 	 */
    257 	avl_tree_t		c_cmd_avl;
    258 
    259 	struct t10_cmd		*c_cmd_next;
    260 } t10_cmd_t;
    261 
    262 /*
    263  * Each LU has a structure which contains common data for all I_T's who
    264  * access this LU.
    265  */
    266 typedef struct t10_lu_common {
    267 	/*
    268 	 * Logic Unit Number
    269 	 */
    270 	int			l_num;
    271 
    272 	/*
    273 	 * state of device
    274 	 */
    275 	t10_lu_state_t		l_state;
    276 
    277 	/*
    278 	 * Internal ID which will be unique for all LUs. This will be
    279 	 * used for log messages to help tracking details.
    280 	 */
    281 	int			l_internal_num;
    282 
    283 	/*
    284 	 * Thread ID which is running this logical unit. This is currently
    285 	 * used for only one purpose which is to locate this structure
    286 	 * in case of a SIGBUS. It's possible for the underlying file system
    287 	 * to run out of space for an mmap'd LU. The only means of notification
    288 	 * the OS has is to send a SIGBUS. The thread only receives the memory
    289 	 * address, so we look for our thread ID amongst all of the LU
    290 	 * available.
    291 	 */
    292 	pthread_t		l_thr_id;
    293 
    294 	/*
    295 	 * If we receive a SIGBUS the initiator needs to be notified that
    296 	 * something bad has occurred. This means we need to know which
    297 	 * command was being emulated so that we can find the appropriate
    298 	 * transport.
    299 	 * Special handling needs to be done if the thread is initializing
    300 	 * the LU so we need a flag to indicate that fact.
    301 	 */
    302 	t10_cmd_t		*l_curr;
    303 	Boolean_t		l_curr_provo;
    304 
    305 	/*
    306 	 * The implementation uses a 16 byte EUI value for the GUID.
    307 	 * Not only is this value used for SCSI INQUIRY data, but it
    308 	 * is used to distinquish this common LUN from other LUNs in
    309 	 * the AVL tree.
    310 	 */
    311 	uint8_t			*l_guid;
    312 	size_t			l_guid_len;
    313 
    314 	/*
    315 	 * Other common information which is needed for ever device
    316 	 * type.
    317 	 */
    318 	int			l_dtype;
    319 	char			*l_pid,
    320 				*l_vid;
    321 
    322 	/*
    323 	 * Each dtype has different parameters that it uses. This
    324 	 * is a place holder for storing a pointer to some structure which
    325 	 * contains that information.
    326 	 */
    327 	void			*l_dtype_params;
    328 
    329 	/*
    330 	 * Parameter information in XML format.
    331 	 */
    332 	tgt_node_t		*l_root;
    333 	Boolean_t		l_root_okay_to_free;
    334 
    335 	/*
    336 	 * File descriptor for the open file which is the backing store
    337 	 * for this device. This can be a regular file or a character
    338 	 * special device if we're acting as a bridge between transports.
    339 	 */
    340 	int			l_fd;
    341 
    342 	void			*l_mmap;
    343 	off64_t			l_size;
    344 
    345 	Boolean_t		l_fast_write_ack;
    346 
    347 	/*
    348 	 * AVL tree containing all I_T_L nexus' which are actively using
    349 	 * this LUN.
    350 	 */
    351 	avl_tree_t		l_all_open;
    352 
    353 	/*
    354 	 * Each I_T will place requests for command emulation on this
    355 	 * queue. Common requests are msg_ste_cmd and msg_ste_shutdown
    356 	 */
    357 	target_queue_t		*l_from_transports;
    358 
    359 	/*
    360 	 * Mutex used to lock access to the AVL tree.
    361 	 */
    362 	pthread_mutex_t		l_common_mutex;
    363 
    364 	/*
    365 	 * When a target is looking to see if an existing LUN is opened
    366 	 * a search of all LUNs needs to be done and will use this
    367 	 * AVL node. This field is modified only by the AVL code.
    368 	 */
    369 	avl_node_t		l_all_luns;
    370 } t10_lu_common_t;
    371 
    372 /*
    373  * Each I_T_L has a LU structure associated with it.
    374  */
    375 typedef struct t10_lu_impl {
    376 	/*
    377 	 * pointer to common area of LUN.
    378 	 */
    379 	t10_lu_common_t		*l_common;
    380 	pthread_mutex_t		l_mutex;
    381 
    382 	/*
    383 	 * Mutex to protect access to active commands
    384 	 */
    385 	pthread_mutex_t		l_cmd_mutex;
    386 	pthread_cond_t		l_cmd_cond;
    387 	Boolean_t		l_wait_for_drain;
    388 
    389 	avl_tree_t		l_cmds;
    390 
    391 	/*
    392 	 * Queue for sending command results and R2T results back
    393 	 * to the transport.
    394 	 */
    395 	target_queue_t		*l_to_transport;
    396 
    397 	/*
    398 	 * Back pointer to target structure who created this LUN reference.
    399 	 */
    400 	struct t10_targ_impl	*l_targ;
    401 
    402 	struct scsi_cmd_table	*l_cmd_table;
    403 
    404 	/*
    405 	 * Per LU methods for issuing commands and data to the
    406 	 * DTYPE emulator.
    407 	 */
    408 	void			(*l_cmd)(t10_cmd_t *cmd, uint8_t *cdb,
    409 	    size_t cdb_len);
    410 	void			(*l_data)(t10_cmd_t *cmd, emul_handle_t e,
    411 	    size_t offset, char *data, size_t data_len);
    412 
    413 	/*
    414 	 * AVL node information for all other I_T nexus' who are referencing
    415 	 * this LUN. This is used by the AVL code and *not* modified by
    416 	 * this daemon directly.
    417 	 */
    418 	avl_node_t		l_open_lu_node;
    419 
    420 	/*
    421 	 * AVL node information for all LUN's being access by this I_T nexus.
    422 	 * This is used by the AVL code and *not* modified by this daemon
    423 	 * directly.
    424 	 */
    425 	avl_node_t		l_open_targ_node;
    426 
    427 	/*
    428 	 * Logical Unit Number. This value is used as the comparision value
    429 	 * for the AVL search at the per target level.
    430 	 */
    431 	int			l_targ_lun;
    432 
    433 	Boolean_t		l_dsense_enabled;
    434 	Boolean_t		l_pgr_read;
    435 
    436 	/*
    437 	 * Statistics on a per ITL basis
    438 	 */
    439 	uint64_t		l_cmds_read,
    440 				l_cmds_write,
    441 				l_sects_read,
    442 				l_sects_write;
    443 
    444 	/*
    445 	 * Each time a command is run the value of l_status is checked.
    446 	 * If non-zero the command isn't executed and instead a transport
    447 	 * complete message is sent with these values. This is commonly
    448 	 * used to send UNIT ATTENTION for things like power on.
    449 	 * -- Do we need some sort of stack to push and pop these values?
    450 	 */
    451 	int			l_status,
    452 				l_asc,
    453 				l_ascq;
    454 } t10_lu_impl_t;
    455 
    456 typedef struct t10_targ_impl {
    457 	char			*s_i_name;
    458 	char			*s_targ_base;
    459 	int			s_targ_num; /* used in log messages */
    460 	avl_tree_t		s_open_lu;
    461 	pthread_mutex_t		s_mutex;
    462 
    463 	/*
    464 	 * The transport layer will set the maximum output size
    465 	 * it's able to deal with during a call to set_create_handle()
    466 	 */
    467 	size_t			s_maxout;
    468 
    469 	/*
    470 	 * Target Port Set
    471 	 */
    472 	int			s_tpgt;
    473 
    474 	/*
    475 	 * transport version number to use in standard inquiry data
    476 	 */
    477 	int			s_trans_vers;
    478 
    479 	/*
    480 	 * Transport response queue. This queue will be stored in each
    481 	 * lun that gets created.
    482 	 */
    483 	target_queue_t		*s_to_transport;
    484 
    485 	/*
    486 	 * During a SCSI WRITE the emulation will call trans_rqst_datain.
    487 	 * If the transport indicated data was available by using non-zero
    488 	 * values for the optional data and length when t10_send_cmd was
    489 	 * called this callback is used when the emulation requests data.
    490 	 */
    491 	void		(*s_dataout_cb)(t10_cmd_t *, char *data,
    492 	    size_t *data_len);
    493 
    494 } t10_targ_impl_t;
    495 
    496 typedef struct t10_shutdown {
    497 	t10_lu_impl_t	*t_lu;
    498 	target_queue_t	*t_q;
    499 } t10_shutdown_t;
    500 
    501 typedef struct scsi_cmd_table {
    502 	void	(*cmd_start)(struct t10_cmd *, uint8_t *, size_t);
    503 	void	(*cmd_data)(struct t10_cmd *, emul_handle_t e,
    504 			    size_t offset, char *data, size_t data_len);
    505 	void	(*cmd_end)(emul_handle_t e);
    506 	char	*cmd_name;
    507 } scsi_cmd_table_t;
    508 
    509 typedef struct sam_device_table {
    510 	Boolean_t	(*t_common_init)(t10_lu_common_t *);
    511 	void		(*t_common_fini)(t10_lu_common_t *);
    512 	void		(*t_per_init)(t10_lu_impl_t *);
    513 	void		(*t_per_fini)(t10_lu_impl_t *);
    514 	void		(*t_task_mgmt)(t10_lu_common_t *, TaskOp_t);
    515 	char		*t_type_name;
    516 } sam_device_table_t;
    517 
    518 typedef struct t10_conn_shutdown {
    519 	target_queue_t *t10_to_conn_q;
    520 	target_queue_t *conn_to_t10_q;
    521 } t10_conn_shutdown_t;
    522 
    523 /*
    524  * []----
    525  * | Interfaces
    526  * []----
    527  */
    528 
    529 extern target_queue_t *mgmtq;
    530 void t10_init(target_queue_t *q);
    531 void lu_buserr_handler(int sig, siginfo_t *sip, void *v);
    532 
    533 /*
    534  * []------------------------------------------------------------------[]
    535  * | Methods called by the transports					|
    536  * []------------------------------------------------------------------[]
    537  */
    538 /*
    539  * t10_handle_create -- create target handle to be used by transports
    540  */
    541 t10_targ_handle_t
    542 t10_handle_create(char *targ, char *init, int trans_vers, int tpg, int max_out,
    543     target_queue_t *tq, void (*datain_cb)(t10_cmd_t *, char *, size_t *));
    544 
    545 /*
    546  * t10_handle_disable -- drains commands from emulation queues
    547  */
    548 void
    549 t10_handle_disable(t10_targ_handle_t t);
    550 
    551 /*
    552  * t10_handle_destroy -- free resources used by handle
    553  */
    554 int
    555 t10_handle_destroy(t10_targ_handle_t t, Boolean_t wait);
    556 
    557 Boolean_t
    558 t10_cmd_create(t10_targ_handle_t t, int lun_number, uint8_t *cdb,
    559     size_t cdb_len, transport_t trans_id, t10_cmd_t **);
    560 
    561 /*
    562  * t10_send_cmd -- send a command block to an target/LUN for emulation
    563  */
    564 Boolean_t
    565 t10_cmd_send(t10_targ_handle_t t, t10_cmd_t *cmd,
    566     char *opt_data, size_t opt_data_len);
    567 
    568 Boolean_t
    569 t10_cmd_data(t10_targ_handle_t t, t10_cmd_t *cmd, size_t offset,
    570     char *data, size_t data_len);
    571 
    572 void
    573 t10_cmd_done(t10_cmd_t *cmd);
    574 
    575 Boolean_t
    576 t10_task_mgmt(t10_targ_handle_t t, TaskOp_t op, int opt_lun, void *tag);
    577 
    578 /*
    579  * t10_cmd_shoot_event -- perform transition to the  state of a T10 command
    580  */
    581 void t10_cmd_shoot_event(t10_cmd_t *c, t10_cmd_event_t e);
    582 
    583 void t10_targ_stat(t10_targ_handle_t t, char **buf);
    584 
    585 /*
    586  * t10_thick_provision -- management function used when creating a new lun
    587  */
    588 Boolean_t t10_thick_provision(char *target, int lun, target_queue_t *q);
    589 
    590 /*
    591  * []------------------------------------------------------------------[]
    592  * | Methods called by the emulation routines				|
    593  * []------------------------------------------------------------------[]
    594  */
    595 
    596 t10_cmd_t *trans_cmd_dup(t10_cmd_t *cmd);
    597 
    598 /*
    599  * trans_send_datain -- Emulation layer sending data to initiator
    600  */
    601 Boolean_t trans_send_datain(t10_cmd_t *cmd, char *data, size_t data_len,
    602     size_t offset, void (*callback)(emul_handle_t t), Boolean_t last,
    603     emul_handle_t id);
    604 
    605 /*
    606  * trans_rqst_dataout -- Emulation needs more data to complete request
    607  */
    608 Boolean_t trans_rqst_dataout(t10_cmd_t *cmd, char *data, size_t data_len,
    609     size_t offset, emul_cmd_t emul_id, void (*callback)(emul_handle_t e));
    610 
    611 /*
    612  * trans_send_complete -- Emulation has completed request w/ opt. sense data
    613  */
    614 void trans_send_complete(t10_cmd_t *cmd, int t10_status);
    615 
    616 /*
    617  * trans_aiowrite -- asynchronous write and kicks the aio wait thread
    618  */
    619 void trans_aiowrite(t10_cmd_t *cmd, char *data, size_t data_len, off_t offset,
    620     t10_aio_t *taio);
    621 
    622 /*
    623  * trans_aioread -- asynchronous read and kicks the aio wait thread
    624  */
    625 void trans_aioread(t10_cmd_t *cmd, char *data, size_t data_len, off_t offset,
    626     t10_aio_t *taio);
    627 
    628 /*
    629  * trans_params_area -- given a t10_cmd return the dtype params
    630  */
    631 void *trans_params_area(t10_cmd_t *cmd);
    632 
    633 /*
    634  * []------------------------------------------------------------------[]
    635  * | Declaration of emulation entry points				|
    636  * []------------------------------------------------------------------[]
    637  */
    638 Boolean_t sbc_common_init(t10_lu_common_t *lu);
    639 void sbc_common_fini(t10_lu_common_t *lu);
    640 void sbc_task_mgmt(t10_lu_common_t *lu, TaskOp_t op);
    641 void sbc_per_init(t10_lu_impl_t *itl);
    642 void sbc_per_fini(t10_lu_impl_t *itl);
    643 Boolean_t ssc_common_init(t10_lu_common_t *lu);
    644 void ssc_common_fini(t10_lu_common_t *lu);
    645 void ssc_task_mgmt(t10_lu_common_t *lu, TaskOp_t op);
    646 void ssc_per_init(t10_lu_impl_t *itl);
    647 void ssc_per_fini(t10_lu_impl_t *itl);
    648 Boolean_t raw_common_init(t10_lu_common_t *lu);
    649 void raw_common_fini(t10_lu_common_t *lu);
    650 void raw_per_init(t10_lu_impl_t *itl);
    651 void raw_per_fini(t10_lu_impl_t *itl);
    652 void raw_task_mgmt(t10_lu_common_t *lu, TaskOp_t op);
    653 Boolean_t osd_common_init(t10_lu_common_t *lu);
    654 void osd_common_fini(t10_lu_common_t *lu);
    655 void osd_per_init(t10_lu_impl_t *itl);
    656 void osd_per_fini(t10_lu_impl_t *itl);
    657 void osd_task_mgmt(t10_lu_common_t *lu, TaskOp_t op);
    658 
    659 #ifdef __cplusplus
    660 }
    661 #endif
    662 
    663 #endif /* _T10_H */
    664