145039663SJohn Forte /*
245039663SJohn Forte  * CDDL HEADER START
345039663SJohn Forte  *
445039663SJohn Forte  * The contents of this file are subject to the terms of the
545039663SJohn Forte  * Common Development and Distribution License (the "License").
645039663SJohn Forte  * You may not use this file except in compliance with the License.
745039663SJohn Forte  *
845039663SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
945039663SJohn Forte  * or http://www.opensolaris.org/os/licensing.
1045039663SJohn Forte  * See the License for the specific language governing permissions
1145039663SJohn Forte  * and limitations under the License.
1245039663SJohn Forte  *
1345039663SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
1445039663SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1545039663SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
1645039663SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
1745039663SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
1845039663SJohn Forte  *
1945039663SJohn Forte  * CDDL HEADER END
2045039663SJohn Forte  */
2145039663SJohn Forte /*
2291159e90SJohn Forte  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2345039663SJohn Forte  */
2445039663SJohn Forte 
2545039663SJohn Forte /*
2645039663SJohn Forte  * XXX TODO
2745039663SJohn Forte  * #includes cribbed from stmf.c -- undoubtedly only a small subset of these
2845039663SJohn Forte  * are actually needed.
2945039663SJohn Forte  */
3045039663SJohn Forte #include <sys/conf.h>
3145039663SJohn Forte #include <sys/file.h>
3245039663SJohn Forte #include <sys/ddi.h>
3345039663SJohn Forte #include <sys/sunddi.h>
3445039663SJohn Forte #include <sys/scsi/scsi.h>
35716c1805SNattuvetty Bhavyan #include <sys/scsi/generic/persist.h>
3645039663SJohn Forte #include <sys/byteorder.h>
3745039663SJohn Forte #include <sys/nvpair.h>
3845039663SJohn Forte #include <sys/door.h>
3945039663SJohn Forte 
4045039663SJohn Forte #include <sys/stmf.h>
4145039663SJohn Forte #include <sys/lpif.h>
4245039663SJohn Forte #include <sys/stmf_ioctl.h>
4345039663SJohn Forte #include <sys/portif.h>
4445039663SJohn Forte #include <sys/pppt_ic_if.h>
4545039663SJohn Forte 
464558d122SViswanathan Kannappan #include "pppt.h"
4745039663SJohn Forte 
4845039663SJohn Forte /*
4945039663SJohn Forte  * Macros
5045039663SJohn Forte  */
5145039663SJohn Forte 
5245039663SJohn Forte /* Free a struct if it was allocated */
5345039663SJohn Forte #define	FREE_IF_ALLOC(m)					\
5445039663SJohn Forte 	do {							\
5545039663SJohn Forte 		if ((m)) kmem_free((m), sizeof (*(m)));		\
5645039663SJohn Forte 		_NOTE(CONSTCOND)				\
5745039663SJohn Forte 	} while (0)
5845039663SJohn Forte 
5945039663SJohn Forte /*
6045039663SJohn Forte  * Macros to simplify the addition of struct fields to an nvlist.
6145039663SJohn Forte  * The name of the fields in the nvlist is the same as the name
6245039663SJohn Forte  * of the struct field.
6345039663SJohn Forte  *
6445039663SJohn Forte  * These macros require an int rc and a "done:" return retval label;
6545039663SJohn Forte  * they assume that the nvlist is named "nvl".
6645039663SJohn Forte  */
6745039663SJohn Forte #define	NVLIST_ADD_FIELD(type, structure, field)			\
6845039663SJohn Forte 	do {								\
6945039663SJohn Forte 		rc = nvlist_add_##type(nvl, #field, structure->field);  \
7045039663SJohn Forte 		if (rc) goto done;					\
7145039663SJohn Forte 		_NOTE(CONSTCOND)					\
7245039663SJohn Forte 	} while (0)
7345039663SJohn Forte 
7445039663SJohn Forte /* use this macro when the array is defined as part of the struct */
7545039663SJohn Forte #define	NVLIST_ADD_ARRAY(type, structure, field)			\
7645039663SJohn Forte 	do {								\
7745039663SJohn Forte 		rc = nvlist_add_##type##_array(nvl, #field,		\
7845039663SJohn Forte 		    structure->field, sizeof (structure->field));	\
7945039663SJohn Forte 		if (rc) goto done;					\
8045039663SJohn Forte 		_NOTE(CONSTCOND)					\
8145039663SJohn Forte 	} while (0)
8245039663SJohn Forte 
8345039663SJohn Forte /*
8445039663SJohn Forte  * use this macro when the array field is a ptr or you need to explictly
8545039663SJohn Forte  * call out the size.
8645039663SJohn Forte  */
8745039663SJohn Forte #define	NVLIST_ADD_ARRAY_LEN(type, structure, field, len)		\
8845039663SJohn Forte 	do {								\
8945039663SJohn Forte 		rc = nvlist_add_##type##_array(nvl, #field,		\
9045039663SJohn Forte 		    structure->field, len);				\
9145039663SJohn Forte 		if (rc) goto done;					\
9245039663SJohn Forte 		_NOTE(CONSTCOND)					\
9345039663SJohn Forte 	} while (0)
9445039663SJohn Forte 
9545039663SJohn Forte #define	NVLIST_ADD_DEVID(structure, field)				\
9645039663SJohn Forte 	do {								\
9745039663SJohn Forte 		rc = stmf_ic_scsi_devid_desc_marshal(nvl, #field,	\
9845039663SJohn Forte 		    structure->field);					\
9945039663SJohn Forte 		if (rc) goto done;					\
10045039663SJohn Forte 		_NOTE(CONSTCOND)					\
10145039663SJohn Forte 	} while (0)
10245039663SJohn Forte 
103716c1805SNattuvetty Bhavyan #define	NVLIST_ADD_RPORT(structure, field)				\
104716c1805SNattuvetty Bhavyan 	do {								\
105716c1805SNattuvetty Bhavyan 		rc = stmf_ic_remote_port_marshal(nvl, #field,		\
106716c1805SNattuvetty Bhavyan 		    structure->field);					\
107716c1805SNattuvetty Bhavyan 		if (rc) goto done;					\
108716c1805SNattuvetty Bhavyan 		_NOTE(CONSTCOND)					\
109716c1805SNattuvetty Bhavyan 	} while (0)
110716c1805SNattuvetty Bhavyan 
11145039663SJohn Forte #define	NVLIST_ADD_FIELD_UINT8(structure, field)			\
11245039663SJohn Forte 	NVLIST_ADD_FIELD(structure, field, uint8)
11345039663SJohn Forte 
11445039663SJohn Forte /*
11545039663SJohn Forte  * Macros to simplify the extraction of struct fields from an nvlist.
11645039663SJohn Forte  * The name of the fields in the nvlist is the same as the name
11745039663SJohn Forte  * of the struct field.
11845039663SJohn Forte  *
11945039663SJohn Forte  * Requires an int rc and a "done:" return retval label.
12045039663SJohn Forte  * Assumes that the nvlist is named "nvl".
12145039663SJohn Forte  *
12245039663SJohn Forte  * Sample usage: NVLIST_LOOKUP_FIELD(uint8, structname, fieldname);
12345039663SJohn Forte  */
12445039663SJohn Forte #define	NVLIST_LOOKUP_FIELD(type, structure, field)			\
12545039663SJohn Forte 	do {								\
12645039663SJohn Forte 		rc = nvlist_lookup_##type(nvl, #field,			\
12745039663SJohn Forte 		    &(structure->field));				\
12845039663SJohn Forte 		if (rc) { 						\
12945039663SJohn Forte 			stmf_ic_nvlookup_warn(__func__, #field);	\
13045039663SJohn Forte 			goto done;					\
13145039663SJohn Forte 		}							\
13245039663SJohn Forte 		_NOTE(CONSTCOND)					\
13345039663SJohn Forte 	} while (0)
13445039663SJohn Forte 
13545039663SJohn Forte /*
13645039663SJohn Forte  * Look up a field which gets stored into a structure bit field.
13745039663SJohn Forte  * The type passed is a uint type which can hold the largest value
13845039663SJohn Forte  * in the bit field.
13945039663SJohn Forte  *
14045039663SJohn Forte  * Requires an int rc and a "done:" return retval label.
14145039663SJohn Forte  * Assumes that the nvlist is named "nvl".
14245039663SJohn Forte  *
14345039663SJohn Forte  * Sample usage: NVLIST_LOOKUP_BIT_FIELD(uint8, structname, fieldname);
14445039663SJohn Forte  */
14545039663SJohn Forte #define	NVLIST_LOOKUP_BIT_FIELD(type, structure, field)			\
14645039663SJohn Forte 	do {								\
14745039663SJohn Forte 		type##_t tmp;						\
14845039663SJohn Forte 		rc = nvlist_lookup_##type(nvl, #field, &tmp);		\
14945039663SJohn Forte 		if (rc) { 						\
15045039663SJohn Forte 			stmf_ic_nvlookup_warn(__func__, #field);	\
15145039663SJohn Forte 			goto done;					\
15245039663SJohn Forte 		}							\
15345039663SJohn Forte 		structure->field = tmp;					\
15445039663SJohn Forte 		_NOTE(CONSTCOND)					\
15545039663SJohn Forte 	} while (0)
15645039663SJohn Forte 
15745039663SJohn Forte /*
15845039663SJohn Forte  * Look up a boolean field which gets stored into a structure bit field.
15945039663SJohn Forte  *
16045039663SJohn Forte  * Requires an int rc and a "done:" return retval label.
16145039663SJohn Forte  * Assumes that the nvlist is named "nvl".
16245039663SJohn Forte  */
16345039663SJohn Forte #define	NVLIST_LOOKUP_BIT_FIELD_BOOLEAN(structure, field)		\
16445039663SJohn Forte 	do {								\
16545039663SJohn Forte 		boolean_t tmp;						\
16645039663SJohn Forte 		rc = nvlist_lookup_boolean_value(nvl, #field, &tmp);	\
16745039663SJohn Forte 		if (rc) { 						\
16845039663SJohn Forte 			stmf_ic_nvlookup_warn(__func__, #field);	\
16945039663SJohn Forte 			goto done;					\
17045039663SJohn Forte 		}							\
17145039663SJohn Forte 		structure->field = (tmp ?  1 : 0);			\
17245039663SJohn Forte 		_NOTE(CONSTCOND)					\
17345039663SJohn Forte 	} while (0)
17445039663SJohn Forte 
17545039663SJohn Forte /* shorthand  for nvlist_lookup_pairs() args */
17645039663SJohn Forte #define	NV_PAIR(type, strct, field) #field, DATA_TYPE_##type, &(strct->field)
17745039663SJohn Forte 
17845039663SJohn Forte /* number of times to retry the upcall to transmit */
17945039663SJohn Forte #define	STMF_MSG_TRANSMIT_RETRY	    3
18045039663SJohn Forte 
18145039663SJohn Forte /*
18245039663SJohn Forte  * How was the message constructed?
18345039663SJohn Forte  *
18445039663SJohn Forte  * We need to know this when we free the message in order to
18545039663SJohn Forte  * determine what to do with pointers in the message:
18645039663SJohn Forte  *
18745039663SJohn Forte  * - messages which were unmarshaled from an nvlist may point to
18845039663SJohn Forte  *   memory within that nvlist; this memory should not be freed since
18945039663SJohn Forte  *   it will be deallocated when we free the nvlist.
19045039663SJohn Forte  *
19145039663SJohn Forte  * - messages which built using a constructor (alloc) function may
19245039663SJohn Forte  *   point to memory which was explicitly allocated by the constructor;
19345039663SJohn Forte  *   it should be freed when the message is freed.
19445039663SJohn Forte  *
19545039663SJohn Forte  */
19645039663SJohn Forte typedef enum {
19745039663SJohn Forte 	STMF_CONSTRUCTOR = 0,
19845039663SJohn Forte 	STMF_UNMARSHAL
19945039663SJohn Forte } stmf_ic_msg_construction_method_t;
20045039663SJohn Forte 
20145039663SJohn Forte 
20245039663SJohn Forte /*
20345039663SJohn Forte  * Function prototypes.
20445039663SJohn Forte  */
20545039663SJohn Forte 
20645039663SJohn Forte /*
20745039663SJohn Forte  * Helpers for msg_alloc routines, used when the msg payload is
20845039663SJohn Forte  * the same for multiple types of messages.
20945039663SJohn Forte  */
21045039663SJohn Forte static stmf_ic_msg_t *stmf_ic_reg_dereg_lun_msg_alloc(
21145039663SJohn Forte     stmf_ic_msg_type_t msg_type, uint8_t *lun_id,
21245039663SJohn Forte     char *lu_provider_name, uint16_t cb_arg_len,
21345039663SJohn Forte     uint8_t *cb_arg, stmf_ic_msgid_t msgid);
21445039663SJohn Forte 
21545039663SJohn Forte static stmf_ic_msg_t *stmf_ic_session_create_destroy_msg_alloc(
21645039663SJohn Forte     stmf_ic_msg_type_t msg_type,
21745039663SJohn Forte     stmf_scsi_session_t *session,
21845039663SJohn Forte     stmf_ic_msgid_t msgid);
21945039663SJohn Forte 
22045039663SJohn Forte static stmf_ic_msg_t *stmf_ic_echo_request_reply_msg_alloc(
22145039663SJohn Forte     stmf_ic_msg_type_t msg_type,
22245039663SJohn Forte     uint32_t data_len,
22345039663SJohn Forte     uint8_t *data,
22445039663SJohn Forte     stmf_ic_msgid_t msgid);
22545039663SJohn Forte 
22645039663SJohn Forte /*
22745039663SJohn Forte  * Msg free routines.
22845039663SJohn Forte  */
22945039663SJohn Forte static void stmf_ic_reg_port_msg_free(stmf_ic_reg_port_msg_t *m,
23045039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
23145039663SJohn Forte static void stmf_ic_dereg_port_msg_free(stmf_ic_dereg_port_msg_t *m,
23245039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
23345039663SJohn Forte static void stmf_ic_reg_dereg_lun_msg_free(stmf_ic_reg_dereg_lun_msg_t *m,
23445039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
23545039663SJohn Forte static void stmf_ic_scsi_cmd_msg_free(stmf_ic_scsi_cmd_msg_t *m,
23645039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
23745039663SJohn Forte static void stmf_ic_scsi_data_msg_free(stmf_ic_scsi_data_msg_t *m,
23845039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
23945039663SJohn Forte static void stmf_ic_scsi_data_xfer_done_msg_free(
24045039663SJohn Forte     stmf_ic_scsi_data_xfer_done_msg_t *m,
24145039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
24245039663SJohn Forte static void stmf_ic_scsi_status_msg_free(stmf_ic_scsi_status_msg_t *m,
24345039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
24445039663SJohn Forte static void stmf_ic_r2t_msg_free(stmf_ic_r2t_msg_t *m,
24545039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
24645039663SJohn Forte static void stmf_ic_status_msg_free(stmf_ic_status_msg_t *m,
24745039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
24845039663SJohn Forte static void stmf_ic_session_create_destroy_msg_free(
24945039663SJohn Forte     stmf_ic_session_create_destroy_msg_t *m,
25045039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
25145039663SJohn Forte static void stmf_ic_echo_request_reply_msg_free(
25245039663SJohn Forte     stmf_ic_echo_request_reply_msg_t *m,
25345039663SJohn Forte     stmf_ic_msg_construction_method_t cmethod);
25445039663SJohn Forte 
25545039663SJohn Forte /*
25645039663SJohn Forte  * Marshaling routines.
25745039663SJohn Forte  */
25845039663SJohn Forte static nvlist_t *stmf_ic_msg_marshal(stmf_ic_msg_t *msg);
25945039663SJohn Forte static int stmf_ic_reg_port_msg_marshal(nvlist_t *nvl, void *msg);
26045039663SJohn Forte static int stmf_ic_dereg_port_msg_marshal(nvlist_t *nvl, void *msg);
26145039663SJohn Forte static int stmf_ic_reg_dereg_lun_msg_marshal(nvlist_t *nvl, void *msg);
26245039663SJohn Forte static int stmf_ic_scsi_cmd_msg_marshal(nvlist_t *nvl, void *msg);
26345039663SJohn Forte static int stmf_ic_scsi_data_msg_marshal(nvlist_t *nvl, void *msg);
26445039663SJohn Forte static int stmf_ic_scsi_data_xfer_done_msg_marshal(nvlist_t *nvl, void *msg);
26545039663SJohn Forte static int stmf_ic_scsi_status_msg_marshal(nvlist_t *nvl, void *msg);
26645039663SJohn Forte static int stmf_ic_r2t_msg_marshal(nvlist_t *nvl, void *msg);
26745039663SJohn Forte static int stmf_ic_status_msg_marshal(nvlist_t *nvl, void *msg);
26845039663SJohn Forte static int stmf_ic_session_create_destroy_msg_marshal(nvlist_t *nvl, void *msg);
26945039663SJohn Forte static int stmf_ic_echo_request_reply_msg_marshal(nvlist_t *nvl, void *msg);
27045039663SJohn Forte static int stmf_ic_scsi_devid_desc_marshal(nvlist_t *parent_nvl,
27145039663SJohn Forte 	char *sdid_name, scsi_devid_desc_t *sdid);
272716c1805SNattuvetty Bhavyan static int stmf_ic_remote_port_marshal(nvlist_t *parent_nvl,
273716c1805SNattuvetty Bhavyan 	char *rport_name, stmf_remote_port_t *rport);
27445039663SJohn Forte 
27545039663SJohn Forte /*
27645039663SJohn Forte  * Unmarshaling routines.
27745039663SJohn Forte  */
27845039663SJohn Forte static stmf_ic_msg_t *stmf_ic_msg_unmarshal(nvlist_t *nvl);
27945039663SJohn Forte static void *stmf_ic_reg_port_msg_unmarshal(nvlist_t *nvl);
28045039663SJohn Forte static void *stmf_ic_dereg_port_msg_unmarshal(nvlist_t *nvl);
28145039663SJohn Forte static void *stmf_ic_reg_dereg_lun_msg_unmarshal(nvlist_t *nvl);
28245039663SJohn Forte static void *stmf_ic_scsi_cmd_msg_unmarshal(nvlist_t *nvl);
28345039663SJohn Forte static void *stmf_ic_scsi_data_msg_unmarshal(nvlist_t *nvl);
28445039663SJohn Forte static void *stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvlist_t *nvl);
28545039663SJohn Forte static void *stmf_ic_scsi_status_msg_unmarshal(nvlist_t *nvl);
28645039663SJohn Forte static void *stmf_ic_r2t_msg_unmarshal(nvlist_t *nvl);
28745039663SJohn Forte static void *stmf_ic_status_msg_unmarshal(nvlist_t *nvl);
28845039663SJohn Forte static void *stmf_ic_session_create_destroy_msg_unmarshal(nvlist_t *nvl);
28945039663SJohn Forte static void *stmf_ic_echo_request_reply_msg_unmarshal(nvlist_t *nvl);
29045039663SJohn Forte static scsi_devid_desc_t *stmf_ic_lookup_scsi_devid_desc_and_unmarshal(
29145039663SJohn Forte     nvlist_t *nvl, char *field_name);
29245039663SJohn Forte static scsi_devid_desc_t *stmf_ic_scsi_devid_desc_unmarshal(
29345039663SJohn Forte     nvlist_t *nvl_devid);
29445039663SJohn Forte static uint8_t *stmf_ic_uint8_array_unmarshal(nvlist_t *nvl, char *field_name,
29591159e90SJohn Forte 	uint64_t len, uint8_t *buf);
29645039663SJohn Forte static char *stmf_ic_string_unmarshal(nvlist_t *nvl, char *field_name);
297716c1805SNattuvetty Bhavyan static stmf_remote_port_t *stmf_ic_lookup_remote_port_and_unmarshal(
298716c1805SNattuvetty Bhavyan 	nvlist_t *nvl, char *field_name);
299716c1805SNattuvetty Bhavyan static stmf_remote_port_t *stmf_ic_remote_port_unmarshal(nvlist_t *nvl);
30045039663SJohn Forte 
30145039663SJohn Forte /*
30245039663SJohn Forte  * Transmit and recieve routines.
30345039663SJohn Forte  */
30445039663SJohn Forte stmf_ic_msg_status_t stmf_ic_transmit(char *buf, size_t size);
30545039663SJohn Forte 
30645039663SJohn Forte /*
30745039663SJohn Forte  * Utilities.
30845039663SJohn Forte  */
30945039663SJohn Forte static stmf_ic_msg_t *stmf_ic_alloc_msg_header(stmf_ic_msg_type_t msg_type,
31045039663SJohn Forte 	stmf_ic_msgid_t msgid);
31145039663SJohn Forte static size_t sizeof_scsi_devid_desc(int ident_length);
31245039663SJohn Forte static char *stmf_ic_strdup(char *str);
31345039663SJohn Forte static scsi_devid_desc_t *scsi_devid_desc_dup(scsi_devid_desc_t *did);
314716c1805SNattuvetty Bhavyan static stmf_remote_port_t *remote_port_dup(stmf_remote_port_t *rport);
31545039663SJohn Forte static void scsi_devid_desc_free(scsi_devid_desc_t *did);
31645039663SJohn Forte static inline void stmf_ic_nvlookup_warn(const char *func, char *field);
31745039663SJohn Forte 
31845039663SJohn Forte /*
31945039663SJohn Forte  * Send a message out over the interconnect, in the process marshalling
32045039663SJohn Forte  * the arguments.
32145039663SJohn Forte  *
32245039663SJohn Forte  * After being sent, the message is freed.
32345039663SJohn Forte  */
32445039663SJohn Forte stmf_ic_msg_status_t
stmf_ic_tx_msg(stmf_ic_msg_t * msg)32545039663SJohn Forte stmf_ic_tx_msg(stmf_ic_msg_t *msg)
32645039663SJohn Forte {
32745039663SJohn Forte 	size_t size = 0;
32845039663SJohn Forte 	nvlist_t *nvl = NULL;
32945039663SJohn Forte 	char *buf = NULL;
33045039663SJohn Forte 	int err = 0;
33145039663SJohn Forte 	stmf_ic_msg_status_t status = STMF_IC_MSG_SUCCESS;
33245039663SJohn Forte 
33345039663SJohn Forte 	nvl = stmf_ic_msg_marshal(msg);
33445039663SJohn Forte 	if (!nvl) {
33545039663SJohn Forte 		cmn_err(CE_WARN, "stmf_ic_tx_msg: marshal failed");
33645039663SJohn Forte 		status = STMF_IC_MSG_INTERNAL_ERROR;
33745039663SJohn Forte 		goto done;
33845039663SJohn Forte 	}
33945039663SJohn Forte 
34045039663SJohn Forte 	err = nvlist_size(nvl, &size, NV_ENCODE_XDR);
34145039663SJohn Forte 	if (err) {
34245039663SJohn Forte 		status = STMF_IC_MSG_INTERNAL_ERROR;
34345039663SJohn Forte 		goto done;
34445039663SJohn Forte 	}
34545039663SJohn Forte 
34645039663SJohn Forte 	buf = kmem_alloc(size, KM_SLEEP);
34745039663SJohn Forte 	err = nvlist_pack(nvl, &buf, &size, NV_ENCODE_XDR, 0);
34845039663SJohn Forte 	if (err) {
34945039663SJohn Forte 		status = STMF_IC_MSG_INTERNAL_ERROR;
35045039663SJohn Forte 		goto done;
35145039663SJohn Forte 	}
35245039663SJohn Forte 
35345039663SJohn Forte 	/* push the bits out on the wire */
35445039663SJohn Forte 
35545039663SJohn Forte 	status = stmf_ic_transmit(buf, size);
35645039663SJohn Forte 
35745039663SJohn Forte done:
358*aab83bb8SJosef 'Jeff' Sipek 	nvlist_free(nvl);
35945039663SJohn Forte 
36045039663SJohn Forte 	if (buf)
36145039663SJohn Forte 		kmem_free(buf, size);
36245039663SJohn Forte 
36345039663SJohn Forte 	stmf_ic_msg_free(msg);
36445039663SJohn Forte 
36545039663SJohn Forte 
36645039663SJohn Forte 	return (status);
36745039663SJohn Forte }
36845039663SJohn Forte 
36945039663SJohn Forte /*
37045039663SJohn Forte  * Pass the command to the daemon for transmission to the other node.
37145039663SJohn Forte  */
37245039663SJohn Forte stmf_ic_msg_status_t
stmf_ic_transmit(char * buf,size_t size)37345039663SJohn Forte stmf_ic_transmit(char *buf, size_t size)
37445039663SJohn Forte {
37545039663SJohn Forte 	int i;
37645039663SJohn Forte 	int rc;
37745039663SJohn Forte 	door_arg_t arg;
37845039663SJohn Forte 	door_handle_t door;
37945039663SJohn Forte 	uint32_t result;
38045039663SJohn Forte 
38145039663SJohn Forte 	mutex_enter(&pppt_global.global_door_lock);
38245039663SJohn Forte 	if (pppt_global.global_door == NULL) {
38345039663SJohn Forte 		/* daemon not listening */
38445039663SJohn Forte 		mutex_exit(&pppt_global.global_door_lock);
38545039663SJohn Forte 		return (STMF_IC_MSG_INTERNAL_ERROR);
38645039663SJohn Forte 	}
38745039663SJohn Forte 	door = pppt_global.global_door;
38845039663SJohn Forte 	door_ki_hold(door);
38945039663SJohn Forte 	mutex_exit(&pppt_global.global_door_lock);
39045039663SJohn Forte 
39145039663SJohn Forte 	arg.data_ptr = buf;
39245039663SJohn Forte 	arg.data_size = size;
39345039663SJohn Forte 	arg.desc_ptr = NULL;
39445039663SJohn Forte 	arg.desc_num = 0;
39545039663SJohn Forte 	arg.rbuf = (char *)&result;
39645039663SJohn Forte 	arg.rsize = sizeof (result);
39745039663SJohn Forte 	/*
39845039663SJohn Forte 	 * Retry a few times if there is a shortage of threads to
39945039663SJohn Forte 	 * service the upcall. This shouldn't happen unless a large
40045039663SJohn Forte 	 * number of initiators issue commands at once.
40145039663SJohn Forte 	 */
40245039663SJohn Forte 	for (i = 0; i < STMF_MSG_TRANSMIT_RETRY; i++) {
40345039663SJohn Forte 		rc = door_ki_upcall(door, &arg);
40445039663SJohn Forte 		if (rc != EAGAIN)
40545039663SJohn Forte 			break;
40645039663SJohn Forte 		delay(hz);
40745039663SJohn Forte 	}
40845039663SJohn Forte 	door_ki_rele(door);
40945039663SJohn Forte 	if (rc != 0) {
41045039663SJohn Forte 		cmn_err(CE_WARN,
41145039663SJohn Forte 		    "stmf_ic_transmit door_ki_upcall failed %d", rc);
41245039663SJohn Forte 		return (STMF_IC_MSG_INTERNAL_ERROR);
41345039663SJohn Forte 	}
41445039663SJohn Forte 	if (result != 0) {
41545039663SJohn Forte 		/* XXX Just warn for now */
41645039663SJohn Forte 		cmn_err(CE_WARN,
41745039663SJohn Forte 		    "stmf_ic_transmit bad result from daemon %d", result);
41845039663SJohn Forte 	}
41945039663SJohn Forte 
42045039663SJohn Forte 	return (STMF_IC_MSG_SUCCESS);
42145039663SJohn Forte }
42245039663SJohn Forte 
42345039663SJohn Forte /*
42445039663SJohn Forte  * This is a low-level upcall which is called when a message has
42545039663SJohn Forte  * been received on the interconnect.
42645039663SJohn Forte  *
42745039663SJohn Forte  * The caller is responsible for freeing the buffer which is passed in.
42845039663SJohn Forte  */
42945039663SJohn Forte /*ARGSUSED*/
43045039663SJohn Forte void
stmf_ic_rx_msg(char * buf,size_t len)43145039663SJohn Forte stmf_ic_rx_msg(char *buf, size_t len)
43245039663SJohn Forte {
43345039663SJohn Forte 	nvlist_t *nvl = NULL;
43445039663SJohn Forte 	stmf_ic_msg_t *m = NULL;
43545039663SJohn Forte 	stmf_ic_echo_request_reply_msg_t *icerr;
43645039663SJohn Forte 	stmf_ic_msg_t *echo_msg;
43745039663SJohn Forte 	int rc = 0;
43845039663SJohn Forte 
43945039663SJohn Forte 	rc = nvlist_unpack(buf, len, &nvl, 0);
44045039663SJohn Forte 	if (rc) {
44145039663SJohn Forte 		cmn_err(CE_WARN, "stmf_ic_rx_msg: unpack failed");
44245039663SJohn Forte 		return;
44345039663SJohn Forte 	}
44445039663SJohn Forte 
44545039663SJohn Forte 	m = stmf_ic_msg_unmarshal(nvl);
44645039663SJohn Forte 	if (m == NULL) {
44745039663SJohn Forte 		cmn_err(CE_WARN, "stmf_ic_rx_msg: unmarshal failed");
44845039663SJohn Forte 		nvlist_free(nvl);
44945039663SJohn Forte 		return;
45045039663SJohn Forte 	}
45145039663SJohn Forte 
45245039663SJohn Forte 	switch (m->icm_msg_type) {
45345039663SJohn Forte 
45445039663SJohn Forte 	case STMF_ICM_REGISTER_PROXY_PORT:
45545039663SJohn Forte 	case STMF_ICM_DEREGISTER_PROXY_PORT:
45645039663SJohn Forte 	case STMF_ICM_SCSI_CMD:
45745039663SJohn Forte 	case STMF_ICM_SCSI_DATA_XFER_DONE:
45845039663SJohn Forte 	case STMF_ICM_SESSION_CREATE:
45945039663SJohn Forte 	case STMF_ICM_SESSION_DESTROY:
46045039663SJohn Forte 		/*
46145039663SJohn Forte 		 * These messages are all received by pppt.
46245039663SJohn Forte 		 * Currently, pppt will parse the message for type
46345039663SJohn Forte 		 */
46445039663SJohn Forte 		(void) pppt_msg_rx(m);
46545039663SJohn Forte 		break;
46645039663SJohn Forte 
46745039663SJohn Forte 	case STMF_ICM_LUN_ACTIVE:
46845039663SJohn Forte 	case STMF_ICM_REGISTER_LUN:
46945039663SJohn Forte 	case STMF_ICM_DEREGISTER_LUN:
47045039663SJohn Forte 	case STMF_ICM_SCSI_DATA:
47145039663SJohn Forte 	case STMF_ICM_SCSI_STATUS:
47245039663SJohn Forte 		/*
47345039663SJohn Forte 		 * These messages are all received by stmf.
47445039663SJohn Forte 		 * Currently, stmf will parse the message for type
47545039663SJohn Forte 		 */
47645039663SJohn Forte 		(void) stmf_msg_rx(m);
47745039663SJohn Forte 		break;
47845039663SJohn Forte 
47945039663SJohn Forte 	case STMF_ICM_ECHO_REQUEST:
48045039663SJohn Forte 		icerr = m->icm_msg;
48145039663SJohn Forte 		echo_msg = stmf_ic_echo_reply_msg_alloc(icerr->icerr_datalen,
48245039663SJohn Forte 		    icerr->icerr_data, 0);
48345039663SJohn Forte 		if (echo_msg != NULL) {
48445039663SJohn Forte 			(void) stmf_ic_tx_msg(echo_msg);
48545039663SJohn Forte 		}
48645039663SJohn Forte 		stmf_ic_msg_free(m);
48745039663SJohn Forte 		break;
48845039663SJohn Forte 
48945039663SJohn Forte 	case STMF_ICM_ECHO_REPLY:
49045039663SJohn Forte 		stmf_ic_msg_free(m);
49145039663SJohn Forte 		break;
49245039663SJohn Forte 
49345039663SJohn Forte 	case STMF_ICM_R2T:
49445039663SJohn Forte 		/*
49545039663SJohn Forte 		 * XXX currently not supported
49645039663SJohn Forte 		 */
49745039663SJohn Forte 		stmf_ic_msg_free(m);
49845039663SJohn Forte 		break;
49945039663SJohn Forte 
50045039663SJohn Forte 	case STMF_ICM_STATUS:
50145039663SJohn Forte 		(void) stmf_msg_rx(m);
50245039663SJohn Forte 		break;
50345039663SJohn Forte 
50445039663SJohn Forte 	default:
50545039663SJohn Forte 		ASSERT(0);
50645039663SJohn Forte 	}
50745039663SJohn Forte }
50845039663SJohn Forte 
50945039663SJohn Forte /*
51045039663SJohn Forte  * IC message allocation routines.
51145039663SJohn Forte  */
51245039663SJohn Forte 
51345039663SJohn Forte stmf_ic_msg_t *
stmf_ic_reg_port_msg_alloc(scsi_devid_desc_t * port_id,uint16_t relative_port_id,uint16_t cb_arg_len,uint8_t * cb_arg,stmf_ic_msgid_t msgid)51445039663SJohn Forte stmf_ic_reg_port_msg_alloc(
51545039663SJohn Forte     scsi_devid_desc_t *port_id,
51645039663SJohn Forte     uint16_t relative_port_id,
51745039663SJohn Forte     uint16_t cb_arg_len,
51845039663SJohn Forte     uint8_t *cb_arg,
51945039663SJohn Forte     stmf_ic_msgid_t msgid)
52045039663SJohn Forte {
52145039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
52245039663SJohn Forte 	stmf_ic_reg_port_msg_t *icrp = NULL;
52345039663SJohn Forte 
52445039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(STMF_ICM_REGISTER_PROXY_PORT, msgid);
52545039663SJohn Forte 	icrp = (stmf_ic_reg_port_msg_t *)kmem_zalloc(sizeof (*icrp), KM_SLEEP);
52645039663SJohn Forte 	icm->icm_msg = (void *)icrp;
52745039663SJohn Forte 
52845039663SJohn Forte 	icrp->icrp_port_id = scsi_devid_desc_dup(port_id);
52945039663SJohn Forte 	icrp->icrp_relative_port_id = relative_port_id;
53045039663SJohn Forte 
53145039663SJohn Forte 	if (cb_arg_len) {
53245039663SJohn Forte 		icrp->icrp_cb_arg_len = cb_arg_len;
53345039663SJohn Forte 		icrp->icrp_cb_arg = cb_arg;
53445039663SJohn Forte 	}
53545039663SJohn Forte 
53645039663SJohn Forte 	return (icm);
53745039663SJohn Forte }
53845039663SJohn Forte 
53945039663SJohn Forte stmf_ic_msg_t *
stmf_ic_dereg_port_msg_alloc(scsi_devid_desc_t * port_id,uint16_t cb_arg_len,uint8_t * cb_arg,stmf_ic_msgid_t msgid)54045039663SJohn Forte stmf_ic_dereg_port_msg_alloc(
54145039663SJohn Forte     scsi_devid_desc_t *port_id,
54245039663SJohn Forte     uint16_t cb_arg_len,
54345039663SJohn Forte     uint8_t *cb_arg,
54445039663SJohn Forte     stmf_ic_msgid_t msgid)
54545039663SJohn Forte {
54645039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
54745039663SJohn Forte 	stmf_ic_dereg_port_msg_t *icdp = NULL;
54845039663SJohn Forte 
54945039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(STMF_ICM_DEREGISTER_PROXY_PORT, msgid);
55045039663SJohn Forte 	icdp = (stmf_ic_dereg_port_msg_t *)kmem_zalloc(sizeof (*icdp),
55145039663SJohn Forte 	    KM_SLEEP);
55245039663SJohn Forte 	icm->icm_msg = (void *)icdp;
55345039663SJohn Forte 
55445039663SJohn Forte 	icdp->icdp_port_id = scsi_devid_desc_dup(port_id);
55545039663SJohn Forte 
55645039663SJohn Forte 	if (cb_arg_len) {
55745039663SJohn Forte 		icdp->icdp_cb_arg_len = cb_arg_len;
55845039663SJohn Forte 		icdp->icdp_cb_arg = cb_arg;
55945039663SJohn Forte 	}
56045039663SJohn Forte 
56145039663SJohn Forte 	return (icm);
56245039663SJohn Forte }
56345039663SJohn Forte 
56445039663SJohn Forte 
56545039663SJohn Forte stmf_ic_msg_t *
stmf_ic_reg_lun_msg_alloc(uint8_t * lun_id,char * lu_provider_name,uint16_t cb_arg_len,uint8_t * cb_arg,stmf_ic_msgid_t msgid)56645039663SJohn Forte stmf_ic_reg_lun_msg_alloc(
56745039663SJohn Forte     uint8_t *lun_id,
56845039663SJohn Forte     char *lu_provider_name,
56945039663SJohn Forte     uint16_t cb_arg_len,
57045039663SJohn Forte     uint8_t *cb_arg,
57145039663SJohn Forte     stmf_ic_msgid_t msgid)
57245039663SJohn Forte {
57345039663SJohn Forte 	return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_REGISTER_LUN, lun_id,
57445039663SJohn Forte 	    lu_provider_name, cb_arg_len, cb_arg, msgid));
57545039663SJohn Forte }
57645039663SJohn Forte 
57745039663SJohn Forte stmf_ic_msg_t *
stmf_ic_lun_active_msg_alloc(uint8_t * lun_id,char * lu_provider_name,uint16_t cb_arg_len,uint8_t * cb_arg,stmf_ic_msgid_t msgid)57845039663SJohn Forte stmf_ic_lun_active_msg_alloc(
57945039663SJohn Forte     uint8_t *lun_id,
58045039663SJohn Forte     char *lu_provider_name,
58145039663SJohn Forte     uint16_t cb_arg_len,
58245039663SJohn Forte     uint8_t *cb_arg,
58345039663SJohn Forte     stmf_ic_msgid_t msgid)
58445039663SJohn Forte {
58545039663SJohn Forte 	return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_LUN_ACTIVE, lun_id,
58645039663SJohn Forte 	    lu_provider_name, cb_arg_len, cb_arg, msgid));
58745039663SJohn Forte }
58845039663SJohn Forte 
58945039663SJohn Forte stmf_ic_msg_t *
stmf_ic_dereg_lun_msg_alloc(uint8_t * lun_id,char * lu_provider_name,uint16_t cb_arg_len,uint8_t * cb_arg,stmf_ic_msgid_t msgid)59045039663SJohn Forte stmf_ic_dereg_lun_msg_alloc(
59145039663SJohn Forte     uint8_t *lun_id,
59245039663SJohn Forte     char *lu_provider_name,
59345039663SJohn Forte     uint16_t cb_arg_len,
59445039663SJohn Forte     uint8_t *cb_arg,
59545039663SJohn Forte     stmf_ic_msgid_t msgid)
59645039663SJohn Forte {
59745039663SJohn Forte 	return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_DEREGISTER_LUN, lun_id,
59845039663SJohn Forte 	    lu_provider_name, cb_arg_len, cb_arg, msgid));
59945039663SJohn Forte }
60045039663SJohn Forte 
60145039663SJohn Forte /*
60245039663SJohn Forte  * Guts of lun register/deregister/active alloc routines.
60345039663SJohn Forte  */
60445039663SJohn Forte static stmf_ic_msg_t *
stmf_ic_reg_dereg_lun_msg_alloc(stmf_ic_msg_type_t msg_type,uint8_t * lun_id,char * lu_provider_name,uint16_t cb_arg_len,uint8_t * cb_arg,stmf_ic_msgid_t msgid)60545039663SJohn Forte stmf_ic_reg_dereg_lun_msg_alloc(
60645039663SJohn Forte     stmf_ic_msg_type_t msg_type,
60745039663SJohn Forte     uint8_t *lun_id,
60845039663SJohn Forte     char *lu_provider_name,
60945039663SJohn Forte     uint16_t cb_arg_len,
61045039663SJohn Forte     uint8_t *cb_arg,
61145039663SJohn Forte     stmf_ic_msgid_t msgid)
61245039663SJohn Forte {
61345039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
61445039663SJohn Forte 	stmf_ic_reg_dereg_lun_msg_t *icrl = NULL;
61545039663SJohn Forte 
61645039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(msg_type, msgid);
61745039663SJohn Forte 	icrl = (stmf_ic_reg_dereg_lun_msg_t *)
61845039663SJohn Forte 	    kmem_zalloc(sizeof (*icrl), KM_SLEEP);
61945039663SJohn Forte 	icm->icm_msg = (void *)icrl;
62045039663SJohn Forte 
62145039663SJohn Forte 	icrl->icrl_lu_provider_name = stmf_ic_strdup(lu_provider_name);
62245039663SJohn Forte 
62345039663SJohn Forte 	bcopy(lun_id, icrl->icrl_lun_id, sizeof (icrl->icrl_lun_id));
62445039663SJohn Forte 
62545039663SJohn Forte 	if (cb_arg_len) {
62645039663SJohn Forte 		icrl->icrl_cb_arg_len = cb_arg_len;
62745039663SJohn Forte 		icrl->icrl_cb_arg = cb_arg;
62845039663SJohn Forte 	}
62945039663SJohn Forte 
63045039663SJohn Forte 	return (icm);
63145039663SJohn Forte }
63245039663SJohn Forte 
63345039663SJohn Forte stmf_ic_msg_t *
stmf_ic_scsi_cmd_msg_alloc(stmf_ic_msgid_t task_msgid,scsi_task_t * task,uint32_t immed_data_len,uint8_t * immed_data,stmf_ic_msgid_t msgid)63445039663SJohn Forte stmf_ic_scsi_cmd_msg_alloc(
63545039663SJohn Forte     stmf_ic_msgid_t task_msgid,
63645039663SJohn Forte     scsi_task_t *task,
63745039663SJohn Forte     uint32_t immed_data_len,
63845039663SJohn Forte     uint8_t *immed_data,
63945039663SJohn Forte     stmf_ic_msgid_t msgid)
64045039663SJohn Forte {
64145039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
64245039663SJohn Forte 	stmf_ic_scsi_cmd_msg_t *icsc = NULL;
64345039663SJohn Forte 	scsi_devid_desc_t *ini_devid = task->task_session->ss_rport_id;
64445039663SJohn Forte 	scsi_devid_desc_t *tgt_devid = task->task_lport->lport_id;
645716c1805SNattuvetty Bhavyan 	stmf_remote_port_t *rport = task->task_session->ss_rport;
64645039663SJohn Forte 
64745039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_CMD, msgid);
64845039663SJohn Forte 	icsc = (stmf_ic_scsi_cmd_msg_t *)kmem_zalloc(sizeof (*icsc), KM_SLEEP);
64945039663SJohn Forte 	icm->icm_msg = (void *)icsc;
65045039663SJohn Forte 
65145039663SJohn Forte 	icsc->icsc_task_msgid = task_msgid;
65245039663SJohn Forte 	icsc->icsc_ini_devid = scsi_devid_desc_dup(ini_devid);
65345039663SJohn Forte 	icsc->icsc_tgt_devid = scsi_devid_desc_dup(tgt_devid);
654716c1805SNattuvetty Bhavyan 	icsc->icsc_rport = remote_port_dup(rport);
65545039663SJohn Forte 	icsc->icsc_session_id = task->task_session->ss_session_id;
65645039663SJohn Forte 
657cbdc6dc7SJohn Forte 	if (!task->task_mgmt_function && task->task_lu->lu_id) {
658cbdc6dc7SJohn Forte 		bcopy(task->task_lu->lu_id->ident,
659cbdc6dc7SJohn Forte 		    icsc->icsc_lun_id, sizeof (icsc->icsc_lun_id));
660cbdc6dc7SJohn Forte 	}
66145039663SJohn Forte 
66245039663SJohn Forte 	bcopy(task->task_lun_no, icsc->icsc_task_lun_no,
66345039663SJohn Forte 	    sizeof (icsc->icsc_task_lun_no));
66445039663SJohn Forte 
66545039663SJohn Forte 	icsc->icsc_task_expected_xfer_length = task->task_expected_xfer_length;
6668f641fa7SSue Gleeson 	if (task->task_cdb_length) {
6678f641fa7SSue Gleeson 		ASSERT(task->task_mgmt_function == TM_NONE);
6688f641fa7SSue Gleeson 		icsc->icsc_task_cdb_length = task->task_cdb_length;
6698f641fa7SSue Gleeson 		icsc->icsc_task_cdb =
6708f641fa7SSue Gleeson 		    (uint8_t *)kmem_zalloc(task->task_cdb_length, KM_SLEEP);
6718f641fa7SSue Gleeson 		bcopy(task->task_cdb, icsc->icsc_task_cdb,
6728f641fa7SSue Gleeson 		    task->task_cdb_length);
6738f641fa7SSue Gleeson 	}
67445039663SJohn Forte 
67545039663SJohn Forte 	icsc->icsc_task_flags = task->task_flags;
67645039663SJohn Forte 	icsc->icsc_task_priority = task->task_priority;
67745039663SJohn Forte 	icsc->icsc_task_mgmt_function = task->task_mgmt_function;
67845039663SJohn Forte 
67945039663SJohn Forte 	icsc->icsc_immed_data_len = immed_data_len;
68045039663SJohn Forte 	icsc->icsc_immed_data = immed_data;
68145039663SJohn Forte 
68245039663SJohn Forte 	return (icm);
68345039663SJohn Forte }
68445039663SJohn Forte 
68545039663SJohn Forte stmf_ic_msg_t *
stmf_ic_scsi_data_msg_alloc(stmf_ic_msgid_t task_msgid,uint64_t session_id,uint8_t * lun_id,uint64_t data_len,uint8_t * data,stmf_ic_msgid_t msgid)68645039663SJohn Forte stmf_ic_scsi_data_msg_alloc(
68745039663SJohn Forte     stmf_ic_msgid_t task_msgid,
68845039663SJohn Forte     uint64_t session_id,
68945039663SJohn Forte     uint8_t *lun_id,
69045039663SJohn Forte     uint64_t data_len,
69145039663SJohn Forte     uint8_t *data,
69245039663SJohn Forte     stmf_ic_msgid_t msgid)
69345039663SJohn Forte {
69445039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
69545039663SJohn Forte 	stmf_ic_scsi_data_msg_t *icsd = NULL;
69645039663SJohn Forte 
69745039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_DATA, msgid);
69845039663SJohn Forte 	icsd = (stmf_ic_scsi_data_msg_t *)kmem_zalloc(sizeof (*icsd), KM_SLEEP);
69945039663SJohn Forte 	icm->icm_msg = (void *)icsd;
70045039663SJohn Forte 
70145039663SJohn Forte 	icsd->icsd_task_msgid = task_msgid;
70245039663SJohn Forte 	icsd->icsd_session_id = session_id;
70345039663SJohn Forte 	bcopy(lun_id, icsd->icsd_lun_id, sizeof (icsd->icsd_lun_id));
70445039663SJohn Forte 	icsd->icsd_data_len = data_len;
70545039663SJohn Forte 	icsd->icsd_data = data;
70645039663SJohn Forte 
70745039663SJohn Forte 	return (icm);
70845039663SJohn Forte }
70945039663SJohn Forte 
71045039663SJohn Forte stmf_ic_msg_t *
stmf_ic_scsi_data_xfer_done_msg_alloc(stmf_ic_msgid_t task_msgid,uint64_t session_id,stmf_status_t status,stmf_ic_msgid_t msgid)71145039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_alloc(
71245039663SJohn Forte     stmf_ic_msgid_t task_msgid,
71345039663SJohn Forte     uint64_t session_id,
71445039663SJohn Forte     stmf_status_t status,
71545039663SJohn Forte     stmf_ic_msgid_t msgid)
71645039663SJohn Forte {
71745039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
71845039663SJohn Forte 	stmf_ic_scsi_data_xfer_done_msg_t *icsx = NULL;
71945039663SJohn Forte 
72045039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_DATA_XFER_DONE, msgid);
72145039663SJohn Forte 	icsx = (stmf_ic_scsi_data_xfer_done_msg_t *)kmem_zalloc(
72245039663SJohn Forte 	    sizeof (*icsx), KM_SLEEP);
72345039663SJohn Forte 	icm->icm_msg = (void *)icsx;
72445039663SJohn Forte 
72545039663SJohn Forte 	icsx->icsx_task_msgid = task_msgid;
72645039663SJohn Forte 	icsx->icsx_session_id = session_id;
72745039663SJohn Forte 	icsx->icsx_status = status;
72845039663SJohn Forte 
72945039663SJohn Forte 	return (icm);
73045039663SJohn Forte }
73145039663SJohn Forte 
73245039663SJohn Forte stmf_ic_msg_t *
stmf_ic_scsi_status_msg_alloc(stmf_ic_msgid_t task_msgid,uint64_t session_id,uint8_t * lun_id,uint8_t response,uint8_t status,uint8_t flags,uint32_t resid,uint8_t sense_len,uint8_t * sense,stmf_ic_msgid_t msgid)73345039663SJohn Forte stmf_ic_scsi_status_msg_alloc(
73445039663SJohn Forte     stmf_ic_msgid_t task_msgid,
73545039663SJohn Forte     uint64_t session_id,
73645039663SJohn Forte     uint8_t *lun_id,
73745039663SJohn Forte     uint8_t response,
73845039663SJohn Forte     uint8_t status,
73945039663SJohn Forte     uint8_t flags,
74045039663SJohn Forte     uint32_t resid,
74145039663SJohn Forte     uint8_t sense_len,
74245039663SJohn Forte     uint8_t *sense,
74345039663SJohn Forte     stmf_ic_msgid_t msgid)
74445039663SJohn Forte {
74545039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
74645039663SJohn Forte 	stmf_ic_scsi_status_msg_t *icss = NULL;
74745039663SJohn Forte 
74845039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_STATUS, msgid);
74945039663SJohn Forte 	icss = (stmf_ic_scsi_status_msg_t *)kmem_zalloc(sizeof (*icss),
75045039663SJohn Forte 	    KM_SLEEP);
75145039663SJohn Forte 	icm->icm_msg = (void *)icss;
75245039663SJohn Forte 
75345039663SJohn Forte 	icss->icss_task_msgid = task_msgid;
75445039663SJohn Forte 	icss->icss_session_id = session_id;
75545039663SJohn Forte 	bcopy(lun_id, icss->icss_lun_id, sizeof (icss->icss_lun_id));
75645039663SJohn Forte 	icss->icss_response = response;
75745039663SJohn Forte 	icss->icss_status = status;
75845039663SJohn Forte 	icss->icss_flags = flags;
75945039663SJohn Forte 	icss->icss_resid = resid;
76045039663SJohn Forte 	icss->icss_sense_len = sense_len;
76145039663SJohn Forte 	icss->icss_sense = sense;
76245039663SJohn Forte 
76345039663SJohn Forte 	return (icm);
76445039663SJohn Forte }
76545039663SJohn Forte 
76645039663SJohn Forte stmf_ic_msg_t *
stmf_ic_r2t_msg_alloc(stmf_ic_msgid_t task_msgid,uint64_t session_id,uint32_t offset,uint32_t length,stmf_ic_msgid_t msgid)76745039663SJohn Forte stmf_ic_r2t_msg_alloc(
76845039663SJohn Forte     stmf_ic_msgid_t task_msgid,
76945039663SJohn Forte     uint64_t session_id,
77045039663SJohn Forte     uint32_t offset,
77145039663SJohn Forte     uint32_t length,
77245039663SJohn Forte     stmf_ic_msgid_t msgid)
77345039663SJohn Forte {
77445039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
77545039663SJohn Forte 	stmf_ic_r2t_msg_t *icrt = NULL;
77645039663SJohn Forte 
77745039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(STMF_ICM_R2T, msgid);
77845039663SJohn Forte 	icrt = (stmf_ic_r2t_msg_t *)kmem_zalloc(sizeof (*icrt), KM_SLEEP);
77945039663SJohn Forte 	icm->icm_msg = (void *)icrt;
78045039663SJohn Forte 
78145039663SJohn Forte 	icrt->icrt_task_msgid = task_msgid;
78245039663SJohn Forte 	icrt->icrt_session_id = session_id;
78345039663SJohn Forte 	icrt->icrt_offset = offset;
78445039663SJohn Forte 	icrt->icrt_length = length;
78545039663SJohn Forte 
78645039663SJohn Forte 	return (icm);
78745039663SJohn Forte }
78845039663SJohn Forte 
78945039663SJohn Forte stmf_ic_msg_t *
stmf_ic_status_msg_alloc(stmf_status_t status,stmf_ic_msg_type_t msg_type,stmf_ic_msgid_t msgid)79045039663SJohn Forte stmf_ic_status_msg_alloc(
79145039663SJohn Forte     stmf_status_t status,
79245039663SJohn Forte     stmf_ic_msg_type_t msg_type,
79345039663SJohn Forte     stmf_ic_msgid_t msgid)
79445039663SJohn Forte {
79545039663SJohn Forte 	stmf_ic_msg_t *icm = NULL;
79645039663SJohn Forte 	stmf_ic_status_msg_t *ics = NULL;
79745039663SJohn Forte 
79845039663SJohn Forte 	icm = stmf_ic_alloc_msg_header(STMF_ICM_STATUS, msgid);
79945039663SJohn Forte 	ics = (stmf_ic_status_msg_t *)kmem_zalloc(sizeof (*ics), KM_SLEEP);
80045039663SJohn Forte 	icm->icm_msg = (void *)ics;
80145039663SJohn Forte 
80245039663SJohn Forte 	ics->ics_status = status;
80345039663SJohn Forte 	ics->ics_msg_type = msg_type;
804