1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 #include <sys/types.h>
27 #include <sys/scsi/generic/commands.h>
28 #include <sys/scsi/impl/commands.h>
29 #include <sys/scsi/generic/smp_frames.h>
30
31 #include <scsi/libsmp.h>
32 #include <scsi/libsmp_plugin.h>
33 #include "sas2.h"
34
35 /*ARGSUSED*/
36 static size_t
sas2_rq_len(size_t user,smp_target_t * tp)37 sas2_rq_len(size_t user, smp_target_t *tp)
38 {
39 if (user != 0) {
40 (void) smp_set_errno(ESMP_RANGE);
41 return (0);
42 }
43
44 return (SMP_REQ_MINLEN);
45 }
46
47 /*ARGSUSED*/
48 static off_t
sas2_rq_dataoff(smp_action_t * ap,smp_target_t * tp)49 sas2_rq_dataoff(smp_action_t *ap, smp_target_t *tp)
50 {
51 size_t len;
52
53 smp_action_get_request_frame(ap, NULL, &len);
54
55 if (len > SMP_REQ_MINLEN)
56 return (offsetof(smp_request_frame_t, srf_data[0]));
57
58 return (-1);
59 }
60
61 static void
sas2_rq_setframe(smp_action_t * ap,smp_target_t * tp)62 sas2_rq_setframe(smp_action_t *ap, smp_target_t *tp)
63 {
64 const smp_function_def_t *dp = smp_action_get_function_def(ap);
65 smp_request_frame_t *fp;
66 uint_t cap;
67 uint16_t change_count;
68 uint16_t *rqcc;
69 size_t rqlen, rslen;
70
71 smp_action_get_request_frame(ap, (void *)&fp, &rqlen);
72 smp_action_get_response_frame(ap, NULL, &rslen);
73 cap = smp_target_getcap(tp);
74
75 fp->srf_frame_type = SMP_FRAME_TYPE_REQUEST;
76 fp->srf_function = dp->sfd_function;
77
78 if (cap & SMP_TARGET_C_LONG_RESP) {
79 fp->srf_allocated_response_len = (rslen - SMP_RESP_MINLEN) / 4;
80 fp->srf_request_len = (rqlen - SMP_REQ_MINLEN) / 4;
81 } else {
82 fp->srf_allocated_response_len = 0;
83 fp->srf_request_len = 0;
84 }
85
86 /*
87 * If this command requires that the expected expander change count
88 * be set (as many do), we will attempt to set it based on the
89 * most recently executed command. However, if the user has set it
90 * already, we will not overwrite that setting. It is the consumer's
91 * responsibility to keep track of expander changes each time it
92 * receives a new change count in a response.
93 */
94 if (dp->sfd_flags & SMP_FD_F_NEEDS_CHANGE_COUNT) {
95 ASSERT(rqlen >= SMP_REQ_MINLEN + sizeof (uint16_t));
96 /* LINTED - alignment */
97 rqcc = (uint16_t *)(&fp->srf_data[0]);
98 if (SCSI_READ16(rqcc) == 0) {
99 change_count = smp_target_get_change_count(tp);
100 SCSI_WRITE16(rqcc, change_count);
101 }
102 }
103 }
104
105 /*ARGSUSED*/
106 static size_t
sas2_rs_datalen(smp_action_t * ap,smp_target_t * tp)107 sas2_rs_datalen(smp_action_t *ap, smp_target_t *tp)
108 {
109 smp_response_frame_t *fp;
110 size_t len;
111
112 smp_action_get_response_frame(ap, (void **)&fp, &len);
113
114 if (len >= SMP_RESP_MINLEN)
115 len -= SMP_RESP_MINLEN;
116 else
117 return (0);
118
119 len &= ~3;
120
121 if (fp->srf_response_len == 0)
122 return (0);
123
124 return (MIN(len, 4 * (fp->srf_response_len)));
125 }
126
127 /*ARGSUSED*/
128 static off_t
sas2_rs_dataoff(smp_action_t * ap,smp_target_t * tp)129 sas2_rs_dataoff(smp_action_t *ap, smp_target_t *tp)
130 {
131 size_t len;
132
133 smp_action_get_response_frame(ap, NULL, &len);
134
135 if (len > SMP_RESP_MINLEN)
136 return (offsetof(smp_request_frame_t, srf_data[0]));
137
138 return (-1);
139 }
140
141 static void
sas2_rs_getparams(smp_action_t * ap,smp_target_t * tp)142 sas2_rs_getparams(smp_action_t *ap, smp_target_t *tp)
143 {
144 const smp_function_def_t *dp;
145 smp_response_frame_t *fp;
146 size_t len;
147 uint16_t change_count;
148
149 dp = smp_action_get_function_def(ap);
150
151 smp_action_get_response_frame(ap, (void **)&fp, &len);
152
153 smp_action_set_result(ap, fp->srf_result);
154
155 if (!(dp->sfd_flags & SMP_FD_F_PROVIDES_CHANGE_COUNT))
156 return;
157
158 if (len <= SMP_RESP_MINLEN + sizeof (uint16_t))
159 return;
160
161 change_count = SCSI_READ16(&fp->srf_data[0]);
162 smp_target_set_change_count(tp, change_count);
163 }
164
165 /*ARGSUSED*/
166 static size_t
sas2_report_general_rs_datalen(smp_action_t * ap,smp_target_t * tp)167 sas2_report_general_rs_datalen(smp_action_t *ap, smp_target_t *tp)
168 {
169 const smp_function_def_t *dp = smp_action_get_function_def(ap);
170 smp_response_frame_t *fp;
171 size_t len;
172
173 ASSERT(dp->sfd_function == SMP_FUNC_REPORT_GENERAL);
174 smp_action_get_response_frame(ap, (void **)&fp, &len);
175
176 if (len >= SMP_RESP_MINLEN)
177 len -= SMP_RESP_MINLEN;
178 else
179 return (0);
180
181 len &= ~3;
182
183 if (fp->srf_response_len == 0)
184 return (MIN(len, 24));
185
186 return (MIN(len, 4 * (fp->srf_response_len)));
187 }
188
189 /*ARGSUSED*/
190 static size_t
sas2_report_manufacturer_info_rs_datalen(smp_action_t * ap,smp_target_t * tp)191 sas2_report_manufacturer_info_rs_datalen(smp_action_t *ap, smp_target_t *tp)
192 {
193 const smp_function_def_t *dp = smp_action_get_function_def(ap);
194 smp_response_frame_t *fp;
195 size_t len;
196
197 ASSERT(dp->sfd_function == SMP_FUNC_REPORT_MANUFACTURER_INFO);
198 smp_action_get_response_frame(ap, (void **)&fp, &len);
199
200 if (len >= SMP_RESP_MINLEN)
201 len -= SMP_RESP_MINLEN;
202 else
203 return (0);
204
205 len &= ~3;
206
207 if (fp->srf_response_len == 0)
208 return (MIN(len, 56));
209
210 return (MIN(len, 4 * (fp->srf_response_len)));
211 }
212
213 /*ARGSUSED*/
214 static size_t
sas2_report_self_config_status_rq_len(size_t user,smp_target_t * tp)215 sas2_report_self_config_status_rq_len(size_t user, smp_target_t *tp)
216 {
217 if (user != 0) {
218 (void) smp_set_errno(ESMP_RANGE);
219 return (0);
220 }
221
222 return (SMP_REQ_MINLEN + sizeof (smp_report_self_config_status_req_t));
223 }
224
225 /*ARGSUSED*/
226 static size_t
sas2_report_zone_perm_table_rq_len(size_t user,smp_target_t * tp)227 sas2_report_zone_perm_table_rq_len(size_t user, smp_target_t *tp)
228 {
229 if (user != 0) {
230 (void) smp_set_errno(ESMP_RANGE);
231 return (0);
232 }
233
234 return (SMP_REQ_MINLEN + sizeof (smp_report_zone_perm_table_req_t));
235 }
236
237 /*ARGSUSED*/
238 static size_t
sas2_report_zone_mgr_password_rq_len(size_t user,smp_target_t * tp)239 sas2_report_zone_mgr_password_rq_len(size_t user, smp_target_t *tp)
240 {
241 if (user != 0) {
242 (void) smp_set_errno(ESMP_RANGE);
243 return (0);
244 }
245
246 return (SMP_REQ_MINLEN + sizeof (smp_report_zone_perm_table_req_t));
247 }
248
249 /*ARGSUSED*/
250 static size_t
sas2_report_broadcast_rq_len(size_t user,smp_target_t * tp)251 sas2_report_broadcast_rq_len(size_t user, smp_target_t *tp)
252 {
253 if (user != 0) {
254 (void) smp_set_errno(ESMP_RANGE);
255 return (0);
256 }
257
258 return (SMP_REQ_MINLEN + sizeof (smp_report_broadcast_req_t));
259 }
260
261 /*ARGSUSED*/
262 static size_t
sas2_discover_rq_len(size_t user,smp_target_t * tp)263 sas2_discover_rq_len(size_t user, smp_target_t *tp)
264 {
265 if (user != 0) {
266 (void) smp_set_errno(ESMP_RANGE);
267 return (0);
268 }
269
270 return (SMP_REQ_MINLEN + sizeof (smp_discover_req_t));
271 }
272
273 /*ARGSUSED*/
274 static size_t
sas2_discover_rs_datalen(smp_action_t * ap,smp_target_t * tp)275 sas2_discover_rs_datalen(smp_action_t *ap, smp_target_t *tp)
276 {
277 const smp_function_def_t *dp = smp_action_get_function_def(ap);
278 smp_response_frame_t *fp;
279 size_t len;
280
281 ASSERT(dp->sfd_function == SMP_FUNC_DISCOVER);
282 smp_action_get_response_frame(ap, (void **)&fp, &len);
283
284 if (len >= SMP_RESP_MINLEN)
285 len -= SMP_RESP_MINLEN;
286 else
287 return (0);
288
289 len &= ~3;
290
291 if (fp->srf_response_len == 0)
292 return (MIN(len, 48));
293
294 return (MIN(len, 4 * (fp->srf_response_len)));
295 }
296
297 /*ARGSUSED*/
298 static size_t
sas2_report_phy_error_log_rq_len(size_t user,smp_target_t * tp)299 sas2_report_phy_error_log_rq_len(size_t user, smp_target_t *tp)
300 {
301 if (user != 0) {
302 (void) smp_set_errno(ESMP_RANGE);
303 return (0);
304 }
305
306 return (SMP_REQ_MINLEN + sizeof (smp_report_phy_error_log_req_t));
307 }
308
309 /*ARGSUSED*/
310 static size_t
sas2_report_phy_error_log_rs_datalen(smp_action_t * ap,smp_target_t * tp)311 sas2_report_phy_error_log_rs_datalen(smp_action_t *ap, smp_target_t *tp)
312 {
313 const smp_function_def_t *dp = smp_action_get_function_def(ap);
314 smp_response_frame_t *fp;
315 size_t len;
316
317 ASSERT(dp->sfd_function == SMP_FUNC_REPORT_PHY_ERROR_LOG);
318 smp_action_get_response_frame(ap, (void **)&fp, &len);
319
320 if (len >= SMP_RESP_MINLEN)
321 len -= SMP_RESP_MINLEN;
322 else
323 return (0);
324
325 len &= ~3;
326
327 if (fp->srf_response_len == 0)
328 return (MIN(len, sizeof (smp_report_phy_error_log_resp_t)));
329
330 return (MIN(len, 4 * (fp->srf_response_len)));
331 }
332
333 /*ARGSUSED*/
334 static size_t
sas2_report_phy_sata_rq_len(size_t user,smp_target_t * tp)335 sas2_report_phy_sata_rq_len(size_t user, smp_target_t *tp)
336 {
337 if (user != 0) {
338 (void) smp_set_errno(ESMP_RANGE);
339 return (0);
340 }
341
342 return (SMP_REQ_MINLEN + sizeof (smp_report_phy_sata_req_t));
343 }
344
345 /*ARGSUSED*/
346 static size_t
sas2_report_phy_sata_rs_datalen(smp_action_t * ap,smp_target_t * tp)347 sas2_report_phy_sata_rs_datalen(smp_action_t *ap, smp_target_t *tp)
348 {
349 const smp_function_def_t *dp = smp_action_get_function_def(ap);
350 smp_response_frame_t *fp;
351 size_t len;
352
353 ASSERT(dp->sfd_function == SMP_FUNC_REPORT_PHY_SATA);
354 smp_action_get_response_frame(ap, (void **)&fp, &len);
355
356 if (len >= SMP_RESP_MINLEN)
357 len -= SMP_RESP_MINLEN;
358 else
359 return (0);
360
361 len &= ~3;
362
363 if (fp->srf_response_len == 0)
364 return (MIN(len, 52));
365
366 return (MIN(len, 4 * (fp->srf_response_len)));
367 }
368
369 /*ARGSUSED*/
370 static size_t
sas2_report_route_info_rq_len(size_t user,smp_target_t * tp)371 sas2_report_route_info_rq_len(size_t user, smp_target_t *tp)
372 {
373 if (user != 0) {
374 (void) smp_set_errno(ESMP_RANGE);
375 return (0);
376 }
377
378 return (SMP_REQ_MINLEN + sizeof (smp_report_route_info_req_t));
379 }
380
381 /*ARGSUSED*/
382 static size_t
sas2_report_route_info_rs_datalen(smp_action_t * ap,smp_target_t * tp)383 sas2_report_route_info_rs_datalen(smp_action_t *ap, smp_target_t *tp)
384 {
385 const smp_function_def_t *dp = smp_action_get_function_def(ap);
386 smp_response_frame_t *fp;
387 size_t len;
388
389 ASSERT(dp->sfd_function == SMP_FUNC_REPORT_ROUTE_INFO);
390 smp_action_get_response_frame(ap, (void **)&fp, &len);
391
392 if (len >= SMP_RESP_MINLEN)
393 len -= SMP_RESP_MINLEN;
394 else
395 return (0);
396
397 len &= ~3;
398
399 if (fp->srf_response_len == 0)
400 return (MIN(len, sizeof (smp_report_route_info_resp_t)));
401
402 return (MIN(len, 4 * (fp->srf_response_len)));
403 }
404
405 /*ARGSUSED*/
406 static size_t
sas2_report_phy_event_rq_len(size_t user,smp_target_t * tp)407 sas2_report_phy_event_rq_len(size_t user, smp_target_t *tp)
408 {
409 if (user != 0) {
410 (void) smp_set_errno(ESMP_RANGE);
411 return (0);
412 }
413
414 return (SMP_REQ_MINLEN + sizeof (smp_report_phy_event_req_t));
415 }
416
417 /*ARGSUSED*/
418 static size_t
sas2_discover_list_rq_len(size_t user,smp_target_t * tp)419 sas2_discover_list_rq_len(size_t user, smp_target_t *tp)
420 {
421 if (user != 0) {
422 (void) smp_set_errno(ESMP_RANGE);
423 return (0);
424 }
425
426 return (SMP_REQ_MINLEN + sizeof (smp_discover_list_req_t));
427 }
428
429 /*ARGSUSED*/
430 static size_t
sas2_report_phy_event_list_rq_len(size_t user,smp_target_t * tp)431 sas2_report_phy_event_list_rq_len(size_t user, smp_target_t *tp)
432 {
433 if (user != 0) {
434 (void) smp_set_errno(ESMP_RANGE);
435 return (0);
436 }
437
438 return (SMP_REQ_MINLEN + sizeof (smp_report_phy_event_list_req_t));
439 }
440
441 /*ARGSUSED*/
442 static size_t
sas2_report_exp_route_table_list_rq_len(size_t user,smp_target_t * tp)443 sas2_report_exp_route_table_list_rq_len(size_t user, smp_target_t *tp)
444 {
445 if (user != 0) {
446 (void) smp_set_errno(ESMP_RANGE);
447 return (0);
448 }
449
450 return (SMP_REQ_MINLEN +
451 sizeof (smp_report_exp_route_table_list_req_t));
452 }
453
454 /*ARGSUSED*/
455 static size_t
sas2_config_general_rq_len(size_t user,smp_target_t * tp)456 sas2_config_general_rq_len(size_t user, smp_target_t *tp)
457 {
458 if (user != 0) {
459 (void) smp_set_errno(ESMP_RANGE);
460 return (0);
461 }
462
463 return (SMP_REQ_MINLEN + sizeof (smp_config_general_req_t));
464 }
465
466 /*ARGSUSED*/
467 static size_t
sas2_enable_disable_zoning_rq_len(size_t user,smp_target_t * tp)468 sas2_enable_disable_zoning_rq_len(size_t user, smp_target_t *tp)
469 {
470 if (user != 0) {
471 (void) smp_set_errno(ESMP_RANGE);
472 return (0);
473 }
474
475 return (SMP_REQ_MINLEN + sizeof (smp_enable_disable_zoning_req_t));
476 }
477
478 /*ARGSUSED*/
479 static size_t
sas2_zoned_broadcast_rq_len(size_t user,smp_target_t * tp)480 sas2_zoned_broadcast_rq_len(size_t user, smp_target_t *tp)
481 {
482 size_t descrsz;
483
484 if (user == 0 || user > 1008) {
485 (void) smp_set_errno(ESMP_RANGE);
486 return (0);
487 }
488
489 descrsz = P2ROUNDUP((user - 1), 4);
490
491 return (SMP_REQ_MINLEN + descrsz + sizeof (smp_zoned_broadcast_req_t));
492 }
493
494 /*ARGSUSED*/
495 static size_t
sas2_zone_lock_rq_len(size_t user,smp_target_t * tp)496 sas2_zone_lock_rq_len(size_t user, smp_target_t *tp)
497 {
498 if (user != 0) {
499 (void) smp_set_errno(ESMP_RANGE);
500 return (0);
501 }
502
503 return (SMP_REQ_MINLEN + sizeof (smp_zone_lock_req_t));
504 }
505
506 /*ARGSUSED*/
507 static size_t
sas2_zone_activate_rq_len(size_t user,smp_target_t * tp)508 sas2_zone_activate_rq_len(size_t user, smp_target_t *tp)
509 {
510 if (user != 0) {
511 (void) smp_set_errno(ESMP_RANGE);
512 return (0);
513 }
514
515 return (SMP_REQ_MINLEN + sizeof (smp_zone_activate_req_t));
516 }
517
518 /*ARGSUSED*/
519 static size_t
sas2_zone_unlock_rq_len(size_t user,smp_target_t * tp)520 sas2_zone_unlock_rq_len(size_t user, smp_target_t *tp)
521 {
522 if (user != 0) {
523 (void) smp_set_errno(ESMP_RANGE);
524 return (0);
525 }
526
527 return (SMP_REQ_MINLEN + sizeof (smp_zone_unlock_req_t));
528 }
529
530 /*ARGSUSED*/
531 static size_t
sas2_config_zone_manager_password_rq_len(size_t user,smp_target_t * tp)532 sas2_config_zone_manager_password_rq_len(size_t user, smp_target_t *tp)
533 {
534 if (user != 0) {
535 (void) smp_set_errno(ESMP_RANGE);
536 return (0);
537 }
538
539 return (SMP_REQ_MINLEN +
540 sizeof (smp_config_zone_manager_password_req_t));
541 }
542
543 /*ARGSUSED*/
544 static size_t
sas2_config_zone_phy_info_rq_len(size_t user,smp_target_t * tp)545 sas2_config_zone_phy_info_rq_len(size_t user, smp_target_t *tp)
546 {
547 if (user == 0 || user > 252) {
548 (void) smp_set_errno(ESMP_RANGE);
549 return (0);
550 }
551
552 return (SMP_REQ_MINLEN + sizeof (smp_config_zone_phy_info_req_t) +
553 (user - 1) * sizeof (smp_zone_phy_config_descr_t));
554 }
555
556 static size_t
sas2_config_zone_perm_table_rq_len(size_t user,smp_target_t * tp)557 sas2_config_zone_perm_table_rq_len(size_t user, smp_target_t *tp)
558 {
559 uint_t cap = smp_target_getcap(tp);
560 size_t maxdescr, descrsz;
561
562 if (cap & SMP_TARGET_C_ZG_256)
563 descrsz = sizeof (smp_zone_perm_descr256_t);
564 else
565 descrsz = sizeof (smp_zone_perm_descr128_t);
566
567 maxdescr = (1020 - sizeof (smp_config_zone_perm_table_req_t)) / descrsz;
568
569 if (user == 0 || user > maxdescr) {
570 (void) smp_set_errno(ESMP_RANGE);
571 return (0);
572 }
573
574 return (SMP_REQ_MINLEN + sizeof (smp_config_zone_perm_table_req_t) - 1 +
575 user * descrsz);
576 }
577
578 /*ARGSUSED*/
579 static size_t
sas2_config_route_info_rq_len(size_t user,smp_target_t * tp)580 sas2_config_route_info_rq_len(size_t user, smp_target_t *tp)
581 {
582 if (user != 0) {
583 (void) smp_set_errno(ESMP_RANGE);
584 return (0);
585 }
586
587 return (SMP_REQ_MINLEN + sizeof (smp_config_route_info_req_t));
588 }
589
590 /*ARGSUSED*/
591 static size_t
sas2_phy_control_rq_len(size_t user,smp_target_t * tp)592 sas2_phy_control_rq_len(size_t user, smp_target_t *tp)
593 {
594 if (user != 0) {
595 (void) smp_set_errno(ESMP_RANGE);
596 return (0);
597 }
598
599 return (SMP_REQ_MINLEN + sizeof (smp_phy_control_req_t));
600 }
601
602 /*ARGSUSED*/
603 static size_t
sas2_phy_test_function_rq_len(size_t user,smp_target_t * tp)604 sas2_phy_test_function_rq_len(size_t user, smp_target_t *tp)
605 {
606 if (user != 0) {
607 (void) smp_set_errno(ESMP_RANGE);
608 return (0);
609 }
610
611 return (SMP_REQ_MINLEN + sizeof (smp_phy_test_function_req_t));
612 }
613
614 /*ARGSUSED*/
615 static size_t
sas2_config_phy_event_rq_len(size_t user,smp_target_t * tp)616 sas2_config_phy_event_rq_len(size_t user, smp_target_t *tp)
617 {
618 if (user == 0 || user > 126) {
619 (void) smp_set_errno(ESMP_RANGE);
620 return (0);
621 }
622
623 return (SMP_REQ_MINLEN + sizeof (smp_config_phy_event_req_t) +
624 (user - 1) * sizeof (smp_phy_event_config_descr_t));
625 }
626
627 smp_function_def_t sas2_functions[] = {
628 {
629 .sfd_function = SMP_FUNC_REPORT_GENERAL,
630 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_PROVIDES_CHANGE_COUNT,
631 .sfd_rq_len = sas2_rq_len,
632 .sfd_rq_dataoff = sas2_rq_dataoff,
633 .sfd_rq_setframe = sas2_rq_setframe,
634 .sfd_rs_datalen = sas2_report_general_rs_datalen,
635 .sfd_rs_dataoff = sas2_rs_dataoff,
636 .sfd_rs_getparams = sas2_rs_getparams
637 },
638 {
639 .sfd_function = SMP_FUNC_REPORT_MANUFACTURER_INFO,
640 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_PROVIDES_CHANGE_COUNT,
641 .sfd_rq_len = sas2_rq_len,
642 .sfd_rq_dataoff = sas2_rq_dataoff,
643 .sfd_rq_setframe = sas2_rq_setframe,
644 .sfd_rs_datalen = sas2_report_manufacturer_info_rs_datalen,
645 .sfd_rs_dataoff = sas2_rs_dataoff,
646 .sfd_rs_getparams = sas2_rs_getparams
647 },
648 {
649 .sfd_function = SMP_FUNC_REPORT_SELF_CONFIG_STATUS,
650 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
651 SMP_FD_F_PROVIDES_CHANGE_COUNT,
652 .sfd_rq_len = sas2_report_self_config_status_rq_len,
653 .sfd_rq_dataoff = sas2_rq_dataoff,
654 .sfd_rq_setframe = sas2_rq_setframe,
655 .sfd_rs_datalen = sas2_rs_datalen,
656 .sfd_rs_dataoff = sas2_rs_dataoff,
657 .sfd_rs_getparams = sas2_rs_getparams
658 },
659 {
660 .sfd_function = SMP_FUNC_REPORT_ZONE_PERM_TABLE,
661 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
662 SMP_FD_F_PROVIDES_CHANGE_COUNT,
663 .sfd_rq_len = sas2_report_zone_perm_table_rq_len,
664 .sfd_rq_dataoff = sas2_rq_dataoff,
665 .sfd_rq_setframe = sas2_rq_setframe,
666 .sfd_rs_datalen = sas2_rs_datalen,
667 .sfd_rs_dataoff = sas2_rs_dataoff,
668 .sfd_rs_getparams = sas2_rs_getparams
669 },
670 {
671 .sfd_function = SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD,
672 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_PROVIDES_CHANGE_COUNT,
673 .sfd_rq_len = sas2_report_zone_mgr_password_rq_len,
674 .sfd_rq_dataoff = sas2_rq_dataoff,
675 .sfd_rq_setframe = sas2_rq_setframe,
676 .sfd_rs_datalen = sas2_rs_datalen,
677 .sfd_rs_dataoff = sas2_rs_dataoff,
678 .sfd_rs_getparams = sas2_rs_getparams
679 },
680 {
681 .sfd_function = SMP_FUNC_REPORT_BROADCAST,
682 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
683 SMP_FD_F_PROVIDES_CHANGE_COUNT,
684 .sfd_rq_len = sas2_report_broadcast_rq_len,
685 .sfd_rq_dataoff = sas2_rq_dataoff,
686 .sfd_rq_setframe = sas2_rq_setframe,
687 .sfd_rs_datalen = sas2_rs_datalen,
688 .sfd_rs_dataoff = sas2_rs_dataoff,
689 .sfd_rs_getparams = sas2_rs_getparams
690 },
691 {
692 .sfd_function = SMP_FUNC_DISCOVER,
693 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
694 SMP_FD_F_PROVIDES_CHANGE_COUNT,
695 .sfd_rq_len = sas2_discover_rq_len,
696 .sfd_rq_dataoff = sas2_rq_dataoff,
697 .sfd_rq_setframe = sas2_rq_setframe,
698 .sfd_rs_datalen = sas2_discover_rs_datalen,
699 .sfd_rs_dataoff = sas2_rs_dataoff,
700 .sfd_rs_getparams = sas2_rs_getparams
701 },
702 {
703 .sfd_function = SMP_FUNC_REPORT_PHY_ERROR_LOG,
704 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
705 SMP_FD_F_PROVIDES_CHANGE_COUNT,
706 .sfd_rq_len = sas2_report_phy_error_log_rq_len,
707 .sfd_rq_dataoff = sas2_rq_dataoff,
708 .sfd_rq_setframe = sas2_rq_setframe,
709 .sfd_rs_datalen = sas2_report_phy_error_log_rs_datalen,
710 .sfd_rs_dataoff = sas2_rs_dataoff,
711 .sfd_rs_getparams = sas2_rs_getparams
712 },
713 {
714 .sfd_function = SMP_FUNC_REPORT_PHY_SATA,
715 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
716 SMP_FD_F_PROVIDES_CHANGE_COUNT,
717 .sfd_rq_len = sas2_report_phy_sata_rq_len,
718 .sfd_rq_dataoff = sas2_rq_dataoff,
719 .sfd_rq_setframe = sas2_rq_setframe,
720 .sfd_rs_datalen = sas2_report_phy_sata_rs_datalen,
721 .sfd_rs_dataoff = sas2_rs_dataoff,
722 .sfd_rs_getparams = sas2_rs_getparams
723 },
724 {
725 .sfd_function = SMP_FUNC_REPORT_ROUTE_INFO,
726 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
727 SMP_FD_F_PROVIDES_CHANGE_COUNT,
728 .sfd_rq_len = sas2_report_route_info_rq_len,
729 .sfd_rq_dataoff = sas2_rq_dataoff,
730 .sfd_rq_setframe = sas2_rq_setframe,
731 .sfd_rs_datalen = sas2_report_route_info_rs_datalen,
732 .sfd_rs_dataoff = sas2_rs_dataoff,
733 .sfd_rs_getparams = sas2_rs_getparams
734 },
735 {
736 .sfd_function = SMP_FUNC_REPORT_PHY_EVENT,
737 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
738 SMP_FD_F_PROVIDES_CHANGE_COUNT,
739 .sfd_rq_len = sas2_report_phy_event_rq_len,
740 .sfd_rq_dataoff = sas2_rq_dataoff,
741 .sfd_rq_setframe = sas2_rq_setframe,
742 .sfd_rs_datalen = sas2_rs_datalen,
743 .sfd_rs_dataoff = sas2_rs_dataoff,
744 .sfd_rs_getparams = sas2_rs_getparams
745 },
746 {
747 .sfd_function = SMP_FUNC_DISCOVER_LIST,
748 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
749 SMP_FD_F_PROVIDES_CHANGE_COUNT,
750 .sfd_rq_len = sas2_discover_list_rq_len,
751 .sfd_rq_dataoff = sas2_rq_dataoff,
752 .sfd_rq_setframe = sas2_rq_setframe,
753 .sfd_rs_datalen = sas2_rs_datalen,
754 .sfd_rs_dataoff = sas2_rs_dataoff,
755 .sfd_rs_getparams = sas2_rs_getparams
756 },
757 {
758 .sfd_function = SMP_FUNC_REPORT_PHY_EVENT_LIST,
759 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
760 SMP_FD_F_PROVIDES_CHANGE_COUNT,
761 .sfd_rq_len = sas2_report_phy_event_list_rq_len,
762 .sfd_rq_dataoff = sas2_rq_dataoff,
763 .sfd_rq_setframe = sas2_rq_setframe,
764 .sfd_rs_datalen = sas2_rs_datalen,
765 .sfd_rs_dataoff = sas2_rs_dataoff,
766 .sfd_rs_getparams = sas2_rs_getparams
767 },
768 {
769 .sfd_function = SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST,
770 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
771 SMP_FD_F_PROVIDES_CHANGE_COUNT,
772 .sfd_rq_len = sas2_report_exp_route_table_list_rq_len,
773 .sfd_rq_dataoff = sas2_rq_dataoff,
774 .sfd_rq_setframe = sas2_rq_setframe,
775 .sfd_rs_datalen = sas2_rs_datalen,
776 .sfd_rs_dataoff = sas2_rs_dataoff,
777 .sfd_rs_getparams = sas2_rs_getparams
778 },
779 {
780 .sfd_function = SMP_FUNC_CONFIG_GENERAL,
781 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
782 .sfd_rq_len = sas2_config_general_rq_len,
783 .sfd_rq_dataoff = sas2_rq_dataoff,
784 .sfd_rq_setframe = sas2_rq_setframe,
785 .sfd_rs_datalen = sas2_rs_datalen,
786 .sfd_rs_dataoff = sas2_rs_dataoff,
787 .sfd_rs_getparams = sas2_rs_getparams
788 },
789 {
790 .sfd_function = SMP_FUNC_ENABLE_DISABLE_ZONING,
791 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
792 .sfd_rq_len = sas2_enable_disable_zoning_rq_len,
793 .sfd_rq_dataoff = sas2_rq_dataoff,
794 .sfd_rq_setframe = sas2_rq_setframe,
795 .sfd_rs_datalen = sas2_rs_datalen,
796 .sfd_rs_dataoff = sas2_rs_dataoff,
797 .sfd_rs_getparams = sas2_rs_getparams
798 },
799 {
800 .sfd_function = SMP_FUNC_ZONED_BROADCAST,
801 .sfd_flags = SMP_FD_F_WRITE,
802 .sfd_rq_len = sas2_zoned_broadcast_rq_len,
803 .sfd_rq_dataoff = sas2_rq_dataoff,
804 .sfd_rq_setframe = sas2_rq_setframe,
805 .sfd_rs_datalen = sas2_rs_datalen,
806 .sfd_rs_dataoff = sas2_rs_dataoff,
807 .sfd_rs_getparams = sas2_rs_getparams
808 },
809 {
810 .sfd_function = SMP_FUNC_ZONE_LOCK,
811 .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
812 SMP_FD_F_NEEDS_CHANGE_COUNT,
813 .sfd_rq_len = sas2_zone_lock_rq_len,
814 .sfd_rq_dataoff = sas2_rq_dataoff,
815 .sfd_rq_setframe = sas2_rq_setframe,
816 .sfd_rs_datalen = sas2_rs_datalen,
817 .sfd_rs_dataoff = sas2_rs_dataoff,
818 .sfd_rs_getparams = sas2_rs_getparams
819 },
820 {
821 .sfd_function = SMP_FUNC_ZONE_ACTIVATE,
822 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
823 .sfd_rq_len = sas2_zone_activate_rq_len,
824 .sfd_rq_dataoff = sas2_rq_dataoff,
825 .sfd_rq_setframe = sas2_rq_setframe,
826 .sfd_rs_datalen = sas2_rs_datalen,
827 .sfd_rs_dataoff = sas2_rs_dataoff,
828 .sfd_rs_getparams = sas2_rs_getparams
829 },
830 {
831 .sfd_function = SMP_FUNC_ZONE_UNLOCK,
832 .sfd_flags = SMP_FD_F_WRITE,
833 .sfd_rq_len = sas2_zone_unlock_rq_len,
834 .sfd_rq_dataoff = sas2_rq_dataoff,
835 .sfd_rq_setframe = sas2_rq_setframe,
836 .sfd_rs_datalen = sas2_rs_datalen,
837 .sfd_rs_dataoff = sas2_rs_dataoff,
838 .sfd_rs_getparams = sas2_rs_getparams
839 },
840 {
841 .sfd_function = SMP_FUNC_CONFIG_ZONE_MANAGER_PASSWORD,
842 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
843 .sfd_rq_len = sas2_config_zone_manager_password_rq_len,
844 .sfd_rq_dataoff = sas2_rq_dataoff,
845 .sfd_rq_setframe = sas2_rq_setframe,
846 .sfd_rs_datalen = sas2_rs_datalen,
847 .sfd_rs_dataoff = sas2_rs_dataoff,
848 .sfd_rs_getparams = sas2_rs_getparams
849 },
850 {
851 .sfd_function = SMP_FUNC_CONFIG_ZONE_PHY_INFO,
852 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
853 .sfd_rq_len = sas2_config_zone_phy_info_rq_len,
854 .sfd_rq_dataoff = sas2_rq_dataoff,
855 .sfd_rq_setframe = sas2_rq_setframe,
856 .sfd_rs_datalen = sas2_rs_datalen,
857 .sfd_rs_dataoff = sas2_rs_dataoff,
858 .sfd_rs_getparams = sas2_rs_getparams
859 },
860 {
861 .sfd_function = SMP_FUNC_CONFIG_ZONE_PERM_TABLE,
862 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
863 .sfd_rq_len = sas2_config_zone_perm_table_rq_len,
864 .sfd_rq_dataoff = sas2_rq_dataoff,
865 .sfd_rq_setframe = sas2_rq_setframe,
866 .sfd_rs_datalen = sas2_rs_datalen,
867 .sfd_rs_dataoff = sas2_rs_dataoff,
868 .sfd_rs_getparams = sas2_rs_getparams
869 },
870 {
871 .sfd_function = SMP_FUNC_CONFIG_ROUTE_INFO,
872 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
873 .sfd_rq_len = sas2_config_route_info_rq_len,
874 .sfd_rq_dataoff = sas2_rq_dataoff,
875 .sfd_rq_setframe = sas2_rq_setframe,
876 .sfd_rs_datalen = sas2_rs_datalen,
877 .sfd_rs_dataoff = sas2_rs_dataoff,
878 .sfd_rs_getparams = sas2_rs_getparams
879 },
880 {
881 .sfd_function = SMP_FUNC_PHY_CONTROL,
882 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
883 .sfd_rq_len = sas2_phy_control_rq_len,
884 .sfd_rq_dataoff = sas2_rq_dataoff,
885 .sfd_rq_setframe = sas2_rq_setframe,
886 .sfd_rs_datalen = sas2_rs_datalen,
887 .sfd_rs_dataoff = sas2_rs_dataoff,
888 .sfd_rs_getparams = sas2_rs_getparams
889 },
890 {
891 .sfd_function = SMP_FUNC_PHY_TEST_FUNCTION,
892 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
893 .sfd_rq_len = sas2_phy_test_function_rq_len,
894 .sfd_rq_dataoff = sas2_rq_dataoff,
895 .sfd_rq_setframe = sas2_rq_setframe,
896 .sfd_rs_datalen = sas2_rs_datalen,
897 .sfd_rs_dataoff = sas2_rs_dataoff,
898 .sfd_rs_getparams = sas2_rs_getparams
899 },
900 {
901 .sfd_function = SMP_FUNC_CONFIG_PHY_EVENT,
902 .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
903 .sfd_rq_len = sas2_config_phy_event_rq_len,
904 .sfd_rq_dataoff = sas2_rq_dataoff,
905 .sfd_rq_setframe = sas2_rq_setframe,
906 .sfd_rs_datalen = sas2_rs_datalen,
907 .sfd_rs_dataoff = sas2_rs_dataoff,
908 .sfd_rs_getparams = sas2_rs_getparams
909 },
910 {
911 .sfd_function = -1
912 }
913 };
914
915 /*
916 * Returns the number of bytes in the request frame, including the header
917 * and footer, for the given function and capabilities. Presently the only
918 * relevant capability is long-request, which in some cases increases the
919 * size of the request from the SAS-1 spec to that found in SAS-2.
920 *
921 * Variably-sized request frames have no default size; we return 0 in that
922 * case, which will often be interpreted by the caller as an error although
923 * in general it is not.
924 */
925 size_t
smp_default_request_len(uint_t cap,smp_function_t fn)926 smp_default_request_len(uint_t cap, smp_function_t fn)
927 {
928 switch (fn) {
929 case SMP_FUNC_REPORT_GENERAL:
930 case SMP_FUNC_REPORT_MANUFACTURER_INFO:
931 return (SMP_REQ_MINLEN);
932 case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD:
933 return (SMP_REQ_MINLEN +
934 sizeof (smp_report_zone_mgr_password_req_t));
935 case SMP_FUNC_REPORT_SELF_CONFIG_STATUS:
936 if (cap & SMP_TARGET_C_LONG_RESP)
937 return (SMP_REQ_MINLEN +
938 sizeof (smp_report_self_config_status_req_t));
939 return (SMP_REQ_MINLEN);
940 case SMP_FUNC_REPORT_ZONE_PERM_TABLE:
941 if (cap & SMP_TARGET_C_LONG_RESP)
942 return (SMP_REQ_MINLEN +
943 sizeof (smp_report_zone_perm_table_req_t));
944 return (SMP_REQ_MINLEN);
945 case SMP_FUNC_REPORT_BROADCAST:
946 if (cap & SMP_TARGET_C_LONG_RESP)
947 return (SMP_REQ_MINLEN +
948 sizeof (smp_report_broadcast_req_t));
949 return (SMP_REQ_MINLEN);
950 case SMP_FUNC_DISCOVER:
951 return (SMP_REQ_MINLEN + sizeof (smp_discover_req_t));
952 case SMP_FUNC_REPORT_PHY_ERROR_LOG:
953 return (SMP_REQ_MINLEN +
954 sizeof (smp_report_phy_error_log_req_t));
955 case SMP_FUNC_REPORT_PHY_SATA:
956 return (SMP_REQ_MINLEN + sizeof (smp_report_phy_sata_req_t));
957 case SMP_FUNC_REPORT_ROUTE_INFO:
958 return (SMP_REQ_MINLEN + sizeof (smp_report_route_info_req_t));
959 case SMP_FUNC_REPORT_PHY_EVENT:
960 if (cap & SMP_TARGET_C_LONG_RESP)
961 return (SMP_REQ_MINLEN +
962 sizeof (smp_report_phy_event_req_t));
963 return (SMP_REQ_MINLEN);
964 case SMP_FUNC_DISCOVER_LIST:
965 if (cap & SMP_TARGET_C_LONG_RESP)
966 return (SMP_REQ_MINLEN +
967 sizeof (smp_discover_list_req_t));
968 return (SMP_REQ_MINLEN);
969 case SMP_FUNC_REPORT_PHY_EVENT_LIST:
970 if (cap & SMP_TARGET_C_LONG_RESP)
971 return (SMP_REQ_MINLEN +
972 sizeof (smp_report_phy_event_list_req_t));
973 return (SMP_REQ_MINLEN);
974 case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST:
975 if (cap & SMP_TARGET_C_LONG_RESP)
976 return (SMP_REQ_MINLEN +
977 sizeof (smp_report_exp_route_table_list_req_t));
978 return (SMP_REQ_MINLEN);
979 case SMP_FUNC_CONFIG_GENERAL:
980 if (cap & SMP_TARGET_C_LONG_RESP)
981 return (SMP_REQ_MINLEN +
982 sizeof (smp_config_general_req_t));
983 return (SMP_REQ_MINLEN);
984 case SMP_FUNC_ENABLE_DISABLE_ZONING:
985 if (cap & SMP_TARGET_C_LONG_RESP)
986 return (SMP_REQ_MINLEN +
987 sizeof (smp_enable_disable_zoning_req_t));
988 return (SMP_REQ_MINLEN);
989 case SMP_FUNC_ZONE_LOCK:
990 if (cap & SMP_TARGET_C_LONG_RESP)
991 return (SMP_REQ_MINLEN +
992 sizeof (smp_zone_lock_req_t));
993 return (SMP_REQ_MINLEN);
994 case SMP_FUNC_ZONE_ACTIVATE:
995 if (cap & SMP_TARGET_C_LONG_RESP)
996 return (SMP_REQ_MINLEN +
997 sizeof (smp_zone_activate_req_t));
998 return (SMP_REQ_MINLEN);
999 case SMP_FUNC_ZONE_UNLOCK:
1000 if (cap & SMP_TARGET_C_LONG_RESP)
1001 return (SMP_REQ_MINLEN +
1002 sizeof (smp_zone_unlock_req_t));
1003 return (SMP_REQ_MINLEN);
1004 case SMP_FUNC_CONFIG_ZONE_MANAGER_PASSWORD:
1005 if (cap & SMP_TARGET_C_LONG_RESP)
1006 return (SMP_REQ_MINLEN +
1007 sizeof (smp_config_zone_manager_password_req_t));
1008 return (SMP_REQ_MINLEN);
1009 case SMP_FUNC_CONFIG_ROUTE_INFO:
1010 return (SMP_REQ_MINLEN + sizeof (smp_config_route_info_req_t));
1011 case SMP_FUNC_PHY_CONTROL:
1012 return (SMP_REQ_MINLEN + sizeof (smp_phy_control_req_t));
1013 case SMP_FUNC_PHY_TEST_FUNCTION:
1014 return (SMP_REQ_MINLEN + sizeof (smp_phy_test_function_req_t));
1015
1016 case SMP_FUNC_ZONED_BROADCAST:
1017 case SMP_FUNC_CONFIG_ZONE_PHY_INFO:
1018 case SMP_FUNC_CONFIG_ZONE_PERM_TABLE:
1019 case SMP_FUNC_CONFIG_PHY_EVENT:
1020 default:
1021 return (0);
1022 }
1023 }
1024
1025 /*
1026 * This is slightly different - return the length in bytes, including the
1027 * header and footer, to be assumed for the response frame type if the
1028 * length field is zero. Since the length field will not be zero unless the
1029 * long response bit is clear or the target is buggy, we always assume that
1030 * the caller wants the size of the v1 frame.
1031 */
1032 /*ARGSUSED*/
1033 size_t
smp_default_response_len(uint_t cap,smp_function_t fn)1034 smp_default_response_len(uint_t cap, smp_function_t fn)
1035 {
1036 switch (fn) {
1037 case SMP_FUNC_REPORT_SELF_CONFIG_STATUS:
1038 case SMP_FUNC_REPORT_ZONE_PERM_TABLE:
1039 case SMP_FUNC_REPORT_BROADCAST:
1040 case SMP_FUNC_REPORT_PHY_EVENT:
1041 case SMP_FUNC_DISCOVER_LIST:
1042 case SMP_FUNC_REPORT_PHY_EVENT_LIST:
1043 case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST:
1044 case SMP_FUNC_CONFIG_GENERAL:
1045 case SMP_FUNC_ENABLE_DISABLE_ZONING:
1046 case SMP_FUNC_ZONED_BROADCAST:
1047 case SMP_FUNC_ZONE_LOCK:
1048 case SMP_FUNC_ZONE_ACTIVATE:
1049 case SMP_FUNC_ZONE_UNLOCK:
1050 case SMP_FUNC_CONFIG_ZONE_MANAGER_PASSWORD:
1051 case SMP_FUNC_CONFIG_ZONE_PHY_INFO:
1052 case SMP_FUNC_CONFIG_ZONE_PERM_TABLE:
1053 case SMP_FUNC_CONFIG_ROUTE_INFO:
1054 case SMP_FUNC_PHY_CONTROL:
1055 case SMP_FUNC_PHY_TEST_FUNCTION:
1056 case SMP_FUNC_CONFIG_PHY_EVENT:
1057 return (SMP_RESP_MINLEN);
1058 case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD:
1059 return (SMP_RESP_MINLEN +
1060 sizeof (smp_report_zone_mgr_password_resp_t));
1061 case SMP_FUNC_REPORT_GENERAL:
1062 return (SMP_RESP_MINLEN + 24);
1063 case SMP_FUNC_REPORT_MANUFACTURER_INFO:
1064 return (SMP_RESP_MINLEN +
1065 sizeof (smp_report_manufacturer_info_resp_t));
1066 case SMP_FUNC_DISCOVER:
1067 return (SMP_RESP_MINLEN + 48);
1068 case SMP_FUNC_REPORT_PHY_ERROR_LOG:
1069 return (SMP_RESP_MINLEN +
1070 sizeof (smp_report_phy_error_log_resp_t));
1071 case SMP_FUNC_REPORT_PHY_SATA:
1072 return (SMP_RESP_MINLEN + 52);
1073 case SMP_FUNC_REPORT_ROUTE_INFO:
1074 return (SMP_RESP_MINLEN +
1075 sizeof (smp_report_route_info_resp_t));
1076
1077 default:
1078 return (0);
1079 }
1080 }
1081