1*45039663SJohn Forte /* 2*45039663SJohn Forte * CDDL HEADER START 3*45039663SJohn Forte * 4*45039663SJohn Forte * The contents of this file are subject to the terms of the 5*45039663SJohn Forte * Common Development and Distribution License (the "License"). 6*45039663SJohn Forte * You may not use this file except in compliance with the License. 7*45039663SJohn Forte * 8*45039663SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*45039663SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*45039663SJohn Forte * See the License for the specific language governing permissions 11*45039663SJohn Forte * and limitations under the License. 12*45039663SJohn Forte * 13*45039663SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*45039663SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*45039663SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*45039663SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*45039663SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*45039663SJohn Forte * 19*45039663SJohn Forte * CDDL HEADER END 20*45039663SJohn Forte */ 21*45039663SJohn Forte /* 22*45039663SJohn Forte * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*45039663SJohn Forte * Use is subject to license terms. 24*45039663SJohn Forte */ 25*45039663SJohn Forte 26*45039663SJohn Forte /* 27*45039663SJohn Forte * XXX TODO 28*45039663SJohn Forte * #includes cribbed from stmf.c -- undoubtedly only a small subset of these 29*45039663SJohn Forte * are actually needed. 30*45039663SJohn Forte */ 31*45039663SJohn Forte #include <sys/conf.h> 32*45039663SJohn Forte #include <sys/file.h> 33*45039663SJohn Forte #include <sys/ddi.h> 34*45039663SJohn Forte #include <sys/sunddi.h> 35*45039663SJohn Forte #include <sys/scsi/scsi.h> 36*45039663SJohn Forte #include <sys/byteorder.h> 37*45039663SJohn Forte #include <sys/nvpair.h> 38*45039663SJohn Forte #include <sys/door.h> 39*45039663SJohn Forte 40*45039663SJohn Forte #include <sys/stmf.h> 41*45039663SJohn Forte #include <sys/lpif.h> 42*45039663SJohn Forte #include <sys/stmf_ioctl.h> 43*45039663SJohn Forte #include <sys/portif.h> 44*45039663SJohn Forte #include <pppt.h> 45*45039663SJohn Forte #include <sys/pppt_ic_if.h> 46*45039663SJohn Forte 47*45039663SJohn Forte 48*45039663SJohn Forte /* 49*45039663SJohn Forte * Macros 50*45039663SJohn Forte */ 51*45039663SJohn Forte 52*45039663SJohn Forte /* Free a struct if it was allocated */ 53*45039663SJohn Forte #define FREE_IF_ALLOC(m) \ 54*45039663SJohn Forte do { \ 55*45039663SJohn Forte if ((m)) kmem_free((m), sizeof (*(m))); \ 56*45039663SJohn Forte _NOTE(CONSTCOND) \ 57*45039663SJohn Forte } while (0) 58*45039663SJohn Forte 59*45039663SJohn Forte /* 60*45039663SJohn Forte * Macros to simplify the addition of struct fields to an nvlist. 61*45039663SJohn Forte * The name of the fields in the nvlist is the same as the name 62*45039663SJohn Forte * of the struct field. 63*45039663SJohn Forte * 64*45039663SJohn Forte * These macros require an int rc and a "done:" return retval label; 65*45039663SJohn Forte * they assume that the nvlist is named "nvl". 66*45039663SJohn Forte */ 67*45039663SJohn Forte #define NVLIST_ADD_FIELD(type, structure, field) \ 68*45039663SJohn Forte do { \ 69*45039663SJohn Forte rc = nvlist_add_##type(nvl, #field, structure->field); \ 70*45039663SJohn Forte if (rc) goto done; \ 71*45039663SJohn Forte _NOTE(CONSTCOND) \ 72*45039663SJohn Forte } while (0) 73*45039663SJohn Forte 74*45039663SJohn Forte /* use this macro when the array is defined as part of the struct */ 75*45039663SJohn Forte #define NVLIST_ADD_ARRAY(type, structure, field) \ 76*45039663SJohn Forte do { \ 77*45039663SJohn Forte rc = nvlist_add_##type##_array(nvl, #field, \ 78*45039663SJohn Forte structure->field, sizeof (structure->field)); \ 79*45039663SJohn Forte if (rc) goto done; \ 80*45039663SJohn Forte _NOTE(CONSTCOND) \ 81*45039663SJohn Forte } while (0) 82*45039663SJohn Forte 83*45039663SJohn Forte /* 84*45039663SJohn Forte * use this macro when the array field is a ptr or you need to explictly 85*45039663SJohn Forte * call out the size. 86*45039663SJohn Forte */ 87*45039663SJohn Forte #define NVLIST_ADD_ARRAY_LEN(type, structure, field, len) \ 88*45039663SJohn Forte do { \ 89*45039663SJohn Forte rc = nvlist_add_##type##_array(nvl, #field, \ 90*45039663SJohn Forte structure->field, len); \ 91*45039663SJohn Forte if (rc) goto done; \ 92*45039663SJohn Forte _NOTE(CONSTCOND) \ 93*45039663SJohn Forte } while (0) 94*45039663SJohn Forte 95*45039663SJohn Forte #define NVLIST_ADD_DEVID(structure, field) \ 96*45039663SJohn Forte do { \ 97*45039663SJohn Forte rc = stmf_ic_scsi_devid_desc_marshal(nvl, #field, \ 98*45039663SJohn Forte structure->field); \ 99*45039663SJohn Forte if (rc) goto done; \ 100*45039663SJohn Forte _NOTE(CONSTCOND) \ 101*45039663SJohn Forte } while (0) 102*45039663SJohn Forte 103*45039663SJohn Forte #define NVLIST_ADD_FIELD_UINT8(structure, field) \ 104*45039663SJohn Forte NVLIST_ADD_FIELD(structure, field, uint8) 105*45039663SJohn Forte 106*45039663SJohn Forte /* 107*45039663SJohn Forte * Macros to simplify the extraction of struct fields from an nvlist. 108*45039663SJohn Forte * The name of the fields in the nvlist is the same as the name 109*45039663SJohn Forte * of the struct field. 110*45039663SJohn Forte * 111*45039663SJohn Forte * Requires an int rc and a "done:" return retval label. 112*45039663SJohn Forte * Assumes that the nvlist is named "nvl". 113*45039663SJohn Forte * 114*45039663SJohn Forte * Sample usage: NVLIST_LOOKUP_FIELD(uint8, structname, fieldname); 115*45039663SJohn Forte */ 116*45039663SJohn Forte #define NVLIST_LOOKUP_FIELD(type, structure, field) \ 117*45039663SJohn Forte do { \ 118*45039663SJohn Forte rc = nvlist_lookup_##type(nvl, #field, \ 119*45039663SJohn Forte &(structure->field)); \ 120*45039663SJohn Forte if (rc) { \ 121*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, #field); \ 122*45039663SJohn Forte goto done; \ 123*45039663SJohn Forte } \ 124*45039663SJohn Forte _NOTE(CONSTCOND) \ 125*45039663SJohn Forte } while (0) 126*45039663SJohn Forte 127*45039663SJohn Forte /* 128*45039663SJohn Forte * Look up a field which gets stored into a structure bit field. 129*45039663SJohn Forte * The type passed is a uint type which can hold the largest value 130*45039663SJohn Forte * in the bit field. 131*45039663SJohn Forte * 132*45039663SJohn Forte * Requires an int rc and a "done:" return retval label. 133*45039663SJohn Forte * Assumes that the nvlist is named "nvl". 134*45039663SJohn Forte * 135*45039663SJohn Forte * Sample usage: NVLIST_LOOKUP_BIT_FIELD(uint8, structname, fieldname); 136*45039663SJohn Forte */ 137*45039663SJohn Forte #define NVLIST_LOOKUP_BIT_FIELD(type, structure, field) \ 138*45039663SJohn Forte do { \ 139*45039663SJohn Forte type##_t tmp; \ 140*45039663SJohn Forte rc = nvlist_lookup_##type(nvl, #field, &tmp); \ 141*45039663SJohn Forte if (rc) { \ 142*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, #field); \ 143*45039663SJohn Forte goto done; \ 144*45039663SJohn Forte } \ 145*45039663SJohn Forte structure->field = tmp; \ 146*45039663SJohn Forte _NOTE(CONSTCOND) \ 147*45039663SJohn Forte } while (0) 148*45039663SJohn Forte 149*45039663SJohn Forte /* 150*45039663SJohn Forte * Look up a boolean field which gets stored into a structure bit field. 151*45039663SJohn Forte * 152*45039663SJohn Forte * Requires an int rc and a "done:" return retval label. 153*45039663SJohn Forte * Assumes that the nvlist is named "nvl". 154*45039663SJohn Forte */ 155*45039663SJohn Forte #define NVLIST_LOOKUP_BIT_FIELD_BOOLEAN(structure, field) \ 156*45039663SJohn Forte do { \ 157*45039663SJohn Forte boolean_t tmp; \ 158*45039663SJohn Forte rc = nvlist_lookup_boolean_value(nvl, #field, &tmp); \ 159*45039663SJohn Forte if (rc) { \ 160*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, #field); \ 161*45039663SJohn Forte goto done; \ 162*45039663SJohn Forte } \ 163*45039663SJohn Forte structure->field = (tmp ? 1 : 0); \ 164*45039663SJohn Forte _NOTE(CONSTCOND) \ 165*45039663SJohn Forte } while (0) 166*45039663SJohn Forte 167*45039663SJohn Forte /* shorthand for nvlist_lookup_pairs() args */ 168*45039663SJohn Forte #define NV_PAIR(type, strct, field) #field, DATA_TYPE_##type, &(strct->field) 169*45039663SJohn Forte 170*45039663SJohn Forte /* number of times to retry the upcall to transmit */ 171*45039663SJohn Forte #define STMF_MSG_TRANSMIT_RETRY 3 172*45039663SJohn Forte 173*45039663SJohn Forte /* 174*45039663SJohn Forte * How was the message constructed? 175*45039663SJohn Forte * 176*45039663SJohn Forte * We need to know this when we free the message in order to 177*45039663SJohn Forte * determine what to do with pointers in the message: 178*45039663SJohn Forte * 179*45039663SJohn Forte * - messages which were unmarshaled from an nvlist may point to 180*45039663SJohn Forte * memory within that nvlist; this memory should not be freed since 181*45039663SJohn Forte * it will be deallocated when we free the nvlist. 182*45039663SJohn Forte * 183*45039663SJohn Forte * - messages which built using a constructor (alloc) function may 184*45039663SJohn Forte * point to memory which was explicitly allocated by the constructor; 185*45039663SJohn Forte * it should be freed when the message is freed. 186*45039663SJohn Forte * 187*45039663SJohn Forte */ 188*45039663SJohn Forte typedef enum { 189*45039663SJohn Forte STMF_CONSTRUCTOR = 0, 190*45039663SJohn Forte STMF_UNMARSHAL 191*45039663SJohn Forte } stmf_ic_msg_construction_method_t; 192*45039663SJohn Forte 193*45039663SJohn Forte 194*45039663SJohn Forte /* 195*45039663SJohn Forte * Function prototypes. 196*45039663SJohn Forte */ 197*45039663SJohn Forte 198*45039663SJohn Forte /* 199*45039663SJohn Forte * Helpers for msg_alloc routines, used when the msg payload is 200*45039663SJohn Forte * the same for multiple types of messages. 201*45039663SJohn Forte */ 202*45039663SJohn Forte static stmf_ic_msg_t *stmf_ic_reg_dereg_lun_msg_alloc( 203*45039663SJohn Forte stmf_ic_msg_type_t msg_type, uint8_t *lun_id, 204*45039663SJohn Forte char *lu_provider_name, uint16_t cb_arg_len, 205*45039663SJohn Forte uint8_t *cb_arg, stmf_ic_msgid_t msgid); 206*45039663SJohn Forte 207*45039663SJohn Forte static stmf_ic_msg_t *stmf_ic_session_create_destroy_msg_alloc( 208*45039663SJohn Forte stmf_ic_msg_type_t msg_type, 209*45039663SJohn Forte stmf_scsi_session_t *session, 210*45039663SJohn Forte stmf_ic_msgid_t msgid); 211*45039663SJohn Forte 212*45039663SJohn Forte static stmf_ic_msg_t *stmf_ic_echo_request_reply_msg_alloc( 213*45039663SJohn Forte stmf_ic_msg_type_t msg_type, 214*45039663SJohn Forte uint32_t data_len, 215*45039663SJohn Forte uint8_t *data, 216*45039663SJohn Forte stmf_ic_msgid_t msgid); 217*45039663SJohn Forte 218*45039663SJohn Forte /* 219*45039663SJohn Forte * Msg free routines. 220*45039663SJohn Forte */ 221*45039663SJohn Forte static void stmf_ic_reg_port_msg_free(stmf_ic_reg_port_msg_t *m, 222*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 223*45039663SJohn Forte static void stmf_ic_dereg_port_msg_free(stmf_ic_dereg_port_msg_t *m, 224*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 225*45039663SJohn Forte static void stmf_ic_reg_dereg_lun_msg_free(stmf_ic_reg_dereg_lun_msg_t *m, 226*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 227*45039663SJohn Forte static void stmf_ic_scsi_cmd_msg_free(stmf_ic_scsi_cmd_msg_t *m, 228*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 229*45039663SJohn Forte static void stmf_ic_scsi_data_msg_free(stmf_ic_scsi_data_msg_t *m, 230*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 231*45039663SJohn Forte static void stmf_ic_scsi_data_xfer_done_msg_free( 232*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *m, 233*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 234*45039663SJohn Forte static void stmf_ic_scsi_status_msg_free(stmf_ic_scsi_status_msg_t *m, 235*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 236*45039663SJohn Forte static void stmf_ic_r2t_msg_free(stmf_ic_r2t_msg_t *m, 237*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 238*45039663SJohn Forte static void stmf_ic_status_msg_free(stmf_ic_status_msg_t *m, 239*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 240*45039663SJohn Forte static void stmf_ic_session_create_destroy_msg_free( 241*45039663SJohn Forte stmf_ic_session_create_destroy_msg_t *m, 242*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 243*45039663SJohn Forte static void stmf_ic_echo_request_reply_msg_free( 244*45039663SJohn Forte stmf_ic_echo_request_reply_msg_t *m, 245*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 246*45039663SJohn Forte 247*45039663SJohn Forte /* 248*45039663SJohn Forte * Marshaling routines. 249*45039663SJohn Forte */ 250*45039663SJohn Forte static nvlist_t *stmf_ic_msg_marshal(stmf_ic_msg_t *msg); 251*45039663SJohn Forte static int stmf_ic_reg_port_msg_marshal(nvlist_t *nvl, void *msg); 252*45039663SJohn Forte static int stmf_ic_dereg_port_msg_marshal(nvlist_t *nvl, void *msg); 253*45039663SJohn Forte static int stmf_ic_reg_dereg_lun_msg_marshal(nvlist_t *nvl, void *msg); 254*45039663SJohn Forte static int stmf_ic_scsi_cmd_msg_marshal(nvlist_t *nvl, void *msg); 255*45039663SJohn Forte static int stmf_ic_scsi_data_msg_marshal(nvlist_t *nvl, void *msg); 256*45039663SJohn Forte static int stmf_ic_scsi_data_xfer_done_msg_marshal(nvlist_t *nvl, void *msg); 257*45039663SJohn Forte static int stmf_ic_scsi_status_msg_marshal(nvlist_t *nvl, void *msg); 258*45039663SJohn Forte static int stmf_ic_r2t_msg_marshal(nvlist_t *nvl, void *msg); 259*45039663SJohn Forte static int stmf_ic_status_msg_marshal(nvlist_t *nvl, void *msg); 260*45039663SJohn Forte static int stmf_ic_session_create_destroy_msg_marshal(nvlist_t *nvl, void *msg); 261*45039663SJohn Forte static int stmf_ic_echo_request_reply_msg_marshal(nvlist_t *nvl, void *msg); 262*45039663SJohn Forte static int stmf_ic_scsi_devid_desc_marshal(nvlist_t *parent_nvl, 263*45039663SJohn Forte char *sdid_name, scsi_devid_desc_t *sdid); 264*45039663SJohn Forte 265*45039663SJohn Forte /* 266*45039663SJohn Forte * Unmarshaling routines. 267*45039663SJohn Forte */ 268*45039663SJohn Forte static stmf_ic_msg_t *stmf_ic_msg_unmarshal(nvlist_t *nvl); 269*45039663SJohn Forte static void *stmf_ic_reg_port_msg_unmarshal(nvlist_t *nvl); 270*45039663SJohn Forte static void *stmf_ic_dereg_port_msg_unmarshal(nvlist_t *nvl); 271*45039663SJohn Forte static void *stmf_ic_reg_dereg_lun_msg_unmarshal(nvlist_t *nvl); 272*45039663SJohn Forte static void *stmf_ic_scsi_cmd_msg_unmarshal(nvlist_t *nvl); 273*45039663SJohn Forte static void *stmf_ic_scsi_data_msg_unmarshal(nvlist_t *nvl); 274*45039663SJohn Forte static void *stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvlist_t *nvl); 275*45039663SJohn Forte static void *stmf_ic_scsi_status_msg_unmarshal(nvlist_t *nvl); 276*45039663SJohn Forte static void *stmf_ic_r2t_msg_unmarshal(nvlist_t *nvl); 277*45039663SJohn Forte static void *stmf_ic_status_msg_unmarshal(nvlist_t *nvl); 278*45039663SJohn Forte static void *stmf_ic_session_create_destroy_msg_unmarshal(nvlist_t *nvl); 279*45039663SJohn Forte static void *stmf_ic_echo_request_reply_msg_unmarshal(nvlist_t *nvl); 280*45039663SJohn Forte static scsi_devid_desc_t *stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 281*45039663SJohn Forte nvlist_t *nvl, char *field_name); 282*45039663SJohn Forte static scsi_devid_desc_t *stmf_ic_scsi_devid_desc_unmarshal( 283*45039663SJohn Forte nvlist_t *nvl_devid); 284*45039663SJohn Forte static uint8_t *stmf_ic_uint8_array_unmarshal(nvlist_t *nvl, char *field_name, 285*45039663SJohn Forte uint16_t len, uint8_t *buf); 286*45039663SJohn Forte static char *stmf_ic_string_unmarshal(nvlist_t *nvl, char *field_name); 287*45039663SJohn Forte 288*45039663SJohn Forte /* 289*45039663SJohn Forte * Transmit and recieve routines. 290*45039663SJohn Forte */ 291*45039663SJohn Forte stmf_ic_msg_status_t stmf_ic_transmit(char *buf, size_t size); 292*45039663SJohn Forte 293*45039663SJohn Forte /* 294*45039663SJohn Forte * Utilities. 295*45039663SJohn Forte */ 296*45039663SJohn Forte static stmf_ic_msg_t *stmf_ic_alloc_msg_header(stmf_ic_msg_type_t msg_type, 297*45039663SJohn Forte stmf_ic_msgid_t msgid); 298*45039663SJohn Forte static size_t sizeof_scsi_devid_desc(int ident_length); 299*45039663SJohn Forte static char *stmf_ic_strdup(char *str); 300*45039663SJohn Forte static scsi_devid_desc_t *scsi_devid_desc_dup(scsi_devid_desc_t *did); 301*45039663SJohn Forte static void scsi_devid_desc_free(scsi_devid_desc_t *did); 302*45039663SJohn Forte static inline void stmf_ic_nvlookup_warn(const char *func, char *field); 303*45039663SJohn Forte 304*45039663SJohn Forte /* 305*45039663SJohn Forte * Send a message out over the interconnect, in the process marshalling 306*45039663SJohn Forte * the arguments. 307*45039663SJohn Forte * 308*45039663SJohn Forte * After being sent, the message is freed. 309*45039663SJohn Forte */ 310*45039663SJohn Forte stmf_ic_msg_status_t 311*45039663SJohn Forte stmf_ic_tx_msg(stmf_ic_msg_t *msg) 312*45039663SJohn Forte { 313*45039663SJohn Forte size_t size = 0; 314*45039663SJohn Forte nvlist_t *nvl = NULL; 315*45039663SJohn Forte char *buf = NULL; 316*45039663SJohn Forte int err = 0; 317*45039663SJohn Forte stmf_ic_msg_status_t status = STMF_IC_MSG_SUCCESS; 318*45039663SJohn Forte 319*45039663SJohn Forte nvl = stmf_ic_msg_marshal(msg); 320*45039663SJohn Forte if (!nvl) { 321*45039663SJohn Forte cmn_err(CE_WARN, "stmf_ic_tx_msg: marshal failed"); 322*45039663SJohn Forte status = STMF_IC_MSG_INTERNAL_ERROR; 323*45039663SJohn Forte goto done; 324*45039663SJohn Forte } 325*45039663SJohn Forte 326*45039663SJohn Forte err = nvlist_size(nvl, &size, NV_ENCODE_XDR); 327*45039663SJohn Forte if (err) { 328*45039663SJohn Forte status = STMF_IC_MSG_INTERNAL_ERROR; 329*45039663SJohn Forte goto done; 330*45039663SJohn Forte } 331*45039663SJohn Forte 332*45039663SJohn Forte buf = kmem_alloc(size, KM_SLEEP); 333*45039663SJohn Forte err = nvlist_pack(nvl, &buf, &size, NV_ENCODE_XDR, 0); 334*45039663SJohn Forte if (err) { 335*45039663SJohn Forte status = STMF_IC_MSG_INTERNAL_ERROR; 336*45039663SJohn Forte goto done; 337*45039663SJohn Forte } 338*45039663SJohn Forte 339*45039663SJohn Forte /* push the bits out on the wire */ 340*45039663SJohn Forte 341*45039663SJohn Forte status = stmf_ic_transmit(buf, size); 342*45039663SJohn Forte 343*45039663SJohn Forte done: 344*45039663SJohn Forte if (nvl) 345*45039663SJohn Forte nvlist_free(nvl); 346*45039663SJohn Forte 347*45039663SJohn Forte if (buf) 348*45039663SJohn Forte kmem_free(buf, size); 349*45039663SJohn Forte 350*45039663SJohn Forte stmf_ic_msg_free(msg); 351*45039663SJohn Forte 352*45039663SJohn Forte 353*45039663SJohn Forte return (status); 354*45039663SJohn Forte } 355*45039663SJohn Forte 356*45039663SJohn Forte /* 357*45039663SJohn Forte * Pass the command to the daemon for transmission to the other node. 358*45039663SJohn Forte */ 359*45039663SJohn Forte stmf_ic_msg_status_t 360*45039663SJohn Forte stmf_ic_transmit(char *buf, size_t size) 361*45039663SJohn Forte { 362*45039663SJohn Forte int i; 363*45039663SJohn Forte int rc; 364*45039663SJohn Forte door_arg_t arg; 365*45039663SJohn Forte door_handle_t door; 366*45039663SJohn Forte uint32_t result; 367*45039663SJohn Forte 368*45039663SJohn Forte mutex_enter(&pppt_global.global_door_lock); 369*45039663SJohn Forte if (pppt_global.global_door == NULL) { 370*45039663SJohn Forte /* daemon not listening */ 371*45039663SJohn Forte mutex_exit(&pppt_global.global_door_lock); 372*45039663SJohn Forte return (STMF_IC_MSG_INTERNAL_ERROR); 373*45039663SJohn Forte } 374*45039663SJohn Forte door = pppt_global.global_door; 375*45039663SJohn Forte door_ki_hold(door); 376*45039663SJohn Forte mutex_exit(&pppt_global.global_door_lock); 377*45039663SJohn Forte 378*45039663SJohn Forte arg.data_ptr = buf; 379*45039663SJohn Forte arg.data_size = size; 380*45039663SJohn Forte arg.desc_ptr = NULL; 381*45039663SJohn Forte arg.desc_num = 0; 382*45039663SJohn Forte arg.rbuf = (char *)&result; 383*45039663SJohn Forte arg.rsize = sizeof (result); 384*45039663SJohn Forte /* 385*45039663SJohn Forte * Retry a few times if there is a shortage of threads to 386*45039663SJohn Forte * service the upcall. This shouldn't happen unless a large 387*45039663SJohn Forte * number of initiators issue commands at once. 388*45039663SJohn Forte */ 389*45039663SJohn Forte for (i = 0; i < STMF_MSG_TRANSMIT_RETRY; i++) { 390*45039663SJohn Forte rc = door_ki_upcall(door, &arg); 391*45039663SJohn Forte if (rc != EAGAIN) 392*45039663SJohn Forte break; 393*45039663SJohn Forte delay(hz); 394*45039663SJohn Forte } 395*45039663SJohn Forte door_ki_rele(door); 396*45039663SJohn Forte if (rc != 0) { 397*45039663SJohn Forte cmn_err(CE_WARN, 398*45039663SJohn Forte "stmf_ic_transmit door_ki_upcall failed %d", rc); 399*45039663SJohn Forte return (STMF_IC_MSG_INTERNAL_ERROR); 400*45039663SJohn Forte } 401*45039663SJohn Forte if (result != 0) { 402*45039663SJohn Forte /* XXX Just warn for now */ 403*45039663SJohn Forte cmn_err(CE_WARN, 404*45039663SJohn Forte "stmf_ic_transmit bad result from daemon %d", result); 405*45039663SJohn Forte } 406*45039663SJohn Forte 407*45039663SJohn Forte return (STMF_IC_MSG_SUCCESS); 408*45039663SJohn Forte } 409*45039663SJohn Forte 410*45039663SJohn Forte /* 411*45039663SJohn Forte * This is a low-level upcall which is called when a message has 412*45039663SJohn Forte * been received on the interconnect. 413*45039663SJohn Forte * 414*45039663SJohn Forte * The caller is responsible for freeing the buffer which is passed in. 415*45039663SJohn Forte */ 416*45039663SJohn Forte /*ARGSUSED*/ 417*45039663SJohn Forte void 418*45039663SJohn Forte stmf_ic_rx_msg(char *buf, size_t len) 419*45039663SJohn Forte { 420*45039663SJohn Forte nvlist_t *nvl = NULL; 421*45039663SJohn Forte stmf_ic_msg_t *m = NULL; 422*45039663SJohn Forte stmf_ic_echo_request_reply_msg_t *icerr; 423*45039663SJohn Forte stmf_ic_msg_t *echo_msg; 424*45039663SJohn Forte int rc = 0; 425*45039663SJohn Forte 426*45039663SJohn Forte rc = nvlist_unpack(buf, len, &nvl, 0); 427*45039663SJohn Forte if (rc) { 428*45039663SJohn Forte cmn_err(CE_WARN, "stmf_ic_rx_msg: unpack failed"); 429*45039663SJohn Forte return; 430*45039663SJohn Forte } 431*45039663SJohn Forte 432*45039663SJohn Forte m = stmf_ic_msg_unmarshal(nvl); 433*45039663SJohn Forte if (m == NULL) { 434*45039663SJohn Forte cmn_err(CE_WARN, "stmf_ic_rx_msg: unmarshal failed"); 435*45039663SJohn Forte nvlist_free(nvl); 436*45039663SJohn Forte return; 437*45039663SJohn Forte } 438*45039663SJohn Forte 439*45039663SJohn Forte switch (m->icm_msg_type) { 440*45039663SJohn Forte 441*45039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 442*45039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 443*45039663SJohn Forte case STMF_ICM_SCSI_CMD: 444*45039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 445*45039663SJohn Forte case STMF_ICM_SESSION_CREATE: 446*45039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 447*45039663SJohn Forte /* 448*45039663SJohn Forte * These messages are all received by pppt. 449*45039663SJohn Forte * Currently, pppt will parse the message for type 450*45039663SJohn Forte */ 451*45039663SJohn Forte (void) pppt_msg_rx(m); 452*45039663SJohn Forte break; 453*45039663SJohn Forte 454*45039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 455*45039663SJohn Forte case STMF_ICM_REGISTER_LUN: 456*45039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 457*45039663SJohn Forte case STMF_ICM_SCSI_DATA: 458*45039663SJohn Forte case STMF_ICM_SCSI_STATUS: 459*45039663SJohn Forte /* 460*45039663SJohn Forte * These messages are all received by stmf. 461*45039663SJohn Forte * Currently, stmf will parse the message for type 462*45039663SJohn Forte */ 463*45039663SJohn Forte (void) stmf_msg_rx(m); 464*45039663SJohn Forte break; 465*45039663SJohn Forte 466*45039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 467*45039663SJohn Forte icerr = m->icm_msg; 468*45039663SJohn Forte echo_msg = stmf_ic_echo_reply_msg_alloc(icerr->icerr_datalen, 469*45039663SJohn Forte icerr->icerr_data, 0); 470*45039663SJohn Forte if (echo_msg != NULL) { 471*45039663SJohn Forte (void) stmf_ic_tx_msg(echo_msg); 472*45039663SJohn Forte } 473*45039663SJohn Forte stmf_ic_msg_free(m); 474*45039663SJohn Forte break; 475*45039663SJohn Forte 476*45039663SJohn Forte case STMF_ICM_ECHO_REPLY: 477*45039663SJohn Forte stmf_ic_msg_free(m); 478*45039663SJohn Forte break; 479*45039663SJohn Forte 480*45039663SJohn Forte case STMF_ICM_R2T: 481*45039663SJohn Forte /* 482*45039663SJohn Forte * XXX currently not supported 483*45039663SJohn Forte */ 484*45039663SJohn Forte stmf_ic_msg_free(m); 485*45039663SJohn Forte break; 486*45039663SJohn Forte 487*45039663SJohn Forte case STMF_ICM_STATUS: 488*45039663SJohn Forte (void) stmf_msg_rx(m); 489*45039663SJohn Forte break; 490*45039663SJohn Forte 491*45039663SJohn Forte default: 492*45039663SJohn Forte ASSERT(0); 493*45039663SJohn Forte } 494*45039663SJohn Forte } 495*45039663SJohn Forte 496*45039663SJohn Forte /* 497*45039663SJohn Forte * IC message allocation routines. 498*45039663SJohn Forte */ 499*45039663SJohn Forte 500*45039663SJohn Forte stmf_ic_msg_t * 501*45039663SJohn Forte stmf_ic_reg_port_msg_alloc( 502*45039663SJohn Forte scsi_devid_desc_t *port_id, 503*45039663SJohn Forte uint16_t relative_port_id, 504*45039663SJohn Forte uint16_t cb_arg_len, 505*45039663SJohn Forte uint8_t *cb_arg, 506*45039663SJohn Forte stmf_ic_msgid_t msgid) 507*45039663SJohn Forte { 508*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 509*45039663SJohn Forte stmf_ic_reg_port_msg_t *icrp = NULL; 510*45039663SJohn Forte 511*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_REGISTER_PROXY_PORT, msgid); 512*45039663SJohn Forte icrp = (stmf_ic_reg_port_msg_t *)kmem_zalloc(sizeof (*icrp), KM_SLEEP); 513*45039663SJohn Forte icm->icm_msg = (void *)icrp; 514*45039663SJohn Forte 515*45039663SJohn Forte icrp->icrp_port_id = scsi_devid_desc_dup(port_id); 516*45039663SJohn Forte icrp->icrp_relative_port_id = relative_port_id; 517*45039663SJohn Forte 518*45039663SJohn Forte if (cb_arg_len) { 519*45039663SJohn Forte icrp->icrp_cb_arg_len = cb_arg_len; 520*45039663SJohn Forte icrp->icrp_cb_arg = cb_arg; 521*45039663SJohn Forte } 522*45039663SJohn Forte 523*45039663SJohn Forte return (icm); 524*45039663SJohn Forte } 525*45039663SJohn Forte 526*45039663SJohn Forte stmf_ic_msg_t * 527*45039663SJohn Forte stmf_ic_dereg_port_msg_alloc( 528*45039663SJohn Forte scsi_devid_desc_t *port_id, 529*45039663SJohn Forte uint16_t cb_arg_len, 530*45039663SJohn Forte uint8_t *cb_arg, 531*45039663SJohn Forte stmf_ic_msgid_t msgid) 532*45039663SJohn Forte { 533*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 534*45039663SJohn Forte stmf_ic_dereg_port_msg_t *icdp = NULL; 535*45039663SJohn Forte 536*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_DEREGISTER_PROXY_PORT, msgid); 537*45039663SJohn Forte icdp = (stmf_ic_dereg_port_msg_t *)kmem_zalloc(sizeof (*icdp), 538*45039663SJohn Forte KM_SLEEP); 539*45039663SJohn Forte icm->icm_msg = (void *)icdp; 540*45039663SJohn Forte 541*45039663SJohn Forte icdp->icdp_port_id = scsi_devid_desc_dup(port_id); 542*45039663SJohn Forte 543*45039663SJohn Forte if (cb_arg_len) { 544*45039663SJohn Forte icdp->icdp_cb_arg_len = cb_arg_len; 545*45039663SJohn Forte icdp->icdp_cb_arg = cb_arg; 546*45039663SJohn Forte } 547*45039663SJohn Forte 548*45039663SJohn Forte return (icm); 549*45039663SJohn Forte } 550*45039663SJohn Forte 551*45039663SJohn Forte 552*45039663SJohn Forte stmf_ic_msg_t * 553*45039663SJohn Forte stmf_ic_reg_lun_msg_alloc( 554*45039663SJohn Forte uint8_t *lun_id, 555*45039663SJohn Forte char *lu_provider_name, 556*45039663SJohn Forte uint16_t cb_arg_len, 557*45039663SJohn Forte uint8_t *cb_arg, 558*45039663SJohn Forte stmf_ic_msgid_t msgid) 559*45039663SJohn Forte { 560*45039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_REGISTER_LUN, lun_id, 561*45039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 562*45039663SJohn Forte } 563*45039663SJohn Forte 564*45039663SJohn Forte stmf_ic_msg_t * 565*45039663SJohn Forte stmf_ic_lun_active_msg_alloc( 566*45039663SJohn Forte uint8_t *lun_id, 567*45039663SJohn Forte char *lu_provider_name, 568*45039663SJohn Forte uint16_t cb_arg_len, 569*45039663SJohn Forte uint8_t *cb_arg, 570*45039663SJohn Forte stmf_ic_msgid_t msgid) 571*45039663SJohn Forte { 572*45039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_LUN_ACTIVE, lun_id, 573*45039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 574*45039663SJohn Forte } 575*45039663SJohn Forte 576*45039663SJohn Forte stmf_ic_msg_t * 577*45039663SJohn Forte stmf_ic_dereg_lun_msg_alloc( 578*45039663SJohn Forte uint8_t *lun_id, 579*45039663SJohn Forte char *lu_provider_name, 580*45039663SJohn Forte uint16_t cb_arg_len, 581*45039663SJohn Forte uint8_t *cb_arg, 582*45039663SJohn Forte stmf_ic_msgid_t msgid) 583*45039663SJohn Forte { 584*45039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_DEREGISTER_LUN, lun_id, 585*45039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 586*45039663SJohn Forte } 587*45039663SJohn Forte 588*45039663SJohn Forte /* 589*45039663SJohn Forte * Guts of lun register/deregister/active alloc routines. 590*45039663SJohn Forte */ 591*45039663SJohn Forte static stmf_ic_msg_t * 592*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_alloc( 593*45039663SJohn Forte stmf_ic_msg_type_t msg_type, 594*45039663SJohn Forte uint8_t *lun_id, 595*45039663SJohn Forte char *lu_provider_name, 596*45039663SJohn Forte uint16_t cb_arg_len, 597*45039663SJohn Forte uint8_t *cb_arg, 598*45039663SJohn Forte stmf_ic_msgid_t msgid) 599*45039663SJohn Forte { 600*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 601*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *icrl = NULL; 602*45039663SJohn Forte 603*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 604*45039663SJohn Forte icrl = (stmf_ic_reg_dereg_lun_msg_t *) 605*45039663SJohn Forte kmem_zalloc(sizeof (*icrl), KM_SLEEP); 606*45039663SJohn Forte icm->icm_msg = (void *)icrl; 607*45039663SJohn Forte 608*45039663SJohn Forte icrl->icrl_lu_provider_name = stmf_ic_strdup(lu_provider_name); 609*45039663SJohn Forte 610*45039663SJohn Forte bcopy(lun_id, icrl->icrl_lun_id, sizeof (icrl->icrl_lun_id)); 611*45039663SJohn Forte 612*45039663SJohn Forte if (cb_arg_len) { 613*45039663SJohn Forte icrl->icrl_cb_arg_len = cb_arg_len; 614*45039663SJohn Forte icrl->icrl_cb_arg = cb_arg; 615*45039663SJohn Forte } 616*45039663SJohn Forte 617*45039663SJohn Forte return (icm); 618*45039663SJohn Forte } 619*45039663SJohn Forte 620*45039663SJohn Forte stmf_ic_msg_t * 621*45039663SJohn Forte stmf_ic_scsi_cmd_msg_alloc( 622*45039663SJohn Forte stmf_ic_msgid_t task_msgid, 623*45039663SJohn Forte scsi_task_t *task, 624*45039663SJohn Forte uint32_t immed_data_len, 625*45039663SJohn Forte uint8_t *immed_data, 626*45039663SJohn Forte stmf_ic_msgid_t msgid) 627*45039663SJohn Forte { 628*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 629*45039663SJohn Forte stmf_ic_scsi_cmd_msg_t *icsc = NULL; 630*45039663SJohn Forte scsi_devid_desc_t *ini_devid = task->task_session->ss_rport_id; 631*45039663SJohn Forte scsi_devid_desc_t *tgt_devid = task->task_lport->lport_id; 632*45039663SJohn Forte uint8_t *lun_id = task->task_lu->lu_id->ident; 633*45039663SJohn Forte 634*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_CMD, msgid); 635*45039663SJohn Forte icsc = (stmf_ic_scsi_cmd_msg_t *)kmem_zalloc(sizeof (*icsc), KM_SLEEP); 636*45039663SJohn Forte icm->icm_msg = (void *)icsc; 637*45039663SJohn Forte 638*45039663SJohn Forte icsc->icsc_task_msgid = task_msgid; 639*45039663SJohn Forte icsc->icsc_ini_devid = scsi_devid_desc_dup(ini_devid); 640*45039663SJohn Forte icsc->icsc_tgt_devid = scsi_devid_desc_dup(tgt_devid); 641*45039663SJohn Forte icsc->icsc_session_id = task->task_session->ss_session_id; 642*45039663SJohn Forte 643*45039663SJohn Forte bcopy(lun_id, icsc->icsc_lun_id, sizeof (icsc->icsc_lun_id)); 644*45039663SJohn Forte 645*45039663SJohn Forte bcopy(task->task_lun_no, icsc->icsc_task_lun_no, 646*45039663SJohn Forte sizeof (icsc->icsc_task_lun_no)); 647*45039663SJohn Forte 648*45039663SJohn Forte icsc->icsc_task_expected_xfer_length = task->task_expected_xfer_length; 649*45039663SJohn Forte icsc->icsc_task_cdb_length = task->task_cdb_length; 650*45039663SJohn Forte 651*45039663SJohn Forte icsc->icsc_task_cdb = (uint8_t *)kmem_zalloc(task->task_cdb_length, 652*45039663SJohn Forte KM_SLEEP); 653*45039663SJohn Forte bcopy(task->task_cdb, icsc->icsc_task_cdb, task->task_cdb_length); 654*45039663SJohn Forte 655*45039663SJohn Forte icsc->icsc_task_flags = task->task_flags; 656*45039663SJohn Forte icsc->icsc_task_priority = task->task_priority; 657*45039663SJohn Forte icsc->icsc_task_mgmt_function = task->task_mgmt_function; 658*45039663SJohn Forte 659*45039663SJohn Forte icsc->icsc_immed_data_len = immed_data_len; 660*45039663SJohn Forte icsc->icsc_immed_data = immed_data; 661*45039663SJohn Forte 662*45039663SJohn Forte return (icm); 663*45039663SJohn Forte } 664*45039663SJohn Forte 665*45039663SJohn Forte stmf_ic_msg_t * 666*45039663SJohn Forte stmf_ic_scsi_data_msg_alloc( 667*45039663SJohn Forte stmf_ic_msgid_t task_msgid, 668*45039663SJohn Forte uint64_t session_id, 669*45039663SJohn Forte uint8_t *lun_id, 670*45039663SJohn Forte uint64_t data_len, 671*45039663SJohn Forte uint8_t *data, 672*45039663SJohn Forte stmf_ic_msgid_t msgid) 673*45039663SJohn Forte { 674*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 675*45039663SJohn Forte stmf_ic_scsi_data_msg_t *icsd = NULL; 676*45039663SJohn Forte 677*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_DATA, msgid); 678*45039663SJohn Forte icsd = (stmf_ic_scsi_data_msg_t *)kmem_zalloc(sizeof (*icsd), KM_SLEEP); 679*45039663SJohn Forte icm->icm_msg = (void *)icsd; 680*45039663SJohn Forte 681*45039663SJohn Forte icsd->icsd_task_msgid = task_msgid; 682*45039663SJohn Forte icsd->icsd_session_id = session_id; 683*45039663SJohn Forte bcopy(lun_id, icsd->icsd_lun_id, sizeof (icsd->icsd_lun_id)); 684*45039663SJohn Forte icsd->icsd_data_len = data_len; 685*45039663SJohn Forte icsd->icsd_data = data; 686*45039663SJohn Forte 687*45039663SJohn Forte return (icm); 688*45039663SJohn Forte } 689*45039663SJohn Forte 690*45039663SJohn Forte stmf_ic_msg_t * 691*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_alloc( 692*45039663SJohn Forte stmf_ic_msgid_t task_msgid, 693*45039663SJohn Forte uint64_t session_id, 694*45039663SJohn Forte stmf_status_t status, 695*45039663SJohn Forte stmf_ic_msgid_t msgid) 696*45039663SJohn Forte { 697*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 698*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *icsx = NULL; 699*45039663SJohn Forte 700*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_DATA_XFER_DONE, msgid); 701*45039663SJohn Forte icsx = (stmf_ic_scsi_data_xfer_done_msg_t *)kmem_zalloc( 702*45039663SJohn Forte sizeof (*icsx), KM_SLEEP); 703*45039663SJohn Forte icm->icm_msg = (void *)icsx; 704*45039663SJohn Forte 705*45039663SJohn Forte icsx->icsx_task_msgid = task_msgid; 706*45039663SJohn Forte icsx->icsx_session_id = session_id; 707*45039663SJohn Forte icsx->icsx_status = status; 708*45039663SJohn Forte 709*45039663SJohn Forte return (icm); 710*45039663SJohn Forte } 711*45039663SJohn Forte 712*45039663SJohn Forte stmf_ic_msg_t * 713*45039663SJohn Forte stmf_ic_scsi_status_msg_alloc( 714*45039663SJohn Forte stmf_ic_msgid_t task_msgid, 715*45039663SJohn Forte uint64_t session_id, 716*45039663SJohn Forte uint8_t *lun_id, 717*45039663SJohn Forte uint8_t response, 718*45039663SJohn Forte uint8_t status, 719*45039663SJohn Forte uint8_t flags, 720*45039663SJohn Forte uint32_t resid, 721*45039663SJohn Forte uint8_t sense_len, 722*45039663SJohn Forte uint8_t *sense, 723*45039663SJohn Forte stmf_ic_msgid_t msgid) 724*45039663SJohn Forte { 725*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 726*45039663SJohn Forte stmf_ic_scsi_status_msg_t *icss = NULL; 727*45039663SJohn Forte 728*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_STATUS, msgid); 729*45039663SJohn Forte icss = (stmf_ic_scsi_status_msg_t *)kmem_zalloc(sizeof (*icss), 730*45039663SJohn Forte KM_SLEEP); 731*45039663SJohn Forte icm->icm_msg = (void *)icss; 732*45039663SJohn Forte 733*45039663SJohn Forte icss->icss_task_msgid = task_msgid; 734*45039663SJohn Forte icss->icss_session_id = session_id; 735*45039663SJohn Forte bcopy(lun_id, icss->icss_lun_id, sizeof (icss->icss_lun_id)); 736*45039663SJohn Forte icss->icss_response = response; 737*45039663SJohn Forte icss->icss_status = status; 738*45039663SJohn Forte icss->icss_flags = flags; 739*45039663SJohn Forte icss->icss_resid = resid; 740*45039663SJohn Forte icss->icss_sense_len = sense_len; 741*45039663SJohn Forte icss->icss_sense = sense; 742*45039663SJohn Forte 743*45039663SJohn Forte return (icm); 744*45039663SJohn Forte } 745*45039663SJohn Forte 746*45039663SJohn Forte stmf_ic_msg_t * 747*45039663SJohn Forte stmf_ic_r2t_msg_alloc( 748*45039663SJohn Forte stmf_ic_msgid_t task_msgid, 749*45039663SJohn Forte uint64_t session_id, 750*45039663SJohn Forte uint32_t offset, 751*45039663SJohn Forte uint32_t length, 752*45039663SJohn Forte stmf_ic_msgid_t msgid) 753*45039663SJohn Forte { 754*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 755*45039663SJohn Forte stmf_ic_r2t_msg_t *icrt = NULL; 756*45039663SJohn Forte 757*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_R2T, msgid); 758*45039663SJohn Forte icrt = (stmf_ic_r2t_msg_t *)kmem_zalloc(sizeof (*icrt), KM_SLEEP); 759*45039663SJohn Forte icm->icm_msg = (void *)icrt; 760*45039663SJohn Forte 761*45039663SJohn Forte icrt->icrt_task_msgid = task_msgid; 762*45039663SJohn Forte icrt->icrt_session_id = session_id; 763*45039663SJohn Forte icrt->icrt_offset = offset; 764*45039663SJohn Forte icrt->icrt_length = length; 765*45039663SJohn Forte 766*45039663SJohn Forte return (icm); 767*45039663SJohn Forte } 768*45039663SJohn Forte 769*45039663SJohn Forte stmf_ic_msg_t * 770*45039663SJohn Forte stmf_ic_status_msg_alloc( 771*45039663SJohn Forte stmf_status_t status, 772*45039663SJohn Forte stmf_ic_msg_type_t msg_type, 773*45039663SJohn Forte stmf_ic_msgid_t msgid) 774*45039663SJohn Forte { 775*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 776*45039663SJohn Forte stmf_ic_status_msg_t *ics = NULL; 777*45039663SJohn Forte 778*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_STATUS, msgid); 779*45039663SJohn Forte ics = (stmf_ic_status_msg_t *)kmem_zalloc(sizeof (*ics), KM_SLEEP); 780*45039663SJohn Forte icm->icm_msg = (void *)ics; 781*45039663SJohn Forte 782*45039663SJohn Forte ics->ics_status = status; 783*45039663SJohn Forte ics->ics_msg_type = msg_type; 784*45039663SJohn Forte ics->ics_msgid = msgid; /* XXX same as msgid in header */ 785*45039663SJohn Forte 786*45039663SJohn Forte return (icm); 787*45039663SJohn Forte } 788*45039663SJohn Forte 789*45039663SJohn Forte stmf_ic_msg_t * 790*45039663SJohn Forte stmf_ic_session_create_msg_alloc( 791*45039663SJohn Forte stmf_scsi_session_t *session, 792*45039663SJohn Forte stmf_ic_msgid_t msgid) 793*45039663SJohn Forte { 794*45039663SJohn Forte return (stmf_ic_session_create_destroy_msg_alloc( 795*45039663SJohn Forte STMF_ICM_SESSION_CREATE, session, msgid)); 796*45039663SJohn Forte } 797*45039663SJohn Forte 798*45039663SJohn Forte stmf_ic_msg_t * 799*45039663SJohn Forte stmf_ic_session_destroy_msg_alloc( 800*45039663SJohn Forte stmf_scsi_session_t *session, 801*45039663SJohn Forte stmf_ic_msgid_t msgid) 802*45039663SJohn Forte { 803*45039663SJohn Forte return (stmf_ic_session_create_destroy_msg_alloc( 804*45039663SJohn Forte STMF_ICM_SESSION_DESTROY, session, msgid)); 805*45039663SJohn Forte } 806*45039663SJohn Forte 807*45039663SJohn Forte /* 808*45039663SJohn Forte * Guts of session create/destroy routines. 809*45039663SJohn Forte */ 810*45039663SJohn Forte static stmf_ic_msg_t * 811*45039663SJohn Forte stmf_ic_session_create_destroy_msg_alloc( 812*45039663SJohn Forte stmf_ic_msg_type_t msg_type, 813*45039663SJohn Forte stmf_scsi_session_t *session, 814*45039663SJohn Forte stmf_ic_msgid_t msgid) 815*45039663SJohn Forte { 816*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 817*45039663SJohn Forte stmf_ic_session_create_destroy_msg_t *icscd = NULL; 818*45039663SJohn Forte scsi_devid_desc_t *ini_devid = session->ss_rport_id; 819*45039663SJohn Forte scsi_devid_desc_t *tgt_devid = session->ss_lport->lport_id; 820*45039663SJohn Forte 821*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 822*45039663SJohn Forte icscd = (stmf_ic_session_create_destroy_msg_t *) 823*45039663SJohn Forte kmem_zalloc(sizeof (*icscd), KM_SLEEP); 824*45039663SJohn Forte icm->icm_msg = (void *)icscd; 825*45039663SJohn Forte 826*45039663SJohn Forte icscd->icscd_session_id = session->ss_session_id; 827*45039663SJohn Forte icscd->icscd_ini_devid = scsi_devid_desc_dup(ini_devid); 828*45039663SJohn Forte icscd->icscd_tgt_devid = scsi_devid_desc_dup(tgt_devid); 829*45039663SJohn Forte 830*45039663SJohn Forte return (icm); 831*45039663SJohn Forte } 832*45039663SJohn Forte 833*45039663SJohn Forte stmf_ic_msg_t * 834*45039663SJohn Forte stmf_ic_echo_request_msg_alloc( 835*45039663SJohn Forte uint32_t data_len, 836*45039663SJohn Forte uint8_t *data, 837*45039663SJohn Forte stmf_ic_msgid_t msgid) 838*45039663SJohn Forte { 839*45039663SJohn Forte return (stmf_ic_echo_request_reply_msg_alloc( 840*45039663SJohn Forte STMF_ICM_ECHO_REQUEST, data_len, data, msgid)); 841*45039663SJohn Forte } 842*45039663SJohn Forte 843*45039663SJohn Forte stmf_ic_msg_t * 844*45039663SJohn Forte stmf_ic_echo_reply_msg_alloc( 845*45039663SJohn Forte uint32_t data_len, 846*45039663SJohn Forte uint8_t *data, 847*45039663SJohn Forte stmf_ic_msgid_t msgid) 848*45039663SJohn Forte { 849*45039663SJohn Forte return (stmf_ic_echo_request_reply_msg_alloc( 850*45039663SJohn Forte STMF_ICM_ECHO_REPLY, data_len, data, msgid)); 851*45039663SJohn Forte } 852*45039663SJohn Forte 853*45039663SJohn Forte 854*45039663SJohn Forte static stmf_ic_msg_t * 855*45039663SJohn Forte stmf_ic_echo_request_reply_msg_alloc( 856*45039663SJohn Forte stmf_ic_msg_type_t msg_type, 857*45039663SJohn Forte uint32_t data_len, 858*45039663SJohn Forte uint8_t *data, 859*45039663SJohn Forte stmf_ic_msgid_t msgid) 860*45039663SJohn Forte { 861*45039663SJohn Forte stmf_ic_msg_t *icm = NULL; 862*45039663SJohn Forte stmf_ic_echo_request_reply_msg_t *icerr = NULL; 863*45039663SJohn Forte 864*45039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 865*45039663SJohn Forte icerr = kmem_zalloc(sizeof (*icerr), KM_SLEEP); 866*45039663SJohn Forte icm->icm_msg = (void *)icerr; 867*45039663SJohn Forte 868*45039663SJohn Forte icerr->icerr_data = data; 869*45039663SJohn Forte icerr->icerr_datalen = data_len; 870*45039663SJohn Forte 871*45039663SJohn Forte return (icm); 872*45039663SJohn Forte } 873*45039663SJohn Forte 874*45039663SJohn Forte /* 875*45039663SJohn Forte * msg free routines. 876*45039663SJohn Forte */ 877*45039663SJohn Forte void 878*45039663SJohn Forte stmf_ic_msg_free(stmf_ic_msg_t *msg) 879*45039663SJohn Forte { 880*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod = 881*45039663SJohn Forte (msg->icm_nvlist ? STMF_UNMARSHAL : STMF_CONSTRUCTOR); 882*45039663SJohn Forte 883*45039663SJohn Forte switch (msg->icm_msg_type) { 884*45039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 885*45039663SJohn Forte stmf_ic_reg_port_msg_free( 886*45039663SJohn Forte (stmf_ic_reg_port_msg_t *)msg->icm_msg, cmethod); 887*45039663SJohn Forte break; 888*45039663SJohn Forte 889*45039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 890*45039663SJohn Forte stmf_ic_dereg_port_msg_free( 891*45039663SJohn Forte (stmf_ic_dereg_port_msg_t *)msg->icm_msg, cmethod); 892*45039663SJohn Forte break; 893*45039663SJohn Forte 894*45039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 895*45039663SJohn Forte case STMF_ICM_REGISTER_LUN: 896*45039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 897*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free( 898*45039663SJohn Forte (stmf_ic_reg_dereg_lun_msg_t *)msg->icm_msg, cmethod); 899*45039663SJohn Forte break; 900*45039663SJohn Forte 901*45039663SJohn Forte case STMF_ICM_SCSI_CMD: 902*45039663SJohn Forte stmf_ic_scsi_cmd_msg_free( 903*45039663SJohn Forte (stmf_ic_scsi_cmd_msg_t *)msg->icm_msg, cmethod); 904*45039663SJohn Forte break; 905*45039663SJohn Forte 906*45039663SJohn Forte case STMF_ICM_SCSI_DATA: 907*45039663SJohn Forte stmf_ic_scsi_data_msg_free( 908*45039663SJohn Forte (stmf_ic_scsi_data_msg_t *)msg->icm_msg, cmethod); 909*45039663SJohn Forte break; 910*45039663SJohn Forte 911*45039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 912*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free( 913*45039663SJohn Forte (stmf_ic_scsi_data_xfer_done_msg_t *)msg->icm_msg, cmethod); 914*45039663SJohn Forte break; 915*45039663SJohn Forte 916*45039663SJohn Forte case STMF_ICM_SCSI_STATUS: 917*45039663SJohn Forte stmf_ic_scsi_status_msg_free( 918*45039663SJohn Forte (stmf_ic_scsi_status_msg_t *)msg->icm_msg, cmethod); 919*45039663SJohn Forte break; 920*45039663SJohn Forte 921*45039663SJohn Forte case STMF_ICM_R2T: 922*45039663SJohn Forte stmf_ic_r2t_msg_free( 923*45039663SJohn Forte (stmf_ic_r2t_msg_t *)msg->icm_msg, cmethod); 924*45039663SJohn Forte break; 925*45039663SJohn Forte 926*45039663SJohn Forte case STMF_ICM_STATUS: 927*45039663SJohn Forte stmf_ic_status_msg_free( 928*45039663SJohn Forte (stmf_ic_status_msg_t *)msg->icm_msg, cmethod); 929*45039663SJohn Forte break; 930*45039663SJohn Forte 931*45039663SJohn Forte case STMF_ICM_SESSION_CREATE: 932*45039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 933*45039663SJohn Forte stmf_ic_session_create_destroy_msg_free( 934*45039663SJohn Forte (stmf_ic_session_create_destroy_msg_t *)msg->icm_msg, 935*45039663SJohn Forte cmethod); 936*45039663SJohn Forte break; 937*45039663SJohn Forte 938*45039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 939*45039663SJohn Forte case STMF_ICM_ECHO_REPLY: 940*45039663SJohn Forte stmf_ic_echo_request_reply_msg_free( 941*45039663SJohn Forte (stmf_ic_echo_request_reply_msg_t *)msg->icm_msg, cmethod); 942*45039663SJohn Forte break; 943*45039663SJohn Forte 944*45039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 945*45039663SJohn Forte ASSERT(0); 946*45039663SJohn Forte break; 947*45039663SJohn Forte 948*45039663SJohn Forte default: 949*45039663SJohn Forte ASSERT(0); 950*45039663SJohn Forte } 951*45039663SJohn Forte 952*45039663SJohn Forte if (msg->icm_nvlist) 953*45039663SJohn Forte nvlist_free(msg->icm_nvlist); 954*45039663SJohn Forte 955*45039663SJohn Forte kmem_free(msg, sizeof (*msg)); 956*45039663SJohn Forte } 957*45039663SJohn Forte 958*45039663SJohn Forte /*ARGSUSED*/ 959*45039663SJohn Forte static void 960*45039663SJohn Forte stmf_ic_reg_port_msg_free(stmf_ic_reg_port_msg_t *m, 961*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 962*45039663SJohn Forte { 963*45039663SJohn Forte scsi_devid_desc_free(m->icrp_port_id); 964*45039663SJohn Forte 965*45039663SJohn Forte kmem_free(m, sizeof (*m)); 966*45039663SJohn Forte } 967*45039663SJohn Forte 968*45039663SJohn Forte 969*45039663SJohn Forte /*ARGSUSED*/ 970*45039663SJohn Forte static void 971*45039663SJohn Forte stmf_ic_dereg_port_msg_free(stmf_ic_dereg_port_msg_t *m, 972*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 973*45039663SJohn Forte { 974*45039663SJohn Forte scsi_devid_desc_free(m->icdp_port_id); 975*45039663SJohn Forte 976*45039663SJohn Forte kmem_free(m, sizeof (*m)); 977*45039663SJohn Forte } 978*45039663SJohn Forte 979*45039663SJohn Forte 980*45039663SJohn Forte /* 981*45039663SJohn Forte * Works for both reg_lun_msg and dereg_lun_msg, since the message 982*45039663SJohn Forte * payload is the same. 983*45039663SJohn Forte */ 984*45039663SJohn Forte static void 985*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free(stmf_ic_reg_dereg_lun_msg_t *m, 986*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 987*45039663SJohn Forte { 988*45039663SJohn Forte if (cmethod == STMF_CONSTRUCTOR) { 989*45039663SJohn Forte kmem_free(m->icrl_lu_provider_name, 990*45039663SJohn Forte strlen(m->icrl_lu_provider_name) + 1); 991*45039663SJohn Forte } 992*45039663SJohn Forte 993*45039663SJohn Forte kmem_free(m, sizeof (*m)); 994*45039663SJohn Forte } 995*45039663SJohn Forte 996*45039663SJohn Forte static void 997*45039663SJohn Forte stmf_ic_scsi_cmd_msg_free(stmf_ic_scsi_cmd_msg_t *m, 998*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 999*45039663SJohn Forte { 1000*45039663SJohn Forte scsi_devid_desc_free(m->icsc_ini_devid); 1001*45039663SJohn Forte scsi_devid_desc_free(m->icsc_tgt_devid); 1002*45039663SJohn Forte if (cmethod == STMF_CONSTRUCTOR) { 1003*45039663SJohn Forte kmem_free(m->icsc_task_cdb, m->icsc_task_cdb_length); 1004*45039663SJohn Forte } 1005*45039663SJohn Forte 1006*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1007*45039663SJohn Forte 1008*45039663SJohn Forte } 1009*45039663SJohn Forte 1010*45039663SJohn Forte /*ARGSUSED*/ 1011*45039663SJohn Forte static void 1012*45039663SJohn Forte stmf_ic_scsi_data_msg_free(stmf_ic_scsi_data_msg_t *m, 1013*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 1014*45039663SJohn Forte { 1015*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1016*45039663SJohn Forte } 1017*45039663SJohn Forte 1018*45039663SJohn Forte /*ARGSUSED*/ 1019*45039663SJohn Forte static void 1020*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free(stmf_ic_scsi_data_xfer_done_msg_t *m, 1021*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 1022*45039663SJohn Forte { 1023*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1024*45039663SJohn Forte } 1025*45039663SJohn Forte 1026*45039663SJohn Forte /*ARGSUSED*/ 1027*45039663SJohn Forte static void 1028*45039663SJohn Forte stmf_ic_scsi_status_msg_free(stmf_ic_scsi_status_msg_t *m, 1029*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 1030*45039663SJohn Forte { 1031*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1032*45039663SJohn Forte } 1033*45039663SJohn Forte 1034*45039663SJohn Forte /*ARGSUSED*/ 1035*45039663SJohn Forte static void 1036*45039663SJohn Forte stmf_ic_r2t_msg_free(stmf_ic_r2t_msg_t *m, 1037*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 1038*45039663SJohn Forte { 1039*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1040*45039663SJohn Forte } 1041*45039663SJohn Forte 1042*45039663SJohn Forte /*ARGSUSED*/ 1043*45039663SJohn Forte static void 1044*45039663SJohn Forte stmf_ic_status_msg_free(stmf_ic_status_msg_t *m, 1045*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 1046*45039663SJohn Forte { 1047*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1048*45039663SJohn Forte } 1049*45039663SJohn Forte 1050*45039663SJohn Forte /* 1051*45039663SJohn Forte * Works for both session_create and session_destroy msgs, since the message 1052*45039663SJohn Forte * payload is the same. 1053*45039663SJohn Forte */ 1054*45039663SJohn Forte /*ARGSUSED*/ 1055*45039663SJohn Forte static void 1056*45039663SJohn Forte stmf_ic_session_create_destroy_msg_free(stmf_ic_session_create_destroy_msg_t *m, 1057*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 1058*45039663SJohn Forte { 1059*45039663SJohn Forte scsi_devid_desc_free(m->icscd_ini_devid); 1060*45039663SJohn Forte scsi_devid_desc_free(m->icscd_tgt_devid); 1061*45039663SJohn Forte 1062*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1063*45039663SJohn Forte } 1064*45039663SJohn Forte 1065*45039663SJohn Forte /*ARGSUSED*/ 1066*45039663SJohn Forte static void 1067*45039663SJohn Forte stmf_ic_echo_request_reply_msg_free(stmf_ic_echo_request_reply_msg_t *m, 1068*45039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 1069*45039663SJohn Forte { 1070*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1071*45039663SJohn Forte } 1072*45039663SJohn Forte 1073*45039663SJohn Forte 1074*45039663SJohn Forte /* 1075*45039663SJohn Forte * Marshaling routines. 1076*45039663SJohn Forte */ 1077*45039663SJohn Forte 1078*45039663SJohn Forte static nvlist_t * 1079*45039663SJohn Forte stmf_ic_msg_marshal(stmf_ic_msg_t *msg) 1080*45039663SJohn Forte { 1081*45039663SJohn Forte nvlist_t *nvl = NULL; 1082*45039663SJohn Forte int rc = 0; 1083*45039663SJohn Forte 1084*45039663SJohn Forte rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); 1085*45039663SJohn Forte if (rc) 1086*45039663SJohn Forte goto done; 1087*45039663SJohn Forte 1088*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, msg, icm_msg_type); 1089*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, msg, icm_msgid); 1090*45039663SJohn Forte 1091*45039663SJohn Forte switch (msg->icm_msg_type) { 1092*45039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 1093*45039663SJohn Forte rc = stmf_ic_reg_port_msg_marshal(nvl, msg->icm_msg); 1094*45039663SJohn Forte break; 1095*45039663SJohn Forte 1096*45039663SJohn Forte 1097*45039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 1098*45039663SJohn Forte rc = stmf_ic_dereg_port_msg_marshal(nvl, msg->icm_msg); 1099*45039663SJohn Forte break; 1100*45039663SJohn Forte 1101*45039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 1102*45039663SJohn Forte case STMF_ICM_REGISTER_LUN: 1103*45039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 1104*45039663SJohn Forte rc = stmf_ic_reg_dereg_lun_msg_marshal(nvl, msg->icm_msg); 1105*45039663SJohn Forte break; 1106*45039663SJohn Forte 1107*45039663SJohn Forte case STMF_ICM_SCSI_CMD: 1108*45039663SJohn Forte rc = stmf_ic_scsi_cmd_msg_marshal(nvl, msg->icm_msg); 1109*45039663SJohn Forte break; 1110*45039663SJohn Forte 1111*45039663SJohn Forte case STMF_ICM_SCSI_DATA: 1112*45039663SJohn Forte rc = stmf_ic_scsi_data_msg_marshal(nvl, msg->icm_msg); 1113*45039663SJohn Forte break; 1114*45039663SJohn Forte 1115*45039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 1116*45039663SJohn Forte rc = stmf_ic_scsi_data_xfer_done_msg_marshal(nvl, msg->icm_msg); 1117*45039663SJohn Forte break; 1118*45039663SJohn Forte 1119*45039663SJohn Forte case STMF_ICM_SCSI_STATUS: 1120*45039663SJohn Forte rc = stmf_ic_scsi_status_msg_marshal(nvl, msg->icm_msg); 1121*45039663SJohn Forte break; 1122*45039663SJohn Forte 1123*45039663SJohn Forte case STMF_ICM_R2T: 1124*45039663SJohn Forte rc = stmf_ic_r2t_msg_marshal(nvl, msg->icm_msg); 1125*45039663SJohn Forte break; 1126*45039663SJohn Forte 1127*45039663SJohn Forte case STMF_ICM_STATUS: 1128*45039663SJohn Forte rc = stmf_ic_status_msg_marshal(nvl, msg->icm_msg); 1129*45039663SJohn Forte break; 1130*45039663SJohn Forte 1131*45039663SJohn Forte case STMF_ICM_SESSION_CREATE: 1132*45039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 1133*45039663SJohn Forte rc = stmf_ic_session_create_destroy_msg_marshal(nvl, 1134*45039663SJohn Forte msg->icm_msg); 1135*45039663SJohn Forte break; 1136*45039663SJohn Forte 1137*45039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 1138*45039663SJohn Forte case STMF_ICM_ECHO_REPLY: 1139*45039663SJohn Forte rc = stmf_ic_echo_request_reply_msg_marshal(nvl, 1140*45039663SJohn Forte msg->icm_msg); 1141*45039663SJohn Forte break; 1142*45039663SJohn Forte 1143*45039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 1144*45039663SJohn Forte ASSERT(0); 1145*45039663SJohn Forte break; 1146*45039663SJohn Forte 1147*45039663SJohn Forte default: 1148*45039663SJohn Forte ASSERT(0); 1149*45039663SJohn Forte } 1150*45039663SJohn Forte 1151*45039663SJohn Forte done: 1152*45039663SJohn Forte if (!rc) 1153*45039663SJohn Forte return (nvl); 1154*45039663SJohn Forte 1155*45039663SJohn Forte if (nvl) 1156*45039663SJohn Forte nvlist_free(nvl); 1157*45039663SJohn Forte 1158*45039663SJohn Forte return (NULL); 1159*45039663SJohn Forte } 1160*45039663SJohn Forte 1161*45039663SJohn Forte 1162*45039663SJohn Forte static int 1163*45039663SJohn Forte stmf_ic_reg_port_msg_marshal(nvlist_t *nvl, void *msg) 1164*45039663SJohn Forte { 1165*45039663SJohn Forte stmf_ic_reg_port_msg_t *m = (stmf_ic_reg_port_msg_t *)msg; 1166*45039663SJohn Forte int rc = 0; 1167*45039663SJohn Forte 1168*45039663SJohn Forte NVLIST_ADD_DEVID(m, icrp_port_id); 1169*45039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrp_relative_port_id); 1170*45039663SJohn Forte 1171*45039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrp_cb_arg_len); 1172*45039663SJohn Forte /* only add the callback arg if necessary */ 1173*45039663SJohn Forte if (m->icrp_cb_arg_len) { 1174*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icrp_cb_arg, m->icrp_cb_arg_len); 1175*45039663SJohn Forte } 1176*45039663SJohn Forte 1177*45039663SJohn Forte done: 1178*45039663SJohn Forte return (rc); 1179*45039663SJohn Forte } 1180*45039663SJohn Forte 1181*45039663SJohn Forte static int 1182*45039663SJohn Forte stmf_ic_dereg_port_msg_marshal(nvlist_t *nvl, void *msg) 1183*45039663SJohn Forte { 1184*45039663SJohn Forte stmf_ic_dereg_port_msg_t *m = (stmf_ic_dereg_port_msg_t *)msg; 1185*45039663SJohn Forte int rc = 0; 1186*45039663SJohn Forte 1187*45039663SJohn Forte NVLIST_ADD_DEVID(m, icdp_port_id); 1188*45039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icdp_cb_arg_len); 1189*45039663SJohn Forte 1190*45039663SJohn Forte /* only add the callback arg if necessary */ 1191*45039663SJohn Forte if (m->icdp_cb_arg_len) { 1192*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icdp_cb_arg, m->icdp_cb_arg_len); 1193*45039663SJohn Forte } 1194*45039663SJohn Forte 1195*45039663SJohn Forte done: 1196*45039663SJohn Forte return (rc); 1197*45039663SJohn Forte } 1198*45039663SJohn Forte 1199*45039663SJohn Forte /* 1200*45039663SJohn Forte * Handles STMF_ICM_LUN_ACTIVE, STMF_ICM_REGISTER_LUN and 1201*45039663SJohn Forte * STMF_ICM_DEREGISTER_LUN; 1202*45039663SJohn Forte * msg payload is the same for all. 1203*45039663SJohn Forte */ 1204*45039663SJohn Forte static int 1205*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_marshal(nvlist_t *nvl, void *msg) 1206*45039663SJohn Forte { 1207*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *m = (stmf_ic_reg_dereg_lun_msg_t *)msg; 1208*45039663SJohn Forte int rc = 0; 1209*45039663SJohn Forte 1210*45039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icrl_lun_id); 1211*45039663SJohn Forte NVLIST_ADD_FIELD(string, m, icrl_lu_provider_name); 1212*45039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrl_cb_arg_len); 1213*45039663SJohn Forte 1214*45039663SJohn Forte /* only add the callback arg if necessary */ 1215*45039663SJohn Forte if (m->icrl_cb_arg_len) { 1216*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icrl_cb_arg, m->icrl_cb_arg_len); 1217*45039663SJohn Forte } 1218*45039663SJohn Forte 1219*45039663SJohn Forte done: 1220*45039663SJohn Forte return (rc); 1221*45039663SJohn Forte } 1222*45039663SJohn Forte 1223*45039663SJohn Forte static int 1224*45039663SJohn Forte stmf_ic_scsi_cmd_msg_marshal(nvlist_t *nvl, void *msg) 1225*45039663SJohn Forte { 1226*45039663SJohn Forte stmf_ic_scsi_cmd_msg_t *m = (stmf_ic_scsi_cmd_msg_t *)msg; 1227*45039663SJohn Forte int rc = 0; 1228*45039663SJohn Forte 1229*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsc_task_msgid); 1230*45039663SJohn Forte NVLIST_ADD_DEVID(m, icsc_ini_devid); 1231*45039663SJohn Forte NVLIST_ADD_DEVID(m, icsc_tgt_devid); 1232*45039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icsc_lun_id); 1233*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsc_session_id); 1234*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_task_lun_no, 8); 1235*45039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icsc_task_expected_xfer_length); 1236*45039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icsc_task_cdb_length); 1237*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_task_cdb, m->icsc_task_cdb_length); 1238*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_flags); 1239*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_priority); 1240*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_mgmt_function); 1241*45039663SJohn Forte 1242*45039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icsc_immed_data_len); 1243*45039663SJohn Forte /* only add immediate data if necessary */ 1244*45039663SJohn Forte if (m->icsc_immed_data_len) { 1245*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_immed_data, 1246*45039663SJohn Forte m->icsc_immed_data_len); 1247*45039663SJohn Forte } 1248*45039663SJohn Forte 1249*45039663SJohn Forte done: 1250*45039663SJohn Forte return (rc); 1251*45039663SJohn Forte } 1252*45039663SJohn Forte 1253*45039663SJohn Forte static int 1254*45039663SJohn Forte stmf_ic_scsi_data_msg_marshal(nvlist_t *nvl, void *msg) 1255*45039663SJohn Forte { 1256*45039663SJohn Forte stmf_ic_scsi_data_msg_t *m = (stmf_ic_scsi_data_msg_t *)msg; 1257*45039663SJohn Forte int rc = 0; 1258*45039663SJohn Forte 1259*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_task_msgid); 1260*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_session_id); 1261*45039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icsd_lun_id); 1262*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_data_len); 1263*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsd_data, m->icsd_data_len); 1264*45039663SJohn Forte 1265*45039663SJohn Forte done: 1266*45039663SJohn Forte return (rc); 1267*45039663SJohn Forte } 1268*45039663SJohn Forte 1269*45039663SJohn Forte static int 1270*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_marshal(nvlist_t *nvl, void *msg) 1271*45039663SJohn Forte { 1272*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *m = 1273*45039663SJohn Forte (stmf_ic_scsi_data_xfer_done_msg_t *)msg; 1274*45039663SJohn Forte int rc = 0; 1275*45039663SJohn Forte 1276*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_task_msgid); 1277*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_session_id); 1278*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_status); 1279*45039663SJohn Forte 1280*45039663SJohn Forte done: 1281*45039663SJohn Forte return (rc); 1282*45039663SJohn Forte } 1283*45039663SJohn Forte 1284*45039663SJohn Forte static int 1285*45039663SJohn Forte stmf_ic_scsi_status_msg_marshal(nvlist_t *nvl, void *msg) 1286*45039663SJohn Forte { 1287*45039663SJohn Forte stmf_ic_scsi_status_msg_t *m = (stmf_ic_scsi_status_msg_t *)msg; 1288*45039663SJohn Forte int rc = 0; 1289*45039663SJohn Forte 1290*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icss_task_msgid); 1291*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icss_session_id); 1292*45039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icss_lun_id); 1293*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_response); 1294*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_status); 1295*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_flags); 1296*45039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icss_resid); 1297*45039663SJohn Forte 1298*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_sense_len); 1299*45039663SJohn Forte 1300*45039663SJohn Forte if (m->icss_sense_len) 1301*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icss_sense, m->icss_sense_len); 1302*45039663SJohn Forte 1303*45039663SJohn Forte done: 1304*45039663SJohn Forte return (rc); 1305*45039663SJohn Forte } 1306*45039663SJohn Forte 1307*45039663SJohn Forte static int 1308*45039663SJohn Forte stmf_ic_r2t_msg_marshal(nvlist_t *nvl, void *msg) 1309*45039663SJohn Forte { 1310*45039663SJohn Forte stmf_ic_r2t_msg_t *m = (stmf_ic_r2t_msg_t *)msg; 1311*45039663SJohn Forte int rc = 0; 1312*45039663SJohn Forte 1313*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icrt_task_msgid); 1314*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icrt_session_id); 1315*45039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icrt_offset); 1316*45039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icrt_length); 1317*45039663SJohn Forte 1318*45039663SJohn Forte done: 1319*45039663SJohn Forte return (rc); 1320*45039663SJohn Forte } 1321*45039663SJohn Forte 1322*45039663SJohn Forte static int 1323*45039663SJohn Forte stmf_ic_status_msg_marshal(nvlist_t *nvl, void *msg) 1324*45039663SJohn Forte { 1325*45039663SJohn Forte stmf_ic_status_msg_t *m = (stmf_ic_status_msg_t *)msg; 1326*45039663SJohn Forte int rc = 0; 1327*45039663SJohn Forte 1328*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, ics_msg_type); 1329*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, ics_msgid); 1330*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, ics_status); 1331*45039663SJohn Forte 1332*45039663SJohn Forte done: 1333*45039663SJohn Forte return (rc); 1334*45039663SJohn Forte } 1335*45039663SJohn Forte 1336*45039663SJohn Forte static int 1337*45039663SJohn Forte stmf_ic_session_create_destroy_msg_marshal(nvlist_t *nvl, void *msg) 1338*45039663SJohn Forte { 1339*45039663SJohn Forte stmf_ic_session_create_destroy_msg_t *m = 1340*45039663SJohn Forte (stmf_ic_session_create_destroy_msg_t *)msg; 1341*45039663SJohn Forte int rc = 0; 1342*45039663SJohn Forte 1343*45039663SJohn Forte NVLIST_ADD_DEVID(m, icscd_ini_devid); 1344*45039663SJohn Forte NVLIST_ADD_DEVID(m, icscd_tgt_devid); 1345*45039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icscd_session_id); 1346*45039663SJohn Forte 1347*45039663SJohn Forte done: 1348*45039663SJohn Forte return (rc); 1349*45039663SJohn Forte } 1350*45039663SJohn Forte 1351*45039663SJohn Forte static int 1352*45039663SJohn Forte stmf_ic_echo_request_reply_msg_marshal(nvlist_t *nvl, void *msg) 1353*45039663SJohn Forte { 1354*45039663SJohn Forte stmf_ic_echo_request_reply_msg_t *m = msg; 1355*45039663SJohn Forte int rc = 0; 1356*45039663SJohn Forte 1357*45039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icerr_datalen); 1358*45039663SJohn Forte if (m->icerr_datalen) 1359*45039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icerr_data, m->icerr_datalen); 1360*45039663SJohn Forte 1361*45039663SJohn Forte done: 1362*45039663SJohn Forte return (rc); 1363*45039663SJohn Forte } 1364*45039663SJohn Forte 1365*45039663SJohn Forte /* 1366*45039663SJohn Forte * Allocate a new nvlist representing the scsi_devid_desc and add it 1367*45039663SJohn Forte * to the nvlist. 1368*45039663SJohn Forte */ 1369*45039663SJohn Forte static int 1370*45039663SJohn Forte stmf_ic_scsi_devid_desc_marshal(nvlist_t *parent_nvl, 1371*45039663SJohn Forte char *sdid_name, 1372*45039663SJohn Forte scsi_devid_desc_t *sdid) 1373*45039663SJohn Forte { 1374*45039663SJohn Forte int rc = 0; 1375*45039663SJohn Forte nvlist_t *nvl = NULL; 1376*45039663SJohn Forte 1377*45039663SJohn Forte rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); 1378*45039663SJohn Forte if (rc) 1379*45039663SJohn Forte goto done; 1380*45039663SJohn Forte 1381*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, protocol_id); 1382*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, code_set); 1383*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, piv); 1384*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, association); 1385*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, ident_type); 1386*45039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, ident_length); 1387*45039663SJohn Forte 1388*45039663SJohn Forte rc = nvlist_add_uint8_array(nvl, "ident", sdid->ident, 1389*45039663SJohn Forte sdid->ident_length); 1390*45039663SJohn Forte if (rc) 1391*45039663SJohn Forte goto done; 1392*45039663SJohn Forte 1393*45039663SJohn Forte rc = nvlist_add_nvlist(parent_nvl, sdid_name, nvl); 1394*45039663SJohn Forte 1395*45039663SJohn Forte done: 1396*45039663SJohn Forte if (nvl) { 1397*45039663SJohn Forte nvlist_free(nvl); 1398*45039663SJohn Forte } 1399*45039663SJohn Forte return (rc); 1400*45039663SJohn Forte } 1401*45039663SJohn Forte 1402*45039663SJohn Forte /* 1403*45039663SJohn Forte * Unmarshaling routines. 1404*45039663SJohn Forte */ 1405*45039663SJohn Forte 1406*45039663SJohn Forte static stmf_ic_msg_t * 1407*45039663SJohn Forte stmf_ic_msg_unmarshal(nvlist_t *nvl) 1408*45039663SJohn Forte { 1409*45039663SJohn Forte stmf_ic_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1410*45039663SJohn Forte uint8_t msg_type; 1411*45039663SJohn Forte int rc = 0; 1412*45039663SJohn Forte 1413*45039663SJohn Forte /* 1414*45039663SJohn Forte * We'd like to do this: 1415*45039663SJohn Forte * 1416*45039663SJohn Forte * NVLIST_LOOKUP_FIELD(uint8, m, icm_msg_type); 1417*45039663SJohn Forte * 1418*45039663SJohn Forte * but the fact that msg type is an enum causes type problems. 1419*45039663SJohn Forte */ 1420*45039663SJohn Forte rc = nvlist_lookup_uint8(nvl, "icm_msg_type", &msg_type); 1421*45039663SJohn Forte if (rc) { 1422*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icm_msg_type"); 1423*45039663SJohn Forte goto done; 1424*45039663SJohn Forte } 1425*45039663SJohn Forte 1426*45039663SJohn Forte m->icm_msg_type = msg_type; 1427*45039663SJohn Forte m->icm_nvlist = nvl; 1428*45039663SJohn Forte 1429*45039663SJohn Forte NVLIST_LOOKUP_FIELD(uint64, m, icm_msgid); 1430*45039663SJohn Forte 1431*45039663SJohn Forte switch (m->icm_msg_type) { 1432*45039663SJohn Forte 1433*45039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 1434*45039663SJohn Forte m->icm_msg = stmf_ic_reg_port_msg_unmarshal(nvl); 1435*45039663SJohn Forte break; 1436*45039663SJohn Forte 1437*45039663SJohn Forte 1438*45039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 1439*45039663SJohn Forte m->icm_msg = stmf_ic_dereg_port_msg_unmarshal(nvl); 1440*45039663SJohn Forte break; 1441*45039663SJohn Forte 1442*45039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 1443*45039663SJohn Forte case STMF_ICM_REGISTER_LUN: 1444*45039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 1445*45039663SJohn Forte m->icm_msg = stmf_ic_reg_dereg_lun_msg_unmarshal(nvl); 1446*45039663SJohn Forte break; 1447*45039663SJohn Forte 1448*45039663SJohn Forte case STMF_ICM_SCSI_CMD: 1449*45039663SJohn Forte m->icm_msg = stmf_ic_scsi_cmd_msg_unmarshal(nvl); 1450*45039663SJohn Forte break; 1451*45039663SJohn Forte 1452*45039663SJohn Forte case STMF_ICM_SCSI_DATA: 1453*45039663SJohn Forte m->icm_msg = stmf_ic_scsi_data_msg_unmarshal(nvl); 1454*45039663SJohn Forte break; 1455*45039663SJohn Forte 1456*45039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 1457*45039663SJohn Forte m->icm_msg = stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvl); 1458*45039663SJohn Forte break; 1459*45039663SJohn Forte 1460*45039663SJohn Forte case STMF_ICM_SCSI_STATUS: 1461*45039663SJohn Forte m->icm_msg = stmf_ic_scsi_status_msg_unmarshal(nvl); 1462*45039663SJohn Forte break; 1463*45039663SJohn Forte 1464*45039663SJohn Forte case STMF_ICM_R2T: 1465*45039663SJohn Forte m->icm_msg = stmf_ic_r2t_msg_unmarshal(nvl); 1466*45039663SJohn Forte break; 1467*45039663SJohn Forte 1468*45039663SJohn Forte case STMF_ICM_STATUS: 1469*45039663SJohn Forte m->icm_msg = stmf_ic_status_msg_unmarshal(nvl); 1470*45039663SJohn Forte break; 1471*45039663SJohn Forte 1472*45039663SJohn Forte case STMF_ICM_SESSION_CREATE: 1473*45039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 1474*45039663SJohn Forte m->icm_msg = stmf_ic_session_create_destroy_msg_unmarshal(nvl); 1475*45039663SJohn Forte break; 1476*45039663SJohn Forte 1477*45039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 1478*45039663SJohn Forte case STMF_ICM_ECHO_REPLY: 1479*45039663SJohn Forte m->icm_msg = stmf_ic_echo_request_reply_msg_unmarshal(nvl); 1480*45039663SJohn Forte break; 1481*45039663SJohn Forte 1482*45039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 1483*45039663SJohn Forte ASSERT(0); 1484*45039663SJohn Forte break; 1485*45039663SJohn Forte 1486*45039663SJohn Forte default: 1487*45039663SJohn Forte ASSERT(0); 1488*45039663SJohn Forte } 1489*45039663SJohn Forte 1490*45039663SJohn Forte done: 1491*45039663SJohn Forte 1492*45039663SJohn Forte if (!m->icm_msg) { 1493*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1494*45039663SJohn Forte return (NULL); 1495*45039663SJohn Forte } 1496*45039663SJohn Forte 1497*45039663SJohn Forte return (m); 1498*45039663SJohn Forte } 1499*45039663SJohn Forte 1500*45039663SJohn Forte static void * 1501*45039663SJohn Forte stmf_ic_reg_port_msg_unmarshal(nvlist_t *nvl) 1502*45039663SJohn Forte { 1503*45039663SJohn Forte nvlist_t *nvl_port_id = NULL; 1504*45039663SJohn Forte int rc = 0; 1505*45039663SJohn Forte stmf_ic_reg_port_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1506*45039663SJohn Forte 1507*45039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, "icrp_port_id", &nvl_port_id); 1508*45039663SJohn Forte if (rc) { 1509*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_port_id nvl"); 1510*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1511*45039663SJohn Forte goto done; 1512*45039663SJohn Forte } 1513*45039663SJohn Forte 1514*45039663SJohn Forte m->icrp_port_id = stmf_ic_scsi_devid_desc_unmarshal(nvl_port_id); 1515*45039663SJohn Forte if (m->icrp_port_id == NULL) { 1516*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_port_id"); 1517*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1518*45039663SJohn Forte goto done; 1519*45039663SJohn Forte } 1520*45039663SJohn Forte 1521*45039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrp_relative_port_id); 1522*45039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrp_cb_arg_len); 1523*45039663SJohn Forte 1524*45039663SJohn Forte if (m->icrp_cb_arg_len) { 1525*45039663SJohn Forte m->icrp_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 1526*45039663SJohn Forte "icrp_cb_arg", m->icrp_cb_arg_len, NULL); 1527*45039663SJohn Forte if (m->icrp_cb_arg == NULL) { 1528*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_cb_arg"); 1529*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1530*45039663SJohn Forte goto done; 1531*45039663SJohn Forte } 1532*45039663SJohn Forte } 1533*45039663SJohn Forte 1534*45039663SJohn Forte done: 1535*45039663SJohn Forte if (!rc) 1536*45039663SJohn Forte return (m); 1537*45039663SJohn Forte 1538*45039663SJohn Forte stmf_ic_reg_port_msg_free(m, STMF_UNMARSHAL); 1539*45039663SJohn Forte 1540*45039663SJohn Forte return (NULL); 1541*45039663SJohn Forte } 1542*45039663SJohn Forte 1543*45039663SJohn Forte /* 1544*45039663SJohn Forte * XXX largely the same as stmf_ic_reg_port_msg_unmarshal() 1545*45039663SJohn Forte * Common stuff should be factored out. Type issues may make this 1546*45039663SJohn Forte * painful. 1547*45039663SJohn Forte */ 1548*45039663SJohn Forte static void * 1549*45039663SJohn Forte stmf_ic_dereg_port_msg_unmarshal(nvlist_t *nvl) 1550*45039663SJohn Forte { 1551*45039663SJohn Forte nvlist_t *nvl_port_id = NULL; 1552*45039663SJohn Forte int rc = 0; 1553*45039663SJohn Forte stmf_ic_dereg_port_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1554*45039663SJohn Forte 1555*45039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, "icdp_port_id", &nvl_port_id); 1556*45039663SJohn Forte if (rc) { 1557*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_port_id nvl"); 1558*45039663SJohn Forte goto done; 1559*45039663SJohn Forte } 1560*45039663SJohn Forte 1561*45039663SJohn Forte m->icdp_port_id = stmf_ic_scsi_devid_desc_unmarshal(nvl_port_id); 1562*45039663SJohn Forte if (m->icdp_port_id == NULL) { 1563*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_port_id"); 1564*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1565*45039663SJohn Forte goto done; 1566*45039663SJohn Forte } 1567*45039663SJohn Forte 1568*45039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icdp_cb_arg_len); 1569*45039663SJohn Forte 1570*45039663SJohn Forte if (m->icdp_cb_arg_len) { 1571*45039663SJohn Forte m->icdp_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 1572*45039663SJohn Forte "icdp_cb_arg", m->icdp_cb_arg_len, NULL); 1573*45039663SJohn Forte if (m->icdp_cb_arg == NULL) { 1574*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_cb_arg"); 1575*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1576*45039663SJohn Forte goto done; 1577*45039663SJohn Forte } 1578*45039663SJohn Forte } 1579*45039663SJohn Forte 1580*45039663SJohn Forte done: 1581*45039663SJohn Forte if (!rc) 1582*45039663SJohn Forte return (m); 1583*45039663SJohn Forte 1584*45039663SJohn Forte stmf_ic_dereg_port_msg_free(m, STMF_UNMARSHAL); 1585*45039663SJohn Forte 1586*45039663SJohn Forte return (NULL); 1587*45039663SJohn Forte } 1588*45039663SJohn Forte 1589*45039663SJohn Forte static void * 1590*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_unmarshal(nvlist_t *nvl) 1591*45039663SJohn Forte { 1592*45039663SJohn Forte int rc = 0; 1593*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1594*45039663SJohn Forte 1595*45039663SJohn Forte if (! stmf_ic_uint8_array_unmarshal(nvl, "icrl_lun_id", 1596*45039663SJohn Forte sizeof (m->icrl_lun_id), m->icrl_lun_id)) { 1597*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_lun_id"); 1598*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1599*45039663SJohn Forte goto done; 1600*45039663SJohn Forte } 1601*45039663SJohn Forte 1602*45039663SJohn Forte m->icrl_lu_provider_name = stmf_ic_string_unmarshal(nvl, 1603*45039663SJohn Forte "icrl_lu_provider_name"); 1604*45039663SJohn Forte 1605*45039663SJohn Forte if (!m->icrl_lu_provider_name) { 1606*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_lu_provider_name"); 1607*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1608*45039663SJohn Forte goto done; 1609*45039663SJohn Forte } 1610*45039663SJohn Forte 1611*45039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrl_cb_arg_len); 1612*45039663SJohn Forte 1613*45039663SJohn Forte if (m->icrl_cb_arg_len) { 1614*45039663SJohn Forte m->icrl_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 1615*45039663SJohn Forte "icrl_cb_arg", m->icrl_cb_arg_len, NULL); 1616*45039663SJohn Forte if (m->icrl_cb_arg == NULL) { 1617*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_cb_arg"); 1618*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1619*45039663SJohn Forte goto done; 1620*45039663SJohn Forte } 1621*45039663SJohn Forte } 1622*45039663SJohn Forte 1623*45039663SJohn Forte done: 1624*45039663SJohn Forte if (!rc) 1625*45039663SJohn Forte return (m); 1626*45039663SJohn Forte 1627*45039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free(m, STMF_UNMARSHAL); 1628*45039663SJohn Forte 1629*45039663SJohn Forte return (NULL); 1630*45039663SJohn Forte } 1631*45039663SJohn Forte 1632*45039663SJohn Forte static void * 1633*45039663SJohn Forte stmf_ic_scsi_cmd_msg_unmarshal(nvlist_t *nvl) 1634*45039663SJohn Forte { 1635*45039663SJohn Forte int rc = 0; 1636*45039663SJohn Forte stmf_ic_scsi_cmd_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1637*45039663SJohn Forte 1638*45039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 1639*45039663SJohn Forte NV_PAIR(UINT64, m, icsc_task_msgid), 1640*45039663SJohn Forte NV_PAIR(UINT64, m, icsc_session_id), 1641*45039663SJohn Forte NV_PAIR(UINT32, m, icsc_task_expected_xfer_length), 1642*45039663SJohn Forte NV_PAIR(UINT16, m, icsc_task_cdb_length), 1643*45039663SJohn Forte NV_PAIR(UINT8, m, icsc_task_flags), 1644*45039663SJohn Forte NV_PAIR(UINT8, m, icsc_task_mgmt_function), 1645*45039663SJohn Forte NV_PAIR(UINT32, m, icsc_immed_data_len), 1646*45039663SJohn Forte NULL) != 0) { 1647*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_task_msgid and friends"); 1648*45039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 1649*45039663SJohn Forte goto done; 1650*45039663SJohn Forte } 1651*45039663SJohn Forte 1652*45039663SJohn Forte m->icsc_ini_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 1653*45039663SJohn Forte nvl, "icsc_ini_devid"); 1654*45039663SJohn Forte if (m->icsc_ini_devid == NULL) { 1655*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_ini_devid"); 1656*45039663SJohn Forte rc = ENOMEM; 1657*45039663SJohn Forte goto done; 1658*45039663SJohn Forte } 1659*45039663SJohn Forte 1660*45039663SJohn Forte m->icsc_tgt_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 1661*45039663SJohn Forte nvl, "icsc_tgt_devid"); 1662*45039663SJohn Forte if (m->icsc_tgt_devid == NULL) { 1663*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_tgt_devid"); 1664*45039663SJohn Forte rc = ENOMEM; 1665*45039663SJohn Forte goto done; 1666*45039663SJohn Forte } 1667*45039663SJohn Forte 1668*45039663SJohn Forte /* icsc_lun_id */ 1669*45039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsc_lun_id", 1670*45039663SJohn Forte sizeof (m->icsc_lun_id), m->icsc_lun_id)) { 1671*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_lun_id"); 1672*45039663SJohn Forte rc = ENOMEM; 1673*45039663SJohn Forte goto done; 1674*45039663SJohn Forte } 1675*45039663SJohn Forte 1676*45039663SJohn Forte /* icsc_task_lun_no */ 1677*45039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsc_task_lun_no", 1678*45039663SJohn Forte sizeof (m->icsc_task_lun_no), m->icsc_task_lun_no)) { 1679*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_task_lun_no"); 1680*45039663SJohn Forte rc = ENOMEM; 1681*45039663SJohn Forte goto done; 1682*45039663SJohn Forte } 1683*45039663SJohn Forte 1684*45039663SJohn Forte /* icsc_task_cdb */ 1685*45039663SJohn Forte m->icsc_task_cdb = stmf_ic_uint8_array_unmarshal(nvl, "icsc_task_cdb", 1686*45039663SJohn Forte m->icsc_task_cdb_length, NULL); 1687*45039663SJohn Forte if (!m->icsc_task_cdb) { 1688*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_task_cdb"); 1689*45039663SJohn Forte rc = ENOMEM; 1690*45039663SJohn Forte goto done; 1691*45039663SJohn Forte } 1692*45039663SJohn Forte 1693*45039663SJohn Forte /* immediate data, if there is any */ 1694*45039663SJohn Forte if (m->icsc_immed_data_len) { 1695*45039663SJohn Forte m->icsc_immed_data = stmf_ic_uint8_array_unmarshal(nvl, 1696*45039663SJohn Forte "icsc_immed_data", m->icsc_immed_data_len, NULL); 1697*45039663SJohn Forte if (!m->icsc_immed_data) { 1698*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_immed_data"); 1699*45039663SJohn Forte rc = ENOMEM; 1700*45039663SJohn Forte goto done; 1701*45039663SJohn Forte } 1702*45039663SJohn Forte } 1703*45039663SJohn Forte 1704*45039663SJohn Forte done: 1705*45039663SJohn Forte if (!rc) 1706*45039663SJohn Forte return (m); 1707*45039663SJohn Forte 1708*45039663SJohn Forte stmf_ic_scsi_cmd_msg_free(m, STMF_UNMARSHAL); 1709*45039663SJohn Forte 1710*45039663SJohn Forte return (NULL); 1711*45039663SJohn Forte } 1712*45039663SJohn Forte 1713*45039663SJohn Forte static void * 1714*45039663SJohn Forte stmf_ic_scsi_data_msg_unmarshal(nvlist_t *nvl) 1715*45039663SJohn Forte { 1716*45039663SJohn Forte int rc = 0; 1717*45039663SJohn Forte stmf_ic_scsi_data_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1718*45039663SJohn Forte 1719*45039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 1720*45039663SJohn Forte NV_PAIR(UINT64, m, icsd_task_msgid), 1721*45039663SJohn Forte NV_PAIR(UINT64, m, icsd_session_id), 1722*45039663SJohn Forte NV_PAIR(UINT64, m, icsd_data_len), 1723*45039663SJohn Forte NULL) != 0) { 1724*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_task_msgid and friends"); 1725*45039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 1726*45039663SJohn Forte goto done; 1727*45039663SJohn Forte } 1728*45039663SJohn Forte 1729*45039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsd_lun_id", 1730*45039663SJohn Forte sizeof (m->icsd_lun_id), m->icsd_lun_id)) { 1731*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_lun_id"); 1732*45039663SJohn Forte rc = ENOMEM; 1733*45039663SJohn Forte goto done; 1734*45039663SJohn Forte } 1735*45039663SJohn Forte 1736*45039663SJohn Forte m->icsd_data = stmf_ic_uint8_array_unmarshal(nvl, "icsd_data", 1737*45039663SJohn Forte m->icsd_data_len, NULL); 1738*45039663SJohn Forte if (!m->icsd_data) { 1739*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_data"); 1740*45039663SJohn Forte rc = ENOMEM; 1741*45039663SJohn Forte goto done; 1742*45039663SJohn Forte } 1743*45039663SJohn Forte 1744*45039663SJohn Forte done: 1745*45039663SJohn Forte if (!rc) 1746*45039663SJohn Forte return (m); 1747*45039663SJohn Forte 1748*45039663SJohn Forte stmf_ic_scsi_data_msg_free(m, STMF_UNMARSHAL); 1749*45039663SJohn Forte 1750*45039663SJohn Forte return (NULL); 1751*45039663SJohn Forte } 1752*45039663SJohn Forte 1753*45039663SJohn Forte static void * 1754*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvlist_t *nvl) 1755*45039663SJohn Forte { 1756*45039663SJohn Forte int rc = 0; 1757*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *m = 1758*45039663SJohn Forte kmem_zalloc(sizeof (*m), KM_SLEEP); 1759*45039663SJohn Forte 1760*45039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 1761*45039663SJohn Forte NV_PAIR(UINT64, m, icsx_task_msgid), 1762*45039663SJohn Forte NV_PAIR(UINT64, m, icsx_session_id), 1763*45039663SJohn Forte NV_PAIR(UINT64, m, icsx_status), 1764*45039663SJohn Forte NULL) != 0) { 1765*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsx_task_msgid and friends"); 1766*45039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 1767*45039663SJohn Forte goto done; 1768*45039663SJohn Forte } 1769*45039663SJohn Forte 1770*45039663SJohn Forte done: 1771*45039663SJohn Forte if (!rc) 1772*45039663SJohn Forte return (m); 1773*45039663SJohn Forte 1774*45039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free(m, STMF_UNMARSHAL); 1775*45039663SJohn Forte 1776*45039663SJohn Forte return (NULL); 1777*45039663SJohn Forte } 1778*45039663SJohn Forte 1779*45039663SJohn Forte static void * 1780*45039663SJohn Forte stmf_ic_scsi_status_msg_unmarshal(nvlist_t *nvl) 1781*45039663SJohn Forte { 1782*45039663SJohn Forte int rc = 0; 1783*45039663SJohn Forte stmf_ic_scsi_status_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1784*45039663SJohn Forte 1785*45039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 1786*45039663SJohn Forte NV_PAIR(UINT64, m, icss_task_msgid), 1787*45039663SJohn Forte NV_PAIR(UINT64, m, icss_session_id), 1788*45039663SJohn Forte NV_PAIR(UINT8, m, icss_response), 1789*45039663SJohn Forte NV_PAIR(UINT8, m, icss_status), 1790*45039663SJohn Forte NV_PAIR(UINT8, m, icss_flags), 1791*45039663SJohn Forte NV_PAIR(UINT32, m, icss_resid), 1792*45039663SJohn Forte NV_PAIR(UINT8, m, icss_sense_len), 1793*45039663SJohn Forte NULL) != 0) { 1794*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_task_msgid and friends"); 1795*45039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 1796*45039663SJohn Forte goto done; 1797*45039663SJohn Forte } 1798*45039663SJohn Forte 1799*45039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icss_lun_id", 1800*45039663SJohn Forte sizeof (m->icss_lun_id), m->icss_lun_id)) { 1801*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_lun_id"); 1802*45039663SJohn Forte rc = ENOMEM; 1803*45039663SJohn Forte goto done; 1804*45039663SJohn Forte } 1805*45039663SJohn Forte 1806*45039663SJohn Forte if (m->icss_sense_len) { 1807*45039663SJohn Forte m->icss_sense = stmf_ic_uint8_array_unmarshal(nvl, "icss_sense", 1808*45039663SJohn Forte m->icss_sense_len, NULL); 1809*45039663SJohn Forte if (!m->icss_sense) { 1810*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_sense"); 1811*45039663SJohn Forte rc = ENOMEM; 1812*45039663SJohn Forte goto done; 1813*45039663SJohn Forte } 1814*45039663SJohn Forte } 1815*45039663SJohn Forte done: 1816*45039663SJohn Forte if (!rc) 1817*45039663SJohn Forte return (m); 1818*45039663SJohn Forte 1819*45039663SJohn Forte stmf_ic_scsi_status_msg_free(m, STMF_UNMARSHAL); 1820*45039663SJohn Forte 1821*45039663SJohn Forte return (NULL); 1822*45039663SJohn Forte } 1823*45039663SJohn Forte 1824*45039663SJohn Forte static void * 1825*45039663SJohn Forte stmf_ic_r2t_msg_unmarshal(nvlist_t *nvl) 1826*45039663SJohn Forte { 1827*45039663SJohn Forte int rc = 0; 1828*45039663SJohn Forte stmf_ic_r2t_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1829*45039663SJohn Forte 1830*45039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 1831*45039663SJohn Forte NV_PAIR(UINT64, m, icrt_task_msgid), 1832*45039663SJohn Forte NV_PAIR(UINT64, m, icrt_session_id), 1833*45039663SJohn Forte NV_PAIR(UINT32, m, icrt_offset), 1834*45039663SJohn Forte NV_PAIR(UINT32, m, icrt_length), 1835*45039663SJohn Forte NULL) != 0) { 1836*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrt_task_msgid and friends"); 1837*45039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 1838*45039663SJohn Forte goto done; 1839*45039663SJohn Forte } 1840*45039663SJohn Forte 1841*45039663SJohn Forte done: 1842*45039663SJohn Forte if (!rc) 1843*45039663SJohn Forte return (m); 1844*45039663SJohn Forte 1845*45039663SJohn Forte stmf_ic_r2t_msg_free(m, STMF_UNMARSHAL); 1846*45039663SJohn Forte 1847*45039663SJohn Forte return (NULL); 1848*45039663SJohn Forte } 1849*45039663SJohn Forte 1850*45039663SJohn Forte static void * 1851*45039663SJohn Forte stmf_ic_session_create_destroy_msg_unmarshal(nvlist_t *nvl) 1852*45039663SJohn Forte { 1853*45039663SJohn Forte int rc = 0; 1854*45039663SJohn Forte stmf_ic_session_create_destroy_msg_t *m = kmem_zalloc(sizeof (*m), 1855*45039663SJohn Forte KM_SLEEP); 1856*45039663SJohn Forte 1857*45039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 1858*45039663SJohn Forte NV_PAIR(UINT64, m, icscd_session_id), 1859*45039663SJohn Forte NULL) != 0) { 1860*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_session_id"); 1861*45039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 1862*45039663SJohn Forte goto done; 1863*45039663SJohn Forte } 1864*45039663SJohn Forte 1865*45039663SJohn Forte m->icscd_ini_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 1866*45039663SJohn Forte nvl, "icscd_ini_devid"); 1867*45039663SJohn Forte if (m->icscd_ini_devid == NULL) { 1868*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_ini_devid"); 1869*45039663SJohn Forte rc = ENOMEM; 1870*45039663SJohn Forte goto done; 1871*45039663SJohn Forte } 1872*45039663SJohn Forte 1873*45039663SJohn Forte m->icscd_tgt_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 1874*45039663SJohn Forte nvl, "icscd_tgt_devid"); 1875*45039663SJohn Forte if (m->icscd_tgt_devid == NULL) { 1876*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_tgt_devid"); 1877*45039663SJohn Forte rc = ENOMEM; 1878*45039663SJohn Forte goto done; 1879*45039663SJohn Forte } 1880*45039663SJohn Forte 1881*45039663SJohn Forte done: 1882*45039663SJohn Forte if (!rc) 1883*45039663SJohn Forte return (m); 1884*45039663SJohn Forte 1885*45039663SJohn Forte stmf_ic_session_create_destroy_msg_free(m, STMF_UNMARSHAL); 1886*45039663SJohn Forte 1887*45039663SJohn Forte return (NULL); 1888*45039663SJohn Forte } 1889*45039663SJohn Forte 1890*45039663SJohn Forte static void * 1891*45039663SJohn Forte stmf_ic_echo_request_reply_msg_unmarshal(nvlist_t *nvl) 1892*45039663SJohn Forte { 1893*45039663SJohn Forte int rc = 0; 1894*45039663SJohn Forte stmf_ic_echo_request_reply_msg_t *m = kmem_zalloc(sizeof (*m), 1895*45039663SJohn Forte KM_SLEEP); 1896*45039663SJohn Forte 1897*45039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 1898*45039663SJohn Forte NV_PAIR(UINT32, m, icerr_datalen), 1899*45039663SJohn Forte NULL) != 0) { 1900*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icerr_datalen"); 1901*45039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 1902*45039663SJohn Forte goto done; 1903*45039663SJohn Forte } 1904*45039663SJohn Forte 1905*45039663SJohn Forte /* immediate data, if there is any */ 1906*45039663SJohn Forte if (m->icerr_datalen) { 1907*45039663SJohn Forte m->icerr_data = stmf_ic_uint8_array_unmarshal(nvl, 1908*45039663SJohn Forte "icerr_data", m->icerr_datalen, NULL); 1909*45039663SJohn Forte if (!m->icerr_data) { 1910*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icerr_data"); 1911*45039663SJohn Forte rc = ENOMEM; 1912*45039663SJohn Forte goto done; 1913*45039663SJohn Forte } 1914*45039663SJohn Forte } 1915*45039663SJohn Forte 1916*45039663SJohn Forte done: 1917*45039663SJohn Forte if (!rc) 1918*45039663SJohn Forte return (m); 1919*45039663SJohn Forte 1920*45039663SJohn Forte stmf_ic_echo_request_reply_msg_free(m, STMF_UNMARSHAL); 1921*45039663SJohn Forte 1922*45039663SJohn Forte return (NULL); 1923*45039663SJohn Forte } 1924*45039663SJohn Forte 1925*45039663SJohn Forte static void * 1926*45039663SJohn Forte stmf_ic_status_msg_unmarshal(nvlist_t *nvl) 1927*45039663SJohn Forte { 1928*45039663SJohn Forte int rc = 0; 1929*45039663SJohn Forte stmf_ic_status_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 1930*45039663SJohn Forte 1931*45039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 1932*45039663SJohn Forte NV_PAIR(UINT8, m, ics_msg_type), 1933*45039663SJohn Forte NV_PAIR(UINT64, m, ics_msgid), 1934*45039663SJohn Forte NV_PAIR(UINT8, m, ics_status), 1935*45039663SJohn Forte NULL) != 0) { 1936*45039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "ics_msg_type and friends"); 1937*45039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 1938*45039663SJohn Forte goto done; 1939*45039663SJohn Forte } 1940*45039663SJohn Forte 1941*45039663SJohn Forte done: 1942*45039663SJohn Forte if (!rc) 1943*45039663SJohn Forte return (m); 1944*45039663SJohn Forte 1945*45039663SJohn Forte kmem_free(m, sizeof (*m)); 1946*45039663SJohn Forte return (NULL); 1947*45039663SJohn Forte } 1948*45039663SJohn Forte 1949*45039663SJohn Forte 1950*45039663SJohn Forte static scsi_devid_desc_t * 1951*45039663SJohn Forte stmf_ic_lookup_scsi_devid_desc_and_unmarshal(nvlist_t *nvl, char *field_name) 1952*45039663SJohn Forte { 1953*45039663SJohn Forte nvlist_t *nvl_devid = NULL; 1954*45039663SJohn Forte scsi_devid_desc_t *did = NULL; 1955*45039663SJohn Forte int rc; 1956*45039663SJohn Forte 1957*45039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, field_name, &nvl_devid); 1958*45039663SJohn Forte if (rc) { 1959*45039663SJohn Forte goto done; 1960*45039663SJohn Forte } 1961*45039663SJohn Forte 1962*45039663SJohn Forte did = stmf_ic_scsi_devid_desc_unmarshal(nvl_devid); 1963*45039663SJohn Forte 1964*45039663SJohn Forte done: 1965*45039663SJohn Forte return (did); 1966*45039663SJohn Forte } 1967*45039663SJohn Forte 1968*45039663SJohn Forte 1969*45039663SJohn Forte static scsi_devid_desc_t * 1970*45039663SJohn Forte stmf_ic_scsi_devid_desc_unmarshal(nvlist_t *nvl) 1971*45039663SJohn Forte { 1972*45039663SJohn Forte scsi_devid_desc_t *sdid = NULL; 1973*45039663SJohn Forte uint8_t ident_length = 0; 1974*45039663SJohn Forte size_t sdid_size; 1975*45039663SJohn Forte int rc = 0; 1976*45039663SJohn Forte 1977*45039663SJohn Forte /* 1978*45039663SJohn Forte * we get the ident_length first, since that's the only 1979*45039663SJohn Forte * variable-sized field in the struct. 1980*45039663SJohn Forte */ 1981*45039663SJohn Forte rc = nvlist_lookup_uint8(nvl, "ident_length", &ident_length); 1982*45039663SJohn Forte if (rc) 1983*45039663SJohn Forte goto done; 1984*45039663SJohn Forte 1985*45039663SJohn Forte sdid_size = sizeof_scsi_devid_desc(ident_length); 1986*45039663SJohn Forte sdid = kmem_zalloc(sdid_size, KM_SLEEP); 1987*45039663SJohn Forte 1988*45039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, protocol_id); 1989*45039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, code_set); 1990*45039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, piv); 1991*45039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, association); 1992*45039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, ident_type); 1993*45039663SJohn Forte 1994*45039663SJohn Forte sdid->ident_length = ident_length; 1995*45039663SJohn Forte 1996*45039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "ident", 1997*45039663SJohn Forte sdid->ident_length, sdid->ident)) { 1998*45039663SJohn Forte rc = ENOMEM; /* XXX */ 1999*45039663SJohn Forte goto done; 2000*45039663SJohn Forte } 2001*45039663SJohn Forte 2002*45039663SJohn Forte done: 2003*45039663SJohn Forte if (!rc) 2004*45039663SJohn Forte return (sdid); 2005*45039663SJohn Forte 2006*45039663SJohn Forte kmem_free(sdid, sdid_size); 2007*45039663SJohn Forte 2008*45039663SJohn Forte return (NULL); 2009*45039663SJohn Forte } 2010*45039663SJohn Forte 2011*45039663SJohn Forte /* 2012*45039663SJohn Forte * Unmarshal a uint8_t array. 2013*45039663SJohn Forte * 2014*45039663SJohn Forte * Takes a buf argument: 2015*45039663SJohn Forte * 2016*45039663SJohn Forte * - if non-null, the array contents are copied into the buf, 2017*45039663SJohn Forte * and we return a pointer to the buffer. 2018*45039663SJohn Forte * 2019*45039663SJohn Forte * - if null, we return a pointer to the unmarshaled data, which 2020*45039663SJohn Forte * resides in the nvlist. 2021*45039663SJohn Forte * 2022*45039663SJohn Forte * Returns NULL on failure. 2023*45039663SJohn Forte */ 2024*45039663SJohn Forte static uint8_t * 2025*45039663SJohn Forte stmf_ic_uint8_array_unmarshal( 2026*45039663SJohn Forte nvlist_t *nvl, 2027*45039663SJohn Forte char *field_name, 2028*45039663SJohn Forte uint16_t len, 2029*45039663SJohn Forte uint8_t *buf) /* non-NULL: copy array into buf */ 2030*45039663SJohn Forte { 2031*45039663SJohn Forte uint8_t *array = NULL; 2032*45039663SJohn Forte uint_t actual_len; 2033*45039663SJohn Forte int rc = 0; 2034*45039663SJohn Forte 2035*45039663SJohn Forte rc = nvlist_lookup_uint8_array(nvl, field_name, &array, &actual_len); 2036*45039663SJohn Forte if (rc) { 2037*45039663SJohn Forte return (NULL); 2038*45039663SJohn Forte } 2039*45039663SJohn Forte 2040*45039663SJohn Forte if (len != actual_len) { 2041*45039663SJohn Forte cmn_err(CE_WARN, 2042*45039663SJohn Forte "stmf_ic_uint8_array_unmarshal: wrong len (%d != %d)", 2043*45039663SJohn Forte len, actual_len); 2044*45039663SJohn Forte return (NULL); 2045*45039663SJohn Forte } 2046*45039663SJohn Forte 2047*45039663SJohn Forte if (buf) { 2048*45039663SJohn Forte /* preallocated buf, copy in */ 2049*45039663SJohn Forte bcopy(array, buf, len); 2050*45039663SJohn Forte } else { 2051*45039663SJohn Forte /* return a pointer to the underlying array in the nvlist */ 2052*45039663SJohn Forte buf = array; 2053*45039663SJohn Forte } 2054*45039663SJohn Forte 2055*45039663SJohn Forte return (buf); 2056*45039663SJohn Forte } 2057*45039663SJohn Forte 2058*45039663SJohn Forte /* 2059*45039663SJohn Forte * Unmarshal a string. 2060*45039663SJohn Forte * 2061*45039663SJohn Forte * Returns NULL on failure. 2062*45039663SJohn Forte */ 2063*45039663SJohn Forte static char * 2064*45039663SJohn Forte stmf_ic_string_unmarshal( 2065*45039663SJohn Forte nvlist_t *nvl, 2066*45039663SJohn Forte char *field_name) 2067*45039663SJohn Forte { 2068*45039663SJohn Forte char *s = NULL; 2069*45039663SJohn Forte int rc = 0; 2070*45039663SJohn Forte 2071*45039663SJohn Forte rc = nvlist_lookup_string(nvl, field_name, &s); 2072*45039663SJohn Forte if (rc) { 2073*45039663SJohn Forte return (NULL); 2074*45039663SJohn Forte } 2075*45039663SJohn Forte 2076*45039663SJohn Forte return (s); 2077*45039663SJohn Forte } 2078*45039663SJohn Forte 2079*45039663SJohn Forte /* 2080*45039663SJohn Forte * Utility routines. 2081*45039663SJohn Forte */ 2082*45039663SJohn Forte 2083*45039663SJohn Forte static stmf_ic_msg_t * 2084*45039663SJohn Forte stmf_ic_alloc_msg_header( 2085*45039663SJohn Forte stmf_ic_msg_type_t msg_type, 2086*45039663SJohn Forte stmf_ic_msgid_t msgid) 2087*45039663SJohn Forte { 2088*45039663SJohn Forte stmf_ic_msg_t *icm; 2089*45039663SJohn Forte 2090*45039663SJohn Forte icm = (stmf_ic_msg_t *)kmem_zalloc(sizeof (*icm), KM_SLEEP); 2091*45039663SJohn Forte icm->icm_msg_type = msg_type; 2092*45039663SJohn Forte icm->icm_msgid = msgid; 2093*45039663SJohn Forte 2094*45039663SJohn Forte return (icm); 2095*45039663SJohn Forte } 2096*45039663SJohn Forte 2097*45039663SJohn Forte static size_t 2098*45039663SJohn Forte sizeof_scsi_devid_desc(int ident_length) 2099*45039663SJohn Forte { 2100*45039663SJohn Forte int num_ident_elems; 2101*45039663SJohn Forte size_t size; 2102*45039663SJohn Forte 2103*45039663SJohn Forte ASSERT(ident_length > 0); 2104*45039663SJohn Forte 2105*45039663SJohn Forte /* 2106*45039663SJohn Forte * Need to account for the fact that there's 2107*45039663SJohn Forte * already a single element in scsi_devid_desc_t. 2108*45039663SJohn Forte * 2109*45039663SJohn Forte * XXX would really like to have a way to determine the 2110*45039663SJohn Forte * sizeof (struct scsi_devid_desc.ident[0]), but 2111*45039663SJohn Forte * it's not clear that can be done. 2112*45039663SJohn Forte * Thus, this code relies on the knowledge of the type of 2113*45039663SJohn Forte * that field. 2114*45039663SJohn Forte */ 2115*45039663SJohn Forte num_ident_elems = ident_length - 1; 2116*45039663SJohn Forte size = sizeof (scsi_devid_desc_t) + 2117*45039663SJohn Forte (num_ident_elems * sizeof (uint8_t)); 2118*45039663SJohn Forte 2119*45039663SJohn Forte return (size); 2120*45039663SJohn Forte } 2121*45039663SJohn Forte 2122*45039663SJohn Forte 2123*45039663SJohn Forte /* 2124*45039663SJohn Forte * Duplicate the scsi_devid_desc_t. 2125*45039663SJohn Forte */ 2126*45039663SJohn Forte static scsi_devid_desc_t * 2127*45039663SJohn Forte scsi_devid_desc_dup(scsi_devid_desc_t *did) 2128*45039663SJohn Forte { 2129*45039663SJohn Forte scsi_devid_desc_t *dup; 2130*45039663SJohn Forte size_t dup_size; 2131*45039663SJohn Forte 2132*45039663SJohn Forte ASSERT(did->ident_length > 0); 2133*45039663SJohn Forte 2134*45039663SJohn Forte dup_size = sizeof_scsi_devid_desc(did->ident_length); 2135*45039663SJohn Forte dup = (scsi_devid_desc_t *)kmem_zalloc(dup_size, KM_SLEEP); 2136*45039663SJohn Forte bcopy(did, dup, dup_size); 2137*45039663SJohn Forte return (dup); 2138*45039663SJohn Forte } 2139*45039663SJohn Forte 2140*45039663SJohn Forte /* 2141*45039663SJohn Forte * May be called with a null pointer. 2142*45039663SJohn Forte */ 2143*45039663SJohn Forte static void 2144*45039663SJohn Forte scsi_devid_desc_free(scsi_devid_desc_t *did) 2145*45039663SJohn Forte { 2146*45039663SJohn Forte if (!did) 2147*45039663SJohn Forte return; 2148*45039663SJohn Forte 2149*45039663SJohn Forte kmem_free(did, sizeof_scsi_devid_desc(did->ident_length)); 2150*45039663SJohn Forte } 2151*45039663SJohn Forte 2152*45039663SJohn Forte /* 2153*45039663SJohn Forte * Helper functions, returns NULL if no memory. 2154*45039663SJohn Forte */ 2155*45039663SJohn Forte static char * 2156*45039663SJohn Forte stmf_ic_strdup(char *str) 2157*45039663SJohn Forte { 2158*45039663SJohn Forte char *copy; 2159*45039663SJohn Forte 2160*45039663SJohn Forte ASSERT(str); 2161*45039663SJohn Forte 2162*45039663SJohn Forte copy = kmem_zalloc(strlen(str) + 1, KM_SLEEP); 2163*45039663SJohn Forte (void) strcpy(copy, str); 2164*45039663SJohn Forte return (copy); 2165*45039663SJohn Forte } 2166*45039663SJohn Forte 2167*45039663SJohn Forte static inline void 2168*45039663SJohn Forte stmf_ic_nvlookup_warn(const char *func, char *field) 2169*45039663SJohn Forte { 2170*45039663SJohn Forte cmn_err(CE_WARN, "%s: nvlist lookup of %s failed", func, field); 2171*45039663SJohn Forte } 2172