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 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: 35845039663SJohn Forte if (nvl) 35945039663SJohn Forte nvlist_free(nvl); 36045039663SJohn Forte 36145039663SJohn Forte if (buf) 36245039663SJohn Forte kmem_free(buf, size); 36345039663SJohn Forte 36445039663SJohn Forte stmf_ic_msg_free(msg); 36545039663SJohn Forte 36645039663SJohn Forte 36745039663SJohn Forte return (status); 36845039663SJohn Forte } 36945039663SJohn Forte 37045039663SJohn Forte /* 37145039663SJohn Forte * Pass the command to the daemon for transmission to the other node. 37245039663SJohn Forte */ 37345039663SJohn Forte stmf_ic_msg_status_t 37445039663SJohn Forte stmf_ic_transmit(char *buf, size_t size) 37545039663SJohn Forte { 37645039663SJohn Forte int i; 37745039663SJohn Forte int rc; 37845039663SJohn Forte door_arg_t arg; 37945039663SJohn Forte door_handle_t door; 38045039663SJohn Forte uint32_t result; 38145039663SJohn Forte 38245039663SJohn Forte mutex_enter(&pppt_global.global_door_lock); 38345039663SJohn Forte if (pppt_global.global_door == NULL) { 38445039663SJohn Forte /* daemon not listening */ 38545039663SJohn Forte mutex_exit(&pppt_global.global_door_lock); 38645039663SJohn Forte return (STMF_IC_MSG_INTERNAL_ERROR); 38745039663SJohn Forte } 38845039663SJohn Forte door = pppt_global.global_door; 38945039663SJohn Forte door_ki_hold(door); 39045039663SJohn Forte mutex_exit(&pppt_global.global_door_lock); 39145039663SJohn Forte 39245039663SJohn Forte arg.data_ptr = buf; 39345039663SJohn Forte arg.data_size = size; 39445039663SJohn Forte arg.desc_ptr = NULL; 39545039663SJohn Forte arg.desc_num = 0; 39645039663SJohn Forte arg.rbuf = (char *)&result; 39745039663SJohn Forte arg.rsize = sizeof (result); 39845039663SJohn Forte /* 39945039663SJohn Forte * Retry a few times if there is a shortage of threads to 40045039663SJohn Forte * service the upcall. This shouldn't happen unless a large 40145039663SJohn Forte * number of initiators issue commands at once. 40245039663SJohn Forte */ 40345039663SJohn Forte for (i = 0; i < STMF_MSG_TRANSMIT_RETRY; i++) { 40445039663SJohn Forte rc = door_ki_upcall(door, &arg); 40545039663SJohn Forte if (rc != EAGAIN) 40645039663SJohn Forte break; 40745039663SJohn Forte delay(hz); 40845039663SJohn Forte } 40945039663SJohn Forte door_ki_rele(door); 41045039663SJohn Forte if (rc != 0) { 41145039663SJohn Forte cmn_err(CE_WARN, 41245039663SJohn Forte "stmf_ic_transmit door_ki_upcall failed %d", rc); 41345039663SJohn Forte return (STMF_IC_MSG_INTERNAL_ERROR); 41445039663SJohn Forte } 41545039663SJohn Forte if (result != 0) { 41645039663SJohn Forte /* XXX Just warn for now */ 41745039663SJohn Forte cmn_err(CE_WARN, 41845039663SJohn Forte "stmf_ic_transmit bad result from daemon %d", result); 41945039663SJohn Forte } 42045039663SJohn Forte 42145039663SJohn Forte return (STMF_IC_MSG_SUCCESS); 42245039663SJohn Forte } 42345039663SJohn Forte 42445039663SJohn Forte /* 42545039663SJohn Forte * This is a low-level upcall which is called when a message has 42645039663SJohn Forte * been received on the interconnect. 42745039663SJohn Forte * 42845039663SJohn Forte * The caller is responsible for freeing the buffer which is passed in. 42945039663SJohn Forte */ 43045039663SJohn Forte /*ARGSUSED*/ 43145039663SJohn Forte void 43245039663SJohn Forte stmf_ic_rx_msg(char *buf, size_t len) 43345039663SJohn Forte { 43445039663SJohn Forte nvlist_t *nvl = NULL; 43545039663SJohn Forte stmf_ic_msg_t *m = NULL; 43645039663SJohn Forte stmf_ic_echo_request_reply_msg_t *icerr; 43745039663SJohn Forte stmf_ic_msg_t *echo_msg; 43845039663SJohn Forte int rc = 0; 43945039663SJohn Forte 44045039663SJohn Forte rc = nvlist_unpack(buf, len, &nvl, 0); 44145039663SJohn Forte if (rc) { 44245039663SJohn Forte cmn_err(CE_WARN, "stmf_ic_rx_msg: unpack failed"); 44345039663SJohn Forte return; 44445039663SJohn Forte } 44545039663SJohn Forte 44645039663SJohn Forte m = stmf_ic_msg_unmarshal(nvl); 44745039663SJohn Forte if (m == NULL) { 44845039663SJohn Forte cmn_err(CE_WARN, "stmf_ic_rx_msg: unmarshal failed"); 44945039663SJohn Forte nvlist_free(nvl); 45045039663SJohn Forte return; 45145039663SJohn Forte } 45245039663SJohn Forte 45345039663SJohn Forte switch (m->icm_msg_type) { 45445039663SJohn Forte 45545039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 45645039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 45745039663SJohn Forte case STMF_ICM_SCSI_CMD: 45845039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 45945039663SJohn Forte case STMF_ICM_SESSION_CREATE: 46045039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 46145039663SJohn Forte /* 46245039663SJohn Forte * These messages are all received by pppt. 46345039663SJohn Forte * Currently, pppt will parse the message for type 46445039663SJohn Forte */ 46545039663SJohn Forte (void) pppt_msg_rx(m); 46645039663SJohn Forte break; 46745039663SJohn Forte 46845039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 46945039663SJohn Forte case STMF_ICM_REGISTER_LUN: 47045039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 47145039663SJohn Forte case STMF_ICM_SCSI_DATA: 47245039663SJohn Forte case STMF_ICM_SCSI_STATUS: 47345039663SJohn Forte /* 47445039663SJohn Forte * These messages are all received by stmf. 47545039663SJohn Forte * Currently, stmf will parse the message for type 47645039663SJohn Forte */ 47745039663SJohn Forte (void) stmf_msg_rx(m); 47845039663SJohn Forte break; 47945039663SJohn Forte 48045039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 48145039663SJohn Forte icerr = m->icm_msg; 48245039663SJohn Forte echo_msg = stmf_ic_echo_reply_msg_alloc(icerr->icerr_datalen, 48345039663SJohn Forte icerr->icerr_data, 0); 48445039663SJohn Forte if (echo_msg != NULL) { 48545039663SJohn Forte (void) stmf_ic_tx_msg(echo_msg); 48645039663SJohn Forte } 48745039663SJohn Forte stmf_ic_msg_free(m); 48845039663SJohn Forte break; 48945039663SJohn Forte 49045039663SJohn Forte case STMF_ICM_ECHO_REPLY: 49145039663SJohn Forte stmf_ic_msg_free(m); 49245039663SJohn Forte break; 49345039663SJohn Forte 49445039663SJohn Forte case STMF_ICM_R2T: 49545039663SJohn Forte /* 49645039663SJohn Forte * XXX currently not supported 49745039663SJohn Forte */ 49845039663SJohn Forte stmf_ic_msg_free(m); 49945039663SJohn Forte break; 50045039663SJohn Forte 50145039663SJohn Forte case STMF_ICM_STATUS: 50245039663SJohn Forte (void) stmf_msg_rx(m); 50345039663SJohn Forte break; 50445039663SJohn Forte 50545039663SJohn Forte default: 50645039663SJohn Forte ASSERT(0); 50745039663SJohn Forte } 50845039663SJohn Forte } 50945039663SJohn Forte 51045039663SJohn Forte /* 51145039663SJohn Forte * IC message allocation routines. 51245039663SJohn Forte */ 51345039663SJohn Forte 51445039663SJohn Forte stmf_ic_msg_t * 51545039663SJohn Forte stmf_ic_reg_port_msg_alloc( 51645039663SJohn Forte scsi_devid_desc_t *port_id, 51745039663SJohn Forte uint16_t relative_port_id, 51845039663SJohn Forte uint16_t cb_arg_len, 51945039663SJohn Forte uint8_t *cb_arg, 52045039663SJohn Forte stmf_ic_msgid_t msgid) 52145039663SJohn Forte { 52245039663SJohn Forte stmf_ic_msg_t *icm = NULL; 52345039663SJohn Forte stmf_ic_reg_port_msg_t *icrp = NULL; 52445039663SJohn Forte 52545039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_REGISTER_PROXY_PORT, msgid); 52645039663SJohn Forte icrp = (stmf_ic_reg_port_msg_t *)kmem_zalloc(sizeof (*icrp), KM_SLEEP); 52745039663SJohn Forte icm->icm_msg = (void *)icrp; 52845039663SJohn Forte 52945039663SJohn Forte icrp->icrp_port_id = scsi_devid_desc_dup(port_id); 53045039663SJohn Forte icrp->icrp_relative_port_id = relative_port_id; 53145039663SJohn Forte 53245039663SJohn Forte if (cb_arg_len) { 53345039663SJohn Forte icrp->icrp_cb_arg_len = cb_arg_len; 53445039663SJohn Forte icrp->icrp_cb_arg = cb_arg; 53545039663SJohn Forte } 53645039663SJohn Forte 53745039663SJohn Forte return (icm); 53845039663SJohn Forte } 53945039663SJohn Forte 54045039663SJohn Forte stmf_ic_msg_t * 54145039663SJohn Forte stmf_ic_dereg_port_msg_alloc( 54245039663SJohn Forte scsi_devid_desc_t *port_id, 54345039663SJohn Forte uint16_t cb_arg_len, 54445039663SJohn Forte uint8_t *cb_arg, 54545039663SJohn Forte stmf_ic_msgid_t msgid) 54645039663SJohn Forte { 54745039663SJohn Forte stmf_ic_msg_t *icm = NULL; 54845039663SJohn Forte stmf_ic_dereg_port_msg_t *icdp = NULL; 54945039663SJohn Forte 55045039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_DEREGISTER_PROXY_PORT, msgid); 55145039663SJohn Forte icdp = (stmf_ic_dereg_port_msg_t *)kmem_zalloc(sizeof (*icdp), 55245039663SJohn Forte KM_SLEEP); 55345039663SJohn Forte icm->icm_msg = (void *)icdp; 55445039663SJohn Forte 55545039663SJohn Forte icdp->icdp_port_id = scsi_devid_desc_dup(port_id); 55645039663SJohn Forte 55745039663SJohn Forte if (cb_arg_len) { 55845039663SJohn Forte icdp->icdp_cb_arg_len = cb_arg_len; 55945039663SJohn Forte icdp->icdp_cb_arg = cb_arg; 56045039663SJohn Forte } 56145039663SJohn Forte 56245039663SJohn Forte return (icm); 56345039663SJohn Forte } 56445039663SJohn Forte 56545039663SJohn Forte 56645039663SJohn Forte stmf_ic_msg_t * 56745039663SJohn Forte stmf_ic_reg_lun_msg_alloc( 56845039663SJohn Forte uint8_t *lun_id, 56945039663SJohn Forte char *lu_provider_name, 57045039663SJohn Forte uint16_t cb_arg_len, 57145039663SJohn Forte uint8_t *cb_arg, 57245039663SJohn Forte stmf_ic_msgid_t msgid) 57345039663SJohn Forte { 57445039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_REGISTER_LUN, lun_id, 57545039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 57645039663SJohn Forte } 57745039663SJohn Forte 57845039663SJohn Forte stmf_ic_msg_t * 57945039663SJohn Forte stmf_ic_lun_active_msg_alloc( 58045039663SJohn Forte uint8_t *lun_id, 58145039663SJohn Forte char *lu_provider_name, 58245039663SJohn Forte uint16_t cb_arg_len, 58345039663SJohn Forte uint8_t *cb_arg, 58445039663SJohn Forte stmf_ic_msgid_t msgid) 58545039663SJohn Forte { 58645039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_LUN_ACTIVE, lun_id, 58745039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 58845039663SJohn Forte } 58945039663SJohn Forte 59045039663SJohn Forte stmf_ic_msg_t * 59145039663SJohn Forte stmf_ic_dereg_lun_msg_alloc( 59245039663SJohn Forte uint8_t *lun_id, 59345039663SJohn Forte char *lu_provider_name, 59445039663SJohn Forte uint16_t cb_arg_len, 59545039663SJohn Forte uint8_t *cb_arg, 59645039663SJohn Forte stmf_ic_msgid_t msgid) 59745039663SJohn Forte { 59845039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_DEREGISTER_LUN, lun_id, 59945039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 60045039663SJohn Forte } 60145039663SJohn Forte 60245039663SJohn Forte /* 60345039663SJohn Forte * Guts of lun register/deregister/active alloc routines. 60445039663SJohn Forte */ 60545039663SJohn Forte static stmf_ic_msg_t * 60645039663SJohn Forte stmf_ic_reg_dereg_lun_msg_alloc( 60745039663SJohn Forte stmf_ic_msg_type_t msg_type, 60845039663SJohn Forte uint8_t *lun_id, 60945039663SJohn Forte char *lu_provider_name, 61045039663SJohn Forte uint16_t cb_arg_len, 61145039663SJohn Forte uint8_t *cb_arg, 61245039663SJohn Forte stmf_ic_msgid_t msgid) 61345039663SJohn Forte { 61445039663SJohn Forte stmf_ic_msg_t *icm = NULL; 61545039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *icrl = NULL; 61645039663SJohn Forte 61745039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 61845039663SJohn Forte icrl = (stmf_ic_reg_dereg_lun_msg_t *) 61945039663SJohn Forte kmem_zalloc(sizeof (*icrl), KM_SLEEP); 62045039663SJohn Forte icm->icm_msg = (void *)icrl; 62145039663SJohn Forte 62245039663SJohn Forte icrl->icrl_lu_provider_name = stmf_ic_strdup(lu_provider_name); 62345039663SJohn Forte 62445039663SJohn Forte bcopy(lun_id, icrl->icrl_lun_id, sizeof (icrl->icrl_lun_id)); 62545039663SJohn Forte 62645039663SJohn Forte if (cb_arg_len) { 62745039663SJohn Forte icrl->icrl_cb_arg_len = cb_arg_len; 62845039663SJohn Forte icrl->icrl_cb_arg = cb_arg; 62945039663SJohn Forte } 63045039663SJohn Forte 63145039663SJohn Forte return (icm); 63245039663SJohn Forte } 63345039663SJohn Forte 63445039663SJohn Forte stmf_ic_msg_t * 63545039663SJohn Forte stmf_ic_scsi_cmd_msg_alloc( 63645039663SJohn Forte stmf_ic_msgid_t task_msgid, 63745039663SJohn Forte scsi_task_t *task, 63845039663SJohn Forte uint32_t immed_data_len, 63945039663SJohn Forte uint8_t *immed_data, 64045039663SJohn Forte stmf_ic_msgid_t msgid) 64145039663SJohn Forte { 64245039663SJohn Forte stmf_ic_msg_t *icm = NULL; 64345039663SJohn Forte stmf_ic_scsi_cmd_msg_t *icsc = NULL; 64445039663SJohn Forte scsi_devid_desc_t *ini_devid = task->task_session->ss_rport_id; 64545039663SJohn Forte scsi_devid_desc_t *tgt_devid = task->task_lport->lport_id; 646716c1805SNattuvetty Bhavyan stmf_remote_port_t *rport = task->task_session->ss_rport; 64745039663SJohn Forte 64845039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_CMD, msgid); 64945039663SJohn Forte icsc = (stmf_ic_scsi_cmd_msg_t *)kmem_zalloc(sizeof (*icsc), KM_SLEEP); 65045039663SJohn Forte icm->icm_msg = (void *)icsc; 65145039663SJohn Forte 65245039663SJohn Forte icsc->icsc_task_msgid = task_msgid; 65345039663SJohn Forte icsc->icsc_ini_devid = scsi_devid_desc_dup(ini_devid); 65445039663SJohn Forte icsc->icsc_tgt_devid = scsi_devid_desc_dup(tgt_devid); 655716c1805SNattuvetty Bhavyan icsc->icsc_rport = remote_port_dup(rport); 65645039663SJohn Forte icsc->icsc_session_id = task->task_session->ss_session_id; 65745039663SJohn Forte 658cbdc6dc7SJohn Forte if (!task->task_mgmt_function && task->task_lu->lu_id) { 659cbdc6dc7SJohn Forte bcopy(task->task_lu->lu_id->ident, 660cbdc6dc7SJohn Forte icsc->icsc_lun_id, sizeof (icsc->icsc_lun_id)); 661cbdc6dc7SJohn Forte } 66245039663SJohn Forte 66345039663SJohn Forte bcopy(task->task_lun_no, icsc->icsc_task_lun_no, 66445039663SJohn Forte sizeof (icsc->icsc_task_lun_no)); 66545039663SJohn Forte 66645039663SJohn Forte icsc->icsc_task_expected_xfer_length = task->task_expected_xfer_length; 667*8f641fa7SSue Gleeson if (task->task_cdb_length) { 668*8f641fa7SSue Gleeson ASSERT(task->task_mgmt_function == TM_NONE); 669*8f641fa7SSue Gleeson icsc->icsc_task_cdb_length = task->task_cdb_length; 670*8f641fa7SSue Gleeson icsc->icsc_task_cdb = 671*8f641fa7SSue Gleeson (uint8_t *)kmem_zalloc(task->task_cdb_length, KM_SLEEP); 672*8f641fa7SSue Gleeson bcopy(task->task_cdb, icsc->icsc_task_cdb, 673*8f641fa7SSue Gleeson task->task_cdb_length); 674*8f641fa7SSue Gleeson } 67545039663SJohn Forte 67645039663SJohn Forte icsc->icsc_task_flags = task->task_flags; 67745039663SJohn Forte icsc->icsc_task_priority = task->task_priority; 67845039663SJohn Forte icsc->icsc_task_mgmt_function = task->task_mgmt_function; 67945039663SJohn Forte 68045039663SJohn Forte icsc->icsc_immed_data_len = immed_data_len; 68145039663SJohn Forte icsc->icsc_immed_data = immed_data; 68245039663SJohn Forte 68345039663SJohn Forte return (icm); 68445039663SJohn Forte } 68545039663SJohn Forte 68645039663SJohn Forte stmf_ic_msg_t * 68745039663SJohn Forte stmf_ic_scsi_data_msg_alloc( 68845039663SJohn Forte stmf_ic_msgid_t task_msgid, 68945039663SJohn Forte uint64_t session_id, 69045039663SJohn Forte uint8_t *lun_id, 69145039663SJohn Forte uint64_t data_len, 69245039663SJohn Forte uint8_t *data, 69345039663SJohn Forte stmf_ic_msgid_t msgid) 69445039663SJohn Forte { 69545039663SJohn Forte stmf_ic_msg_t *icm = NULL; 69645039663SJohn Forte stmf_ic_scsi_data_msg_t *icsd = NULL; 69745039663SJohn Forte 69845039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_DATA, msgid); 69945039663SJohn Forte icsd = (stmf_ic_scsi_data_msg_t *)kmem_zalloc(sizeof (*icsd), KM_SLEEP); 70045039663SJohn Forte icm->icm_msg = (void *)icsd; 70145039663SJohn Forte 70245039663SJohn Forte icsd->icsd_task_msgid = task_msgid; 70345039663SJohn Forte icsd->icsd_session_id = session_id; 70445039663SJohn Forte bcopy(lun_id, icsd->icsd_lun_id, sizeof (icsd->icsd_lun_id)); 70545039663SJohn Forte icsd->icsd_data_len = data_len; 70645039663SJohn Forte icsd->icsd_data = data; 70745039663SJohn Forte 70845039663SJohn Forte return (icm); 70945039663SJohn Forte } 71045039663SJohn Forte 71145039663SJohn Forte stmf_ic_msg_t * 71245039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_alloc( 71345039663SJohn Forte stmf_ic_msgid_t task_msgid, 71445039663SJohn Forte uint64_t session_id, 71545039663SJohn Forte stmf_status_t status, 71645039663SJohn Forte stmf_ic_msgid_t msgid) 71745039663SJohn Forte { 71845039663SJohn Forte stmf_ic_msg_t *icm = NULL; 71945039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *icsx = NULL; 72045039663SJohn Forte 72145039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_DATA_XFER_DONE, msgid); 72245039663SJohn Forte icsx = (stmf_ic_scsi_data_xfer_done_msg_t *)kmem_zalloc( 72345039663SJohn Forte sizeof (*icsx), KM_SLEEP); 72445039663SJohn Forte icm->icm_msg = (void *)icsx; 72545039663SJohn Forte 72645039663SJohn Forte icsx->icsx_task_msgid = task_msgid; 72745039663SJohn Forte icsx->icsx_session_id = session_id; 72845039663SJohn Forte icsx->icsx_status = status; 72945039663SJohn Forte 73045039663SJohn Forte return (icm); 73145039663SJohn Forte } 73245039663SJohn Forte 73345039663SJohn Forte stmf_ic_msg_t * 73445039663SJohn Forte stmf_ic_scsi_status_msg_alloc( 73545039663SJohn Forte stmf_ic_msgid_t task_msgid, 73645039663SJohn Forte uint64_t session_id, 73745039663SJohn Forte uint8_t *lun_id, 73845039663SJohn Forte uint8_t response, 73945039663SJohn Forte uint8_t status, 74045039663SJohn Forte uint8_t flags, 74145039663SJohn Forte uint32_t resid, 74245039663SJohn Forte uint8_t sense_len, 74345039663SJohn Forte uint8_t *sense, 74445039663SJohn Forte stmf_ic_msgid_t msgid) 74545039663SJohn Forte { 74645039663SJohn Forte stmf_ic_msg_t *icm = NULL; 74745039663SJohn Forte stmf_ic_scsi_status_msg_t *icss = NULL; 74845039663SJohn Forte 74945039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_STATUS, msgid); 75045039663SJohn Forte icss = (stmf_ic_scsi_status_msg_t *)kmem_zalloc(sizeof (*icss), 75145039663SJohn Forte KM_SLEEP); 75245039663SJohn Forte icm->icm_msg = (void *)icss; 75345039663SJohn Forte 75445039663SJohn Forte icss->icss_task_msgid = task_msgid; 75545039663SJohn Forte icss->icss_session_id = session_id; 75645039663SJohn Forte bcopy(lun_id, icss->icss_lun_id, sizeof (icss->icss_lun_id)); 75745039663SJohn Forte icss->icss_response = response; 75845039663SJohn Forte icss->icss_status = status; 75945039663SJohn Forte icss->icss_flags = flags; 76045039663SJohn Forte icss->icss_resid = resid; 76145039663SJohn Forte icss->icss_sense_len = sense_len; 76245039663SJohn Forte icss->icss_sense = sense; 76345039663SJohn Forte 76445039663SJohn Forte return (icm); 76545039663SJohn Forte } 76645039663SJohn Forte 76745039663SJohn Forte stmf_ic_msg_t * 76845039663SJohn Forte stmf_ic_r2t_msg_alloc( 76945039663SJohn Forte stmf_ic_msgid_t task_msgid, 77045039663SJohn Forte uint64_t session_id, 77145039663SJohn Forte uint32_t offset, 77245039663SJohn Forte uint32_t length, 77345039663SJohn Forte stmf_ic_msgid_t msgid) 77445039663SJohn Forte { 77545039663SJohn Forte stmf_ic_msg_t *icm = NULL; 77645039663SJohn Forte stmf_ic_r2t_msg_t *icrt = NULL; 77745039663SJohn Forte 77845039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_R2T, msgid); 77945039663SJohn Forte icrt = (stmf_ic_r2t_msg_t *)kmem_zalloc(sizeof (*icrt), KM_SLEEP); 78045039663SJohn Forte icm->icm_msg = (void *)icrt; 78145039663SJohn Forte 78245039663SJohn Forte icrt->icrt_task_msgid = task_msgid; 78345039663SJohn Forte icrt->icrt_session_id = session_id; 78445039663SJohn Forte icrt->icrt_offset = offset; 78545039663SJohn Forte icrt->icrt_length = length; 78645039663SJohn Forte 78745039663SJohn Forte return (icm); 78845039663SJohn Forte } 78945039663SJohn Forte 79045039663SJohn Forte stmf_ic_msg_t * 79145039663SJohn Forte stmf_ic_status_msg_alloc( 79245039663SJohn Forte stmf_status_t status, 79345039663SJohn Forte stmf_ic_msg_type_t msg_type, 79445039663SJohn Forte stmf_ic_msgid_t msgid) 79545039663SJohn Forte { 79645039663SJohn Forte stmf_ic_msg_t *icm = NULL; 79745039663SJohn Forte stmf_ic_status_msg_t *ics = NULL; 79845039663SJohn Forte 79945039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_STATUS, msgid); 80045039663SJohn Forte ics = (stmf_ic_status_msg_t *)kmem_zalloc(sizeof (*ics), KM_SLEEP); 80145039663SJohn Forte icm->icm_msg = (void *)ics; 80245039663SJohn Forte 80345039663SJohn Forte ics->ics_status = status; 80445039663SJohn Forte ics->ics_msg_type = msg_type; 80545039663SJohn Forte ics->ics_msgid = msgid; /* XXX same as msgid in header */ 80645039663SJohn Forte 80745039663SJohn Forte return (icm); 80845039663SJohn Forte } 80945039663SJohn Forte 81045039663SJohn Forte stmf_ic_msg_t * 81145039663SJohn Forte stmf_ic_session_create_msg_alloc( 81245039663SJohn Forte stmf_scsi_session_t *session, 81345039663SJohn Forte stmf_ic_msgid_t msgid) 81445039663SJohn Forte { 81545039663SJohn Forte return (stmf_ic_session_create_destroy_msg_alloc( 81645039663SJohn Forte STMF_ICM_SESSION_CREATE, session, msgid)); 81745039663SJohn Forte } 81845039663SJohn Forte 81945039663SJohn Forte stmf_ic_msg_t * 82045039663SJohn Forte stmf_ic_session_destroy_msg_alloc( 82145039663SJohn Forte stmf_scsi_session_t *session, 82245039663SJohn Forte stmf_ic_msgid_t msgid) 82345039663SJohn Forte { 82445039663SJohn Forte return (stmf_ic_session_create_destroy_msg_alloc( 82545039663SJohn Forte STMF_ICM_SESSION_DESTROY, session, msgid)); 82645039663SJohn Forte } 82745039663SJohn Forte 82845039663SJohn Forte /* 82945039663SJohn Forte * Guts of session create/destroy routines. 83045039663SJohn Forte */ 83145039663SJohn Forte static stmf_ic_msg_t * 83245039663SJohn Forte stmf_ic_session_create_destroy_msg_alloc( 83345039663SJohn Forte stmf_ic_msg_type_t msg_type, 83445039663SJohn Forte stmf_scsi_session_t *session, 83545039663SJohn Forte stmf_ic_msgid_t msgid) 83645039663SJohn Forte { 83745039663SJohn Forte stmf_ic_msg_t *icm = NULL; 83845039663SJohn Forte stmf_ic_session_create_destroy_msg_t *icscd = NULL; 83945039663SJohn Forte scsi_devid_desc_t *ini_devid = session->ss_rport_id; 84045039663SJohn Forte scsi_devid_desc_t *tgt_devid = session->ss_lport->lport_id; 84145039663SJohn Forte 84245039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 84345039663SJohn Forte icscd = (stmf_ic_session_create_destroy_msg_t *) 84445039663SJohn Forte kmem_zalloc(sizeof (*icscd), KM_SLEEP); 84545039663SJohn Forte icm->icm_msg = (void *)icscd; 84645039663SJohn Forte 84745039663SJohn Forte icscd->icscd_session_id = session->ss_session_id; 84845039663SJohn Forte icscd->icscd_ini_devid = scsi_devid_desc_dup(ini_devid); 84945039663SJohn Forte icscd->icscd_tgt_devid = scsi_devid_desc_dup(tgt_devid); 850716c1805SNattuvetty Bhavyan icscd->icscd_rport = remote_port_dup(session->ss_rport); 85145039663SJohn Forte 85245039663SJohn Forte return (icm); 85345039663SJohn Forte } 85445039663SJohn Forte 85545039663SJohn Forte stmf_ic_msg_t * 85645039663SJohn Forte stmf_ic_echo_request_msg_alloc( 85745039663SJohn Forte uint32_t data_len, 85845039663SJohn Forte uint8_t *data, 85945039663SJohn Forte stmf_ic_msgid_t msgid) 86045039663SJohn Forte { 86145039663SJohn Forte return (stmf_ic_echo_request_reply_msg_alloc( 86245039663SJohn Forte STMF_ICM_ECHO_REQUEST, data_len, data, msgid)); 86345039663SJohn Forte } 86445039663SJohn Forte 86545039663SJohn Forte stmf_ic_msg_t * 86645039663SJohn Forte stmf_ic_echo_reply_msg_alloc( 86745039663SJohn Forte uint32_t data_len, 86845039663SJohn Forte uint8_t *data, 86945039663SJohn Forte stmf_ic_msgid_t msgid) 87045039663SJohn Forte { 87145039663SJohn Forte return (stmf_ic_echo_request_reply_msg_alloc( 87245039663SJohn Forte STMF_ICM_ECHO_REPLY, data_len, data, msgid)); 87345039663SJohn Forte } 87445039663SJohn Forte 87545039663SJohn Forte 87645039663SJohn Forte static stmf_ic_msg_t * 87745039663SJohn Forte stmf_ic_echo_request_reply_msg_alloc( 87845039663SJohn Forte stmf_ic_msg_type_t msg_type, 87945039663SJohn Forte uint32_t data_len, 88045039663SJohn Forte uint8_t *data, 88145039663SJohn Forte stmf_ic_msgid_t msgid) 88245039663SJohn Forte { 88345039663SJohn Forte stmf_ic_msg_t *icm = NULL; 88445039663SJohn Forte stmf_ic_echo_request_reply_msg_t *icerr = NULL; 88545039663SJohn Forte 88645039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 88745039663SJohn Forte icerr = kmem_zalloc(sizeof (*icerr), KM_SLEEP); 88845039663SJohn Forte icm->icm_msg = (void *)icerr; 88945039663SJohn Forte 89045039663SJohn Forte icerr->icerr_data = data; 89145039663SJohn Forte icerr->icerr_datalen = data_len; 89245039663SJohn Forte 89345039663SJohn Forte return (icm); 89445039663SJohn Forte } 89545039663SJohn Forte 89645039663SJohn Forte /* 89745039663SJohn Forte * msg free routines. 89845039663SJohn Forte */ 89945039663SJohn Forte void 90045039663SJohn Forte stmf_ic_msg_free(stmf_ic_msg_t *msg) 90145039663SJohn Forte { 90245039663SJohn Forte stmf_ic_msg_construction_method_t cmethod = 90345039663SJohn Forte (msg->icm_nvlist ? STMF_UNMARSHAL : STMF_CONSTRUCTOR); 90445039663SJohn Forte 90545039663SJohn Forte switch (msg->icm_msg_type) { 90645039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 90745039663SJohn Forte stmf_ic_reg_port_msg_free( 90845039663SJohn Forte (stmf_ic_reg_port_msg_t *)msg->icm_msg, cmethod); 90945039663SJohn Forte break; 91045039663SJohn Forte 91145039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 91245039663SJohn Forte stmf_ic_dereg_port_msg_free( 91345039663SJohn Forte (stmf_ic_dereg_port_msg_t *)msg->icm_msg, cmethod); 91445039663SJohn Forte break; 91545039663SJohn Forte 91645039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 91745039663SJohn Forte case STMF_ICM_REGISTER_LUN: 91845039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 91945039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free( 92045039663SJohn Forte (stmf_ic_reg_dereg_lun_msg_t *)msg->icm_msg, cmethod); 92145039663SJohn Forte break; 92245039663SJohn Forte 92345039663SJohn Forte case STMF_ICM_SCSI_CMD: 92445039663SJohn Forte stmf_ic_scsi_cmd_msg_free( 92545039663SJohn Forte (stmf_ic_scsi_cmd_msg_t *)msg->icm_msg, cmethod); 92645039663SJohn Forte break; 92745039663SJohn Forte 92845039663SJohn Forte case STMF_ICM_SCSI_DATA: 92945039663SJohn Forte stmf_ic_scsi_data_msg_free( 93045039663SJohn Forte (stmf_ic_scsi_data_msg_t *)msg->icm_msg, cmethod); 93145039663SJohn Forte break; 93245039663SJohn Forte 93345039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 93445039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free( 93545039663SJohn Forte (stmf_ic_scsi_data_xfer_done_msg_t *)msg->icm_msg, cmethod); 93645039663SJohn Forte break; 93745039663SJohn Forte 93845039663SJohn Forte case STMF_ICM_SCSI_STATUS: 93945039663SJohn Forte stmf_ic_scsi_status_msg_free( 94045039663SJohn Forte (stmf_ic_scsi_status_msg_t *)msg->icm_msg, cmethod); 94145039663SJohn Forte break; 94245039663SJohn Forte 94345039663SJohn Forte case STMF_ICM_R2T: 94445039663SJohn Forte stmf_ic_r2t_msg_free( 94545039663SJohn Forte (stmf_ic_r2t_msg_t *)msg->icm_msg, cmethod); 94645039663SJohn Forte break; 94745039663SJohn Forte 94845039663SJohn Forte case STMF_ICM_STATUS: 94945039663SJohn Forte stmf_ic_status_msg_free( 95045039663SJohn Forte (stmf_ic_status_msg_t *)msg->icm_msg, cmethod); 95145039663SJohn Forte break; 95245039663SJohn Forte 95345039663SJohn Forte case STMF_ICM_SESSION_CREATE: 95445039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 95545039663SJohn Forte stmf_ic_session_create_destroy_msg_free( 95645039663SJohn Forte (stmf_ic_session_create_destroy_msg_t *)msg->icm_msg, 95745039663SJohn Forte cmethod); 95845039663SJohn Forte break; 95945039663SJohn Forte 96045039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 96145039663SJohn Forte case STMF_ICM_ECHO_REPLY: 96245039663SJohn Forte stmf_ic_echo_request_reply_msg_free( 96345039663SJohn Forte (stmf_ic_echo_request_reply_msg_t *)msg->icm_msg, cmethod); 96445039663SJohn Forte break; 96545039663SJohn Forte 96645039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 96745039663SJohn Forte ASSERT(0); 96845039663SJohn Forte break; 96945039663SJohn Forte 97045039663SJohn Forte default: 97145039663SJohn Forte ASSERT(0); 97245039663SJohn Forte } 97345039663SJohn Forte 97445039663SJohn Forte if (msg->icm_nvlist) 97545039663SJohn Forte nvlist_free(msg->icm_nvlist); 97645039663SJohn Forte 97745039663SJohn Forte kmem_free(msg, sizeof (*msg)); 97845039663SJohn Forte } 97945039663SJohn Forte 98045039663SJohn Forte /*ARGSUSED*/ 98145039663SJohn Forte static void 98245039663SJohn Forte stmf_ic_reg_port_msg_free(stmf_ic_reg_port_msg_t *m, 98345039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 98445039663SJohn Forte { 98545039663SJohn Forte scsi_devid_desc_free(m->icrp_port_id); 98645039663SJohn Forte 98745039663SJohn Forte kmem_free(m, sizeof (*m)); 98845039663SJohn Forte } 98945039663SJohn Forte 99045039663SJohn Forte 99145039663SJohn Forte /*ARGSUSED*/ 99245039663SJohn Forte static void 99345039663SJohn Forte stmf_ic_dereg_port_msg_free(stmf_ic_dereg_port_msg_t *m, 99445039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 99545039663SJohn Forte { 99645039663SJohn Forte scsi_devid_desc_free(m->icdp_port_id); 99745039663SJohn Forte 99845039663SJohn Forte kmem_free(m, sizeof (*m)); 99945039663SJohn Forte } 100045039663SJohn Forte 100145039663SJohn Forte 100245039663SJohn Forte /* 100345039663SJohn Forte * Works for both reg_lun_msg and dereg_lun_msg, since the message 100445039663SJohn Forte * payload is the same. 100545039663SJohn Forte */ 100645039663SJohn Forte static void 100745039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free(stmf_ic_reg_dereg_lun_msg_t *m, 100845039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 100945039663SJohn Forte { 101045039663SJohn Forte if (cmethod == STMF_CONSTRUCTOR) { 101145039663SJohn Forte kmem_free(m->icrl_lu_provider_name, 101245039663SJohn Forte strlen(m->icrl_lu_provider_name) + 1); 101345039663SJohn Forte } 101445039663SJohn Forte 101545039663SJohn Forte kmem_free(m, sizeof (*m)); 101645039663SJohn Forte } 101745039663SJohn Forte 101845039663SJohn Forte static void 101945039663SJohn Forte stmf_ic_scsi_cmd_msg_free(stmf_ic_scsi_cmd_msg_t *m, 102045039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 102145039663SJohn Forte { 102245039663SJohn Forte scsi_devid_desc_free(m->icsc_ini_devid); 102345039663SJohn Forte scsi_devid_desc_free(m->icsc_tgt_devid); 1024716c1805SNattuvetty Bhavyan stmf_remote_port_free(m->icsc_rport); 1025*8f641fa7SSue Gleeson if ((cmethod == STMF_CONSTRUCTOR) && m->icsc_task_cdb) { 102645039663SJohn Forte kmem_free(m->icsc_task_cdb, m->icsc_task_cdb_length); 102745039663SJohn Forte } 102845039663SJohn Forte 102945039663SJohn Forte kmem_free(m, sizeof (*m)); 103045039663SJohn Forte 103145039663SJohn Forte } 103245039663SJohn Forte 103345039663SJohn Forte /*ARGSUSED*/ 103445039663SJohn Forte static void 103545039663SJohn Forte stmf_ic_scsi_data_msg_free(stmf_ic_scsi_data_msg_t *m, 103645039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 103745039663SJohn Forte { 103845039663SJohn Forte kmem_free(m, sizeof (*m)); 103945039663SJohn Forte } 104045039663SJohn Forte 104145039663SJohn Forte /*ARGSUSED*/ 104245039663SJohn Forte static void 104345039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free(stmf_ic_scsi_data_xfer_done_msg_t *m, 104445039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 104545039663SJohn Forte { 104645039663SJohn Forte kmem_free(m, sizeof (*m)); 104745039663SJohn Forte } 104845039663SJohn Forte 104945039663SJohn Forte /*ARGSUSED*/ 105045039663SJohn Forte static void 105145039663SJohn Forte stmf_ic_scsi_status_msg_free(stmf_ic_scsi_status_msg_t *m, 105245039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 105345039663SJohn Forte { 105445039663SJohn Forte kmem_free(m, sizeof (*m)); 105545039663SJohn Forte } 105645039663SJohn Forte 105745039663SJohn Forte /*ARGSUSED*/ 105845039663SJohn Forte static void 105945039663SJohn Forte stmf_ic_r2t_msg_free(stmf_ic_r2t_msg_t *m, 106045039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 106145039663SJohn Forte { 106245039663SJohn Forte kmem_free(m, sizeof (*m)); 106345039663SJohn Forte } 106445039663SJohn Forte 106545039663SJohn Forte /*ARGSUSED*/ 106645039663SJohn Forte static void 106745039663SJohn Forte stmf_ic_status_msg_free(stmf_ic_status_msg_t *m, 106845039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 106945039663SJohn Forte { 107045039663SJohn Forte kmem_free(m, sizeof (*m)); 107145039663SJohn Forte } 107245039663SJohn Forte 107345039663SJohn Forte /* 107445039663SJohn Forte * Works for both session_create and session_destroy msgs, since the message 107545039663SJohn Forte * payload is the same. 107645039663SJohn Forte */ 107745039663SJohn Forte /*ARGSUSED*/ 107845039663SJohn Forte static void 107945039663SJohn Forte stmf_ic_session_create_destroy_msg_free(stmf_ic_session_create_destroy_msg_t *m, 108045039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 108145039663SJohn Forte { 108245039663SJohn Forte scsi_devid_desc_free(m->icscd_ini_devid); 108345039663SJohn Forte scsi_devid_desc_free(m->icscd_tgt_devid); 1084716c1805SNattuvetty Bhavyan stmf_remote_port_free(m->icscd_rport); 108545039663SJohn Forte 108645039663SJohn Forte kmem_free(m, sizeof (*m)); 108745039663SJohn Forte } 108845039663SJohn Forte 108945039663SJohn Forte /*ARGSUSED*/ 109045039663SJohn Forte static void 109145039663SJohn Forte stmf_ic_echo_request_reply_msg_free(stmf_ic_echo_request_reply_msg_t *m, 109245039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 109345039663SJohn Forte { 109445039663SJohn Forte kmem_free(m, sizeof (*m)); 109545039663SJohn Forte } 109645039663SJohn Forte 109745039663SJohn Forte 109845039663SJohn Forte /* 109945039663SJohn Forte * Marshaling routines. 110045039663SJohn Forte */ 110145039663SJohn Forte 110245039663SJohn Forte static nvlist_t * 110345039663SJohn Forte stmf_ic_msg_marshal(stmf_ic_msg_t *msg) 110445039663SJohn Forte { 110545039663SJohn Forte nvlist_t *nvl = NULL; 110645039663SJohn Forte int rc = 0; 110745039663SJohn Forte 110845039663SJohn Forte rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); 110945039663SJohn Forte if (rc) 111045039663SJohn Forte goto done; 111145039663SJohn Forte 111245039663SJohn Forte NVLIST_ADD_FIELD(uint8, msg, icm_msg_type); 111345039663SJohn Forte NVLIST_ADD_FIELD(uint64, msg, icm_msgid); 111445039663SJohn Forte 111545039663SJohn Forte switch (msg->icm_msg_type) { 111645039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 111745039663SJohn Forte rc = stmf_ic_reg_port_msg_marshal(nvl, msg->icm_msg); 111845039663SJohn Forte break; 111945039663SJohn Forte 112045039663SJohn Forte 112145039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 112245039663SJohn Forte rc = stmf_ic_dereg_port_msg_marshal(nvl, msg->icm_msg); 112345039663SJohn Forte break; 112445039663SJohn Forte 112545039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 112645039663SJohn Forte case STMF_ICM_REGISTER_LUN: 112745039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 112845039663SJohn Forte rc = stmf_ic_reg_dereg_lun_msg_marshal(nvl, msg->icm_msg); 112945039663SJohn Forte break; 113045039663SJohn Forte 113145039663SJohn Forte case STMF_ICM_SCSI_CMD: 113245039663SJohn Forte rc = stmf_ic_scsi_cmd_msg_marshal(nvl, msg->icm_msg); 113345039663SJohn Forte break; 113445039663SJohn Forte 113545039663SJohn Forte case STMF_ICM_SCSI_DATA: 113645039663SJohn Forte rc = stmf_ic_scsi_data_msg_marshal(nvl, msg->icm_msg); 113745039663SJohn Forte break; 113845039663SJohn Forte 113945039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 114045039663SJohn Forte rc = stmf_ic_scsi_data_xfer_done_msg_marshal(nvl, msg->icm_msg); 114145039663SJohn Forte break; 114245039663SJohn Forte 114345039663SJohn Forte case STMF_ICM_SCSI_STATUS: 114445039663SJohn Forte rc = stmf_ic_scsi_status_msg_marshal(nvl, msg->icm_msg); 114545039663SJohn Forte break; 114645039663SJohn Forte 114745039663SJohn Forte case STMF_ICM_R2T: 114845039663SJohn Forte rc = stmf_ic_r2t_msg_marshal(nvl, msg->icm_msg); 114945039663SJohn Forte break; 115045039663SJohn Forte 115145039663SJohn Forte case STMF_ICM_STATUS: 115245039663SJohn Forte rc = stmf_ic_status_msg_marshal(nvl, msg->icm_msg); 115345039663SJohn Forte break; 115445039663SJohn Forte 115545039663SJohn Forte case STMF_ICM_SESSION_CREATE: 115645039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 115745039663SJohn Forte rc = stmf_ic_session_create_destroy_msg_marshal(nvl, 115845039663SJohn Forte msg->icm_msg); 115945039663SJohn Forte break; 116045039663SJohn Forte 116145039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 116245039663SJohn Forte case STMF_ICM_ECHO_REPLY: 116345039663SJohn Forte rc = stmf_ic_echo_request_reply_msg_marshal(nvl, 116445039663SJohn Forte msg->icm_msg); 116545039663SJohn Forte break; 116645039663SJohn Forte 116745039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 116845039663SJohn Forte ASSERT(0); 116945039663SJohn Forte break; 117045039663SJohn Forte 117145039663SJohn Forte default: 117245039663SJohn Forte ASSERT(0); 117345039663SJohn Forte } 117445039663SJohn Forte 117545039663SJohn Forte done: 117645039663SJohn Forte if (!rc) 117745039663SJohn Forte return (nvl); 117845039663SJohn Forte 117945039663SJohn Forte if (nvl) 118045039663SJohn Forte nvlist_free(nvl); 118145039663SJohn Forte 118245039663SJohn Forte return (NULL); 118345039663SJohn Forte } 118445039663SJohn Forte 118545039663SJohn Forte 118645039663SJohn Forte static int 118745039663SJohn Forte stmf_ic_reg_port_msg_marshal(nvlist_t *nvl, void *msg) 118845039663SJohn Forte { 118945039663SJohn Forte stmf_ic_reg_port_msg_t *m = (stmf_ic_reg_port_msg_t *)msg; 119045039663SJohn Forte int rc = 0; 119145039663SJohn Forte 119245039663SJohn Forte NVLIST_ADD_DEVID(m, icrp_port_id); 119345039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrp_relative_port_id); 119445039663SJohn Forte 119545039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrp_cb_arg_len); 119645039663SJohn Forte /* only add the callback arg if necessary */ 119745039663SJohn Forte if (m->icrp_cb_arg_len) { 119845039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icrp_cb_arg, m->icrp_cb_arg_len); 119945039663SJohn Forte } 120045039663SJohn Forte 120145039663SJohn Forte done: 120245039663SJohn Forte return (rc); 120345039663SJohn Forte } 120445039663SJohn Forte 120545039663SJohn Forte static int 120645039663SJohn Forte stmf_ic_dereg_port_msg_marshal(nvlist_t *nvl, void *msg) 120745039663SJohn Forte { 120845039663SJohn Forte stmf_ic_dereg_port_msg_t *m = (stmf_ic_dereg_port_msg_t *)msg; 120945039663SJohn Forte int rc = 0; 121045039663SJohn Forte 121145039663SJohn Forte NVLIST_ADD_DEVID(m, icdp_port_id); 121245039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icdp_cb_arg_len); 121345039663SJohn Forte 121445039663SJohn Forte /* only add the callback arg if necessary */ 121545039663SJohn Forte if (m->icdp_cb_arg_len) { 121645039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icdp_cb_arg, m->icdp_cb_arg_len); 121745039663SJohn Forte } 121845039663SJohn Forte 121945039663SJohn Forte done: 122045039663SJohn Forte return (rc); 122145039663SJohn Forte } 122245039663SJohn Forte 122345039663SJohn Forte /* 122445039663SJohn Forte * Handles STMF_ICM_LUN_ACTIVE, STMF_ICM_REGISTER_LUN and 122545039663SJohn Forte * STMF_ICM_DEREGISTER_LUN; 122645039663SJohn Forte * msg payload is the same for all. 122745039663SJohn Forte */ 122845039663SJohn Forte static int 122945039663SJohn Forte stmf_ic_reg_dereg_lun_msg_marshal(nvlist_t *nvl, void *msg) 123045039663SJohn Forte { 123145039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *m = (stmf_ic_reg_dereg_lun_msg_t *)msg; 123245039663SJohn Forte int rc = 0; 123345039663SJohn Forte 123445039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icrl_lun_id); 123545039663SJohn Forte NVLIST_ADD_FIELD(string, m, icrl_lu_provider_name); 123645039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrl_cb_arg_len); 123745039663SJohn Forte 123845039663SJohn Forte /* only add the callback arg if necessary */ 123945039663SJohn Forte if (m->icrl_cb_arg_len) { 124045039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icrl_cb_arg, m->icrl_cb_arg_len); 124145039663SJohn Forte } 124245039663SJohn Forte 124345039663SJohn Forte done: 124445039663SJohn Forte return (rc); 124545039663SJohn Forte } 124645039663SJohn Forte 124745039663SJohn Forte static int 124845039663SJohn Forte stmf_ic_scsi_cmd_msg_marshal(nvlist_t *nvl, void *msg) 124945039663SJohn Forte { 125045039663SJohn Forte stmf_ic_scsi_cmd_msg_t *m = (stmf_ic_scsi_cmd_msg_t *)msg; 125145039663SJohn Forte int rc = 0; 125245039663SJohn Forte 125345039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsc_task_msgid); 125445039663SJohn Forte NVLIST_ADD_DEVID(m, icsc_ini_devid); 125545039663SJohn Forte NVLIST_ADD_DEVID(m, icsc_tgt_devid); 1256716c1805SNattuvetty Bhavyan NVLIST_ADD_RPORT(m, icsc_rport); 125745039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icsc_lun_id); 125845039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsc_session_id); 125945039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_task_lun_no, 8); 126045039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icsc_task_expected_xfer_length); 126145039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icsc_task_cdb_length); 1262*8f641fa7SSue Gleeson /* 1263*8f641fa7SSue Gleeson * icsc_task_cdb_length may be zero in the case of a task 1264*8f641fa7SSue Gleeson * management function. 1265*8f641fa7SSue Gleeson */ 126645039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_task_cdb, m->icsc_task_cdb_length); 126745039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_flags); 126845039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_priority); 126945039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_mgmt_function); 127045039663SJohn Forte 127145039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icsc_immed_data_len); 127245039663SJohn Forte /* only add immediate data if necessary */ 127345039663SJohn Forte if (m->icsc_immed_data_len) { 127445039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_immed_data, 127545039663SJohn Forte m->icsc_immed_data_len); 127645039663SJohn Forte } 127745039663SJohn Forte 127845039663SJohn Forte done: 127945039663SJohn Forte return (rc); 128045039663SJohn Forte } 128145039663SJohn Forte 128245039663SJohn Forte static int 128345039663SJohn Forte stmf_ic_scsi_data_msg_marshal(nvlist_t *nvl, void *msg) 128445039663SJohn Forte { 128545039663SJohn Forte stmf_ic_scsi_data_msg_t *m = (stmf_ic_scsi_data_msg_t *)msg; 128645039663SJohn Forte int rc = 0; 128745039663SJohn Forte 128845039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_task_msgid); 128945039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_session_id); 129045039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icsd_lun_id); 129145039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_data_len); 129245039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsd_data, m->icsd_data_len); 129345039663SJohn Forte 129445039663SJohn Forte done: 129545039663SJohn Forte return (rc); 129645039663SJohn Forte } 129745039663SJohn Forte 129845039663SJohn Forte static int 129945039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_marshal(nvlist_t *nvl, void *msg) 130045039663SJohn Forte { 130145039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *m = 130245039663SJohn Forte (stmf_ic_scsi_data_xfer_done_msg_t *)msg; 130345039663SJohn Forte int rc = 0; 130445039663SJohn Forte 130545039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_task_msgid); 130645039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_session_id); 130745039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_status); 130845039663SJohn Forte 130945039663SJohn Forte done: 131045039663SJohn Forte return (rc); 131145039663SJohn Forte } 131245039663SJohn Forte 131345039663SJohn Forte static int 131445039663SJohn Forte stmf_ic_scsi_status_msg_marshal(nvlist_t *nvl, void *msg) 131545039663SJohn Forte { 131645039663SJohn Forte stmf_ic_scsi_status_msg_t *m = (stmf_ic_scsi_status_msg_t *)msg; 131745039663SJohn Forte int rc = 0; 131845039663SJohn Forte 131945039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icss_task_msgid); 132045039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icss_session_id); 132145039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icss_lun_id); 132245039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_response); 132345039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_status); 132445039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_flags); 132545039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icss_resid); 132645039663SJohn Forte 132745039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_sense_len); 132845039663SJohn Forte 132945039663SJohn Forte if (m->icss_sense_len) 133045039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icss_sense, m->icss_sense_len); 133145039663SJohn Forte 133245039663SJohn Forte done: 133345039663SJohn Forte return (rc); 133445039663SJohn Forte } 133545039663SJohn Forte 133645039663SJohn Forte static int 133745039663SJohn Forte stmf_ic_r2t_msg_marshal(nvlist_t *nvl, void *msg) 133845039663SJohn Forte { 133945039663SJohn Forte stmf_ic_r2t_msg_t *m = (stmf_ic_r2t_msg_t *)msg; 134045039663SJohn Forte int rc = 0; 134145039663SJohn Forte 134245039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icrt_task_msgid); 134345039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icrt_session_id); 134445039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icrt_offset); 134545039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icrt_length); 134645039663SJohn Forte 134745039663SJohn Forte done: 134845039663SJohn Forte return (rc); 134945039663SJohn Forte } 135045039663SJohn Forte 135145039663SJohn Forte static int 135245039663SJohn Forte stmf_ic_status_msg_marshal(nvlist_t *nvl, void *msg) 135345039663SJohn Forte { 135445039663SJohn Forte stmf_ic_status_msg_t *m = (stmf_ic_status_msg_t *)msg; 135545039663SJohn Forte int rc = 0; 135645039663SJohn Forte 135745039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, ics_msg_type); 135845039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, ics_msgid); 135945039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, ics_status); 136045039663SJohn Forte 136145039663SJohn Forte done: 136245039663SJohn Forte return (rc); 136345039663SJohn Forte } 136445039663SJohn Forte 136545039663SJohn Forte static int 136645039663SJohn Forte stmf_ic_session_create_destroy_msg_marshal(nvlist_t *nvl, void *msg) 136745039663SJohn Forte { 136845039663SJohn Forte stmf_ic_session_create_destroy_msg_t *m = 136945039663SJohn Forte (stmf_ic_session_create_destroy_msg_t *)msg; 137045039663SJohn Forte int rc = 0; 137145039663SJohn Forte 137245039663SJohn Forte NVLIST_ADD_DEVID(m, icscd_ini_devid); 137345039663SJohn Forte NVLIST_ADD_DEVID(m, icscd_tgt_devid); 1374716c1805SNattuvetty Bhavyan NVLIST_ADD_RPORT(m, icscd_rport); 137545039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icscd_session_id); 137645039663SJohn Forte 137745039663SJohn Forte done: 137845039663SJohn Forte return (rc); 137945039663SJohn Forte } 138045039663SJohn Forte 138145039663SJohn Forte static int 138245039663SJohn Forte stmf_ic_echo_request_reply_msg_marshal(nvlist_t *nvl, void *msg) 138345039663SJohn Forte { 138445039663SJohn Forte stmf_ic_echo_request_reply_msg_t *m = msg; 138545039663SJohn Forte int rc = 0; 138645039663SJohn Forte 138745039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icerr_datalen); 138845039663SJohn Forte if (m->icerr_datalen) 138945039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icerr_data, m->icerr_datalen); 139045039663SJohn Forte 139145039663SJohn Forte done: 139245039663SJohn Forte return (rc); 139345039663SJohn Forte } 139445039663SJohn Forte 139545039663SJohn Forte /* 139645039663SJohn Forte * Allocate a new nvlist representing the scsi_devid_desc and add it 139745039663SJohn Forte * to the nvlist. 139845039663SJohn Forte */ 139945039663SJohn Forte static int 140045039663SJohn Forte stmf_ic_scsi_devid_desc_marshal(nvlist_t *parent_nvl, 140145039663SJohn Forte char *sdid_name, 140245039663SJohn Forte scsi_devid_desc_t *sdid) 140345039663SJohn Forte { 140445039663SJohn Forte int rc = 0; 140545039663SJohn Forte nvlist_t *nvl = NULL; 140645039663SJohn Forte 140745039663SJohn Forte rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); 140845039663SJohn Forte if (rc) 140945039663SJohn Forte goto done; 141045039663SJohn Forte 141145039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, protocol_id); 141245039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, code_set); 141345039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, piv); 141445039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, association); 141545039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, ident_type); 141645039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, ident_length); 141745039663SJohn Forte 141845039663SJohn Forte rc = nvlist_add_uint8_array(nvl, "ident", sdid->ident, 141945039663SJohn Forte sdid->ident_length); 142045039663SJohn Forte if (rc) 142145039663SJohn Forte goto done; 142245039663SJohn Forte 142345039663SJohn Forte rc = nvlist_add_nvlist(parent_nvl, sdid_name, nvl); 1424716c1805SNattuvetty Bhavyan done: 1425716c1805SNattuvetty Bhavyan if (nvl) { 1426716c1805SNattuvetty Bhavyan nvlist_free(nvl); 1427716c1805SNattuvetty Bhavyan } 1428716c1805SNattuvetty Bhavyan return (rc); 1429716c1805SNattuvetty Bhavyan } 1430716c1805SNattuvetty Bhavyan 1431716c1805SNattuvetty Bhavyan /* 1432716c1805SNattuvetty Bhavyan * Allocate a new nvlist representing the stmf_remote_port and add it 1433716c1805SNattuvetty Bhavyan * to the nvlist. 1434716c1805SNattuvetty Bhavyan */ 1435716c1805SNattuvetty Bhavyan static int 1436716c1805SNattuvetty Bhavyan stmf_ic_remote_port_marshal(nvlist_t *parent_nvl, char *rport_name, 1437716c1805SNattuvetty Bhavyan stmf_remote_port_t *rport) { 1438716c1805SNattuvetty Bhavyan 1439716c1805SNattuvetty Bhavyan int rc = 0; 1440716c1805SNattuvetty Bhavyan nvlist_t *nvl = NULL; 1441716c1805SNattuvetty Bhavyan 1442716c1805SNattuvetty Bhavyan rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); 1443716c1805SNattuvetty Bhavyan if (rc) 1444716c1805SNattuvetty Bhavyan goto done; 144545039663SJohn Forte 1446716c1805SNattuvetty Bhavyan NVLIST_ADD_FIELD(uint16, rport, rport_tptid_sz); 1447716c1805SNattuvetty Bhavyan rc = nvlist_add_uint8_array(nvl, "rport_tptid", 1448716c1805SNattuvetty Bhavyan (uint8_t *)rport->rport_tptid, rport->rport_tptid_sz); 1449716c1805SNattuvetty Bhavyan if (rc) 1450716c1805SNattuvetty Bhavyan goto done; 1451716c1805SNattuvetty Bhavyan 1452716c1805SNattuvetty Bhavyan rc = nvlist_add_nvlist(parent_nvl, rport_name, nvl); 145345039663SJohn Forte done: 145445039663SJohn Forte if (nvl) { 145545039663SJohn Forte nvlist_free(nvl); 145645039663SJohn Forte } 145745039663SJohn Forte return (rc); 145845039663SJohn Forte } 145945039663SJohn Forte 146045039663SJohn Forte /* 146145039663SJohn Forte * Unmarshaling routines. 146245039663SJohn Forte */ 146345039663SJohn Forte 146445039663SJohn Forte static stmf_ic_msg_t * 146545039663SJohn Forte stmf_ic_msg_unmarshal(nvlist_t *nvl) 146645039663SJohn Forte { 146745039663SJohn Forte stmf_ic_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 146845039663SJohn Forte uint8_t msg_type; 146945039663SJohn Forte int rc = 0; 147045039663SJohn Forte 147145039663SJohn Forte /* 147245039663SJohn Forte * We'd like to do this: 147345039663SJohn Forte * 147445039663SJohn Forte * NVLIST_LOOKUP_FIELD(uint8, m, icm_msg_type); 147545039663SJohn Forte * 147645039663SJohn Forte * but the fact that msg type is an enum causes type problems. 147745039663SJohn Forte */ 147845039663SJohn Forte rc = nvlist_lookup_uint8(nvl, "icm_msg_type", &msg_type); 147945039663SJohn Forte if (rc) { 148045039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icm_msg_type"); 148145039663SJohn Forte goto done; 148245039663SJohn Forte } 148345039663SJohn Forte 148445039663SJohn Forte m->icm_msg_type = msg_type; 148545039663SJohn Forte m->icm_nvlist = nvl; 148645039663SJohn Forte 148745039663SJohn Forte NVLIST_LOOKUP_FIELD(uint64, m, icm_msgid); 148845039663SJohn Forte 148945039663SJohn Forte switch (m->icm_msg_type) { 149045039663SJohn Forte 149145039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 149245039663SJohn Forte m->icm_msg = stmf_ic_reg_port_msg_unmarshal(nvl); 149345039663SJohn Forte break; 149445039663SJohn Forte 149545039663SJohn Forte 149645039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 149745039663SJohn Forte m->icm_msg = stmf_ic_dereg_port_msg_unmarshal(nvl); 149845039663SJohn Forte break; 149945039663SJohn Forte 150045039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 150145039663SJohn Forte case STMF_ICM_REGISTER_LUN: 150245039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 150345039663SJohn Forte m->icm_msg = stmf_ic_reg_dereg_lun_msg_unmarshal(nvl); 150445039663SJohn Forte break; 150545039663SJohn Forte 150645039663SJohn Forte case STMF_ICM_SCSI_CMD: 150745039663SJohn Forte m->icm_msg = stmf_ic_scsi_cmd_msg_unmarshal(nvl); 150845039663SJohn Forte break; 150945039663SJohn Forte 151045039663SJohn Forte case STMF_ICM_SCSI_DATA: 151145039663SJohn Forte m->icm_msg = stmf_ic_scsi_data_msg_unmarshal(nvl); 151245039663SJohn Forte break; 151345039663SJohn Forte 151445039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 151545039663SJohn Forte m->icm_msg = stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvl); 151645039663SJohn Forte break; 151745039663SJohn Forte 151845039663SJohn Forte case STMF_ICM_SCSI_STATUS: 151945039663SJohn Forte m->icm_msg = stmf_ic_scsi_status_msg_unmarshal(nvl); 152045039663SJohn Forte break; 152145039663SJohn Forte 152245039663SJohn Forte case STMF_ICM_R2T: 152345039663SJohn Forte m->icm_msg = stmf_ic_r2t_msg_unmarshal(nvl); 152445039663SJohn Forte break; 152545039663SJohn Forte 152645039663SJohn Forte case STMF_ICM_STATUS: 152745039663SJohn Forte m->icm_msg = stmf_ic_status_msg_unmarshal(nvl); 152845039663SJohn Forte break; 152945039663SJohn Forte 153045039663SJohn Forte case STMF_ICM_SESSION_CREATE: 153145039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 153245039663SJohn Forte m->icm_msg = stmf_ic_session_create_destroy_msg_unmarshal(nvl); 153345039663SJohn Forte break; 153445039663SJohn Forte 153545039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 153645039663SJohn Forte case STMF_ICM_ECHO_REPLY: 153745039663SJohn Forte m->icm_msg = stmf_ic_echo_request_reply_msg_unmarshal(nvl); 153845039663SJohn Forte break; 153945039663SJohn Forte 154045039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 154145039663SJohn Forte ASSERT(0); 154245039663SJohn Forte break; 154345039663SJohn Forte 154445039663SJohn Forte default: 154545039663SJohn Forte ASSERT(0); 154645039663SJohn Forte } 154745039663SJohn Forte 154845039663SJohn Forte done: 154945039663SJohn Forte 155045039663SJohn Forte if (!m->icm_msg) { 155145039663SJohn Forte kmem_free(m, sizeof (*m)); 155245039663SJohn Forte return (NULL); 155345039663SJohn Forte } 155445039663SJohn Forte 155545039663SJohn Forte return (m); 155645039663SJohn Forte } 155745039663SJohn Forte 155845039663SJohn Forte static void * 155945039663SJohn Forte stmf_ic_reg_port_msg_unmarshal(nvlist_t *nvl) 156045039663SJohn Forte { 156145039663SJohn Forte nvlist_t *nvl_port_id = NULL; 156245039663SJohn Forte int rc = 0; 156345039663SJohn Forte stmf_ic_reg_port_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 156445039663SJohn Forte 156545039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, "icrp_port_id", &nvl_port_id); 156645039663SJohn Forte if (rc) { 156745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_port_id nvl"); 156845039663SJohn Forte rc = ENOMEM; /* XXX */ 156945039663SJohn Forte goto done; 157045039663SJohn Forte } 157145039663SJohn Forte 157245039663SJohn Forte m->icrp_port_id = stmf_ic_scsi_devid_desc_unmarshal(nvl_port_id); 157345039663SJohn Forte if (m->icrp_port_id == NULL) { 157445039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_port_id"); 157545039663SJohn Forte rc = ENOMEM; /* XXX */ 157645039663SJohn Forte goto done; 157745039663SJohn Forte } 157845039663SJohn Forte 157945039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrp_relative_port_id); 158045039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrp_cb_arg_len); 158145039663SJohn Forte 158245039663SJohn Forte if (m->icrp_cb_arg_len) { 158345039663SJohn Forte m->icrp_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 158445039663SJohn Forte "icrp_cb_arg", m->icrp_cb_arg_len, NULL); 158545039663SJohn Forte if (m->icrp_cb_arg == NULL) { 158645039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_cb_arg"); 158745039663SJohn Forte rc = ENOMEM; /* XXX */ 158845039663SJohn Forte goto done; 158945039663SJohn Forte } 159045039663SJohn Forte } 159145039663SJohn Forte 159245039663SJohn Forte done: 159345039663SJohn Forte if (!rc) 159445039663SJohn Forte return (m); 159545039663SJohn Forte 159645039663SJohn Forte stmf_ic_reg_port_msg_free(m, STMF_UNMARSHAL); 159745039663SJohn Forte 159845039663SJohn Forte return (NULL); 159945039663SJohn Forte } 160045039663SJohn Forte 160145039663SJohn Forte /* 160245039663SJohn Forte * XXX largely the same as stmf_ic_reg_port_msg_unmarshal() 160345039663SJohn Forte * Common stuff should be factored out. Type issues may make this 160445039663SJohn Forte * painful. 160545039663SJohn Forte */ 160645039663SJohn Forte static void * 160745039663SJohn Forte stmf_ic_dereg_port_msg_unmarshal(nvlist_t *nvl) 160845039663SJohn Forte { 160945039663SJohn Forte nvlist_t *nvl_port_id = NULL; 161045039663SJohn Forte int rc = 0; 161145039663SJohn Forte stmf_ic_dereg_port_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 161245039663SJohn Forte 161345039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, "icdp_port_id", &nvl_port_id); 161445039663SJohn Forte if (rc) { 161545039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_port_id nvl"); 161645039663SJohn Forte goto done; 161745039663SJohn Forte } 161845039663SJohn Forte 161945039663SJohn Forte m->icdp_port_id = stmf_ic_scsi_devid_desc_unmarshal(nvl_port_id); 162045039663SJohn Forte if (m->icdp_port_id == NULL) { 162145039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_port_id"); 162245039663SJohn Forte rc = ENOMEM; /* XXX */ 162345039663SJohn Forte goto done; 162445039663SJohn Forte } 162545039663SJohn Forte 162645039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icdp_cb_arg_len); 162745039663SJohn Forte 162845039663SJohn Forte if (m->icdp_cb_arg_len) { 162945039663SJohn Forte m->icdp_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 163045039663SJohn Forte "icdp_cb_arg", m->icdp_cb_arg_len, NULL); 163145039663SJohn Forte if (m->icdp_cb_arg == NULL) { 163245039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_cb_arg"); 163345039663SJohn Forte rc = ENOMEM; /* XXX */ 163445039663SJohn Forte goto done; 163545039663SJohn Forte } 163645039663SJohn Forte } 163745039663SJohn Forte 163845039663SJohn Forte done: 163945039663SJohn Forte if (!rc) 164045039663SJohn Forte return (m); 164145039663SJohn Forte 164245039663SJohn Forte stmf_ic_dereg_port_msg_free(m, STMF_UNMARSHAL); 164345039663SJohn Forte 164445039663SJohn Forte return (NULL); 164545039663SJohn Forte } 164645039663SJohn Forte 164745039663SJohn Forte static void * 164845039663SJohn Forte stmf_ic_reg_dereg_lun_msg_unmarshal(nvlist_t *nvl) 164945039663SJohn Forte { 165045039663SJohn Forte int rc = 0; 165145039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 165245039663SJohn Forte 165345039663SJohn Forte if (! stmf_ic_uint8_array_unmarshal(nvl, "icrl_lun_id", 165445039663SJohn Forte sizeof (m->icrl_lun_id), m->icrl_lun_id)) { 165545039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_lun_id"); 165645039663SJohn Forte rc = ENOMEM; /* XXX */ 165745039663SJohn Forte goto done; 165845039663SJohn Forte } 165945039663SJohn Forte 166045039663SJohn Forte m->icrl_lu_provider_name = stmf_ic_string_unmarshal(nvl, 166145039663SJohn Forte "icrl_lu_provider_name"); 166245039663SJohn Forte 166345039663SJohn Forte if (!m->icrl_lu_provider_name) { 166445039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_lu_provider_name"); 166545039663SJohn Forte rc = ENOMEM; /* XXX */ 166645039663SJohn Forte goto done; 166745039663SJohn Forte } 166845039663SJohn Forte 166945039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrl_cb_arg_len); 167045039663SJohn Forte 167145039663SJohn Forte if (m->icrl_cb_arg_len) { 167245039663SJohn Forte m->icrl_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 167345039663SJohn Forte "icrl_cb_arg", m->icrl_cb_arg_len, NULL); 167445039663SJohn Forte if (m->icrl_cb_arg == NULL) { 167545039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_cb_arg"); 167645039663SJohn Forte rc = ENOMEM; /* XXX */ 167745039663SJohn Forte goto done; 167845039663SJohn Forte } 167945039663SJohn Forte } 168045039663SJohn Forte 168145039663SJohn Forte done: 168245039663SJohn Forte if (!rc) 168345039663SJohn Forte return (m); 168445039663SJohn Forte 168545039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free(m, STMF_UNMARSHAL); 168645039663SJohn Forte 168745039663SJohn Forte return (NULL); 168845039663SJohn Forte } 168945039663SJohn Forte 169045039663SJohn Forte static void * 169145039663SJohn Forte stmf_ic_scsi_cmd_msg_unmarshal(nvlist_t *nvl) 169245039663SJohn Forte { 169345039663SJohn Forte int rc = 0; 169445039663SJohn Forte stmf_ic_scsi_cmd_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 169545039663SJohn Forte 169645039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 169745039663SJohn Forte NV_PAIR(UINT64, m, icsc_task_msgid), 169845039663SJohn Forte NV_PAIR(UINT64, m, icsc_session_id), 169945039663SJohn Forte NV_PAIR(UINT32, m, icsc_task_expected_xfer_length), 170045039663SJohn Forte NV_PAIR(UINT16, m, icsc_task_cdb_length), 170145039663SJohn Forte NV_PAIR(UINT8, m, icsc_task_flags), 170245039663SJohn Forte NV_PAIR(UINT8, m, icsc_task_mgmt_function), 170345039663SJohn Forte NV_PAIR(UINT32, m, icsc_immed_data_len), 170445039663SJohn Forte NULL) != 0) { 170545039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_task_msgid and friends"); 170645039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 170745039663SJohn Forte goto done; 170845039663SJohn Forte } 170945039663SJohn Forte 171045039663SJohn Forte m->icsc_ini_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 171145039663SJohn Forte nvl, "icsc_ini_devid"); 171245039663SJohn Forte if (m->icsc_ini_devid == NULL) { 171345039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_ini_devid"); 171445039663SJohn Forte rc = ENOMEM; 171545039663SJohn Forte goto done; 171645039663SJohn Forte } 171745039663SJohn Forte 171845039663SJohn Forte m->icsc_tgt_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 171945039663SJohn Forte nvl, "icsc_tgt_devid"); 172045039663SJohn Forte if (m->icsc_tgt_devid == NULL) { 172145039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_tgt_devid"); 172245039663SJohn Forte rc = ENOMEM; 172345039663SJohn Forte goto done; 172445039663SJohn Forte } 172545039663SJohn Forte 1726716c1805SNattuvetty Bhavyan m->icsc_rport = stmf_ic_lookup_remote_port_and_unmarshal( 1727716c1805SNattuvetty Bhavyan nvl, "icsc_rport"); 1728716c1805SNattuvetty Bhavyan if (m->icsc_rport == NULL) { 1729716c1805SNattuvetty Bhavyan stmf_ic_nvlookup_warn(__func__, "icsc_rport"); 1730716c1805SNattuvetty Bhavyan rc = ENOMEM; 1731716c1805SNattuvetty Bhavyan goto done; 1732716c1805SNattuvetty Bhavyan } 1733716c1805SNattuvetty Bhavyan 173445039663SJohn Forte /* icsc_lun_id */ 173545039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsc_lun_id", 173645039663SJohn Forte sizeof (m->icsc_lun_id), m->icsc_lun_id)) { 173745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_lun_id"); 173845039663SJohn Forte rc = ENOMEM; 173945039663SJohn Forte goto done; 174045039663SJohn Forte } 174145039663SJohn Forte 174245039663SJohn Forte /* icsc_task_lun_no */ 174345039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsc_task_lun_no", 174445039663SJohn Forte sizeof (m->icsc_task_lun_no), m->icsc_task_lun_no)) { 174545039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_task_lun_no"); 174645039663SJohn Forte rc = ENOMEM; 174745039663SJohn Forte goto done; 174845039663SJohn Forte } 174945039663SJohn Forte 175045039663SJohn Forte /* icsc_task_cdb */ 1751*8f641fa7SSue Gleeson if (m->icsc_task_cdb_length) { 1752*8f641fa7SSue Gleeson m->icsc_task_cdb = stmf_ic_uint8_array_unmarshal(nvl, 1753*8f641fa7SSue Gleeson "icsc_task_cdb", m->icsc_task_cdb_length, NULL); 1754*8f641fa7SSue Gleeson if (!m->icsc_task_cdb) { 1755*8f641fa7SSue Gleeson stmf_ic_nvlookup_warn(__func__, "icsc_task_cdb"); 1756*8f641fa7SSue Gleeson rc = ENOMEM; 1757*8f641fa7SSue Gleeson goto done; 1758*8f641fa7SSue Gleeson } 175945039663SJohn Forte } 176045039663SJohn Forte 176145039663SJohn Forte /* immediate data, if there is any */ 176245039663SJohn Forte if (m->icsc_immed_data_len) { 176345039663SJohn Forte m->icsc_immed_data = stmf_ic_uint8_array_unmarshal(nvl, 176445039663SJohn Forte "icsc_immed_data", m->icsc_immed_data_len, NULL); 176545039663SJohn Forte if (!m->icsc_immed_data) { 176645039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_immed_data"); 176745039663SJohn Forte rc = ENOMEM; 176845039663SJohn Forte goto done; 176945039663SJohn Forte } 177045039663SJohn Forte } 177145039663SJohn Forte 177245039663SJohn Forte done: 177345039663SJohn Forte if (!rc) 177445039663SJohn Forte return (m); 177545039663SJohn Forte 177645039663SJohn Forte stmf_ic_scsi_cmd_msg_free(m, STMF_UNMARSHAL); 177745039663SJohn Forte 177845039663SJohn Forte return (NULL); 177945039663SJohn Forte } 178045039663SJohn Forte 178145039663SJohn Forte static void * 178245039663SJohn Forte stmf_ic_scsi_data_msg_unmarshal(nvlist_t *nvl) 178345039663SJohn Forte { 178445039663SJohn Forte int rc = 0; 178545039663SJohn Forte stmf_ic_scsi_data_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 178645039663SJohn Forte 178745039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 178845039663SJohn Forte NV_PAIR(UINT64, m, icsd_task_msgid), 178945039663SJohn Forte NV_PAIR(UINT64, m, icsd_session_id), 179045039663SJohn Forte NV_PAIR(UINT64, m, icsd_data_len), 179145039663SJohn Forte NULL) != 0) { 179245039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_task_msgid and friends"); 179345039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 179445039663SJohn Forte goto done; 179545039663SJohn Forte } 179645039663SJohn Forte 179745039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsd_lun_id", 179845039663SJohn Forte sizeof (m->icsd_lun_id), m->icsd_lun_id)) { 179945039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_lun_id"); 180045039663SJohn Forte rc = ENOMEM; 180145039663SJohn Forte goto done; 180245039663SJohn Forte } 180345039663SJohn Forte 180445039663SJohn Forte m->icsd_data = stmf_ic_uint8_array_unmarshal(nvl, "icsd_data", 180545039663SJohn Forte m->icsd_data_len, NULL); 180645039663SJohn Forte if (!m->icsd_data) { 180745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_data"); 180845039663SJohn Forte rc = ENOMEM; 180945039663SJohn Forte goto done; 181045039663SJohn Forte } 181145039663SJohn Forte 181245039663SJohn Forte done: 181345039663SJohn Forte if (!rc) 181445039663SJohn Forte return (m); 181545039663SJohn Forte 181645039663SJohn Forte stmf_ic_scsi_data_msg_free(m, STMF_UNMARSHAL); 181745039663SJohn Forte 181845039663SJohn Forte return (NULL); 181945039663SJohn Forte } 182045039663SJohn Forte 182145039663SJohn Forte static void * 182245039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvlist_t *nvl) 182345039663SJohn Forte { 182445039663SJohn Forte int rc = 0; 182545039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *m = 182645039663SJohn Forte kmem_zalloc(sizeof (*m), KM_SLEEP); 182745039663SJohn Forte 182845039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 182945039663SJohn Forte NV_PAIR(UINT64, m, icsx_task_msgid), 183045039663SJohn Forte NV_PAIR(UINT64, m, icsx_session_id), 183145039663SJohn Forte NV_PAIR(UINT64, m, icsx_status), 183245039663SJohn Forte NULL) != 0) { 183345039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsx_task_msgid and friends"); 183445039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 183545039663SJohn Forte goto done; 183645039663SJohn Forte } 183745039663SJohn Forte 183845039663SJohn Forte done: 183945039663SJohn Forte if (!rc) 184045039663SJohn Forte return (m); 184145039663SJohn Forte 184245039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free(m, STMF_UNMARSHAL); 184345039663SJohn Forte 184445039663SJohn Forte return (NULL); 184545039663SJohn Forte } 184645039663SJohn Forte 184745039663SJohn Forte static void * 184845039663SJohn Forte stmf_ic_scsi_status_msg_unmarshal(nvlist_t *nvl) 184945039663SJohn Forte { 185045039663SJohn Forte int rc = 0; 185145039663SJohn Forte stmf_ic_scsi_status_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 185245039663SJohn Forte 185345039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 185445039663SJohn Forte NV_PAIR(UINT64, m, icss_task_msgid), 185545039663SJohn Forte NV_PAIR(UINT64, m, icss_session_id), 185645039663SJohn Forte NV_PAIR(UINT8, m, icss_response), 185745039663SJohn Forte NV_PAIR(UINT8, m, icss_status), 185845039663SJohn Forte NV_PAIR(UINT8, m, icss_flags), 185945039663SJohn Forte NV_PAIR(UINT32, m, icss_resid), 186045039663SJohn Forte NV_PAIR(UINT8, m, icss_sense_len), 186145039663SJohn Forte NULL) != 0) { 186245039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_task_msgid and friends"); 186345039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 186445039663SJohn Forte goto done; 186545039663SJohn Forte } 186645039663SJohn Forte 186745039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icss_lun_id", 186845039663SJohn Forte sizeof (m->icss_lun_id), m->icss_lun_id)) { 186945039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_lun_id"); 187045039663SJohn Forte rc = ENOMEM; 187145039663SJohn Forte goto done; 187245039663SJohn Forte } 187345039663SJohn Forte 187445039663SJohn Forte if (m->icss_sense_len) { 187545039663SJohn Forte m->icss_sense = stmf_ic_uint8_array_unmarshal(nvl, "icss_sense", 187645039663SJohn Forte m->icss_sense_len, NULL); 187745039663SJohn Forte if (!m->icss_sense) { 187845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_sense"); 187945039663SJohn Forte rc = ENOMEM; 188045039663SJohn Forte goto done; 188145039663SJohn Forte } 188245039663SJohn Forte } 188345039663SJohn Forte done: 188445039663SJohn Forte if (!rc) 188545039663SJohn Forte return (m); 188645039663SJohn Forte 188745039663SJohn Forte stmf_ic_scsi_status_msg_free(m, STMF_UNMARSHAL); 188845039663SJohn Forte 188945039663SJohn Forte return (NULL); 189045039663SJohn Forte } 189145039663SJohn Forte 189245039663SJohn Forte static void * 189345039663SJohn Forte stmf_ic_r2t_msg_unmarshal(nvlist_t *nvl) 189445039663SJohn Forte { 189545039663SJohn Forte int rc = 0; 189645039663SJohn Forte stmf_ic_r2t_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 189745039663SJohn Forte 189845039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 189945039663SJohn Forte NV_PAIR(UINT64, m, icrt_task_msgid), 190045039663SJohn Forte NV_PAIR(UINT64, m, icrt_session_id), 190145039663SJohn Forte NV_PAIR(UINT32, m, icrt_offset), 190245039663SJohn Forte NV_PAIR(UINT32, m, icrt_length), 190345039663SJohn Forte NULL) != 0) { 190445039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrt_task_msgid and friends"); 190545039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 190645039663SJohn Forte goto done; 190745039663SJohn Forte } 190845039663SJohn Forte 190945039663SJohn Forte done: 191045039663SJohn Forte if (!rc) 191145039663SJohn Forte return (m); 191245039663SJohn Forte 191345039663SJohn Forte stmf_ic_r2t_msg_free(m, STMF_UNMARSHAL); 191445039663SJohn Forte 191545039663SJohn Forte return (NULL); 191645039663SJohn Forte } 191745039663SJohn Forte 191845039663SJohn Forte static void * 191945039663SJohn Forte stmf_ic_session_create_destroy_msg_unmarshal(nvlist_t *nvl) 192045039663SJohn Forte { 192145039663SJohn Forte int rc = 0; 192245039663SJohn Forte stmf_ic_session_create_destroy_msg_t *m = kmem_zalloc(sizeof (*m), 192345039663SJohn Forte KM_SLEEP); 192445039663SJohn Forte 192545039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 192645039663SJohn Forte NV_PAIR(UINT64, m, icscd_session_id), 192745039663SJohn Forte NULL) != 0) { 192845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_session_id"); 192945039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 193045039663SJohn Forte goto done; 193145039663SJohn Forte } 193245039663SJohn Forte 193345039663SJohn Forte m->icscd_ini_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 193445039663SJohn Forte nvl, "icscd_ini_devid"); 193545039663SJohn Forte if (m->icscd_ini_devid == NULL) { 193645039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_ini_devid"); 193745039663SJohn Forte rc = ENOMEM; 193845039663SJohn Forte goto done; 193945039663SJohn Forte } 194045039663SJohn Forte 194145039663SJohn Forte m->icscd_tgt_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 194245039663SJohn Forte nvl, "icscd_tgt_devid"); 194345039663SJohn Forte if (m->icscd_tgt_devid == NULL) { 194445039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_tgt_devid"); 194545039663SJohn Forte rc = ENOMEM; 194645039663SJohn Forte goto done; 194745039663SJohn Forte } 194845039663SJohn Forte 1949716c1805SNattuvetty Bhavyan m->icscd_rport = stmf_ic_lookup_remote_port_and_unmarshal( 1950716c1805SNattuvetty Bhavyan nvl, "icscd_rport"); 1951716c1805SNattuvetty Bhavyan if (m->icscd_rport == NULL) { 1952716c1805SNattuvetty Bhavyan stmf_ic_nvlookup_warn(__func__, "icscd_rport"); 1953716c1805SNattuvetty Bhavyan rc = ENOMEM; 1954716c1805SNattuvetty Bhavyan goto done; 1955716c1805SNattuvetty Bhavyan } 1956716c1805SNattuvetty Bhavyan 195745039663SJohn Forte done: 195845039663SJohn Forte if (!rc) 195945039663SJohn Forte return (m); 196045039663SJohn Forte 196145039663SJohn Forte stmf_ic_session_create_destroy_msg_free(m, STMF_UNMARSHAL); 196245039663SJohn Forte 196345039663SJohn Forte return (NULL); 196445039663SJohn Forte } 196545039663SJohn Forte 196645039663SJohn Forte static void * 196745039663SJohn Forte stmf_ic_echo_request_reply_msg_unmarshal(nvlist_t *nvl) 196845039663SJohn Forte { 196945039663SJohn Forte int rc = 0; 197045039663SJohn Forte stmf_ic_echo_request_reply_msg_t *m = kmem_zalloc(sizeof (*m), 197145039663SJohn Forte KM_SLEEP); 197245039663SJohn Forte 197345039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 197445039663SJohn Forte NV_PAIR(UINT32, m, icerr_datalen), 197545039663SJohn Forte NULL) != 0) { 197645039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icerr_datalen"); 197745039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 197845039663SJohn Forte goto done; 197945039663SJohn Forte } 198045039663SJohn Forte 198145039663SJohn Forte /* immediate data, if there is any */ 198245039663SJohn Forte if (m->icerr_datalen) { 198345039663SJohn Forte m->icerr_data = stmf_ic_uint8_array_unmarshal(nvl, 198445039663SJohn Forte "icerr_data", m->icerr_datalen, NULL); 198545039663SJohn Forte if (!m->icerr_data) { 198645039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icerr_data"); 198745039663SJohn Forte rc = ENOMEM; 198845039663SJohn Forte goto done; 198945039663SJohn Forte } 199045039663SJohn Forte } 199145039663SJohn Forte 199245039663SJohn Forte done: 199345039663SJohn Forte if (!rc) 199445039663SJohn Forte return (m); 199545039663SJohn Forte 199645039663SJohn Forte stmf_ic_echo_request_reply_msg_free(m, STMF_UNMARSHAL); 199745039663SJohn Forte 199845039663SJohn Forte return (NULL); 199945039663SJohn Forte } 200045039663SJohn Forte 200145039663SJohn Forte static void * 200245039663SJohn Forte stmf_ic_status_msg_unmarshal(nvlist_t *nvl) 200345039663SJohn Forte { 200445039663SJohn Forte int rc = 0; 200545039663SJohn Forte stmf_ic_status_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 200645039663SJohn Forte 200745039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 200845039663SJohn Forte NV_PAIR(UINT8, m, ics_msg_type), 200945039663SJohn Forte NV_PAIR(UINT64, m, ics_msgid), 201045039663SJohn Forte NV_PAIR(UINT8, m, ics_status), 201145039663SJohn Forte NULL) != 0) { 201245039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "ics_msg_type and friends"); 201345039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 201445039663SJohn Forte goto done; 201545039663SJohn Forte } 201645039663SJohn Forte 201745039663SJohn Forte done: 201845039663SJohn Forte if (!rc) 201945039663SJohn Forte return (m); 202045039663SJohn Forte 202145039663SJohn Forte kmem_free(m, sizeof (*m)); 202245039663SJohn Forte return (NULL); 202345039663SJohn Forte } 202445039663SJohn Forte 202545039663SJohn Forte 202645039663SJohn Forte static scsi_devid_desc_t * 202745039663SJohn Forte stmf_ic_lookup_scsi_devid_desc_and_unmarshal(nvlist_t *nvl, char *field_name) 202845039663SJohn Forte { 202945039663SJohn Forte nvlist_t *nvl_devid = NULL; 203045039663SJohn Forte scsi_devid_desc_t *did = NULL; 203145039663SJohn Forte int rc; 203245039663SJohn Forte 203345039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, field_name, &nvl_devid); 203445039663SJohn Forte if (rc) { 203545039663SJohn Forte goto done; 203645039663SJohn Forte } 203745039663SJohn Forte 203845039663SJohn Forte did = stmf_ic_scsi_devid_desc_unmarshal(nvl_devid); 203945039663SJohn Forte 204045039663SJohn Forte done: 204145039663SJohn Forte return (did); 204245039663SJohn Forte } 204345039663SJohn Forte 204445039663SJohn Forte 204545039663SJohn Forte static scsi_devid_desc_t * 204645039663SJohn Forte stmf_ic_scsi_devid_desc_unmarshal(nvlist_t *nvl) 204745039663SJohn Forte { 204845039663SJohn Forte scsi_devid_desc_t *sdid = NULL; 204945039663SJohn Forte uint8_t ident_length = 0; 205045039663SJohn Forte size_t sdid_size; 205145039663SJohn Forte int rc = 0; 205245039663SJohn Forte 205345039663SJohn Forte /* 205445039663SJohn Forte * we get the ident_length first, since that's the only 205545039663SJohn Forte * variable-sized field in the struct. 205645039663SJohn Forte */ 205745039663SJohn Forte rc = nvlist_lookup_uint8(nvl, "ident_length", &ident_length); 205845039663SJohn Forte if (rc) 205945039663SJohn Forte goto done; 206045039663SJohn Forte 206145039663SJohn Forte sdid_size = sizeof_scsi_devid_desc(ident_length); 206245039663SJohn Forte sdid = kmem_zalloc(sdid_size, KM_SLEEP); 206345039663SJohn Forte 206445039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, protocol_id); 206545039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, code_set); 206645039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, piv); 206745039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, association); 206845039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, ident_type); 206945039663SJohn Forte 207045039663SJohn Forte sdid->ident_length = ident_length; 207145039663SJohn Forte 207245039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "ident", 207345039663SJohn Forte sdid->ident_length, sdid->ident)) { 207445039663SJohn Forte rc = ENOMEM; /* XXX */ 207545039663SJohn Forte goto done; 207645039663SJohn Forte } 207745039663SJohn Forte 207845039663SJohn Forte done: 207945039663SJohn Forte if (!rc) 208045039663SJohn Forte return (sdid); 208145039663SJohn Forte 208245039663SJohn Forte kmem_free(sdid, sdid_size); 208345039663SJohn Forte 208445039663SJohn Forte return (NULL); 208545039663SJohn Forte } 208645039663SJohn Forte 2087716c1805SNattuvetty Bhavyan static stmf_remote_port_t * 2088716c1805SNattuvetty Bhavyan stmf_ic_lookup_remote_port_and_unmarshal(nvlist_t *nvl, char *field_name) 2089716c1805SNattuvetty Bhavyan { 2090716c1805SNattuvetty Bhavyan nvlist_t *nvl_rport = NULL; 2091716c1805SNattuvetty Bhavyan 2092716c1805SNattuvetty Bhavyan if (nvlist_lookup_nvlist(nvl, field_name, &nvl_rport) != 0) 2093716c1805SNattuvetty Bhavyan return (NULL); 2094716c1805SNattuvetty Bhavyan 2095716c1805SNattuvetty Bhavyan return (stmf_ic_remote_port_unmarshal(nvl_rport)); 2096716c1805SNattuvetty Bhavyan } 2097716c1805SNattuvetty Bhavyan 2098716c1805SNattuvetty Bhavyan static stmf_remote_port_t * 2099716c1805SNattuvetty Bhavyan stmf_ic_remote_port_unmarshal(nvlist_t *nvl) 2100716c1805SNattuvetty Bhavyan { 2101716c1805SNattuvetty Bhavyan stmf_remote_port_t *rport = NULL; 2102716c1805SNattuvetty Bhavyan uint16_t rport_tptid_sz = 0; 2103716c1805SNattuvetty Bhavyan int rc = 0; 2104716c1805SNattuvetty Bhavyan 2105716c1805SNattuvetty Bhavyan rc = nvlist_lookup_uint16(nvl, "rport_tptid_sz", &rport_tptid_sz); 2106716c1805SNattuvetty Bhavyan if (rc || rport_tptid_sz < sizeof (scsi_transport_id_t)) 2107716c1805SNattuvetty Bhavyan return (NULL); 2108716c1805SNattuvetty Bhavyan 2109716c1805SNattuvetty Bhavyan rport = stmf_remote_port_alloc(rport_tptid_sz); 2110716c1805SNattuvetty Bhavyan if (!stmf_ic_uint8_array_unmarshal(nvl, "rport_tptid", rport_tptid_sz, 2111716c1805SNattuvetty Bhavyan (uint8_t *)rport->rport_tptid)) { 2112716c1805SNattuvetty Bhavyan stmf_remote_port_free(rport); 2113716c1805SNattuvetty Bhavyan rport = NULL; 2114716c1805SNattuvetty Bhavyan } 2115716c1805SNattuvetty Bhavyan return (rport); 2116716c1805SNattuvetty Bhavyan } 2117716c1805SNattuvetty Bhavyan 211845039663SJohn Forte /* 211945039663SJohn Forte * Unmarshal a uint8_t array. 212045039663SJohn Forte * 212145039663SJohn Forte * Takes a buf argument: 212245039663SJohn Forte * 212345039663SJohn Forte * - if non-null, the array contents are copied into the buf, 212445039663SJohn Forte * and we return a pointer to the buffer. 212545039663SJohn Forte * 212645039663SJohn Forte * - if null, we return a pointer to the unmarshaled data, which 212745039663SJohn Forte * resides in the nvlist. 212845039663SJohn Forte * 212945039663SJohn Forte * Returns NULL on failure. 213045039663SJohn Forte */ 213145039663SJohn Forte static uint8_t * 213245039663SJohn Forte stmf_ic_uint8_array_unmarshal( 213345039663SJohn Forte nvlist_t *nvl, 213445039663SJohn Forte char *field_name, 213591159e90SJohn Forte uint64_t len, 213645039663SJohn Forte uint8_t *buf) /* non-NULL: copy array into buf */ 213745039663SJohn Forte { 213845039663SJohn Forte uint8_t *array = NULL; 213945039663SJohn Forte uint_t actual_len; 214045039663SJohn Forte int rc = 0; 214145039663SJohn Forte 214245039663SJohn Forte rc = nvlist_lookup_uint8_array(nvl, field_name, &array, &actual_len); 214345039663SJohn Forte if (rc) { 214445039663SJohn Forte return (NULL); 214545039663SJohn Forte } 214645039663SJohn Forte 214745039663SJohn Forte if (len != actual_len) { 214845039663SJohn Forte cmn_err(CE_WARN, 214945039663SJohn Forte "stmf_ic_uint8_array_unmarshal: wrong len (%d != %d)", 215091159e90SJohn Forte (int)len, actual_len); 215145039663SJohn Forte return (NULL); 215245039663SJohn Forte } 215345039663SJohn Forte 215445039663SJohn Forte if (buf) { 215545039663SJohn Forte /* preallocated buf, copy in */ 215645039663SJohn Forte bcopy(array, buf, len); 215745039663SJohn Forte } else { 215845039663SJohn Forte /* return a pointer to the underlying array in the nvlist */ 215945039663SJohn Forte buf = array; 216045039663SJohn Forte } 216145039663SJohn Forte 216245039663SJohn Forte return (buf); 216345039663SJohn Forte } 216445039663SJohn Forte 216545039663SJohn Forte /* 216645039663SJohn Forte * Unmarshal a string. 216745039663SJohn Forte * 216845039663SJohn Forte * Returns NULL on failure. 216945039663SJohn Forte */ 217045039663SJohn Forte static char * 217145039663SJohn Forte stmf_ic_string_unmarshal( 217245039663SJohn Forte nvlist_t *nvl, 217345039663SJohn Forte char *field_name) 217445039663SJohn Forte { 217545039663SJohn Forte char *s = NULL; 217645039663SJohn Forte int rc = 0; 217745039663SJohn Forte 217845039663SJohn Forte rc = nvlist_lookup_string(nvl, field_name, &s); 217945039663SJohn Forte if (rc) { 218045039663SJohn Forte return (NULL); 218145039663SJohn Forte } 218245039663SJohn Forte 218345039663SJohn Forte return (s); 218445039663SJohn Forte } 218545039663SJohn Forte 218645039663SJohn Forte /* 218745039663SJohn Forte * Utility routines. 218845039663SJohn Forte */ 218945039663SJohn Forte 219045039663SJohn Forte static stmf_ic_msg_t * 219145039663SJohn Forte stmf_ic_alloc_msg_header( 219245039663SJohn Forte stmf_ic_msg_type_t msg_type, 219345039663SJohn Forte stmf_ic_msgid_t msgid) 219445039663SJohn Forte { 219545039663SJohn Forte stmf_ic_msg_t *icm; 219645039663SJohn Forte 219745039663SJohn Forte icm = (stmf_ic_msg_t *)kmem_zalloc(sizeof (*icm), KM_SLEEP); 219845039663SJohn Forte icm->icm_msg_type = msg_type; 219945039663SJohn Forte icm->icm_msgid = msgid; 220045039663SJohn Forte 220145039663SJohn Forte return (icm); 220245039663SJohn Forte } 220345039663SJohn Forte 220445039663SJohn Forte static size_t 220545039663SJohn Forte sizeof_scsi_devid_desc(int ident_length) 220645039663SJohn Forte { 220745039663SJohn Forte int num_ident_elems; 220845039663SJohn Forte size_t size; 220945039663SJohn Forte 221045039663SJohn Forte ASSERT(ident_length > 0); 221145039663SJohn Forte 221245039663SJohn Forte /* 221345039663SJohn Forte * Need to account for the fact that there's 221445039663SJohn Forte * already a single element in scsi_devid_desc_t. 221545039663SJohn Forte * 221645039663SJohn Forte * XXX would really like to have a way to determine the 221745039663SJohn Forte * sizeof (struct scsi_devid_desc.ident[0]), but 221845039663SJohn Forte * it's not clear that can be done. 221945039663SJohn Forte * Thus, this code relies on the knowledge of the type of 222045039663SJohn Forte * that field. 222145039663SJohn Forte */ 222245039663SJohn Forte num_ident_elems = ident_length - 1; 222345039663SJohn Forte size = sizeof (scsi_devid_desc_t) + 222445039663SJohn Forte (num_ident_elems * sizeof (uint8_t)); 222545039663SJohn Forte 222645039663SJohn Forte return (size); 222745039663SJohn Forte } 222845039663SJohn Forte 222945039663SJohn Forte 223045039663SJohn Forte /* 223145039663SJohn Forte * Duplicate the scsi_devid_desc_t. 223245039663SJohn Forte */ 223345039663SJohn Forte static scsi_devid_desc_t * 223445039663SJohn Forte scsi_devid_desc_dup(scsi_devid_desc_t *did) 223545039663SJohn Forte { 223645039663SJohn Forte scsi_devid_desc_t *dup; 223745039663SJohn Forte size_t dup_size; 223845039663SJohn Forte 223945039663SJohn Forte ASSERT(did->ident_length > 0); 224045039663SJohn Forte 224145039663SJohn Forte dup_size = sizeof_scsi_devid_desc(did->ident_length); 224245039663SJohn Forte dup = (scsi_devid_desc_t *)kmem_zalloc(dup_size, KM_SLEEP); 224345039663SJohn Forte bcopy(did, dup, dup_size); 224445039663SJohn Forte return (dup); 224545039663SJohn Forte } 224645039663SJohn Forte 224745039663SJohn Forte /* 224845039663SJohn Forte * May be called with a null pointer. 224945039663SJohn Forte */ 225045039663SJohn Forte static void 225145039663SJohn Forte scsi_devid_desc_free(scsi_devid_desc_t *did) 225245039663SJohn Forte { 225345039663SJohn Forte if (!did) 225445039663SJohn Forte return; 225545039663SJohn Forte 225645039663SJohn Forte kmem_free(did, sizeof_scsi_devid_desc(did->ident_length)); 225745039663SJohn Forte } 225845039663SJohn Forte 2259716c1805SNattuvetty Bhavyan /* 2260716c1805SNattuvetty Bhavyan * Duplicate the stmf_remote_port_t. 2261716c1805SNattuvetty Bhavyan */ 2262716c1805SNattuvetty Bhavyan static stmf_remote_port_t * 2263716c1805SNattuvetty Bhavyan remote_port_dup(stmf_remote_port_t *rport) 2264716c1805SNattuvetty Bhavyan { 2265716c1805SNattuvetty Bhavyan stmf_remote_port_t *dup = NULL; 2266716c1805SNattuvetty Bhavyan if (rport) { 2267716c1805SNattuvetty Bhavyan dup = stmf_remote_port_alloc(rport->rport_tptid_sz); 2268716c1805SNattuvetty Bhavyan bcopy(rport->rport_tptid, dup->rport_tptid, 2269716c1805SNattuvetty Bhavyan rport->rport_tptid_sz); 2270716c1805SNattuvetty Bhavyan } 2271716c1805SNattuvetty Bhavyan return (dup); 2272716c1805SNattuvetty Bhavyan } 2273716c1805SNattuvetty Bhavyan 227445039663SJohn Forte /* 227545039663SJohn Forte * Helper functions, returns NULL if no memory. 227645039663SJohn Forte */ 227745039663SJohn Forte static char * 227845039663SJohn Forte stmf_ic_strdup(char *str) 227945039663SJohn Forte { 228045039663SJohn Forte char *copy; 228145039663SJohn Forte 228245039663SJohn Forte ASSERT(str); 228345039663SJohn Forte 228445039663SJohn Forte copy = kmem_zalloc(strlen(str) + 1, KM_SLEEP); 228545039663SJohn Forte (void) strcpy(copy, str); 228645039663SJohn Forte return (copy); 228745039663SJohn Forte } 228845039663SJohn Forte 228945039663SJohn Forte static inline void 229045039663SJohn Forte stmf_ic_nvlookup_warn(const char *func, char *field) 229145039663SJohn Forte { 229245039663SJohn Forte cmn_err(CE_WARN, "%s: nvlist lookup of %s failed", func, field); 229345039663SJohn Forte } 2294