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