145039663SJohn Forte /* 245039663SJohn Forte * CDDL HEADER START 345039663SJohn Forte * 445039663SJohn Forte * The contents of this file are subject to the terms of the 545039663SJohn Forte * Common Development and Distribution License (the "License"). 645039663SJohn Forte * You may not use this file except in compliance with the License. 745039663SJohn Forte * 845039663SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 945039663SJohn Forte * or http://www.opensolaris.org/os/licensing. 1045039663SJohn Forte * See the License for the specific language governing permissions 1145039663SJohn Forte * and limitations under the License. 1245039663SJohn Forte * 1345039663SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 1445039663SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1545039663SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 1645039663SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 1745039663SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 1845039663SJohn Forte * 1945039663SJohn Forte * CDDL HEADER END 2045039663SJohn Forte */ 2145039663SJohn Forte /* 2291159e90SJohn Forte * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2345039663SJohn Forte */ 2445039663SJohn Forte 2545039663SJohn Forte /* 2645039663SJohn Forte * XXX TODO 2745039663SJohn Forte * #includes cribbed from stmf.c -- undoubtedly only a small subset of these 2845039663SJohn Forte * are actually needed. 2945039663SJohn Forte */ 3045039663SJohn Forte #include <sys/conf.h> 3145039663SJohn Forte #include <sys/file.h> 3245039663SJohn Forte #include <sys/ddi.h> 3345039663SJohn Forte #include <sys/sunddi.h> 3445039663SJohn Forte #include <sys/scsi/scsi.h> 35*716c1805SNattuvetty Bhavyan #include <sys/scsi/generic/persist.h> 3645039663SJohn Forte #include <sys/byteorder.h> 3745039663SJohn Forte #include <sys/nvpair.h> 3845039663SJohn Forte #include <sys/door.h> 3945039663SJohn Forte 4045039663SJohn Forte #include <sys/stmf.h> 4145039663SJohn Forte #include <sys/lpif.h> 4245039663SJohn Forte #include <sys/stmf_ioctl.h> 4345039663SJohn Forte #include <sys/portif.h> 4445039663SJohn Forte #include <sys/pppt_ic_if.h> 4545039663SJohn Forte 464558d122SViswanathan Kannappan #include "pppt.h" 4745039663SJohn Forte 4845039663SJohn Forte /* 4945039663SJohn Forte * Macros 5045039663SJohn Forte */ 5145039663SJohn Forte 5245039663SJohn Forte /* Free a struct if it was allocated */ 5345039663SJohn Forte #define FREE_IF_ALLOC(m) \ 5445039663SJohn Forte do { \ 5545039663SJohn Forte if ((m)) kmem_free((m), sizeof (*(m))); \ 5645039663SJohn Forte _NOTE(CONSTCOND) \ 5745039663SJohn Forte } while (0) 5845039663SJohn Forte 5945039663SJohn Forte /* 6045039663SJohn Forte * Macros to simplify the addition of struct fields to an nvlist. 6145039663SJohn Forte * The name of the fields in the nvlist is the same as the name 6245039663SJohn Forte * of the struct field. 6345039663SJohn Forte * 6445039663SJohn Forte * These macros require an int rc and a "done:" return retval label; 6545039663SJohn Forte * they assume that the nvlist is named "nvl". 6645039663SJohn Forte */ 6745039663SJohn Forte #define NVLIST_ADD_FIELD(type, structure, field) \ 6845039663SJohn Forte do { \ 6945039663SJohn Forte rc = nvlist_add_##type(nvl, #field, structure->field); \ 7045039663SJohn Forte if (rc) goto done; \ 7145039663SJohn Forte _NOTE(CONSTCOND) \ 7245039663SJohn Forte } while (0) 7345039663SJohn Forte 7445039663SJohn Forte /* use this macro when the array is defined as part of the struct */ 7545039663SJohn Forte #define NVLIST_ADD_ARRAY(type, structure, field) \ 7645039663SJohn Forte do { \ 7745039663SJohn Forte rc = nvlist_add_##type##_array(nvl, #field, \ 7845039663SJohn Forte structure->field, sizeof (structure->field)); \ 7945039663SJohn Forte if (rc) goto done; \ 8045039663SJohn Forte _NOTE(CONSTCOND) \ 8145039663SJohn Forte } while (0) 8245039663SJohn Forte 8345039663SJohn Forte /* 8445039663SJohn Forte * use this macro when the array field is a ptr or you need to explictly 8545039663SJohn Forte * call out the size. 8645039663SJohn Forte */ 8745039663SJohn Forte #define NVLIST_ADD_ARRAY_LEN(type, structure, field, len) \ 8845039663SJohn Forte do { \ 8945039663SJohn Forte rc = nvlist_add_##type##_array(nvl, #field, \ 9045039663SJohn Forte structure->field, len); \ 9145039663SJohn Forte if (rc) goto done; \ 9245039663SJohn Forte _NOTE(CONSTCOND) \ 9345039663SJohn Forte } while (0) 9445039663SJohn Forte 9545039663SJohn Forte #define NVLIST_ADD_DEVID(structure, field) \ 9645039663SJohn Forte do { \ 9745039663SJohn Forte rc = stmf_ic_scsi_devid_desc_marshal(nvl, #field, \ 9845039663SJohn Forte structure->field); \ 9945039663SJohn Forte if (rc) goto done; \ 10045039663SJohn Forte _NOTE(CONSTCOND) \ 10145039663SJohn Forte } while (0) 10245039663SJohn Forte 103*716c1805SNattuvetty Bhavyan #define NVLIST_ADD_RPORT(structure, field) \ 104*716c1805SNattuvetty Bhavyan do { \ 105*716c1805SNattuvetty Bhavyan rc = stmf_ic_remote_port_marshal(nvl, #field, \ 106*716c1805SNattuvetty Bhavyan structure->field); \ 107*716c1805SNattuvetty Bhavyan if (rc) goto done; \ 108*716c1805SNattuvetty Bhavyan _NOTE(CONSTCOND) \ 109*716c1805SNattuvetty Bhavyan } while (0) 110*716c1805SNattuvetty Bhavyan 11145039663SJohn Forte #define NVLIST_ADD_FIELD_UINT8(structure, field) \ 11245039663SJohn Forte NVLIST_ADD_FIELD(structure, field, uint8) 11345039663SJohn Forte 11445039663SJohn Forte /* 11545039663SJohn Forte * Macros to simplify the extraction of struct fields from an nvlist. 11645039663SJohn Forte * The name of the fields in the nvlist is the same as the name 11745039663SJohn Forte * of the struct field. 11845039663SJohn Forte * 11945039663SJohn Forte * Requires an int rc and a "done:" return retval label. 12045039663SJohn Forte * Assumes that the nvlist is named "nvl". 12145039663SJohn Forte * 12245039663SJohn Forte * Sample usage: NVLIST_LOOKUP_FIELD(uint8, structname, fieldname); 12345039663SJohn Forte */ 12445039663SJohn Forte #define NVLIST_LOOKUP_FIELD(type, structure, field) \ 12545039663SJohn Forte do { \ 12645039663SJohn Forte rc = nvlist_lookup_##type(nvl, #field, \ 12745039663SJohn Forte &(structure->field)); \ 12845039663SJohn Forte if (rc) { \ 12945039663SJohn Forte stmf_ic_nvlookup_warn(__func__, #field); \ 13045039663SJohn Forte goto done; \ 13145039663SJohn Forte } \ 13245039663SJohn Forte _NOTE(CONSTCOND) \ 13345039663SJohn Forte } while (0) 13445039663SJohn Forte 13545039663SJohn Forte /* 13645039663SJohn Forte * Look up a field which gets stored into a structure bit field. 13745039663SJohn Forte * The type passed is a uint type which can hold the largest value 13845039663SJohn Forte * in the bit field. 13945039663SJohn Forte * 14045039663SJohn Forte * Requires an int rc and a "done:" return retval label. 14145039663SJohn Forte * Assumes that the nvlist is named "nvl". 14245039663SJohn Forte * 14345039663SJohn Forte * Sample usage: NVLIST_LOOKUP_BIT_FIELD(uint8, structname, fieldname); 14445039663SJohn Forte */ 14545039663SJohn Forte #define NVLIST_LOOKUP_BIT_FIELD(type, structure, field) \ 14645039663SJohn Forte do { \ 14745039663SJohn Forte type##_t tmp; \ 14845039663SJohn Forte rc = nvlist_lookup_##type(nvl, #field, &tmp); \ 14945039663SJohn Forte if (rc) { \ 15045039663SJohn Forte stmf_ic_nvlookup_warn(__func__, #field); \ 15145039663SJohn Forte goto done; \ 15245039663SJohn Forte } \ 15345039663SJohn Forte structure->field = tmp; \ 15445039663SJohn Forte _NOTE(CONSTCOND) \ 15545039663SJohn Forte } while (0) 15645039663SJohn Forte 15745039663SJohn Forte /* 15845039663SJohn Forte * Look up a boolean field which gets stored into a structure bit field. 15945039663SJohn Forte * 16045039663SJohn Forte * Requires an int rc and a "done:" return retval label. 16145039663SJohn Forte * Assumes that the nvlist is named "nvl". 16245039663SJohn Forte */ 16345039663SJohn Forte #define NVLIST_LOOKUP_BIT_FIELD_BOOLEAN(structure, field) \ 16445039663SJohn Forte do { \ 16545039663SJohn Forte boolean_t tmp; \ 16645039663SJohn Forte rc = nvlist_lookup_boolean_value(nvl, #field, &tmp); \ 16745039663SJohn Forte if (rc) { \ 16845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, #field); \ 16945039663SJohn Forte goto done; \ 17045039663SJohn Forte } \ 17145039663SJohn Forte structure->field = (tmp ? 1 : 0); \ 17245039663SJohn Forte _NOTE(CONSTCOND) \ 17345039663SJohn Forte } while (0) 17445039663SJohn Forte 17545039663SJohn Forte /* shorthand for nvlist_lookup_pairs() args */ 17645039663SJohn Forte #define NV_PAIR(type, strct, field) #field, DATA_TYPE_##type, &(strct->field) 17745039663SJohn Forte 17845039663SJohn Forte /* number of times to retry the upcall to transmit */ 17945039663SJohn Forte #define STMF_MSG_TRANSMIT_RETRY 3 18045039663SJohn Forte 18145039663SJohn Forte /* 18245039663SJohn Forte * How was the message constructed? 18345039663SJohn Forte * 18445039663SJohn Forte * We need to know this when we free the message in order to 18545039663SJohn Forte * determine what to do with pointers in the message: 18645039663SJohn Forte * 18745039663SJohn Forte * - messages which were unmarshaled from an nvlist may point to 18845039663SJohn Forte * memory within that nvlist; this memory should not be freed since 18945039663SJohn Forte * it will be deallocated when we free the nvlist. 19045039663SJohn Forte * 19145039663SJohn Forte * - messages which built using a constructor (alloc) function may 19245039663SJohn Forte * point to memory which was explicitly allocated by the constructor; 19345039663SJohn Forte * it should be freed when the message is freed. 19445039663SJohn Forte * 19545039663SJohn Forte */ 19645039663SJohn Forte typedef enum { 19745039663SJohn Forte STMF_CONSTRUCTOR = 0, 19845039663SJohn Forte STMF_UNMARSHAL 19945039663SJohn Forte } stmf_ic_msg_construction_method_t; 20045039663SJohn Forte 20145039663SJohn Forte 20245039663SJohn Forte /* 20345039663SJohn Forte * Function prototypes. 20445039663SJohn Forte */ 20545039663SJohn Forte 20645039663SJohn Forte /* 20745039663SJohn Forte * Helpers for msg_alloc routines, used when the msg payload is 20845039663SJohn Forte * the same for multiple types of messages. 20945039663SJohn Forte */ 21045039663SJohn Forte static stmf_ic_msg_t *stmf_ic_reg_dereg_lun_msg_alloc( 21145039663SJohn Forte stmf_ic_msg_type_t msg_type, uint8_t *lun_id, 21245039663SJohn Forte char *lu_provider_name, uint16_t cb_arg_len, 21345039663SJohn Forte uint8_t *cb_arg, stmf_ic_msgid_t msgid); 21445039663SJohn Forte 21545039663SJohn Forte static stmf_ic_msg_t *stmf_ic_session_create_destroy_msg_alloc( 21645039663SJohn Forte stmf_ic_msg_type_t msg_type, 21745039663SJohn Forte stmf_scsi_session_t *session, 21845039663SJohn Forte stmf_ic_msgid_t msgid); 21945039663SJohn Forte 22045039663SJohn Forte static stmf_ic_msg_t *stmf_ic_echo_request_reply_msg_alloc( 22145039663SJohn Forte stmf_ic_msg_type_t msg_type, 22245039663SJohn Forte uint32_t data_len, 22345039663SJohn Forte uint8_t *data, 22445039663SJohn Forte stmf_ic_msgid_t msgid); 22545039663SJohn Forte 22645039663SJohn Forte /* 22745039663SJohn Forte * Msg free routines. 22845039663SJohn Forte */ 22945039663SJohn Forte static void stmf_ic_reg_port_msg_free(stmf_ic_reg_port_msg_t *m, 23045039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 23145039663SJohn Forte static void stmf_ic_dereg_port_msg_free(stmf_ic_dereg_port_msg_t *m, 23245039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 23345039663SJohn Forte static void stmf_ic_reg_dereg_lun_msg_free(stmf_ic_reg_dereg_lun_msg_t *m, 23445039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 23545039663SJohn Forte static void stmf_ic_scsi_cmd_msg_free(stmf_ic_scsi_cmd_msg_t *m, 23645039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 23745039663SJohn Forte static void stmf_ic_scsi_data_msg_free(stmf_ic_scsi_data_msg_t *m, 23845039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 23945039663SJohn Forte static void stmf_ic_scsi_data_xfer_done_msg_free( 24045039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *m, 24145039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 24245039663SJohn Forte static void stmf_ic_scsi_status_msg_free(stmf_ic_scsi_status_msg_t *m, 24345039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 24445039663SJohn Forte static void stmf_ic_r2t_msg_free(stmf_ic_r2t_msg_t *m, 24545039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 24645039663SJohn Forte static void stmf_ic_status_msg_free(stmf_ic_status_msg_t *m, 24745039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 24845039663SJohn Forte static void stmf_ic_session_create_destroy_msg_free( 24945039663SJohn Forte stmf_ic_session_create_destroy_msg_t *m, 25045039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 25145039663SJohn Forte static void stmf_ic_echo_request_reply_msg_free( 25245039663SJohn Forte stmf_ic_echo_request_reply_msg_t *m, 25345039663SJohn Forte stmf_ic_msg_construction_method_t cmethod); 25445039663SJohn Forte 25545039663SJohn Forte /* 25645039663SJohn Forte * Marshaling routines. 25745039663SJohn Forte */ 25845039663SJohn Forte static nvlist_t *stmf_ic_msg_marshal(stmf_ic_msg_t *msg); 25945039663SJohn Forte static int stmf_ic_reg_port_msg_marshal(nvlist_t *nvl, void *msg); 26045039663SJohn Forte static int stmf_ic_dereg_port_msg_marshal(nvlist_t *nvl, void *msg); 26145039663SJohn Forte static int stmf_ic_reg_dereg_lun_msg_marshal(nvlist_t *nvl, void *msg); 26245039663SJohn Forte static int stmf_ic_scsi_cmd_msg_marshal(nvlist_t *nvl, void *msg); 26345039663SJohn Forte static int stmf_ic_scsi_data_msg_marshal(nvlist_t *nvl, void *msg); 26445039663SJohn Forte static int stmf_ic_scsi_data_xfer_done_msg_marshal(nvlist_t *nvl, void *msg); 26545039663SJohn Forte static int stmf_ic_scsi_status_msg_marshal(nvlist_t *nvl, void *msg); 26645039663SJohn Forte static int stmf_ic_r2t_msg_marshal(nvlist_t *nvl, void *msg); 26745039663SJohn Forte static int stmf_ic_status_msg_marshal(nvlist_t *nvl, void *msg); 26845039663SJohn Forte static int stmf_ic_session_create_destroy_msg_marshal(nvlist_t *nvl, void *msg); 26945039663SJohn Forte static int stmf_ic_echo_request_reply_msg_marshal(nvlist_t *nvl, void *msg); 27045039663SJohn Forte static int stmf_ic_scsi_devid_desc_marshal(nvlist_t *parent_nvl, 27145039663SJohn Forte char *sdid_name, scsi_devid_desc_t *sdid); 272*716c1805SNattuvetty Bhavyan static int stmf_ic_remote_port_marshal(nvlist_t *parent_nvl, 273*716c1805SNattuvetty Bhavyan char *rport_name, stmf_remote_port_t *rport); 27445039663SJohn Forte 27545039663SJohn Forte /* 27645039663SJohn Forte * Unmarshaling routines. 27745039663SJohn Forte */ 27845039663SJohn Forte static stmf_ic_msg_t *stmf_ic_msg_unmarshal(nvlist_t *nvl); 27945039663SJohn Forte static void *stmf_ic_reg_port_msg_unmarshal(nvlist_t *nvl); 28045039663SJohn Forte static void *stmf_ic_dereg_port_msg_unmarshal(nvlist_t *nvl); 28145039663SJohn Forte static void *stmf_ic_reg_dereg_lun_msg_unmarshal(nvlist_t *nvl); 28245039663SJohn Forte static void *stmf_ic_scsi_cmd_msg_unmarshal(nvlist_t *nvl); 28345039663SJohn Forte static void *stmf_ic_scsi_data_msg_unmarshal(nvlist_t *nvl); 28445039663SJohn Forte static void *stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvlist_t *nvl); 28545039663SJohn Forte static void *stmf_ic_scsi_status_msg_unmarshal(nvlist_t *nvl); 28645039663SJohn Forte static void *stmf_ic_r2t_msg_unmarshal(nvlist_t *nvl); 28745039663SJohn Forte static void *stmf_ic_status_msg_unmarshal(nvlist_t *nvl); 28845039663SJohn Forte static void *stmf_ic_session_create_destroy_msg_unmarshal(nvlist_t *nvl); 28945039663SJohn Forte static void *stmf_ic_echo_request_reply_msg_unmarshal(nvlist_t *nvl); 29045039663SJohn Forte static scsi_devid_desc_t *stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 29145039663SJohn Forte nvlist_t *nvl, char *field_name); 29245039663SJohn Forte static scsi_devid_desc_t *stmf_ic_scsi_devid_desc_unmarshal( 29345039663SJohn Forte nvlist_t *nvl_devid); 29445039663SJohn Forte static uint8_t *stmf_ic_uint8_array_unmarshal(nvlist_t *nvl, char *field_name, 29591159e90SJohn Forte uint64_t len, uint8_t *buf); 29645039663SJohn Forte static char *stmf_ic_string_unmarshal(nvlist_t *nvl, char *field_name); 297*716c1805SNattuvetty Bhavyan static stmf_remote_port_t *stmf_ic_lookup_remote_port_and_unmarshal( 298*716c1805SNattuvetty Bhavyan nvlist_t *nvl, char *field_name); 299*716c1805SNattuvetty Bhavyan static stmf_remote_port_t *stmf_ic_remote_port_unmarshal(nvlist_t *nvl); 30045039663SJohn Forte 30145039663SJohn Forte /* 30245039663SJohn Forte * Transmit and recieve routines. 30345039663SJohn Forte */ 30445039663SJohn Forte stmf_ic_msg_status_t stmf_ic_transmit(char *buf, size_t size); 30545039663SJohn Forte 30645039663SJohn Forte /* 30745039663SJohn Forte * Utilities. 30845039663SJohn Forte */ 30945039663SJohn Forte static stmf_ic_msg_t *stmf_ic_alloc_msg_header(stmf_ic_msg_type_t msg_type, 31045039663SJohn Forte stmf_ic_msgid_t msgid); 31145039663SJohn Forte static size_t sizeof_scsi_devid_desc(int ident_length); 31245039663SJohn Forte static char *stmf_ic_strdup(char *str); 31345039663SJohn Forte static scsi_devid_desc_t *scsi_devid_desc_dup(scsi_devid_desc_t *did); 314*716c1805SNattuvetty Bhavyan static stmf_remote_port_t *remote_port_dup(stmf_remote_port_t *rport); 31545039663SJohn Forte static void scsi_devid_desc_free(scsi_devid_desc_t *did); 31645039663SJohn Forte static inline void stmf_ic_nvlookup_warn(const char *func, char *field); 31745039663SJohn Forte 31845039663SJohn Forte /* 31945039663SJohn Forte * Send a message out over the interconnect, in the process marshalling 32045039663SJohn Forte * the arguments. 32145039663SJohn Forte * 32245039663SJohn Forte * After being sent, the message is freed. 32345039663SJohn Forte */ 32445039663SJohn Forte stmf_ic_msg_status_t 32545039663SJohn Forte stmf_ic_tx_msg(stmf_ic_msg_t *msg) 32645039663SJohn Forte { 32745039663SJohn Forte size_t size = 0; 32845039663SJohn Forte nvlist_t *nvl = NULL; 32945039663SJohn Forte char *buf = NULL; 33045039663SJohn Forte int err = 0; 33145039663SJohn Forte stmf_ic_msg_status_t status = STMF_IC_MSG_SUCCESS; 33245039663SJohn Forte 33345039663SJohn Forte nvl = stmf_ic_msg_marshal(msg); 33445039663SJohn Forte if (!nvl) { 33545039663SJohn Forte cmn_err(CE_WARN, "stmf_ic_tx_msg: marshal failed"); 33645039663SJohn Forte status = STMF_IC_MSG_INTERNAL_ERROR; 33745039663SJohn Forte goto done; 33845039663SJohn Forte } 33945039663SJohn Forte 34045039663SJohn Forte err = nvlist_size(nvl, &size, NV_ENCODE_XDR); 34145039663SJohn Forte if (err) { 34245039663SJohn Forte status = STMF_IC_MSG_INTERNAL_ERROR; 34345039663SJohn Forte goto done; 34445039663SJohn Forte } 34545039663SJohn Forte 34645039663SJohn Forte buf = kmem_alloc(size, KM_SLEEP); 34745039663SJohn Forte err = nvlist_pack(nvl, &buf, &size, NV_ENCODE_XDR, 0); 34845039663SJohn Forte if (err) { 34945039663SJohn Forte status = STMF_IC_MSG_INTERNAL_ERROR; 35045039663SJohn Forte goto done; 35145039663SJohn Forte } 35245039663SJohn Forte 35345039663SJohn Forte /* push the bits out on the wire */ 35445039663SJohn Forte 35545039663SJohn Forte status = stmf_ic_transmit(buf, size); 35645039663SJohn Forte 35745039663SJohn Forte done: 35845039663SJohn Forte if (nvl) 35945039663SJohn Forte nvlist_free(nvl); 36045039663SJohn Forte 36145039663SJohn Forte if (buf) 36245039663SJohn Forte kmem_free(buf, size); 36345039663SJohn Forte 36445039663SJohn Forte stmf_ic_msg_free(msg); 36545039663SJohn Forte 36645039663SJohn Forte 36745039663SJohn Forte return (status); 36845039663SJohn Forte } 36945039663SJohn Forte 37045039663SJohn Forte /* 37145039663SJohn Forte * Pass the command to the daemon for transmission to the other node. 37245039663SJohn Forte */ 37345039663SJohn Forte stmf_ic_msg_status_t 37445039663SJohn Forte stmf_ic_transmit(char *buf, size_t size) 37545039663SJohn Forte { 37645039663SJohn Forte int i; 37745039663SJohn Forte int rc; 37845039663SJohn Forte door_arg_t arg; 37945039663SJohn Forte door_handle_t door; 38045039663SJohn Forte uint32_t result; 38145039663SJohn Forte 38245039663SJohn Forte mutex_enter(&pppt_global.global_door_lock); 38345039663SJohn Forte if (pppt_global.global_door == NULL) { 38445039663SJohn Forte /* daemon not listening */ 38545039663SJohn Forte mutex_exit(&pppt_global.global_door_lock); 38645039663SJohn Forte return (STMF_IC_MSG_INTERNAL_ERROR); 38745039663SJohn Forte } 38845039663SJohn Forte door = pppt_global.global_door; 38945039663SJohn Forte door_ki_hold(door); 39045039663SJohn Forte mutex_exit(&pppt_global.global_door_lock); 39145039663SJohn Forte 39245039663SJohn Forte arg.data_ptr = buf; 39345039663SJohn Forte arg.data_size = size; 39445039663SJohn Forte arg.desc_ptr = NULL; 39545039663SJohn Forte arg.desc_num = 0; 39645039663SJohn Forte arg.rbuf = (char *)&result; 39745039663SJohn Forte arg.rsize = sizeof (result); 39845039663SJohn Forte /* 39945039663SJohn Forte * Retry a few times if there is a shortage of threads to 40045039663SJohn Forte * service the upcall. This shouldn't happen unless a large 40145039663SJohn Forte * number of initiators issue commands at once. 40245039663SJohn Forte */ 40345039663SJohn Forte for (i = 0; i < STMF_MSG_TRANSMIT_RETRY; i++) { 40445039663SJohn Forte rc = door_ki_upcall(door, &arg); 40545039663SJohn Forte if (rc != EAGAIN) 40645039663SJohn Forte break; 40745039663SJohn Forte delay(hz); 40845039663SJohn Forte } 40945039663SJohn Forte door_ki_rele(door); 41045039663SJohn Forte if (rc != 0) { 41145039663SJohn Forte cmn_err(CE_WARN, 41245039663SJohn Forte "stmf_ic_transmit door_ki_upcall failed %d", rc); 41345039663SJohn Forte return (STMF_IC_MSG_INTERNAL_ERROR); 41445039663SJohn Forte } 41545039663SJohn Forte if (result != 0) { 41645039663SJohn Forte /* XXX Just warn for now */ 41745039663SJohn Forte cmn_err(CE_WARN, 41845039663SJohn Forte "stmf_ic_transmit bad result from daemon %d", result); 41945039663SJohn Forte } 42045039663SJohn Forte 42145039663SJohn Forte return (STMF_IC_MSG_SUCCESS); 42245039663SJohn Forte } 42345039663SJohn Forte 42445039663SJohn Forte /* 42545039663SJohn Forte * This is a low-level upcall which is called when a message has 42645039663SJohn Forte * been received on the interconnect. 42745039663SJohn Forte * 42845039663SJohn Forte * The caller is responsible for freeing the buffer which is passed in. 42945039663SJohn Forte */ 43045039663SJohn Forte /*ARGSUSED*/ 43145039663SJohn Forte void 43245039663SJohn Forte stmf_ic_rx_msg(char *buf, size_t len) 43345039663SJohn Forte { 43445039663SJohn Forte nvlist_t *nvl = NULL; 43545039663SJohn Forte stmf_ic_msg_t *m = NULL; 43645039663SJohn Forte stmf_ic_echo_request_reply_msg_t *icerr; 43745039663SJohn Forte stmf_ic_msg_t *echo_msg; 43845039663SJohn Forte int rc = 0; 43945039663SJohn Forte 44045039663SJohn Forte rc = nvlist_unpack(buf, len, &nvl, 0); 44145039663SJohn Forte if (rc) { 44245039663SJohn Forte cmn_err(CE_WARN, "stmf_ic_rx_msg: unpack failed"); 44345039663SJohn Forte return; 44445039663SJohn Forte } 44545039663SJohn Forte 44645039663SJohn Forte m = stmf_ic_msg_unmarshal(nvl); 44745039663SJohn Forte if (m == NULL) { 44845039663SJohn Forte cmn_err(CE_WARN, "stmf_ic_rx_msg: unmarshal failed"); 44945039663SJohn Forte nvlist_free(nvl); 45045039663SJohn Forte return; 45145039663SJohn Forte } 45245039663SJohn Forte 45345039663SJohn Forte switch (m->icm_msg_type) { 45445039663SJohn Forte 45545039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 45645039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 45745039663SJohn Forte case STMF_ICM_SCSI_CMD: 45845039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 45945039663SJohn Forte case STMF_ICM_SESSION_CREATE: 46045039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 46145039663SJohn Forte /* 46245039663SJohn Forte * These messages are all received by pppt. 46345039663SJohn Forte * Currently, pppt will parse the message for type 46445039663SJohn Forte */ 46545039663SJohn Forte (void) pppt_msg_rx(m); 46645039663SJohn Forte break; 46745039663SJohn Forte 46845039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 46945039663SJohn Forte case STMF_ICM_REGISTER_LUN: 47045039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 47145039663SJohn Forte case STMF_ICM_SCSI_DATA: 47245039663SJohn Forte case STMF_ICM_SCSI_STATUS: 47345039663SJohn Forte /* 47445039663SJohn Forte * These messages are all received by stmf. 47545039663SJohn Forte * Currently, stmf will parse the message for type 47645039663SJohn Forte */ 47745039663SJohn Forte (void) stmf_msg_rx(m); 47845039663SJohn Forte break; 47945039663SJohn Forte 48045039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 48145039663SJohn Forte icerr = m->icm_msg; 48245039663SJohn Forte echo_msg = stmf_ic_echo_reply_msg_alloc(icerr->icerr_datalen, 48345039663SJohn Forte icerr->icerr_data, 0); 48445039663SJohn Forte if (echo_msg != NULL) { 48545039663SJohn Forte (void) stmf_ic_tx_msg(echo_msg); 48645039663SJohn Forte } 48745039663SJohn Forte stmf_ic_msg_free(m); 48845039663SJohn Forte break; 48945039663SJohn Forte 49045039663SJohn Forte case STMF_ICM_ECHO_REPLY: 49145039663SJohn Forte stmf_ic_msg_free(m); 49245039663SJohn Forte break; 49345039663SJohn Forte 49445039663SJohn Forte case STMF_ICM_R2T: 49545039663SJohn Forte /* 49645039663SJohn Forte * XXX currently not supported 49745039663SJohn Forte */ 49845039663SJohn Forte stmf_ic_msg_free(m); 49945039663SJohn Forte break; 50045039663SJohn Forte 50145039663SJohn Forte case STMF_ICM_STATUS: 50245039663SJohn Forte (void) stmf_msg_rx(m); 50345039663SJohn Forte break; 50445039663SJohn Forte 50545039663SJohn Forte default: 50645039663SJohn Forte ASSERT(0); 50745039663SJohn Forte } 50845039663SJohn Forte } 50945039663SJohn Forte 51045039663SJohn Forte /* 51145039663SJohn Forte * IC message allocation routines. 51245039663SJohn Forte */ 51345039663SJohn Forte 51445039663SJohn Forte stmf_ic_msg_t * 51545039663SJohn Forte stmf_ic_reg_port_msg_alloc( 51645039663SJohn Forte scsi_devid_desc_t *port_id, 51745039663SJohn Forte uint16_t relative_port_id, 51845039663SJohn Forte uint16_t cb_arg_len, 51945039663SJohn Forte uint8_t *cb_arg, 52045039663SJohn Forte stmf_ic_msgid_t msgid) 52145039663SJohn Forte { 52245039663SJohn Forte stmf_ic_msg_t *icm = NULL; 52345039663SJohn Forte stmf_ic_reg_port_msg_t *icrp = NULL; 52445039663SJohn Forte 52545039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_REGISTER_PROXY_PORT, msgid); 52645039663SJohn Forte icrp = (stmf_ic_reg_port_msg_t *)kmem_zalloc(sizeof (*icrp), KM_SLEEP); 52745039663SJohn Forte icm->icm_msg = (void *)icrp; 52845039663SJohn Forte 52945039663SJohn Forte icrp->icrp_port_id = scsi_devid_desc_dup(port_id); 53045039663SJohn Forte icrp->icrp_relative_port_id = relative_port_id; 53145039663SJohn Forte 53245039663SJohn Forte if (cb_arg_len) { 53345039663SJohn Forte icrp->icrp_cb_arg_len = cb_arg_len; 53445039663SJohn Forte icrp->icrp_cb_arg = cb_arg; 53545039663SJohn Forte } 53645039663SJohn Forte 53745039663SJohn Forte return (icm); 53845039663SJohn Forte } 53945039663SJohn Forte 54045039663SJohn Forte stmf_ic_msg_t * 54145039663SJohn Forte stmf_ic_dereg_port_msg_alloc( 54245039663SJohn Forte scsi_devid_desc_t *port_id, 54345039663SJohn Forte uint16_t cb_arg_len, 54445039663SJohn Forte uint8_t *cb_arg, 54545039663SJohn Forte stmf_ic_msgid_t msgid) 54645039663SJohn Forte { 54745039663SJohn Forte stmf_ic_msg_t *icm = NULL; 54845039663SJohn Forte stmf_ic_dereg_port_msg_t *icdp = NULL; 54945039663SJohn Forte 55045039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_DEREGISTER_PROXY_PORT, msgid); 55145039663SJohn Forte icdp = (stmf_ic_dereg_port_msg_t *)kmem_zalloc(sizeof (*icdp), 55245039663SJohn Forte KM_SLEEP); 55345039663SJohn Forte icm->icm_msg = (void *)icdp; 55445039663SJohn Forte 55545039663SJohn Forte icdp->icdp_port_id = scsi_devid_desc_dup(port_id); 55645039663SJohn Forte 55745039663SJohn Forte if (cb_arg_len) { 55845039663SJohn Forte icdp->icdp_cb_arg_len = cb_arg_len; 55945039663SJohn Forte icdp->icdp_cb_arg = cb_arg; 56045039663SJohn Forte } 56145039663SJohn Forte 56245039663SJohn Forte return (icm); 56345039663SJohn Forte } 56445039663SJohn Forte 56545039663SJohn Forte 56645039663SJohn Forte stmf_ic_msg_t * 56745039663SJohn Forte stmf_ic_reg_lun_msg_alloc( 56845039663SJohn Forte uint8_t *lun_id, 56945039663SJohn Forte char *lu_provider_name, 57045039663SJohn Forte uint16_t cb_arg_len, 57145039663SJohn Forte uint8_t *cb_arg, 57245039663SJohn Forte stmf_ic_msgid_t msgid) 57345039663SJohn Forte { 57445039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_REGISTER_LUN, lun_id, 57545039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 57645039663SJohn Forte } 57745039663SJohn Forte 57845039663SJohn Forte stmf_ic_msg_t * 57945039663SJohn Forte stmf_ic_lun_active_msg_alloc( 58045039663SJohn Forte uint8_t *lun_id, 58145039663SJohn Forte char *lu_provider_name, 58245039663SJohn Forte uint16_t cb_arg_len, 58345039663SJohn Forte uint8_t *cb_arg, 58445039663SJohn Forte stmf_ic_msgid_t msgid) 58545039663SJohn Forte { 58645039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_LUN_ACTIVE, lun_id, 58745039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 58845039663SJohn Forte } 58945039663SJohn Forte 59045039663SJohn Forte stmf_ic_msg_t * 59145039663SJohn Forte stmf_ic_dereg_lun_msg_alloc( 59245039663SJohn Forte uint8_t *lun_id, 59345039663SJohn Forte char *lu_provider_name, 59445039663SJohn Forte uint16_t cb_arg_len, 59545039663SJohn Forte uint8_t *cb_arg, 59645039663SJohn Forte stmf_ic_msgid_t msgid) 59745039663SJohn Forte { 59845039663SJohn Forte return (stmf_ic_reg_dereg_lun_msg_alloc(STMF_ICM_DEREGISTER_LUN, lun_id, 59945039663SJohn Forte lu_provider_name, cb_arg_len, cb_arg, msgid)); 60045039663SJohn Forte } 60145039663SJohn Forte 60245039663SJohn Forte /* 60345039663SJohn Forte * Guts of lun register/deregister/active alloc routines. 60445039663SJohn Forte */ 60545039663SJohn Forte static stmf_ic_msg_t * 60645039663SJohn Forte stmf_ic_reg_dereg_lun_msg_alloc( 60745039663SJohn Forte stmf_ic_msg_type_t msg_type, 60845039663SJohn Forte uint8_t *lun_id, 60945039663SJohn Forte char *lu_provider_name, 61045039663SJohn Forte uint16_t cb_arg_len, 61145039663SJohn Forte uint8_t *cb_arg, 61245039663SJohn Forte stmf_ic_msgid_t msgid) 61345039663SJohn Forte { 61445039663SJohn Forte stmf_ic_msg_t *icm = NULL; 61545039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *icrl = NULL; 61645039663SJohn Forte 61745039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 61845039663SJohn Forte icrl = (stmf_ic_reg_dereg_lun_msg_t *) 61945039663SJohn Forte kmem_zalloc(sizeof (*icrl), KM_SLEEP); 62045039663SJohn Forte icm->icm_msg = (void *)icrl; 62145039663SJohn Forte 62245039663SJohn Forte icrl->icrl_lu_provider_name = stmf_ic_strdup(lu_provider_name); 62345039663SJohn Forte 62445039663SJohn Forte bcopy(lun_id, icrl->icrl_lun_id, sizeof (icrl->icrl_lun_id)); 62545039663SJohn Forte 62645039663SJohn Forte if (cb_arg_len) { 62745039663SJohn Forte icrl->icrl_cb_arg_len = cb_arg_len; 62845039663SJohn Forte icrl->icrl_cb_arg = cb_arg; 62945039663SJohn Forte } 63045039663SJohn Forte 63145039663SJohn Forte return (icm); 63245039663SJohn Forte } 63345039663SJohn Forte 63445039663SJohn Forte stmf_ic_msg_t * 63545039663SJohn Forte stmf_ic_scsi_cmd_msg_alloc( 63645039663SJohn Forte stmf_ic_msgid_t task_msgid, 63745039663SJohn Forte scsi_task_t *task, 63845039663SJohn Forte uint32_t immed_data_len, 63945039663SJohn Forte uint8_t *immed_data, 64045039663SJohn Forte stmf_ic_msgid_t msgid) 64145039663SJohn Forte { 64245039663SJohn Forte stmf_ic_msg_t *icm = NULL; 64345039663SJohn Forte stmf_ic_scsi_cmd_msg_t *icsc = NULL; 64445039663SJohn Forte scsi_devid_desc_t *ini_devid = task->task_session->ss_rport_id; 64545039663SJohn Forte scsi_devid_desc_t *tgt_devid = task->task_lport->lport_id; 646*716c1805SNattuvetty Bhavyan stmf_remote_port_t *rport = task->task_session->ss_rport; 64745039663SJohn Forte 64845039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_CMD, msgid); 64945039663SJohn Forte icsc = (stmf_ic_scsi_cmd_msg_t *)kmem_zalloc(sizeof (*icsc), KM_SLEEP); 65045039663SJohn Forte icm->icm_msg = (void *)icsc; 65145039663SJohn Forte 65245039663SJohn Forte icsc->icsc_task_msgid = task_msgid; 65345039663SJohn Forte icsc->icsc_ini_devid = scsi_devid_desc_dup(ini_devid); 65445039663SJohn Forte icsc->icsc_tgt_devid = scsi_devid_desc_dup(tgt_devid); 655*716c1805SNattuvetty Bhavyan icsc->icsc_rport = remote_port_dup(rport); 65645039663SJohn Forte icsc->icsc_session_id = task->task_session->ss_session_id; 65745039663SJohn Forte 658cbdc6dc7SJohn Forte if (!task->task_mgmt_function && task->task_lu->lu_id) { 659cbdc6dc7SJohn Forte bcopy(task->task_lu->lu_id->ident, 660cbdc6dc7SJohn Forte icsc->icsc_lun_id, sizeof (icsc->icsc_lun_id)); 661cbdc6dc7SJohn Forte } 66245039663SJohn Forte 66345039663SJohn Forte bcopy(task->task_lun_no, icsc->icsc_task_lun_no, 66445039663SJohn Forte sizeof (icsc->icsc_task_lun_no)); 66545039663SJohn Forte 66645039663SJohn Forte icsc->icsc_task_expected_xfer_length = task->task_expected_xfer_length; 66745039663SJohn Forte icsc->icsc_task_cdb_length = task->task_cdb_length; 66845039663SJohn Forte 66945039663SJohn Forte icsc->icsc_task_cdb = (uint8_t *)kmem_zalloc(task->task_cdb_length, 67045039663SJohn Forte KM_SLEEP); 67145039663SJohn Forte bcopy(task->task_cdb, icsc->icsc_task_cdb, task->task_cdb_length); 67245039663SJohn Forte 67345039663SJohn Forte icsc->icsc_task_flags = task->task_flags; 67445039663SJohn Forte icsc->icsc_task_priority = task->task_priority; 67545039663SJohn Forte icsc->icsc_task_mgmt_function = task->task_mgmt_function; 67645039663SJohn Forte 67745039663SJohn Forte icsc->icsc_immed_data_len = immed_data_len; 67845039663SJohn Forte icsc->icsc_immed_data = immed_data; 67945039663SJohn Forte 68045039663SJohn Forte return (icm); 68145039663SJohn Forte } 68245039663SJohn Forte 68345039663SJohn Forte stmf_ic_msg_t * 68445039663SJohn Forte stmf_ic_scsi_data_msg_alloc( 68545039663SJohn Forte stmf_ic_msgid_t task_msgid, 68645039663SJohn Forte uint64_t session_id, 68745039663SJohn Forte uint8_t *lun_id, 68845039663SJohn Forte uint64_t data_len, 68945039663SJohn Forte uint8_t *data, 69045039663SJohn Forte stmf_ic_msgid_t msgid) 69145039663SJohn Forte { 69245039663SJohn Forte stmf_ic_msg_t *icm = NULL; 69345039663SJohn Forte stmf_ic_scsi_data_msg_t *icsd = NULL; 69445039663SJohn Forte 69545039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_DATA, msgid); 69645039663SJohn Forte icsd = (stmf_ic_scsi_data_msg_t *)kmem_zalloc(sizeof (*icsd), KM_SLEEP); 69745039663SJohn Forte icm->icm_msg = (void *)icsd; 69845039663SJohn Forte 69945039663SJohn Forte icsd->icsd_task_msgid = task_msgid; 70045039663SJohn Forte icsd->icsd_session_id = session_id; 70145039663SJohn Forte bcopy(lun_id, icsd->icsd_lun_id, sizeof (icsd->icsd_lun_id)); 70245039663SJohn Forte icsd->icsd_data_len = data_len; 70345039663SJohn Forte icsd->icsd_data = data; 70445039663SJohn Forte 70545039663SJohn Forte return (icm); 70645039663SJohn Forte } 70745039663SJohn Forte 70845039663SJohn Forte stmf_ic_msg_t * 70945039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_alloc( 71045039663SJohn Forte stmf_ic_msgid_t task_msgid, 71145039663SJohn Forte uint64_t session_id, 71245039663SJohn Forte stmf_status_t status, 71345039663SJohn Forte stmf_ic_msgid_t msgid) 71445039663SJohn Forte { 71545039663SJohn Forte stmf_ic_msg_t *icm = NULL; 71645039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *icsx = NULL; 71745039663SJohn Forte 71845039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_DATA_XFER_DONE, msgid); 71945039663SJohn Forte icsx = (stmf_ic_scsi_data_xfer_done_msg_t *)kmem_zalloc( 72045039663SJohn Forte sizeof (*icsx), KM_SLEEP); 72145039663SJohn Forte icm->icm_msg = (void *)icsx; 72245039663SJohn Forte 72345039663SJohn Forte icsx->icsx_task_msgid = task_msgid; 72445039663SJohn Forte icsx->icsx_session_id = session_id; 72545039663SJohn Forte icsx->icsx_status = status; 72645039663SJohn Forte 72745039663SJohn Forte return (icm); 72845039663SJohn Forte } 72945039663SJohn Forte 73045039663SJohn Forte stmf_ic_msg_t * 73145039663SJohn Forte stmf_ic_scsi_status_msg_alloc( 73245039663SJohn Forte stmf_ic_msgid_t task_msgid, 73345039663SJohn Forte uint64_t session_id, 73445039663SJohn Forte uint8_t *lun_id, 73545039663SJohn Forte uint8_t response, 73645039663SJohn Forte uint8_t status, 73745039663SJohn Forte uint8_t flags, 73845039663SJohn Forte uint32_t resid, 73945039663SJohn Forte uint8_t sense_len, 74045039663SJohn Forte uint8_t *sense, 74145039663SJohn Forte stmf_ic_msgid_t msgid) 74245039663SJohn Forte { 74345039663SJohn Forte stmf_ic_msg_t *icm = NULL; 74445039663SJohn Forte stmf_ic_scsi_status_msg_t *icss = NULL; 74545039663SJohn Forte 74645039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_STATUS, msgid); 74745039663SJohn Forte icss = (stmf_ic_scsi_status_msg_t *)kmem_zalloc(sizeof (*icss), 74845039663SJohn Forte KM_SLEEP); 74945039663SJohn Forte icm->icm_msg = (void *)icss; 75045039663SJohn Forte 75145039663SJohn Forte icss->icss_task_msgid = task_msgid; 75245039663SJohn Forte icss->icss_session_id = session_id; 75345039663SJohn Forte bcopy(lun_id, icss->icss_lun_id, sizeof (icss->icss_lun_id)); 75445039663SJohn Forte icss->icss_response = response; 75545039663SJohn Forte icss->icss_status = status; 75645039663SJohn Forte icss->icss_flags = flags; 75745039663SJohn Forte icss->icss_resid = resid; 75845039663SJohn Forte icss->icss_sense_len = sense_len; 75945039663SJohn Forte icss->icss_sense = sense; 76045039663SJohn Forte 76145039663SJohn Forte return (icm); 76245039663SJohn Forte } 76345039663SJohn Forte 76445039663SJohn Forte stmf_ic_msg_t * 76545039663SJohn Forte stmf_ic_r2t_msg_alloc( 76645039663SJohn Forte stmf_ic_msgid_t task_msgid, 76745039663SJohn Forte uint64_t session_id, 76845039663SJohn Forte uint32_t offset, 76945039663SJohn Forte uint32_t length, 77045039663SJohn Forte stmf_ic_msgid_t msgid) 77145039663SJohn Forte { 77245039663SJohn Forte stmf_ic_msg_t *icm = NULL; 77345039663SJohn Forte stmf_ic_r2t_msg_t *icrt = NULL; 77445039663SJohn Forte 77545039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_R2T, msgid); 77645039663SJohn Forte icrt = (stmf_ic_r2t_msg_t *)kmem_zalloc(sizeof (*icrt), KM_SLEEP); 77745039663SJohn Forte icm->icm_msg = (void *)icrt; 77845039663SJohn Forte 77945039663SJohn Forte icrt->icrt_task_msgid = task_msgid; 78045039663SJohn Forte icrt->icrt_session_id = session_id; 78145039663SJohn Forte icrt->icrt_offset = offset; 78245039663SJohn Forte icrt->icrt_length = length; 78345039663SJohn Forte 78445039663SJohn Forte return (icm); 78545039663SJohn Forte } 78645039663SJohn Forte 78745039663SJohn Forte stmf_ic_msg_t * 78845039663SJohn Forte stmf_ic_status_msg_alloc( 78945039663SJohn Forte stmf_status_t status, 79045039663SJohn Forte stmf_ic_msg_type_t msg_type, 79145039663SJohn Forte stmf_ic_msgid_t msgid) 79245039663SJohn Forte { 79345039663SJohn Forte stmf_ic_msg_t *icm = NULL; 79445039663SJohn Forte stmf_ic_status_msg_t *ics = NULL; 79545039663SJohn Forte 79645039663SJohn Forte icm = stmf_ic_alloc_msg_header(STMF_ICM_STATUS, msgid); 79745039663SJohn Forte ics = (stmf_ic_status_msg_t *)kmem_zalloc(sizeof (*ics), KM_SLEEP); 79845039663SJohn Forte icm->icm_msg = (void *)ics; 79945039663SJohn Forte 80045039663SJohn Forte ics->ics_status = status; 80145039663SJohn Forte ics->ics_msg_type = msg_type; 80245039663SJohn Forte ics->ics_msgid = msgid; /* XXX same as msgid in header */ 80345039663SJohn Forte 80445039663SJohn Forte return (icm); 80545039663SJohn Forte } 80645039663SJohn Forte 80745039663SJohn Forte stmf_ic_msg_t * 80845039663SJohn Forte stmf_ic_session_create_msg_alloc( 80945039663SJohn Forte stmf_scsi_session_t *session, 81045039663SJohn Forte stmf_ic_msgid_t msgid) 81145039663SJohn Forte { 81245039663SJohn Forte return (stmf_ic_session_create_destroy_msg_alloc( 81345039663SJohn Forte STMF_ICM_SESSION_CREATE, session, msgid)); 81445039663SJohn Forte } 81545039663SJohn Forte 81645039663SJohn Forte stmf_ic_msg_t * 81745039663SJohn Forte stmf_ic_session_destroy_msg_alloc( 81845039663SJohn Forte stmf_scsi_session_t *session, 81945039663SJohn Forte stmf_ic_msgid_t msgid) 82045039663SJohn Forte { 82145039663SJohn Forte return (stmf_ic_session_create_destroy_msg_alloc( 82245039663SJohn Forte STMF_ICM_SESSION_DESTROY, session, msgid)); 82345039663SJohn Forte } 82445039663SJohn Forte 82545039663SJohn Forte /* 82645039663SJohn Forte * Guts of session create/destroy routines. 82745039663SJohn Forte */ 82845039663SJohn Forte static stmf_ic_msg_t * 82945039663SJohn Forte stmf_ic_session_create_destroy_msg_alloc( 83045039663SJohn Forte stmf_ic_msg_type_t msg_type, 83145039663SJohn Forte stmf_scsi_session_t *session, 83245039663SJohn Forte stmf_ic_msgid_t msgid) 83345039663SJohn Forte { 83445039663SJohn Forte stmf_ic_msg_t *icm = NULL; 83545039663SJohn Forte stmf_ic_session_create_destroy_msg_t *icscd = NULL; 83645039663SJohn Forte scsi_devid_desc_t *ini_devid = session->ss_rport_id; 83745039663SJohn Forte scsi_devid_desc_t *tgt_devid = session->ss_lport->lport_id; 83845039663SJohn Forte 83945039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 84045039663SJohn Forte icscd = (stmf_ic_session_create_destroy_msg_t *) 84145039663SJohn Forte kmem_zalloc(sizeof (*icscd), KM_SLEEP); 84245039663SJohn Forte icm->icm_msg = (void *)icscd; 84345039663SJohn Forte 84445039663SJohn Forte icscd->icscd_session_id = session->ss_session_id; 84545039663SJohn Forte icscd->icscd_ini_devid = scsi_devid_desc_dup(ini_devid); 84645039663SJohn Forte icscd->icscd_tgt_devid = scsi_devid_desc_dup(tgt_devid); 847*716c1805SNattuvetty Bhavyan icscd->icscd_rport = remote_port_dup(session->ss_rport); 84845039663SJohn Forte 84945039663SJohn Forte return (icm); 85045039663SJohn Forte } 85145039663SJohn Forte 85245039663SJohn Forte stmf_ic_msg_t * 85345039663SJohn Forte stmf_ic_echo_request_msg_alloc( 85445039663SJohn Forte uint32_t data_len, 85545039663SJohn Forte uint8_t *data, 85645039663SJohn Forte stmf_ic_msgid_t msgid) 85745039663SJohn Forte { 85845039663SJohn Forte return (stmf_ic_echo_request_reply_msg_alloc( 85945039663SJohn Forte STMF_ICM_ECHO_REQUEST, data_len, data, msgid)); 86045039663SJohn Forte } 86145039663SJohn Forte 86245039663SJohn Forte stmf_ic_msg_t * 86345039663SJohn Forte stmf_ic_echo_reply_msg_alloc( 86445039663SJohn Forte uint32_t data_len, 86545039663SJohn Forte uint8_t *data, 86645039663SJohn Forte stmf_ic_msgid_t msgid) 86745039663SJohn Forte { 86845039663SJohn Forte return (stmf_ic_echo_request_reply_msg_alloc( 86945039663SJohn Forte STMF_ICM_ECHO_REPLY, data_len, data, msgid)); 87045039663SJohn Forte } 87145039663SJohn Forte 87245039663SJohn Forte 87345039663SJohn Forte static stmf_ic_msg_t * 87445039663SJohn Forte stmf_ic_echo_request_reply_msg_alloc( 87545039663SJohn Forte stmf_ic_msg_type_t msg_type, 87645039663SJohn Forte uint32_t data_len, 87745039663SJohn Forte uint8_t *data, 87845039663SJohn Forte stmf_ic_msgid_t msgid) 87945039663SJohn Forte { 88045039663SJohn Forte stmf_ic_msg_t *icm = NULL; 88145039663SJohn Forte stmf_ic_echo_request_reply_msg_t *icerr = NULL; 88245039663SJohn Forte 88345039663SJohn Forte icm = stmf_ic_alloc_msg_header(msg_type, msgid); 88445039663SJohn Forte icerr = kmem_zalloc(sizeof (*icerr), KM_SLEEP); 88545039663SJohn Forte icm->icm_msg = (void *)icerr; 88645039663SJohn Forte 88745039663SJohn Forte icerr->icerr_data = data; 88845039663SJohn Forte icerr->icerr_datalen = data_len; 88945039663SJohn Forte 89045039663SJohn Forte return (icm); 89145039663SJohn Forte } 89245039663SJohn Forte 89345039663SJohn Forte /* 89445039663SJohn Forte * msg free routines. 89545039663SJohn Forte */ 89645039663SJohn Forte void 89745039663SJohn Forte stmf_ic_msg_free(stmf_ic_msg_t *msg) 89845039663SJohn Forte { 89945039663SJohn Forte stmf_ic_msg_construction_method_t cmethod = 90045039663SJohn Forte (msg->icm_nvlist ? STMF_UNMARSHAL : STMF_CONSTRUCTOR); 90145039663SJohn Forte 90245039663SJohn Forte switch (msg->icm_msg_type) { 90345039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 90445039663SJohn Forte stmf_ic_reg_port_msg_free( 90545039663SJohn Forte (stmf_ic_reg_port_msg_t *)msg->icm_msg, cmethod); 90645039663SJohn Forte break; 90745039663SJohn Forte 90845039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 90945039663SJohn Forte stmf_ic_dereg_port_msg_free( 91045039663SJohn Forte (stmf_ic_dereg_port_msg_t *)msg->icm_msg, cmethod); 91145039663SJohn Forte break; 91245039663SJohn Forte 91345039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 91445039663SJohn Forte case STMF_ICM_REGISTER_LUN: 91545039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 91645039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free( 91745039663SJohn Forte (stmf_ic_reg_dereg_lun_msg_t *)msg->icm_msg, cmethod); 91845039663SJohn Forte break; 91945039663SJohn Forte 92045039663SJohn Forte case STMF_ICM_SCSI_CMD: 92145039663SJohn Forte stmf_ic_scsi_cmd_msg_free( 92245039663SJohn Forte (stmf_ic_scsi_cmd_msg_t *)msg->icm_msg, cmethod); 92345039663SJohn Forte break; 92445039663SJohn Forte 92545039663SJohn Forte case STMF_ICM_SCSI_DATA: 92645039663SJohn Forte stmf_ic_scsi_data_msg_free( 92745039663SJohn Forte (stmf_ic_scsi_data_msg_t *)msg->icm_msg, cmethod); 92845039663SJohn Forte break; 92945039663SJohn Forte 93045039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 93145039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free( 93245039663SJohn Forte (stmf_ic_scsi_data_xfer_done_msg_t *)msg->icm_msg, cmethod); 93345039663SJohn Forte break; 93445039663SJohn Forte 93545039663SJohn Forte case STMF_ICM_SCSI_STATUS: 93645039663SJohn Forte stmf_ic_scsi_status_msg_free( 93745039663SJohn Forte (stmf_ic_scsi_status_msg_t *)msg->icm_msg, cmethod); 93845039663SJohn Forte break; 93945039663SJohn Forte 94045039663SJohn Forte case STMF_ICM_R2T: 94145039663SJohn Forte stmf_ic_r2t_msg_free( 94245039663SJohn Forte (stmf_ic_r2t_msg_t *)msg->icm_msg, cmethod); 94345039663SJohn Forte break; 94445039663SJohn Forte 94545039663SJohn Forte case STMF_ICM_STATUS: 94645039663SJohn Forte stmf_ic_status_msg_free( 94745039663SJohn Forte (stmf_ic_status_msg_t *)msg->icm_msg, cmethod); 94845039663SJohn Forte break; 94945039663SJohn Forte 95045039663SJohn Forte case STMF_ICM_SESSION_CREATE: 95145039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 95245039663SJohn Forte stmf_ic_session_create_destroy_msg_free( 95345039663SJohn Forte (stmf_ic_session_create_destroy_msg_t *)msg->icm_msg, 95445039663SJohn Forte cmethod); 95545039663SJohn Forte break; 95645039663SJohn Forte 95745039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 95845039663SJohn Forte case STMF_ICM_ECHO_REPLY: 95945039663SJohn Forte stmf_ic_echo_request_reply_msg_free( 96045039663SJohn Forte (stmf_ic_echo_request_reply_msg_t *)msg->icm_msg, cmethod); 96145039663SJohn Forte break; 96245039663SJohn Forte 96345039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 96445039663SJohn Forte ASSERT(0); 96545039663SJohn Forte break; 96645039663SJohn Forte 96745039663SJohn Forte default: 96845039663SJohn Forte ASSERT(0); 96945039663SJohn Forte } 97045039663SJohn Forte 97145039663SJohn Forte if (msg->icm_nvlist) 97245039663SJohn Forte nvlist_free(msg->icm_nvlist); 97345039663SJohn Forte 97445039663SJohn Forte kmem_free(msg, sizeof (*msg)); 97545039663SJohn Forte } 97645039663SJohn Forte 97745039663SJohn Forte /*ARGSUSED*/ 97845039663SJohn Forte static void 97945039663SJohn Forte stmf_ic_reg_port_msg_free(stmf_ic_reg_port_msg_t *m, 98045039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 98145039663SJohn Forte { 98245039663SJohn Forte scsi_devid_desc_free(m->icrp_port_id); 98345039663SJohn Forte 98445039663SJohn Forte kmem_free(m, sizeof (*m)); 98545039663SJohn Forte } 98645039663SJohn Forte 98745039663SJohn Forte 98845039663SJohn Forte /*ARGSUSED*/ 98945039663SJohn Forte static void 99045039663SJohn Forte stmf_ic_dereg_port_msg_free(stmf_ic_dereg_port_msg_t *m, 99145039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 99245039663SJohn Forte { 99345039663SJohn Forte scsi_devid_desc_free(m->icdp_port_id); 99445039663SJohn Forte 99545039663SJohn Forte kmem_free(m, sizeof (*m)); 99645039663SJohn Forte } 99745039663SJohn Forte 99845039663SJohn Forte 99945039663SJohn Forte /* 100045039663SJohn Forte * Works for both reg_lun_msg and dereg_lun_msg, since the message 100145039663SJohn Forte * payload is the same. 100245039663SJohn Forte */ 100345039663SJohn Forte static void 100445039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free(stmf_ic_reg_dereg_lun_msg_t *m, 100545039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 100645039663SJohn Forte { 100745039663SJohn Forte if (cmethod == STMF_CONSTRUCTOR) { 100845039663SJohn Forte kmem_free(m->icrl_lu_provider_name, 100945039663SJohn Forte strlen(m->icrl_lu_provider_name) + 1); 101045039663SJohn Forte } 101145039663SJohn Forte 101245039663SJohn Forte kmem_free(m, sizeof (*m)); 101345039663SJohn Forte } 101445039663SJohn Forte 101545039663SJohn Forte static void 101645039663SJohn Forte stmf_ic_scsi_cmd_msg_free(stmf_ic_scsi_cmd_msg_t *m, 101745039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 101845039663SJohn Forte { 101945039663SJohn Forte scsi_devid_desc_free(m->icsc_ini_devid); 102045039663SJohn Forte scsi_devid_desc_free(m->icsc_tgt_devid); 1021*716c1805SNattuvetty Bhavyan stmf_remote_port_free(m->icsc_rport); 102245039663SJohn Forte if (cmethod == STMF_CONSTRUCTOR) { 102345039663SJohn Forte kmem_free(m->icsc_task_cdb, m->icsc_task_cdb_length); 102445039663SJohn Forte } 102545039663SJohn Forte 102645039663SJohn Forte kmem_free(m, sizeof (*m)); 102745039663SJohn Forte 102845039663SJohn Forte } 102945039663SJohn Forte 103045039663SJohn Forte /*ARGSUSED*/ 103145039663SJohn Forte static void 103245039663SJohn Forte stmf_ic_scsi_data_msg_free(stmf_ic_scsi_data_msg_t *m, 103345039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 103445039663SJohn Forte { 103545039663SJohn Forte kmem_free(m, sizeof (*m)); 103645039663SJohn Forte } 103745039663SJohn Forte 103845039663SJohn Forte /*ARGSUSED*/ 103945039663SJohn Forte static void 104045039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free(stmf_ic_scsi_data_xfer_done_msg_t *m, 104145039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 104245039663SJohn Forte { 104345039663SJohn Forte kmem_free(m, sizeof (*m)); 104445039663SJohn Forte } 104545039663SJohn Forte 104645039663SJohn Forte /*ARGSUSED*/ 104745039663SJohn Forte static void 104845039663SJohn Forte stmf_ic_scsi_status_msg_free(stmf_ic_scsi_status_msg_t *m, 104945039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 105045039663SJohn Forte { 105145039663SJohn Forte kmem_free(m, sizeof (*m)); 105245039663SJohn Forte } 105345039663SJohn Forte 105445039663SJohn Forte /*ARGSUSED*/ 105545039663SJohn Forte static void 105645039663SJohn Forte stmf_ic_r2t_msg_free(stmf_ic_r2t_msg_t *m, 105745039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 105845039663SJohn Forte { 105945039663SJohn Forte kmem_free(m, sizeof (*m)); 106045039663SJohn Forte } 106145039663SJohn Forte 106245039663SJohn Forte /*ARGSUSED*/ 106345039663SJohn Forte static void 106445039663SJohn Forte stmf_ic_status_msg_free(stmf_ic_status_msg_t *m, 106545039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 106645039663SJohn Forte { 106745039663SJohn Forte kmem_free(m, sizeof (*m)); 106845039663SJohn Forte } 106945039663SJohn Forte 107045039663SJohn Forte /* 107145039663SJohn Forte * Works for both session_create and session_destroy msgs, since the message 107245039663SJohn Forte * payload is the same. 107345039663SJohn Forte */ 107445039663SJohn Forte /*ARGSUSED*/ 107545039663SJohn Forte static void 107645039663SJohn Forte stmf_ic_session_create_destroy_msg_free(stmf_ic_session_create_destroy_msg_t *m, 107745039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 107845039663SJohn Forte { 107945039663SJohn Forte scsi_devid_desc_free(m->icscd_ini_devid); 108045039663SJohn Forte scsi_devid_desc_free(m->icscd_tgt_devid); 1081*716c1805SNattuvetty Bhavyan stmf_remote_port_free(m->icscd_rport); 108245039663SJohn Forte 108345039663SJohn Forte kmem_free(m, sizeof (*m)); 108445039663SJohn Forte } 108545039663SJohn Forte 108645039663SJohn Forte /*ARGSUSED*/ 108745039663SJohn Forte static void 108845039663SJohn Forte stmf_ic_echo_request_reply_msg_free(stmf_ic_echo_request_reply_msg_t *m, 108945039663SJohn Forte stmf_ic_msg_construction_method_t cmethod) 109045039663SJohn Forte { 109145039663SJohn Forte kmem_free(m, sizeof (*m)); 109245039663SJohn Forte } 109345039663SJohn Forte 109445039663SJohn Forte 109545039663SJohn Forte /* 109645039663SJohn Forte * Marshaling routines. 109745039663SJohn Forte */ 109845039663SJohn Forte 109945039663SJohn Forte static nvlist_t * 110045039663SJohn Forte stmf_ic_msg_marshal(stmf_ic_msg_t *msg) 110145039663SJohn Forte { 110245039663SJohn Forte nvlist_t *nvl = NULL; 110345039663SJohn Forte int rc = 0; 110445039663SJohn Forte 110545039663SJohn Forte rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); 110645039663SJohn Forte if (rc) 110745039663SJohn Forte goto done; 110845039663SJohn Forte 110945039663SJohn Forte NVLIST_ADD_FIELD(uint8, msg, icm_msg_type); 111045039663SJohn Forte NVLIST_ADD_FIELD(uint64, msg, icm_msgid); 111145039663SJohn Forte 111245039663SJohn Forte switch (msg->icm_msg_type) { 111345039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 111445039663SJohn Forte rc = stmf_ic_reg_port_msg_marshal(nvl, msg->icm_msg); 111545039663SJohn Forte break; 111645039663SJohn Forte 111745039663SJohn Forte 111845039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 111945039663SJohn Forte rc = stmf_ic_dereg_port_msg_marshal(nvl, msg->icm_msg); 112045039663SJohn Forte break; 112145039663SJohn Forte 112245039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 112345039663SJohn Forte case STMF_ICM_REGISTER_LUN: 112445039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 112545039663SJohn Forte rc = stmf_ic_reg_dereg_lun_msg_marshal(nvl, msg->icm_msg); 112645039663SJohn Forte break; 112745039663SJohn Forte 112845039663SJohn Forte case STMF_ICM_SCSI_CMD: 112945039663SJohn Forte rc = stmf_ic_scsi_cmd_msg_marshal(nvl, msg->icm_msg); 113045039663SJohn Forte break; 113145039663SJohn Forte 113245039663SJohn Forte case STMF_ICM_SCSI_DATA: 113345039663SJohn Forte rc = stmf_ic_scsi_data_msg_marshal(nvl, msg->icm_msg); 113445039663SJohn Forte break; 113545039663SJohn Forte 113645039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 113745039663SJohn Forte rc = stmf_ic_scsi_data_xfer_done_msg_marshal(nvl, msg->icm_msg); 113845039663SJohn Forte break; 113945039663SJohn Forte 114045039663SJohn Forte case STMF_ICM_SCSI_STATUS: 114145039663SJohn Forte rc = stmf_ic_scsi_status_msg_marshal(nvl, msg->icm_msg); 114245039663SJohn Forte break; 114345039663SJohn Forte 114445039663SJohn Forte case STMF_ICM_R2T: 114545039663SJohn Forte rc = stmf_ic_r2t_msg_marshal(nvl, msg->icm_msg); 114645039663SJohn Forte break; 114745039663SJohn Forte 114845039663SJohn Forte case STMF_ICM_STATUS: 114945039663SJohn Forte rc = stmf_ic_status_msg_marshal(nvl, msg->icm_msg); 115045039663SJohn Forte break; 115145039663SJohn Forte 115245039663SJohn Forte case STMF_ICM_SESSION_CREATE: 115345039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 115445039663SJohn Forte rc = stmf_ic_session_create_destroy_msg_marshal(nvl, 115545039663SJohn Forte msg->icm_msg); 115645039663SJohn Forte break; 115745039663SJohn Forte 115845039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 115945039663SJohn Forte case STMF_ICM_ECHO_REPLY: 116045039663SJohn Forte rc = stmf_ic_echo_request_reply_msg_marshal(nvl, 116145039663SJohn Forte msg->icm_msg); 116245039663SJohn Forte break; 116345039663SJohn Forte 116445039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 116545039663SJohn Forte ASSERT(0); 116645039663SJohn Forte break; 116745039663SJohn Forte 116845039663SJohn Forte default: 116945039663SJohn Forte ASSERT(0); 117045039663SJohn Forte } 117145039663SJohn Forte 117245039663SJohn Forte done: 117345039663SJohn Forte if (!rc) 117445039663SJohn Forte return (nvl); 117545039663SJohn Forte 117645039663SJohn Forte if (nvl) 117745039663SJohn Forte nvlist_free(nvl); 117845039663SJohn Forte 117945039663SJohn Forte return (NULL); 118045039663SJohn Forte } 118145039663SJohn Forte 118245039663SJohn Forte 118345039663SJohn Forte static int 118445039663SJohn Forte stmf_ic_reg_port_msg_marshal(nvlist_t *nvl, void *msg) 118545039663SJohn Forte { 118645039663SJohn Forte stmf_ic_reg_port_msg_t *m = (stmf_ic_reg_port_msg_t *)msg; 118745039663SJohn Forte int rc = 0; 118845039663SJohn Forte 118945039663SJohn Forte NVLIST_ADD_DEVID(m, icrp_port_id); 119045039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrp_relative_port_id); 119145039663SJohn Forte 119245039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrp_cb_arg_len); 119345039663SJohn Forte /* only add the callback arg if necessary */ 119445039663SJohn Forte if (m->icrp_cb_arg_len) { 119545039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icrp_cb_arg, m->icrp_cb_arg_len); 119645039663SJohn Forte } 119745039663SJohn Forte 119845039663SJohn Forte done: 119945039663SJohn Forte return (rc); 120045039663SJohn Forte } 120145039663SJohn Forte 120245039663SJohn Forte static int 120345039663SJohn Forte stmf_ic_dereg_port_msg_marshal(nvlist_t *nvl, void *msg) 120445039663SJohn Forte { 120545039663SJohn Forte stmf_ic_dereg_port_msg_t *m = (stmf_ic_dereg_port_msg_t *)msg; 120645039663SJohn Forte int rc = 0; 120745039663SJohn Forte 120845039663SJohn Forte NVLIST_ADD_DEVID(m, icdp_port_id); 120945039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icdp_cb_arg_len); 121045039663SJohn Forte 121145039663SJohn Forte /* only add the callback arg if necessary */ 121245039663SJohn Forte if (m->icdp_cb_arg_len) { 121345039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icdp_cb_arg, m->icdp_cb_arg_len); 121445039663SJohn Forte } 121545039663SJohn Forte 121645039663SJohn Forte done: 121745039663SJohn Forte return (rc); 121845039663SJohn Forte } 121945039663SJohn Forte 122045039663SJohn Forte /* 122145039663SJohn Forte * Handles STMF_ICM_LUN_ACTIVE, STMF_ICM_REGISTER_LUN and 122245039663SJohn Forte * STMF_ICM_DEREGISTER_LUN; 122345039663SJohn Forte * msg payload is the same for all. 122445039663SJohn Forte */ 122545039663SJohn Forte static int 122645039663SJohn Forte stmf_ic_reg_dereg_lun_msg_marshal(nvlist_t *nvl, void *msg) 122745039663SJohn Forte { 122845039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *m = (stmf_ic_reg_dereg_lun_msg_t *)msg; 122945039663SJohn Forte int rc = 0; 123045039663SJohn Forte 123145039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icrl_lun_id); 123245039663SJohn Forte NVLIST_ADD_FIELD(string, m, icrl_lu_provider_name); 123345039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icrl_cb_arg_len); 123445039663SJohn Forte 123545039663SJohn Forte /* only add the callback arg if necessary */ 123645039663SJohn Forte if (m->icrl_cb_arg_len) { 123745039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icrl_cb_arg, m->icrl_cb_arg_len); 123845039663SJohn Forte } 123945039663SJohn Forte 124045039663SJohn Forte done: 124145039663SJohn Forte return (rc); 124245039663SJohn Forte } 124345039663SJohn Forte 124445039663SJohn Forte static int 124545039663SJohn Forte stmf_ic_scsi_cmd_msg_marshal(nvlist_t *nvl, void *msg) 124645039663SJohn Forte { 124745039663SJohn Forte stmf_ic_scsi_cmd_msg_t *m = (stmf_ic_scsi_cmd_msg_t *)msg; 124845039663SJohn Forte int rc = 0; 124945039663SJohn Forte 125045039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsc_task_msgid); 125145039663SJohn Forte NVLIST_ADD_DEVID(m, icsc_ini_devid); 125245039663SJohn Forte NVLIST_ADD_DEVID(m, icsc_tgt_devid); 1253*716c1805SNattuvetty Bhavyan NVLIST_ADD_RPORT(m, icsc_rport); 125445039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icsc_lun_id); 125545039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsc_session_id); 125645039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_task_lun_no, 8); 125745039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icsc_task_expected_xfer_length); 125845039663SJohn Forte NVLIST_ADD_FIELD(uint16, m, icsc_task_cdb_length); 125945039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_task_cdb, m->icsc_task_cdb_length); 126045039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_flags); 126145039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_priority); 126245039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icsc_task_mgmt_function); 126345039663SJohn Forte 126445039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icsc_immed_data_len); 126545039663SJohn Forte /* only add immediate data if necessary */ 126645039663SJohn Forte if (m->icsc_immed_data_len) { 126745039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_immed_data, 126845039663SJohn Forte m->icsc_immed_data_len); 126945039663SJohn Forte } 127045039663SJohn Forte 127145039663SJohn Forte done: 127245039663SJohn Forte return (rc); 127345039663SJohn Forte } 127445039663SJohn Forte 127545039663SJohn Forte static int 127645039663SJohn Forte stmf_ic_scsi_data_msg_marshal(nvlist_t *nvl, void *msg) 127745039663SJohn Forte { 127845039663SJohn Forte stmf_ic_scsi_data_msg_t *m = (stmf_ic_scsi_data_msg_t *)msg; 127945039663SJohn Forte int rc = 0; 128045039663SJohn Forte 128145039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_task_msgid); 128245039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_session_id); 128345039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icsd_lun_id); 128445039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsd_data_len); 128545039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icsd_data, m->icsd_data_len); 128645039663SJohn Forte 128745039663SJohn Forte done: 128845039663SJohn Forte return (rc); 128945039663SJohn Forte } 129045039663SJohn Forte 129145039663SJohn Forte static int 129245039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_marshal(nvlist_t *nvl, void *msg) 129345039663SJohn Forte { 129445039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *m = 129545039663SJohn Forte (stmf_ic_scsi_data_xfer_done_msg_t *)msg; 129645039663SJohn Forte int rc = 0; 129745039663SJohn Forte 129845039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_task_msgid); 129945039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_session_id); 130045039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icsx_status); 130145039663SJohn Forte 130245039663SJohn Forte done: 130345039663SJohn Forte return (rc); 130445039663SJohn Forte } 130545039663SJohn Forte 130645039663SJohn Forte static int 130745039663SJohn Forte stmf_ic_scsi_status_msg_marshal(nvlist_t *nvl, void *msg) 130845039663SJohn Forte { 130945039663SJohn Forte stmf_ic_scsi_status_msg_t *m = (stmf_ic_scsi_status_msg_t *)msg; 131045039663SJohn Forte int rc = 0; 131145039663SJohn Forte 131245039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icss_task_msgid); 131345039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icss_session_id); 131445039663SJohn Forte NVLIST_ADD_ARRAY(uint8, m, icss_lun_id); 131545039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_response); 131645039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_status); 131745039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_flags); 131845039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icss_resid); 131945039663SJohn Forte 132045039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, icss_sense_len); 132145039663SJohn Forte 132245039663SJohn Forte if (m->icss_sense_len) 132345039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icss_sense, m->icss_sense_len); 132445039663SJohn Forte 132545039663SJohn Forte done: 132645039663SJohn Forte return (rc); 132745039663SJohn Forte } 132845039663SJohn Forte 132945039663SJohn Forte static int 133045039663SJohn Forte stmf_ic_r2t_msg_marshal(nvlist_t *nvl, void *msg) 133145039663SJohn Forte { 133245039663SJohn Forte stmf_ic_r2t_msg_t *m = (stmf_ic_r2t_msg_t *)msg; 133345039663SJohn Forte int rc = 0; 133445039663SJohn Forte 133545039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icrt_task_msgid); 133645039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icrt_session_id); 133745039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icrt_offset); 133845039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icrt_length); 133945039663SJohn Forte 134045039663SJohn Forte done: 134145039663SJohn Forte return (rc); 134245039663SJohn Forte } 134345039663SJohn Forte 134445039663SJohn Forte static int 134545039663SJohn Forte stmf_ic_status_msg_marshal(nvlist_t *nvl, void *msg) 134645039663SJohn Forte { 134745039663SJohn Forte stmf_ic_status_msg_t *m = (stmf_ic_status_msg_t *)msg; 134845039663SJohn Forte int rc = 0; 134945039663SJohn Forte 135045039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, ics_msg_type); 135145039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, ics_msgid); 135245039663SJohn Forte NVLIST_ADD_FIELD(uint8, m, ics_status); 135345039663SJohn Forte 135445039663SJohn Forte done: 135545039663SJohn Forte return (rc); 135645039663SJohn Forte } 135745039663SJohn Forte 135845039663SJohn Forte static int 135945039663SJohn Forte stmf_ic_session_create_destroy_msg_marshal(nvlist_t *nvl, void *msg) 136045039663SJohn Forte { 136145039663SJohn Forte stmf_ic_session_create_destroy_msg_t *m = 136245039663SJohn Forte (stmf_ic_session_create_destroy_msg_t *)msg; 136345039663SJohn Forte int rc = 0; 136445039663SJohn Forte 136545039663SJohn Forte NVLIST_ADD_DEVID(m, icscd_ini_devid); 136645039663SJohn Forte NVLIST_ADD_DEVID(m, icscd_tgt_devid); 1367*716c1805SNattuvetty Bhavyan NVLIST_ADD_RPORT(m, icscd_rport); 136845039663SJohn Forte NVLIST_ADD_FIELD(uint64, m, icscd_session_id); 136945039663SJohn Forte 137045039663SJohn Forte done: 137145039663SJohn Forte return (rc); 137245039663SJohn Forte } 137345039663SJohn Forte 137445039663SJohn Forte static int 137545039663SJohn Forte stmf_ic_echo_request_reply_msg_marshal(nvlist_t *nvl, void *msg) 137645039663SJohn Forte { 137745039663SJohn Forte stmf_ic_echo_request_reply_msg_t *m = msg; 137845039663SJohn Forte int rc = 0; 137945039663SJohn Forte 138045039663SJohn Forte NVLIST_ADD_FIELD(uint32, m, icerr_datalen); 138145039663SJohn Forte if (m->icerr_datalen) 138245039663SJohn Forte NVLIST_ADD_ARRAY_LEN(uint8, m, icerr_data, m->icerr_datalen); 138345039663SJohn Forte 138445039663SJohn Forte done: 138545039663SJohn Forte return (rc); 138645039663SJohn Forte } 138745039663SJohn Forte 138845039663SJohn Forte /* 138945039663SJohn Forte * Allocate a new nvlist representing the scsi_devid_desc and add it 139045039663SJohn Forte * to the nvlist. 139145039663SJohn Forte */ 139245039663SJohn Forte static int 139345039663SJohn Forte stmf_ic_scsi_devid_desc_marshal(nvlist_t *parent_nvl, 139445039663SJohn Forte char *sdid_name, 139545039663SJohn Forte scsi_devid_desc_t *sdid) 139645039663SJohn Forte { 139745039663SJohn Forte int rc = 0; 139845039663SJohn Forte nvlist_t *nvl = NULL; 139945039663SJohn Forte 140045039663SJohn Forte rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); 140145039663SJohn Forte if (rc) 140245039663SJohn Forte goto done; 140345039663SJohn Forte 140445039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, protocol_id); 140545039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, code_set); 140645039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, piv); 140745039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, association); 140845039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, ident_type); 140945039663SJohn Forte NVLIST_ADD_FIELD(uint8, sdid, ident_length); 141045039663SJohn Forte 141145039663SJohn Forte rc = nvlist_add_uint8_array(nvl, "ident", sdid->ident, 141245039663SJohn Forte sdid->ident_length); 141345039663SJohn Forte if (rc) 141445039663SJohn Forte goto done; 141545039663SJohn Forte 141645039663SJohn Forte rc = nvlist_add_nvlist(parent_nvl, sdid_name, nvl); 1417*716c1805SNattuvetty Bhavyan done: 1418*716c1805SNattuvetty Bhavyan if (nvl) { 1419*716c1805SNattuvetty Bhavyan nvlist_free(nvl); 1420*716c1805SNattuvetty Bhavyan } 1421*716c1805SNattuvetty Bhavyan return (rc); 1422*716c1805SNattuvetty Bhavyan } 1423*716c1805SNattuvetty Bhavyan 1424*716c1805SNattuvetty Bhavyan /* 1425*716c1805SNattuvetty Bhavyan * Allocate a new nvlist representing the stmf_remote_port and add it 1426*716c1805SNattuvetty Bhavyan * to the nvlist. 1427*716c1805SNattuvetty Bhavyan */ 1428*716c1805SNattuvetty Bhavyan static int 1429*716c1805SNattuvetty Bhavyan stmf_ic_remote_port_marshal(nvlist_t *parent_nvl, char *rport_name, 1430*716c1805SNattuvetty Bhavyan stmf_remote_port_t *rport) { 1431*716c1805SNattuvetty Bhavyan 1432*716c1805SNattuvetty Bhavyan int rc = 0; 1433*716c1805SNattuvetty Bhavyan nvlist_t *nvl = NULL; 1434*716c1805SNattuvetty Bhavyan 1435*716c1805SNattuvetty Bhavyan rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); 1436*716c1805SNattuvetty Bhavyan if (rc) 1437*716c1805SNattuvetty Bhavyan goto done; 143845039663SJohn Forte 1439*716c1805SNattuvetty Bhavyan NVLIST_ADD_FIELD(uint16, rport, rport_tptid_sz); 1440*716c1805SNattuvetty Bhavyan rc = nvlist_add_uint8_array(nvl, "rport_tptid", 1441*716c1805SNattuvetty Bhavyan (uint8_t *)rport->rport_tptid, rport->rport_tptid_sz); 1442*716c1805SNattuvetty Bhavyan if (rc) 1443*716c1805SNattuvetty Bhavyan goto done; 1444*716c1805SNattuvetty Bhavyan 1445*716c1805SNattuvetty Bhavyan rc = nvlist_add_nvlist(parent_nvl, rport_name, nvl); 144645039663SJohn Forte done: 144745039663SJohn Forte if (nvl) { 144845039663SJohn Forte nvlist_free(nvl); 144945039663SJohn Forte } 145045039663SJohn Forte return (rc); 145145039663SJohn Forte } 145245039663SJohn Forte 145345039663SJohn Forte /* 145445039663SJohn Forte * Unmarshaling routines. 145545039663SJohn Forte */ 145645039663SJohn Forte 145745039663SJohn Forte static stmf_ic_msg_t * 145845039663SJohn Forte stmf_ic_msg_unmarshal(nvlist_t *nvl) 145945039663SJohn Forte { 146045039663SJohn Forte stmf_ic_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 146145039663SJohn Forte uint8_t msg_type; 146245039663SJohn Forte int rc = 0; 146345039663SJohn Forte 146445039663SJohn Forte /* 146545039663SJohn Forte * We'd like to do this: 146645039663SJohn Forte * 146745039663SJohn Forte * NVLIST_LOOKUP_FIELD(uint8, m, icm_msg_type); 146845039663SJohn Forte * 146945039663SJohn Forte * but the fact that msg type is an enum causes type problems. 147045039663SJohn Forte */ 147145039663SJohn Forte rc = nvlist_lookup_uint8(nvl, "icm_msg_type", &msg_type); 147245039663SJohn Forte if (rc) { 147345039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icm_msg_type"); 147445039663SJohn Forte goto done; 147545039663SJohn Forte } 147645039663SJohn Forte 147745039663SJohn Forte m->icm_msg_type = msg_type; 147845039663SJohn Forte m->icm_nvlist = nvl; 147945039663SJohn Forte 148045039663SJohn Forte NVLIST_LOOKUP_FIELD(uint64, m, icm_msgid); 148145039663SJohn Forte 148245039663SJohn Forte switch (m->icm_msg_type) { 148345039663SJohn Forte 148445039663SJohn Forte case STMF_ICM_REGISTER_PROXY_PORT: 148545039663SJohn Forte m->icm_msg = stmf_ic_reg_port_msg_unmarshal(nvl); 148645039663SJohn Forte break; 148745039663SJohn Forte 148845039663SJohn Forte 148945039663SJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT: 149045039663SJohn Forte m->icm_msg = stmf_ic_dereg_port_msg_unmarshal(nvl); 149145039663SJohn Forte break; 149245039663SJohn Forte 149345039663SJohn Forte case STMF_ICM_LUN_ACTIVE: 149445039663SJohn Forte case STMF_ICM_REGISTER_LUN: 149545039663SJohn Forte case STMF_ICM_DEREGISTER_LUN: 149645039663SJohn Forte m->icm_msg = stmf_ic_reg_dereg_lun_msg_unmarshal(nvl); 149745039663SJohn Forte break; 149845039663SJohn Forte 149945039663SJohn Forte case STMF_ICM_SCSI_CMD: 150045039663SJohn Forte m->icm_msg = stmf_ic_scsi_cmd_msg_unmarshal(nvl); 150145039663SJohn Forte break; 150245039663SJohn Forte 150345039663SJohn Forte case STMF_ICM_SCSI_DATA: 150445039663SJohn Forte m->icm_msg = stmf_ic_scsi_data_msg_unmarshal(nvl); 150545039663SJohn Forte break; 150645039663SJohn Forte 150745039663SJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE: 150845039663SJohn Forte m->icm_msg = stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvl); 150945039663SJohn Forte break; 151045039663SJohn Forte 151145039663SJohn Forte case STMF_ICM_SCSI_STATUS: 151245039663SJohn Forte m->icm_msg = stmf_ic_scsi_status_msg_unmarshal(nvl); 151345039663SJohn Forte break; 151445039663SJohn Forte 151545039663SJohn Forte case STMF_ICM_R2T: 151645039663SJohn Forte m->icm_msg = stmf_ic_r2t_msg_unmarshal(nvl); 151745039663SJohn Forte break; 151845039663SJohn Forte 151945039663SJohn Forte case STMF_ICM_STATUS: 152045039663SJohn Forte m->icm_msg = stmf_ic_status_msg_unmarshal(nvl); 152145039663SJohn Forte break; 152245039663SJohn Forte 152345039663SJohn Forte case STMF_ICM_SESSION_CREATE: 152445039663SJohn Forte case STMF_ICM_SESSION_DESTROY: 152545039663SJohn Forte m->icm_msg = stmf_ic_session_create_destroy_msg_unmarshal(nvl); 152645039663SJohn Forte break; 152745039663SJohn Forte 152845039663SJohn Forte case STMF_ICM_ECHO_REQUEST: 152945039663SJohn Forte case STMF_ICM_ECHO_REPLY: 153045039663SJohn Forte m->icm_msg = stmf_ic_echo_request_reply_msg_unmarshal(nvl); 153145039663SJohn Forte break; 153245039663SJohn Forte 153345039663SJohn Forte case STMF_ICM_MAX_MSG_TYPE: 153445039663SJohn Forte ASSERT(0); 153545039663SJohn Forte break; 153645039663SJohn Forte 153745039663SJohn Forte default: 153845039663SJohn Forte ASSERT(0); 153945039663SJohn Forte } 154045039663SJohn Forte 154145039663SJohn Forte done: 154245039663SJohn Forte 154345039663SJohn Forte if (!m->icm_msg) { 154445039663SJohn Forte kmem_free(m, sizeof (*m)); 154545039663SJohn Forte return (NULL); 154645039663SJohn Forte } 154745039663SJohn Forte 154845039663SJohn Forte return (m); 154945039663SJohn Forte } 155045039663SJohn Forte 155145039663SJohn Forte static void * 155245039663SJohn Forte stmf_ic_reg_port_msg_unmarshal(nvlist_t *nvl) 155345039663SJohn Forte { 155445039663SJohn Forte nvlist_t *nvl_port_id = NULL; 155545039663SJohn Forte int rc = 0; 155645039663SJohn Forte stmf_ic_reg_port_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 155745039663SJohn Forte 155845039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, "icrp_port_id", &nvl_port_id); 155945039663SJohn Forte if (rc) { 156045039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_port_id nvl"); 156145039663SJohn Forte rc = ENOMEM; /* XXX */ 156245039663SJohn Forte goto done; 156345039663SJohn Forte } 156445039663SJohn Forte 156545039663SJohn Forte m->icrp_port_id = stmf_ic_scsi_devid_desc_unmarshal(nvl_port_id); 156645039663SJohn Forte if (m->icrp_port_id == NULL) { 156745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_port_id"); 156845039663SJohn Forte rc = ENOMEM; /* XXX */ 156945039663SJohn Forte goto done; 157045039663SJohn Forte } 157145039663SJohn Forte 157245039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrp_relative_port_id); 157345039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrp_cb_arg_len); 157445039663SJohn Forte 157545039663SJohn Forte if (m->icrp_cb_arg_len) { 157645039663SJohn Forte m->icrp_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 157745039663SJohn Forte "icrp_cb_arg", m->icrp_cb_arg_len, NULL); 157845039663SJohn Forte if (m->icrp_cb_arg == NULL) { 157945039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrp_cb_arg"); 158045039663SJohn Forte rc = ENOMEM; /* XXX */ 158145039663SJohn Forte goto done; 158245039663SJohn Forte } 158345039663SJohn Forte } 158445039663SJohn Forte 158545039663SJohn Forte done: 158645039663SJohn Forte if (!rc) 158745039663SJohn Forte return (m); 158845039663SJohn Forte 158945039663SJohn Forte stmf_ic_reg_port_msg_free(m, STMF_UNMARSHAL); 159045039663SJohn Forte 159145039663SJohn Forte return (NULL); 159245039663SJohn Forte } 159345039663SJohn Forte 159445039663SJohn Forte /* 159545039663SJohn Forte * XXX largely the same as stmf_ic_reg_port_msg_unmarshal() 159645039663SJohn Forte * Common stuff should be factored out. Type issues may make this 159745039663SJohn Forte * painful. 159845039663SJohn Forte */ 159945039663SJohn Forte static void * 160045039663SJohn Forte stmf_ic_dereg_port_msg_unmarshal(nvlist_t *nvl) 160145039663SJohn Forte { 160245039663SJohn Forte nvlist_t *nvl_port_id = NULL; 160345039663SJohn Forte int rc = 0; 160445039663SJohn Forte stmf_ic_dereg_port_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 160545039663SJohn Forte 160645039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, "icdp_port_id", &nvl_port_id); 160745039663SJohn Forte if (rc) { 160845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_port_id nvl"); 160945039663SJohn Forte goto done; 161045039663SJohn Forte } 161145039663SJohn Forte 161245039663SJohn Forte m->icdp_port_id = stmf_ic_scsi_devid_desc_unmarshal(nvl_port_id); 161345039663SJohn Forte if (m->icdp_port_id == NULL) { 161445039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_port_id"); 161545039663SJohn Forte rc = ENOMEM; /* XXX */ 161645039663SJohn Forte goto done; 161745039663SJohn Forte } 161845039663SJohn Forte 161945039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icdp_cb_arg_len); 162045039663SJohn Forte 162145039663SJohn Forte if (m->icdp_cb_arg_len) { 162245039663SJohn Forte m->icdp_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 162345039663SJohn Forte "icdp_cb_arg", m->icdp_cb_arg_len, NULL); 162445039663SJohn Forte if (m->icdp_cb_arg == NULL) { 162545039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icdp_cb_arg"); 162645039663SJohn Forte rc = ENOMEM; /* XXX */ 162745039663SJohn Forte goto done; 162845039663SJohn Forte } 162945039663SJohn Forte } 163045039663SJohn Forte 163145039663SJohn Forte done: 163245039663SJohn Forte if (!rc) 163345039663SJohn Forte return (m); 163445039663SJohn Forte 163545039663SJohn Forte stmf_ic_dereg_port_msg_free(m, STMF_UNMARSHAL); 163645039663SJohn Forte 163745039663SJohn Forte return (NULL); 163845039663SJohn Forte } 163945039663SJohn Forte 164045039663SJohn Forte static void * 164145039663SJohn Forte stmf_ic_reg_dereg_lun_msg_unmarshal(nvlist_t *nvl) 164245039663SJohn Forte { 164345039663SJohn Forte int rc = 0; 164445039663SJohn Forte stmf_ic_reg_dereg_lun_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 164545039663SJohn Forte 164645039663SJohn Forte if (! stmf_ic_uint8_array_unmarshal(nvl, "icrl_lun_id", 164745039663SJohn Forte sizeof (m->icrl_lun_id), m->icrl_lun_id)) { 164845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_lun_id"); 164945039663SJohn Forte rc = ENOMEM; /* XXX */ 165045039663SJohn Forte goto done; 165145039663SJohn Forte } 165245039663SJohn Forte 165345039663SJohn Forte m->icrl_lu_provider_name = stmf_ic_string_unmarshal(nvl, 165445039663SJohn Forte "icrl_lu_provider_name"); 165545039663SJohn Forte 165645039663SJohn Forte if (!m->icrl_lu_provider_name) { 165745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_lu_provider_name"); 165845039663SJohn Forte rc = ENOMEM; /* XXX */ 165945039663SJohn Forte goto done; 166045039663SJohn Forte } 166145039663SJohn Forte 166245039663SJohn Forte NVLIST_LOOKUP_FIELD(uint16, m, icrl_cb_arg_len); 166345039663SJohn Forte 166445039663SJohn Forte if (m->icrl_cb_arg_len) { 166545039663SJohn Forte m->icrl_cb_arg = stmf_ic_uint8_array_unmarshal(nvl, 166645039663SJohn Forte "icrl_cb_arg", m->icrl_cb_arg_len, NULL); 166745039663SJohn Forte if (m->icrl_cb_arg == NULL) { 166845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrl_cb_arg"); 166945039663SJohn Forte rc = ENOMEM; /* XXX */ 167045039663SJohn Forte goto done; 167145039663SJohn Forte } 167245039663SJohn Forte } 167345039663SJohn Forte 167445039663SJohn Forte done: 167545039663SJohn Forte if (!rc) 167645039663SJohn Forte return (m); 167745039663SJohn Forte 167845039663SJohn Forte stmf_ic_reg_dereg_lun_msg_free(m, STMF_UNMARSHAL); 167945039663SJohn Forte 168045039663SJohn Forte return (NULL); 168145039663SJohn Forte } 168245039663SJohn Forte 168345039663SJohn Forte static void * 168445039663SJohn Forte stmf_ic_scsi_cmd_msg_unmarshal(nvlist_t *nvl) 168545039663SJohn Forte { 168645039663SJohn Forte int rc = 0; 168745039663SJohn Forte stmf_ic_scsi_cmd_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 168845039663SJohn Forte 168945039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 169045039663SJohn Forte NV_PAIR(UINT64, m, icsc_task_msgid), 169145039663SJohn Forte NV_PAIR(UINT64, m, icsc_session_id), 169245039663SJohn Forte NV_PAIR(UINT32, m, icsc_task_expected_xfer_length), 169345039663SJohn Forte NV_PAIR(UINT16, m, icsc_task_cdb_length), 169445039663SJohn Forte NV_PAIR(UINT8, m, icsc_task_flags), 169545039663SJohn Forte NV_PAIR(UINT8, m, icsc_task_mgmt_function), 169645039663SJohn Forte NV_PAIR(UINT32, m, icsc_immed_data_len), 169745039663SJohn Forte NULL) != 0) { 169845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_task_msgid and friends"); 169945039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 170045039663SJohn Forte goto done; 170145039663SJohn Forte } 170245039663SJohn Forte 170345039663SJohn Forte m->icsc_ini_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 170445039663SJohn Forte nvl, "icsc_ini_devid"); 170545039663SJohn Forte if (m->icsc_ini_devid == NULL) { 170645039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_ini_devid"); 170745039663SJohn Forte rc = ENOMEM; 170845039663SJohn Forte goto done; 170945039663SJohn Forte } 171045039663SJohn Forte 171145039663SJohn Forte m->icsc_tgt_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 171245039663SJohn Forte nvl, "icsc_tgt_devid"); 171345039663SJohn Forte if (m->icsc_tgt_devid == NULL) { 171445039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_tgt_devid"); 171545039663SJohn Forte rc = ENOMEM; 171645039663SJohn Forte goto done; 171745039663SJohn Forte } 171845039663SJohn Forte 1719*716c1805SNattuvetty Bhavyan m->icsc_rport = stmf_ic_lookup_remote_port_and_unmarshal( 1720*716c1805SNattuvetty Bhavyan nvl, "icsc_rport"); 1721*716c1805SNattuvetty Bhavyan if (m->icsc_rport == NULL) { 1722*716c1805SNattuvetty Bhavyan stmf_ic_nvlookup_warn(__func__, "icsc_rport"); 1723*716c1805SNattuvetty Bhavyan rc = ENOMEM; 1724*716c1805SNattuvetty Bhavyan goto done; 1725*716c1805SNattuvetty Bhavyan } 1726*716c1805SNattuvetty Bhavyan 172745039663SJohn Forte /* icsc_lun_id */ 172845039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsc_lun_id", 172945039663SJohn Forte sizeof (m->icsc_lun_id), m->icsc_lun_id)) { 173045039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_lun_id"); 173145039663SJohn Forte rc = ENOMEM; 173245039663SJohn Forte goto done; 173345039663SJohn Forte } 173445039663SJohn Forte 173545039663SJohn Forte /* icsc_task_lun_no */ 173645039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsc_task_lun_no", 173745039663SJohn Forte sizeof (m->icsc_task_lun_no), m->icsc_task_lun_no)) { 173845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_task_lun_no"); 173945039663SJohn Forte rc = ENOMEM; 174045039663SJohn Forte goto done; 174145039663SJohn Forte } 174245039663SJohn Forte 174345039663SJohn Forte /* icsc_task_cdb */ 174445039663SJohn Forte m->icsc_task_cdb = stmf_ic_uint8_array_unmarshal(nvl, "icsc_task_cdb", 174545039663SJohn Forte m->icsc_task_cdb_length, NULL); 174645039663SJohn Forte if (!m->icsc_task_cdb) { 174745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_task_cdb"); 174845039663SJohn Forte rc = ENOMEM; 174945039663SJohn Forte goto done; 175045039663SJohn Forte } 175145039663SJohn Forte 175245039663SJohn Forte /* immediate data, if there is any */ 175345039663SJohn Forte if (m->icsc_immed_data_len) { 175445039663SJohn Forte m->icsc_immed_data = stmf_ic_uint8_array_unmarshal(nvl, 175545039663SJohn Forte "icsc_immed_data", m->icsc_immed_data_len, NULL); 175645039663SJohn Forte if (!m->icsc_immed_data) { 175745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsc_immed_data"); 175845039663SJohn Forte rc = ENOMEM; 175945039663SJohn Forte goto done; 176045039663SJohn Forte } 176145039663SJohn Forte } 176245039663SJohn Forte 176345039663SJohn Forte done: 176445039663SJohn Forte if (!rc) 176545039663SJohn Forte return (m); 176645039663SJohn Forte 176745039663SJohn Forte stmf_ic_scsi_cmd_msg_free(m, STMF_UNMARSHAL); 176845039663SJohn Forte 176945039663SJohn Forte return (NULL); 177045039663SJohn Forte } 177145039663SJohn Forte 177245039663SJohn Forte static void * 177345039663SJohn Forte stmf_ic_scsi_data_msg_unmarshal(nvlist_t *nvl) 177445039663SJohn Forte { 177545039663SJohn Forte int rc = 0; 177645039663SJohn Forte stmf_ic_scsi_data_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 177745039663SJohn Forte 177845039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 177945039663SJohn Forte NV_PAIR(UINT64, m, icsd_task_msgid), 178045039663SJohn Forte NV_PAIR(UINT64, m, icsd_session_id), 178145039663SJohn Forte NV_PAIR(UINT64, m, icsd_data_len), 178245039663SJohn Forte NULL) != 0) { 178345039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_task_msgid and friends"); 178445039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 178545039663SJohn Forte goto done; 178645039663SJohn Forte } 178745039663SJohn Forte 178845039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icsd_lun_id", 178945039663SJohn Forte sizeof (m->icsd_lun_id), m->icsd_lun_id)) { 179045039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_lun_id"); 179145039663SJohn Forte rc = ENOMEM; 179245039663SJohn Forte goto done; 179345039663SJohn Forte } 179445039663SJohn Forte 179545039663SJohn Forte m->icsd_data = stmf_ic_uint8_array_unmarshal(nvl, "icsd_data", 179645039663SJohn Forte m->icsd_data_len, NULL); 179745039663SJohn Forte if (!m->icsd_data) { 179845039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_data"); 179945039663SJohn Forte rc = ENOMEM; 180045039663SJohn Forte goto done; 180145039663SJohn Forte } 180245039663SJohn Forte 180345039663SJohn Forte done: 180445039663SJohn Forte if (!rc) 180545039663SJohn Forte return (m); 180645039663SJohn Forte 180745039663SJohn Forte stmf_ic_scsi_data_msg_free(m, STMF_UNMARSHAL); 180845039663SJohn Forte 180945039663SJohn Forte return (NULL); 181045039663SJohn Forte } 181145039663SJohn Forte 181245039663SJohn Forte static void * 181345039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_unmarshal(nvlist_t *nvl) 181445039663SJohn Forte { 181545039663SJohn Forte int rc = 0; 181645039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *m = 181745039663SJohn Forte kmem_zalloc(sizeof (*m), KM_SLEEP); 181845039663SJohn Forte 181945039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 182045039663SJohn Forte NV_PAIR(UINT64, m, icsx_task_msgid), 182145039663SJohn Forte NV_PAIR(UINT64, m, icsx_session_id), 182245039663SJohn Forte NV_PAIR(UINT64, m, icsx_status), 182345039663SJohn Forte NULL) != 0) { 182445039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsx_task_msgid and friends"); 182545039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 182645039663SJohn Forte goto done; 182745039663SJohn Forte } 182845039663SJohn Forte 182945039663SJohn Forte done: 183045039663SJohn Forte if (!rc) 183145039663SJohn Forte return (m); 183245039663SJohn Forte 183345039663SJohn Forte stmf_ic_scsi_data_xfer_done_msg_free(m, STMF_UNMARSHAL); 183445039663SJohn Forte 183545039663SJohn Forte return (NULL); 183645039663SJohn Forte } 183745039663SJohn Forte 183845039663SJohn Forte static void * 183945039663SJohn Forte stmf_ic_scsi_status_msg_unmarshal(nvlist_t *nvl) 184045039663SJohn Forte { 184145039663SJohn Forte int rc = 0; 184245039663SJohn Forte stmf_ic_scsi_status_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 184345039663SJohn Forte 184445039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 184545039663SJohn Forte NV_PAIR(UINT64, m, icss_task_msgid), 184645039663SJohn Forte NV_PAIR(UINT64, m, icss_session_id), 184745039663SJohn Forte NV_PAIR(UINT8, m, icss_response), 184845039663SJohn Forte NV_PAIR(UINT8, m, icss_status), 184945039663SJohn Forte NV_PAIR(UINT8, m, icss_flags), 185045039663SJohn Forte NV_PAIR(UINT32, m, icss_resid), 185145039663SJohn Forte NV_PAIR(UINT8, m, icss_sense_len), 185245039663SJohn Forte NULL) != 0) { 185345039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_task_msgid and friends"); 185445039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 185545039663SJohn Forte goto done; 185645039663SJohn Forte } 185745039663SJohn Forte 185845039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "icss_lun_id", 185945039663SJohn Forte sizeof (m->icss_lun_id), m->icss_lun_id)) { 186045039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_lun_id"); 186145039663SJohn Forte rc = ENOMEM; 186245039663SJohn Forte goto done; 186345039663SJohn Forte } 186445039663SJohn Forte 186545039663SJohn Forte if (m->icss_sense_len) { 186645039663SJohn Forte m->icss_sense = stmf_ic_uint8_array_unmarshal(nvl, "icss_sense", 186745039663SJohn Forte m->icss_sense_len, NULL); 186845039663SJohn Forte if (!m->icss_sense) { 186945039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icss_sense"); 187045039663SJohn Forte rc = ENOMEM; 187145039663SJohn Forte goto done; 187245039663SJohn Forte } 187345039663SJohn Forte } 187445039663SJohn Forte done: 187545039663SJohn Forte if (!rc) 187645039663SJohn Forte return (m); 187745039663SJohn Forte 187845039663SJohn Forte stmf_ic_scsi_status_msg_free(m, STMF_UNMARSHAL); 187945039663SJohn Forte 188045039663SJohn Forte return (NULL); 188145039663SJohn Forte } 188245039663SJohn Forte 188345039663SJohn Forte static void * 188445039663SJohn Forte stmf_ic_r2t_msg_unmarshal(nvlist_t *nvl) 188545039663SJohn Forte { 188645039663SJohn Forte int rc = 0; 188745039663SJohn Forte stmf_ic_r2t_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 188845039663SJohn Forte 188945039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 189045039663SJohn Forte NV_PAIR(UINT64, m, icrt_task_msgid), 189145039663SJohn Forte NV_PAIR(UINT64, m, icrt_session_id), 189245039663SJohn Forte NV_PAIR(UINT32, m, icrt_offset), 189345039663SJohn Forte NV_PAIR(UINT32, m, icrt_length), 189445039663SJohn Forte NULL) != 0) { 189545039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icrt_task_msgid and friends"); 189645039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 189745039663SJohn Forte goto done; 189845039663SJohn Forte } 189945039663SJohn Forte 190045039663SJohn Forte done: 190145039663SJohn Forte if (!rc) 190245039663SJohn Forte return (m); 190345039663SJohn Forte 190445039663SJohn Forte stmf_ic_r2t_msg_free(m, STMF_UNMARSHAL); 190545039663SJohn Forte 190645039663SJohn Forte return (NULL); 190745039663SJohn Forte } 190845039663SJohn Forte 190945039663SJohn Forte static void * 191045039663SJohn Forte stmf_ic_session_create_destroy_msg_unmarshal(nvlist_t *nvl) 191145039663SJohn Forte { 191245039663SJohn Forte int rc = 0; 191345039663SJohn Forte stmf_ic_session_create_destroy_msg_t *m = kmem_zalloc(sizeof (*m), 191445039663SJohn Forte KM_SLEEP); 191545039663SJohn Forte 191645039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 191745039663SJohn Forte NV_PAIR(UINT64, m, icscd_session_id), 191845039663SJohn Forte NULL) != 0) { 191945039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_session_id"); 192045039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 192145039663SJohn Forte goto done; 192245039663SJohn Forte } 192345039663SJohn Forte 192445039663SJohn Forte m->icscd_ini_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 192545039663SJohn Forte nvl, "icscd_ini_devid"); 192645039663SJohn Forte if (m->icscd_ini_devid == NULL) { 192745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_ini_devid"); 192845039663SJohn Forte rc = ENOMEM; 192945039663SJohn Forte goto done; 193045039663SJohn Forte } 193145039663SJohn Forte 193245039663SJohn Forte m->icscd_tgt_devid = stmf_ic_lookup_scsi_devid_desc_and_unmarshal( 193345039663SJohn Forte nvl, "icscd_tgt_devid"); 193445039663SJohn Forte if (m->icscd_tgt_devid == NULL) { 193545039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icsd_tgt_devid"); 193645039663SJohn Forte rc = ENOMEM; 193745039663SJohn Forte goto done; 193845039663SJohn Forte } 193945039663SJohn Forte 1940*716c1805SNattuvetty Bhavyan m->icscd_rport = stmf_ic_lookup_remote_port_and_unmarshal( 1941*716c1805SNattuvetty Bhavyan nvl, "icscd_rport"); 1942*716c1805SNattuvetty Bhavyan if (m->icscd_rport == NULL) { 1943*716c1805SNattuvetty Bhavyan stmf_ic_nvlookup_warn(__func__, "icscd_rport"); 1944*716c1805SNattuvetty Bhavyan rc = ENOMEM; 1945*716c1805SNattuvetty Bhavyan goto done; 1946*716c1805SNattuvetty Bhavyan } 1947*716c1805SNattuvetty Bhavyan 194845039663SJohn Forte done: 194945039663SJohn Forte if (!rc) 195045039663SJohn Forte return (m); 195145039663SJohn Forte 195245039663SJohn Forte stmf_ic_session_create_destroy_msg_free(m, STMF_UNMARSHAL); 195345039663SJohn Forte 195445039663SJohn Forte return (NULL); 195545039663SJohn Forte } 195645039663SJohn Forte 195745039663SJohn Forte static void * 195845039663SJohn Forte stmf_ic_echo_request_reply_msg_unmarshal(nvlist_t *nvl) 195945039663SJohn Forte { 196045039663SJohn Forte int rc = 0; 196145039663SJohn Forte stmf_ic_echo_request_reply_msg_t *m = kmem_zalloc(sizeof (*m), 196245039663SJohn Forte KM_SLEEP); 196345039663SJohn Forte 196445039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 196545039663SJohn Forte NV_PAIR(UINT32, m, icerr_datalen), 196645039663SJohn Forte NULL) != 0) { 196745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icerr_datalen"); 196845039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 196945039663SJohn Forte goto done; 197045039663SJohn Forte } 197145039663SJohn Forte 197245039663SJohn Forte /* immediate data, if there is any */ 197345039663SJohn Forte if (m->icerr_datalen) { 197445039663SJohn Forte m->icerr_data = stmf_ic_uint8_array_unmarshal(nvl, 197545039663SJohn Forte "icerr_data", m->icerr_datalen, NULL); 197645039663SJohn Forte if (!m->icerr_data) { 197745039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "icerr_data"); 197845039663SJohn Forte rc = ENOMEM; 197945039663SJohn Forte goto done; 198045039663SJohn Forte } 198145039663SJohn Forte } 198245039663SJohn Forte 198345039663SJohn Forte done: 198445039663SJohn Forte if (!rc) 198545039663SJohn Forte return (m); 198645039663SJohn Forte 198745039663SJohn Forte stmf_ic_echo_request_reply_msg_free(m, STMF_UNMARSHAL); 198845039663SJohn Forte 198945039663SJohn Forte return (NULL); 199045039663SJohn Forte } 199145039663SJohn Forte 199245039663SJohn Forte static void * 199345039663SJohn Forte stmf_ic_status_msg_unmarshal(nvlist_t *nvl) 199445039663SJohn Forte { 199545039663SJohn Forte int rc = 0; 199645039663SJohn Forte stmf_ic_status_msg_t *m = kmem_zalloc(sizeof (*m), KM_SLEEP); 199745039663SJohn Forte 199845039663SJohn Forte if (nvlist_lookup_pairs(nvl, 0, 199945039663SJohn Forte NV_PAIR(UINT8, m, ics_msg_type), 200045039663SJohn Forte NV_PAIR(UINT64, m, ics_msgid), 200145039663SJohn Forte NV_PAIR(UINT8, m, ics_status), 200245039663SJohn Forte NULL) != 0) { 200345039663SJohn Forte stmf_ic_nvlookup_warn(__func__, "ics_msg_type and friends"); 200445039663SJohn Forte rc = ENOMEM; /* XXX need something better */ 200545039663SJohn Forte goto done; 200645039663SJohn Forte } 200745039663SJohn Forte 200845039663SJohn Forte done: 200945039663SJohn Forte if (!rc) 201045039663SJohn Forte return (m); 201145039663SJohn Forte 201245039663SJohn Forte kmem_free(m, sizeof (*m)); 201345039663SJohn Forte return (NULL); 201445039663SJohn Forte } 201545039663SJohn Forte 201645039663SJohn Forte 201745039663SJohn Forte static scsi_devid_desc_t * 201845039663SJohn Forte stmf_ic_lookup_scsi_devid_desc_and_unmarshal(nvlist_t *nvl, char *field_name) 201945039663SJohn Forte { 202045039663SJohn Forte nvlist_t *nvl_devid = NULL; 202145039663SJohn Forte scsi_devid_desc_t *did = NULL; 202245039663SJohn Forte int rc; 202345039663SJohn Forte 202445039663SJohn Forte rc = nvlist_lookup_nvlist(nvl, field_name, &nvl_devid); 202545039663SJohn Forte if (rc) { 202645039663SJohn Forte goto done; 202745039663SJohn Forte } 202845039663SJohn Forte 202945039663SJohn Forte did = stmf_ic_scsi_devid_desc_unmarshal(nvl_devid); 203045039663SJohn Forte 203145039663SJohn Forte done: 203245039663SJohn Forte return (did); 203345039663SJohn Forte } 203445039663SJohn Forte 203545039663SJohn Forte 203645039663SJohn Forte static scsi_devid_desc_t * 203745039663SJohn Forte stmf_ic_scsi_devid_desc_unmarshal(nvlist_t *nvl) 203845039663SJohn Forte { 203945039663SJohn Forte scsi_devid_desc_t *sdid = NULL; 204045039663SJohn Forte uint8_t ident_length = 0; 204145039663SJohn Forte size_t sdid_size; 204245039663SJohn Forte int rc = 0; 204345039663SJohn Forte 204445039663SJohn Forte /* 204545039663SJohn Forte * we get the ident_length first, since that's the only 204645039663SJohn Forte * variable-sized field in the struct. 204745039663SJohn Forte */ 204845039663SJohn Forte rc = nvlist_lookup_uint8(nvl, "ident_length", &ident_length); 204945039663SJohn Forte if (rc) 205045039663SJohn Forte goto done; 205145039663SJohn Forte 205245039663SJohn Forte sdid_size = sizeof_scsi_devid_desc(ident_length); 205345039663SJohn Forte sdid = kmem_zalloc(sdid_size, KM_SLEEP); 205445039663SJohn Forte 205545039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, protocol_id); 205645039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, code_set); 205745039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, piv); 205845039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, association); 205945039663SJohn Forte NVLIST_LOOKUP_BIT_FIELD(uint8, sdid, ident_type); 206045039663SJohn Forte 206145039663SJohn Forte sdid->ident_length = ident_length; 206245039663SJohn Forte 206345039663SJohn Forte if (!stmf_ic_uint8_array_unmarshal(nvl, "ident", 206445039663SJohn Forte sdid->ident_length, sdid->ident)) { 206545039663SJohn Forte rc = ENOMEM; /* XXX */ 206645039663SJohn Forte goto done; 206745039663SJohn Forte } 206845039663SJohn Forte 206945039663SJohn Forte done: 207045039663SJohn Forte if (!rc) 207145039663SJohn Forte return (sdid); 207245039663SJohn Forte 207345039663SJohn Forte kmem_free(sdid, sdid_size); 207445039663SJohn Forte 207545039663SJohn Forte return (NULL); 207645039663SJohn Forte } 207745039663SJohn Forte 2078*716c1805SNattuvetty Bhavyan static stmf_remote_port_t * 2079*716c1805SNattuvetty Bhavyan stmf_ic_lookup_remote_port_and_unmarshal(nvlist_t *nvl, char *field_name) 2080*716c1805SNattuvetty Bhavyan { 2081*716c1805SNattuvetty Bhavyan nvlist_t *nvl_rport = NULL; 2082*716c1805SNattuvetty Bhavyan 2083*716c1805SNattuvetty Bhavyan if (nvlist_lookup_nvlist(nvl, field_name, &nvl_rport) != 0) 2084*716c1805SNattuvetty Bhavyan return (NULL); 2085*716c1805SNattuvetty Bhavyan 2086*716c1805SNattuvetty Bhavyan return (stmf_ic_remote_port_unmarshal(nvl_rport)); 2087*716c1805SNattuvetty Bhavyan } 2088*716c1805SNattuvetty Bhavyan 2089*716c1805SNattuvetty Bhavyan static stmf_remote_port_t * 2090*716c1805SNattuvetty Bhavyan stmf_ic_remote_port_unmarshal(nvlist_t *nvl) 2091*716c1805SNattuvetty Bhavyan { 2092*716c1805SNattuvetty Bhavyan stmf_remote_port_t *rport = NULL; 2093*716c1805SNattuvetty Bhavyan uint16_t rport_tptid_sz = 0; 2094*716c1805SNattuvetty Bhavyan int rc = 0; 2095*716c1805SNattuvetty Bhavyan 2096*716c1805SNattuvetty Bhavyan rc = nvlist_lookup_uint16(nvl, "rport_tptid_sz", &rport_tptid_sz); 2097*716c1805SNattuvetty Bhavyan if (rc || rport_tptid_sz < sizeof (scsi_transport_id_t)) 2098*716c1805SNattuvetty Bhavyan return (NULL); 2099*716c1805SNattuvetty Bhavyan 2100*716c1805SNattuvetty Bhavyan rport = stmf_remote_port_alloc(rport_tptid_sz); 2101*716c1805SNattuvetty Bhavyan if (!stmf_ic_uint8_array_unmarshal(nvl, "rport_tptid", rport_tptid_sz, 2102*716c1805SNattuvetty Bhavyan (uint8_t *)rport->rport_tptid)) { 2103*716c1805SNattuvetty Bhavyan stmf_remote_port_free(rport); 2104*716c1805SNattuvetty Bhavyan rport = NULL; 2105*716c1805SNattuvetty Bhavyan } 2106*716c1805SNattuvetty Bhavyan return (rport); 2107*716c1805SNattuvetty Bhavyan } 2108*716c1805SNattuvetty Bhavyan 210945039663SJohn Forte /* 211045039663SJohn Forte * Unmarshal a uint8_t array. 211145039663SJohn Forte * 211245039663SJohn Forte * Takes a buf argument: 211345039663SJohn Forte * 211445039663SJohn Forte * - if non-null, the array contents are copied into the buf, 211545039663SJohn Forte * and we return a pointer to the buffer. 211645039663SJohn Forte * 211745039663SJohn Forte * - if null, we return a pointer to the unmarshaled data, which 211845039663SJohn Forte * resides in the nvlist. 211945039663SJohn Forte * 212045039663SJohn Forte * Returns NULL on failure. 212145039663SJohn Forte */ 212245039663SJohn Forte static uint8_t * 212345039663SJohn Forte stmf_ic_uint8_array_unmarshal( 212445039663SJohn Forte nvlist_t *nvl, 212545039663SJohn Forte char *field_name, 212691159e90SJohn Forte uint64_t len, 212745039663SJohn Forte uint8_t *buf) /* non-NULL: copy array into buf */ 212845039663SJohn Forte { 212945039663SJohn Forte uint8_t *array = NULL; 213045039663SJohn Forte uint_t actual_len; 213145039663SJohn Forte int rc = 0; 213245039663SJohn Forte 213345039663SJohn Forte rc = nvlist_lookup_uint8_array(nvl, field_name, &array, &actual_len); 213445039663SJohn Forte if (rc) { 213545039663SJohn Forte return (NULL); 213645039663SJohn Forte } 213745039663SJohn Forte 213845039663SJohn Forte if (len != actual_len) { 213945039663SJohn Forte cmn_err(CE_WARN, 214045039663SJohn Forte "stmf_ic_uint8_array_unmarshal: wrong len (%d != %d)", 214191159e90SJohn Forte (int)len, actual_len); 214245039663SJohn Forte return (NULL); 214345039663SJohn Forte } 214445039663SJohn Forte 214545039663SJohn Forte if (buf) { 214645039663SJohn Forte /* preallocated buf, copy in */ 214745039663SJohn Forte bcopy(array, buf, len); 214845039663SJohn Forte } else { 214945039663SJohn Forte /* return a pointer to the underlying array in the nvlist */ 215045039663SJohn Forte buf = array; 215145039663SJohn Forte } 215245039663SJohn Forte 215345039663SJohn Forte return (buf); 215445039663SJohn Forte } 215545039663SJohn Forte 215645039663SJohn Forte /* 215745039663SJohn Forte * Unmarshal a string. 215845039663SJohn Forte * 215945039663SJohn Forte * Returns NULL on failure. 216045039663SJohn Forte */ 216145039663SJohn Forte static char * 216245039663SJohn Forte stmf_ic_string_unmarshal( 216345039663SJohn Forte nvlist_t *nvl, 216445039663SJohn Forte char *field_name) 216545039663SJohn Forte { 216645039663SJohn Forte char *s = NULL; 216745039663SJohn Forte int rc = 0; 216845039663SJohn Forte 216945039663SJohn Forte rc = nvlist_lookup_string(nvl, field_name, &s); 217045039663SJohn Forte if (rc) { 217145039663SJohn Forte return (NULL); 217245039663SJohn Forte } 217345039663SJohn Forte 217445039663SJohn Forte return (s); 217545039663SJohn Forte } 217645039663SJohn Forte 217745039663SJohn Forte /* 217845039663SJohn Forte * Utility routines. 217945039663SJohn Forte */ 218045039663SJohn Forte 218145039663SJohn Forte static stmf_ic_msg_t * 218245039663SJohn Forte stmf_ic_alloc_msg_header( 218345039663SJohn Forte stmf_ic_msg_type_t msg_type, 218445039663SJohn Forte stmf_ic_msgid_t msgid) 218545039663SJohn Forte { 218645039663SJohn Forte stmf_ic_msg_t *icm; 218745039663SJohn Forte 218845039663SJohn Forte icm = (stmf_ic_msg_t *)kmem_zalloc(sizeof (*icm), KM_SLEEP); 218945039663SJohn Forte icm->icm_msg_type = msg_type; 219045039663SJohn Forte icm->icm_msgid = msgid; 219145039663SJohn Forte 219245039663SJohn Forte return (icm); 219345039663SJohn Forte } 219445039663SJohn Forte 219545039663SJohn Forte static size_t 219645039663SJohn Forte sizeof_scsi_devid_desc(int ident_length) 219745039663SJohn Forte { 219845039663SJohn Forte int num_ident_elems; 219945039663SJohn Forte size_t size; 220045039663SJohn Forte 220145039663SJohn Forte ASSERT(ident_length > 0); 220245039663SJohn Forte 220345039663SJohn Forte /* 220445039663SJohn Forte * Need to account for the fact that there's 220545039663SJohn Forte * already a single element in scsi_devid_desc_t. 220645039663SJohn Forte * 220745039663SJohn Forte * XXX would really like to have a way to determine the 220845039663SJohn Forte * sizeof (struct scsi_devid_desc.ident[0]), but 220945039663SJohn Forte * it's not clear that can be done. 221045039663SJohn Forte * Thus, this code relies on the knowledge of the type of 221145039663SJohn Forte * that field. 221245039663SJohn Forte */ 221345039663SJohn Forte num_ident_elems = ident_length - 1; 221445039663SJohn Forte size = sizeof (scsi_devid_desc_t) + 221545039663SJohn Forte (num_ident_elems * sizeof (uint8_t)); 221645039663SJohn Forte 221745039663SJohn Forte return (size); 221845039663SJohn Forte } 221945039663SJohn Forte 222045039663SJohn Forte 222145039663SJohn Forte /* 222245039663SJohn Forte * Duplicate the scsi_devid_desc_t. 222345039663SJohn Forte */ 222445039663SJohn Forte static scsi_devid_desc_t * 222545039663SJohn Forte scsi_devid_desc_dup(scsi_devid_desc_t *did) 222645039663SJohn Forte { 222745039663SJohn Forte scsi_devid_desc_t *dup; 222845039663SJohn Forte size_t dup_size; 222945039663SJohn Forte 223045039663SJohn Forte ASSERT(did->ident_length > 0); 223145039663SJohn Forte 223245039663SJohn Forte dup_size = sizeof_scsi_devid_desc(did->ident_length); 223345039663SJohn Forte dup = (scsi_devid_desc_t *)kmem_zalloc(dup_size, KM_SLEEP); 223445039663SJohn Forte bcopy(did, dup, dup_size); 223545039663SJohn Forte return (dup); 223645039663SJohn Forte } 223745039663SJohn Forte 223845039663SJohn Forte /* 223945039663SJohn Forte * May be called with a null pointer. 224045039663SJohn Forte */ 224145039663SJohn Forte static void 224245039663SJohn Forte scsi_devid_desc_free(scsi_devid_desc_t *did) 224345039663SJohn Forte { 224445039663SJohn Forte if (!did) 224545039663SJohn Forte return; 224645039663SJohn Forte 224745039663SJohn Forte kmem_free(did, sizeof_scsi_devid_desc(did->ident_length)); 224845039663SJohn Forte } 224945039663SJohn Forte 2250*716c1805SNattuvetty Bhavyan /* 2251*716c1805SNattuvetty Bhavyan * Duplicate the stmf_remote_port_t. 2252*716c1805SNattuvetty Bhavyan */ 2253*716c1805SNattuvetty Bhavyan static stmf_remote_port_t * 2254*716c1805SNattuvetty Bhavyan remote_port_dup(stmf_remote_port_t *rport) 2255*716c1805SNattuvetty Bhavyan { 2256*716c1805SNattuvetty Bhavyan stmf_remote_port_t *dup = NULL; 2257*716c1805SNattuvetty Bhavyan if (rport) { 2258*716c1805SNattuvetty Bhavyan dup = stmf_remote_port_alloc(rport->rport_tptid_sz); 2259*716c1805SNattuvetty Bhavyan bcopy(rport->rport_tptid, dup->rport_tptid, 2260*716c1805SNattuvetty Bhavyan rport->rport_tptid_sz); 2261*716c1805SNattuvetty Bhavyan } 2262*716c1805SNattuvetty Bhavyan return (dup); 2263*716c1805SNattuvetty Bhavyan } 2264*716c1805SNattuvetty Bhavyan 226545039663SJohn Forte /* 226645039663SJohn Forte * Helper functions, returns NULL if no memory. 226745039663SJohn Forte */ 226845039663SJohn Forte static char * 226945039663SJohn Forte stmf_ic_strdup(char *str) 227045039663SJohn Forte { 227145039663SJohn Forte char *copy; 227245039663SJohn Forte 227345039663SJohn Forte ASSERT(str); 227445039663SJohn Forte 227545039663SJohn Forte copy = kmem_zalloc(strlen(str) + 1, KM_SLEEP); 227645039663SJohn Forte (void) strcpy(copy, str); 227745039663SJohn Forte return (copy); 227845039663SJohn Forte } 227945039663SJohn Forte 228045039663SJohn Forte static inline void 228145039663SJohn Forte stmf_ic_nvlookup_warn(const char *func, char *field) 228245039663SJohn Forte { 228345039663SJohn Forte cmn_err(CE_WARN, "%s: nvlist lookup of %s failed", func, field); 228445039663SJohn Forte } 2285