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.
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.
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]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 PALO, Richard
26 #include <sys/types.h>
27 #include <sys/scsi/generic/smp_frames.h>
28 #include <sys/scsi/generic/commands.h>
29 #include <sys/scsi/impl/commands.h>
30 #include <sys/ccompile.h>
31 #include <sys/byteorder.h>
42 #include <scsi/libsmp.h>
43 #include <scsi/libsmp_plugin.h>
45 static char *yes
= "Yes";
46 static char *no
= "No";
48 static void fatal(int, const char *, ...) __NORETURN
;
50 static smp_target_t
*tp
= NULL
;
51 static smp_action_t
*ap
= NULL
;
52 static smp_function_t func
;
53 static smp_result_t result
;
54 static smp_target_def_t tdef
;
55 static uint8_t *smp_resp
;
56 static size_t smp_resp_len
;
59 fatal(int err
, const char *fmt
, ...)
64 (void) vfprintf(stderr
, fmt
, ap
);
67 (void) fprintf(stderr
, "\n");
68 (void) fflush(stderr
);
74 smp_get_result(smp_result_t result
)
77 case SMP_RES_FUNCTION_ACCEPTED
:
78 return ("Function accepted");
80 case SMP_RES_UNKNOWN_FUNCTION
:
81 return ("Unknown function");
83 case SMP_RES_FUNCTION_FAILED
:
84 return ("Function failed");
86 case SMP_RES_INVALID_REQUEST_FRAME_LENGTH
:
87 return ("Invalid request frame length");
89 case SMP_RES_INVALID_EXPANDER_CHANGE_COUNT
:
90 return ("Invalid expander change count");
95 case SMP_RES_INCOMPLETE_DESCRIPTOR_LIST
:
96 return ("Incomplete descriptor list");
98 case SMP_RES_PHY_DOES_NOT_EXIST
:
99 return ("PHY does not exist");
101 case SMP_RES_INDEX_DOES_NOT_EXIST
:
102 return ("Index does not exist");
104 case SMP_RES_PHY_DOES_NOT_SUPPORT_SATA
:
105 return ("PHY does not support SATA");
107 case SMP_RES_UNKNOWN_PHY_OPERATION
:
108 return ("Unknown PHY operation");
110 case SMP_RES_UNKNOWN_PHY_TEST_FUNCTION
:
111 return ("Unknown PHY test function");
113 case SMP_RES_PHY_TEST_IN_PROGRESS
:
114 return ("PHY test in progress");
116 case SMP_RES_PHY_VACANT
:
117 return ("PHY vacant");
119 case SMP_RES_UNKNOWN_PHY_EVENT_SOURCE
:
120 return ("Unknown PHY event source");
122 case SMP_RES_UNKNOWN_DESCRIPTOR_TYPE
:
123 return ("Unknown descriptor type");
125 case SMP_RES_UNKNOWN_PHY_FILTER
:
126 return ("Unknown PHY filter");
128 case SMP_RES_AFFILIATION_VIOLATION
:
129 return ("Affiliation violation");
131 case SMP_RES_ZONE_VIOLATION
:
132 return ("Zone violation");
134 case SMP_RES_NO_MANAGEMENT_ACCESS_RIGHTS
:
135 return ("No management access rights");
137 case SMP_RES_UNKNOWN_ENABLE_DISABLE_ZONING
:
138 return ("Unknown enable/disable zoning value");
140 case SMP_RES_ZONE_LOCK_VIOLATION
:
141 return ("Zone lock violation");
143 case SMP_RES_NOT_ACTIVATED
:
144 return ("Not activated");
146 case SMP_RES_ZONE_GROUP_OUT_OF_RANGE
:
147 return ("Zone group out of range");
149 case SMP_RES_NO_PHYSICAL_PRESENCE
:
150 return ("No physical presence");
152 case SMP_RES_SAVING_NOT_SUPPORTED
:
153 return ("Saving not supported");
155 case SMP_RES_SOURCE_ZONE_GROUP_DNE
:
156 return ("Source zone group does not exist");
158 case SMP_RES_DISABLED_PW_NOT_SUPPORTED
:
159 return ("Disabled password not supported");
171 if (smp_exec(ap
, tp
) != 0) {
175 fatal(-4, "exec failed: %s", smp_errmsg());
180 smp_cmd_failed(smp_result_t result
)
182 char *smp_result_str
= smp_get_result(result
);
184 if (smp_result_str
== NULL
) {
185 fatal(-5, "Command failed: Unknown result (0x%x)",
188 fatal(-5, "Command failed: %s", smp_result_str
);
193 smp_get_response(boolean_t close_on_fail
)
195 smp_action_get_response(ap
, &result
, (void **)&smp_resp
, &smp_resp_len
);
197 if (close_on_fail
&& (result
!= SMP_RES_FUNCTION_ACCEPTED
)) {
201 smp_cmd_failed(result
);
218 smp_handle_report_route_info(int argc
, char *argv
[])
220 smp_report_route_info_req_t
*rp
;
221 smp_report_route_info_resp_t
*rirp
;
222 uint16_t route_indexes
= smp_target_get_exp_route_indexes(tp
);
223 uint8_t num_phys
= smp_target_get_number_of_phys(tp
);
224 uint16_t rt_idx_req
, ri_idx
, ri_end
;
225 uint8_t phy_id_req
, pi_idx
, pi_end
;
226 boolean_t enabled_entries
= B_FALSE
;
229 * Verify the expander supports the PHY-based expander route table
231 if (route_indexes
== 0) {
233 fatal(-6, "Expander does not support PHY-based route table\n");
236 rt_idx_req
= strtol(argv
[3], NULL
, 0);
237 phy_id_req
= strtol(argv
[4], NULL
, 0);
239 if (((int16_t)rt_idx_req
== -1) && ((int8_t)phy_id_req
== -1)) {
241 ri_end
= route_indexes
- 1;
243 pi_end
= num_phys
- 1;
244 } else if (((int16_t)rt_idx_req
< 0) || (rt_idx_req
>= route_indexes
) ||
245 ((int8_t)phy_id_req
< 0) || (phy_id_req
>= num_phys
)) {
247 fatal(-1, "Invalid route index (%d) or PHY ID (%d)\n",
248 rt_idx_req
, phy_id_req
);
250 ri_end
= ri_idx
= rt_idx_req
;
251 pi_end
= pi_idx
= phy_id_req
;
254 (void) printf("%6s %6s %3s %14s\n",
255 "RT Idx", "PHY ID", "DIS", "Routed SASAddr");
257 smp_action_get_request(ap
, (void **)&rp
, NULL
);
259 while (ri_idx
<= ri_end
) {
260 while (pi_idx
<= pi_end
) {
261 rp
->srrir_phy_identifier
= pi_idx
;
262 rp
->srrir_exp_route_index
= ri_idx
;
265 smp_get_response(B_FALSE
);
267 if (result
!= SMP_RES_FUNCTION_ACCEPTED
) {
272 rirp
= (smp_report_route_info_resp_t
*)smp_resp
;
274 if (rirp
->srrir_exp_route_entry_disabled
== 0) {
275 enabled_entries
= B_TRUE
;
276 (void) printf("%6d %6d %3d %016llx\n",
277 rirp
->srrir_exp_route_index
,
278 rirp
->srrir_phy_identifier
,
279 rirp
->srrir_exp_route_entry_disabled
,
280 BE_64(rirp
->srrir_routed_sas_addr
));
290 if (!enabled_entries
) {
291 (void) printf("No enabled entries in the table.\n");
299 smp_phy_event_src_str(smp_phy_event_source_t src
, boolean_t
*peak_detector
)
303 *peak_detector
= B_FALSE
;
306 case SMP_PHY_EVENT_NO_EVENT
:
307 src_str
= "No event";
309 case SMP_PHY_EVENT_INVALID_DWORD_COUNT
:
310 src_str
= "Invalid DWORD count";
312 case SMP_PHY_EVENT_RUNNING_DISPARITY_ERROR_COUNT
:
313 src_str
= "Running disparity error count";
315 case SMP_PHY_EVENT_LOSS_OF_DWORD_SYNC_COUNT
:
316 src_str
= "Loss of DWORD sync count";
318 case SMP_PHY_EVENT_PHY_RESET_PROBLEM_COUNT
:
319 src_str
= "PHY reset problem count";
321 case SMP_PHY_EVENT_ELASTICITY_BUFFER_OVERFLOW_COUNT
:
322 src_str
= "Elasticity buffer overflow count";
324 case SMP_PHY_EVENT_RX_ERROR_COUNT
:
325 src_str
= "Received ERROR count";
327 case SMP_PHY_EVENT_RX_ADDR_FRAME_ERROR_COUNT
:
328 src_str
= "Received address frame error count";
330 case SMP_PHY_EVENT_TX_ABANDON_CLASS_OPEN_REJ_COUNT
:
331 src_str
= "Transmitted abandon-class OPEN_REJECT count";
333 case SMP_PHY_EVENT_RX_ABANDON_CLASS_OPEN_REJ_COUNT
:
334 src_str
= "Received abandon-class OPEN_REJECT count";
336 case SMP_PHY_EVENT_TX_RETRY_CLASS_OPEN_REJ_COUNT
:
337 src_str
= "Transmitted retry-class OPEN_REJECT count";
339 case SMP_PHY_EVENT_RX_RETRY_CLASS_OPEN_REJ_COUNT
:
340 src_str
= "Received retry-class OPEN_REJECT count";
342 case SMP_PHY_EVENT_RX_AIP_W_O_PARTIAL_COUNT
:
343 src_str
= "Received AIP (WAITING ON PARTIAL) count";
345 case SMP_PHY_EVENT_RX_AIP_W_O_CONN_COUNT
:
346 src_str
= "Received AIP (WAITING ON CONNECTION) count";
348 case SMP_PHY_EVENT_TX_BREAK_COUNT
:
349 src_str
= "Transmitted BREAK count";
351 case SMP_PHY_EVENT_RX_BREAK_COUNT
:
352 src_str
= "Received BREAK count";
354 case SMP_PHY_EVENT_BREAK_TIMEOUT_COUNT
:
355 src_str
= "BREAK timeout count";
357 case SMP_PHY_EVENT_CONNECTION_COUNT
:
358 src_str
= "Connection count";
360 case SMP_PHY_EVENT_PEAK_TX_PATHWAY_BLOCKED_COUNT
:
361 src_str
= "Peak transmitted pathway blocked count";
362 *peak_detector
= B_TRUE
;
364 case SMP_PHY_EVENT_PEAK_TX_ARB_WAIT_TIME
:
365 src_str
= "Peak transmitted arbitration wait time";
366 *peak_detector
= B_TRUE
;
368 case SMP_PHY_EVENT_PEAK_ARB_TIME
:
369 src_str
= "Peak arbitration time";
370 *peak_detector
= B_TRUE
;
372 case SMP_PHY_EVENT_PEAK_CONNECTION_TIME
:
373 src_str
= "Peak connection time";
374 *peak_detector
= B_TRUE
;
376 case SMP_PHY_EVENT_TX_SSP_FRAME_COUNT
:
377 src_str
= "Transmitted SSP frame count";
379 case SMP_PHY_EVENT_RX_SSP_FRAME_COUNT
:
380 src_str
= "Received SSP frame count";
382 case SMP_PHY_EVENT_TX_SSP_FRAME_ERROR_COUNT
:
383 src_str
= "Transmitted SSP frame error count";
385 case SMP_PHY_EVENT_RX_SSP_FRAME_ERROR_COUNT
:
386 src_str
= "Received SSP frame error count";
388 case SMP_PHY_EVENT_TX_CREDIT_BLOCKED_COUNT
:
389 src_str
= "Transmitted CREDIT_BLOCKED count";
391 case SMP_PHY_EVENT_RX_CREDIT_BLOCKED_COUNT
:
392 src_str
= "Received CREDIT_BLOCKED count";
394 case SMP_PHY_EVENT_TX_SATA_FRAME_COUNT
:
395 src_str
= "Transmitted SATA frame count";
397 case SMP_PHY_EVENT_RX_SATA_FRAME_COUNT
:
398 src_str
= "Received SATA frame count";
400 case SMP_PHY_EVENT_SATA_FLOW_CTRL_BUF_OVERFLOW_COUNT
:
401 src_str
= "SATA flow control buffer overflow count";
403 case SMP_PHY_EVENT_TX_SMP_FRAME_COUNT
:
404 src_str
= "Transmitted SMP frame count";
406 case SMP_PHY_EVENT_RX_SMP_FRAME_COUNT
:
407 src_str
= "Received SMP frame count";
409 case SMP_PHY_EVENT_RX_SMP_FRAME_ERROR_COUNT
:
410 src_str
= "Received SMP frame error count";
413 src_str
= "<Unknown>";
421 smp_validate_args(int argc
, char *argv
[])
426 fatal(-1, "Usage: %s <device> <function> ...\n", argv
[0]);
428 func
= strtoul(argv
[2], NULL
, 0);
431 fatal(-1, "Usage: %s <device> <function> ...\n", argv
[0]);
434 case SMP_FUNC_DISCOVER
:
435 case SMP_FUNC_REPORT_PHY_EVENT
:
436 case SMP_FUNC_REPORT_PHY_ERROR_LOG
: {
439 "Usage: %s <device> 0x%x <phy identifier>\n",
444 case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST
: {
447 "Usage: %s <device> 0x%x <SAS Address Index>\n",
452 case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD
: {
455 "Usage: %s <device> 0x%x <report type>\n",
460 case SMP_FUNC_ENABLE_DISABLE_ZONING
: {
463 "Usage: %s <device> 0x%x "
464 "[0(no change) | 1(enable)| 2(disable)]\n",
469 case SMP_FUNC_REPORT_BROADCAST
: {
471 fatal(-1, "Usage: %s <device> 0x%x <bcast type>\n",
476 case SMP_FUNC_REPORT_ROUTE_INFO
: {
479 "Usage: %s <device> 0x%x <exp_route_idx> "
480 "<phy_identifier>\n", argv
[0], func
);
484 case SMP_FUNC_PHY_CONTROL
: {
487 "Usage: %s <device> 0x%x <phy identifier> "
488 " <phy operation>\n",
494 fatal(-1, "Usage: %s <device> <function> ...\n", argv
[0]);
501 main(int argc
, char *argv
[])
505 uint16_t exp_change_count
;
508 * If the arguments are invalid, this function will not return.
510 smp_validate_args(argc
, argv
);
512 if (smp_init(LIBSMP_VERSION
) != 0)
513 fatal(-1, "libsmp initialization failed: %s", smp_errmsg());
515 bzero(&tdef
, sizeof (smp_target_def_t
));
516 tdef
.std_def
= argv
[1];
518 if ((tp
= smp_open(&tdef
)) == NULL
) {
520 fatal(-2, "failed to open %s: %s", argv
[1], smp_errmsg());
523 exp_change_count
= smp_target_get_change_count(tp
);
525 (void) printf("%s\n", argv
[0]);
526 (void) printf("\tSAS Address: %016llx\n", smp_target_addr(tp
));
527 (void) printf("\tVendor/Product/Revision: %s/%s/%s\n",
528 smp_target_vendor(tp
), smp_target_product(tp
),
529 smp_target_revision(tp
));
530 (void) printf("\tExp Vendor/ID/Rev: %s/%04x/%02x\n",
531 smp_target_component_vendor(tp
), smp_target_component_id(tp
),
532 smp_target_component_revision(tp
));
533 (void) printf("\tExpander change count: 0x%04x\n", exp_change_count
);
535 ap
= smp_action_alloc(func
, tp
, 0);
539 fatal(-3, "failed to allocate action: %s", smp_errmsg());
543 case SMP_FUNC_DISCOVER
: {
544 smp_discover_req_t
*dp
;
546 smp_action_get_request(ap
, (void **)&dp
, NULL
);
547 dp
->sdr_phy_identifier
= strtoul(argv
[3], NULL
, 0);
550 case SMP_FUNC_REPORT_ROUTE_INFO
: {
551 smp_handle_report_route_info(argc
, argv
);
554 case SMP_FUNC_ENABLE_DISABLE_ZONING
: {
555 smp_enable_disable_zoning_req_t
*rp
;
557 smp_action_get_request(ap
, (void **)&rp
, NULL
);
558 rp
->sedzr_enable_disable_zoning
= strtoul(argv
[3], NULL
, 0);
561 case SMP_FUNC_PHY_CONTROL
: {
562 smp_phy_control_req_t
*rp
;
564 smp_action_get_request(ap
, (void **)&rp
, NULL
);
565 rp
->spcr_phy_identifier
= strtoul(argv
[3], NULL
, 0);
566 rp
->spcr_phy_operation
= strtoul(argv
[4], NULL
, 0);
569 case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST
: {
570 smp_report_exp_route_table_list_req_t
*rp
;
572 smp_action_get_request(ap
, (void **)&rp
, NULL
);
573 SCSI_WRITE16(&rp
->srertlr_max_descrs
, 64);
574 SCSI_WRITE16(&rp
->srertlr_starting_routed_sas_addr_index
,
575 strtoull(argv
[3], NULL
, 0));
576 rp
->srertlr_starting_phy_identifier
= 0;
579 case SMP_FUNC_REPORT_PHY_ERROR_LOG
: {
580 smp_report_phy_error_log_req_t
*pelp
;
582 smp_action_get_request(ap
, (void **)&pelp
, NULL
);
583 pelp
->srpelr_phy_identifier
= strtoul(argv
[3], NULL
, 0);
586 case SMP_FUNC_REPORT_PHY_EVENT
: {
587 smp_report_phy_event_req_t
*rpep
;
589 smp_action_get_request(ap
, (void **)&rpep
, NULL
);
590 rpep
->srper_phy_identifier
= strtoul(argv
[3], NULL
, 0);
593 case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD
: {
594 smp_report_zone_mgr_password_req_t
*rzmprp
;
596 smp_action_get_request(ap
, (void **)&rzmprp
, NULL
);
597 rzmprp
->srzmpr_rpt_type
= strtoul(argv
[3], NULL
, 0);
600 case SMP_FUNC_REPORT_BROADCAST
: {
601 smp_report_broadcast_req_t
*rbrp
;
603 smp_action_get_request(ap
, (void **)&rbrp
, NULL
);
604 rbrp
->srbr_broadcast_type
= strtoul(argv
[3], NULL
, 0);
611 smp_cmd_failed(result
);
615 smp_get_response(B_TRUE
);
618 case SMP_FUNC_DISCOVER
: {
619 smp_discover_resp_t
*rp
= (smp_discover_resp_t
*)smp_resp
;
620 (void) printf("Addr: %016llx Phy: %02x\n",
621 SCSI_READ64(&rp
->sdr_sas_addr
), rp
->sdr_phy_identifier
);
622 (void) printf("Peer: %016llx Phy: %02x\n",
623 SCSI_READ64(&rp
->sdr_attached_sas_addr
),
624 rp
->sdr_attached_phy_identifier
);
625 (void) printf("Device type: %01x\n",
626 rp
->sdr_attached_device_type
);
629 case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD
: {
630 smp_report_zone_mgr_password_resp_t
*rp
=
631 (smp_report_zone_mgr_password_resp_t
*)smp_resp
;
632 char *rpt_type
= NULL
;
634 switch (rp
->srzmpr_rpt_type
) {
635 case SMP_ZMP_TYPE_CURRENT
:
636 rpt_type
= "Current";
638 case SMP_ZMP_TYPE_SAVED
:
641 case SMP_ZMP_TYPE_DEFAULT
:
642 rpt_type
= "Default";
645 rpt_type
= "(Unknown Type)";
648 (void) printf("%s zone manager password: 0x", rpt_type
);
649 for (idx
= 0; idx
< 32; idx
++) {
650 (void) printf("%02x",
651 rp
->srzmpr_zone_mgr_password
[idx
]);
656 case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST
: {
657 smp_report_exp_route_table_list_resp_t
*rtlr
=
658 (smp_report_exp_route_table_list_resp_t
*)smp_resp
;
659 smp_route_table_descr_t
*descp
= &rtlr
->srertlr_descrs
[0];
660 int idx
, idxx
, ndescrs
, zoning
, startnum
;
662 (void) printf("Expander change count: 0x%04x\n",
663 BE_16(rtlr
->srertlr_exp_change_count
));
664 (void) printf("Expander route table change count: 0x%04x\n",
665 BE_16(rtlr
->srertlr_route_table_change_count
));
667 if (rtlr
->srertlr_zoning_enabled
) {
674 (void) printf("Zoning enabled: %s\n", yesorno
);
676 if (rtlr
->srertlr_configuring
) {
681 (void) printf("Configuring: %s\n", yesorno
);
683 ndescrs
= rtlr
->srertlr_n_descrs
;
684 (void) printf("Number of descriptors: %d\n", ndescrs
);
685 startnum
= BE_16(rtlr
->srertlr_first_routed_sas_addr_index
);
686 (void) printf("First/Last routed SAS address index: %d/%d\n",
687 startnum
, BE_16(rtlr
->srertlr_last_routed_sas_addr_index
));
688 (void) printf("Starting PHY identifier: %d\n",
689 rtlr
->srertlr_starting_phy_identifier
);
691 for (idx
= 0; idx
< ndescrs
; idx
++, descp
++) {
692 (void) printf("#%03d: Routed SAS addr: %016llx ",
693 idx
+ startnum
, BE_64(descp
->srtd_routed_sas_addr
));
694 (void) printf("PHY bitmap: 0x");
695 for (idxx
= 0; idxx
< 6; idxx
++) {
696 (void) printf("%02x",
697 descp
->srtd_phy_bitmap
[idxx
]);
701 (void) printf("\tZone group: %d\n",
702 descp
->srtd_zone_group
);
709 case SMP_FUNC_REPORT_PHY_ERROR_LOG
: {
710 smp_report_phy_error_log_resp_t
*pelr
=
711 (smp_report_phy_error_log_resp_t
*)smp_resp
;
712 (void) printf("PHY error log for PHY %d:\n",
713 pelr
->srpelr_phy_identifier
);
714 (void) printf("\tInvalid DWORD count: %d\n",
715 BE_32(pelr
->srpelr_invalid_dword_count
));
716 (void) printf("\tRunning disparity error count: %d\n",
717 BE_32(pelr
->srpelr_running_disparity_error_count
));
718 (void) printf("\tLoss of DWORD sync count: %d\n",
719 BE_32(pelr
->srpelr_loss_dword_sync_count
));
720 (void) printf("\tPHY reset problem count: %d\n",
721 BE_32(pelr
->srpelr_phy_reset_problem_count
));
724 case SMP_FUNC_REPORT_PHY_EVENT
: {
725 smp_report_phy_event_resp_t
*rper
=
726 (smp_report_phy_event_resp_t
*)smp_resp
;
727 smp_phy_event_report_descr_t
*perd
=
728 &rper
->srper_phy_event_descrs
[0];
732 (void) printf("PHY event for PHY %d:\n",
733 rper
->srper_phy_identifier
);
734 (void) printf("Number of PHY event descriptors: %d\n",
735 rper
->srper_n_phy_event_descrs
);
737 for (idx
= 0; idx
< rper
->srper_n_phy_event_descrs
; idx
++) {
738 (void) printf("%50s : %d\n",
739 smp_phy_event_src_str(perd
->sped_phy_event_source
,
740 &peak
), BE_32(perd
->sped_phy_event
));
742 (void) printf("\tPeak value detector "
744 BE_32(perd
->sped_peak_detector_threshold
));
751 case SMP_FUNC_REPORT_BROADCAST
: {
752 smp_report_broadcast_resp_t
*brp
=
753 (smp_report_broadcast_resp_t
*)smp_resp
;
754 smp_broadcast_descr_t
*bdp
= &brp
->srbr_descrs
[0];
755 uint16_t bcount
, idx
;
757 bcount
= brp
->srbr_number_broadcast_descrs
;
759 (void) printf("\tNumber of broadcast descriptors: %d\n",
761 (void) printf("\t%7s %5s %5s %8s\n",
762 "BCType", "PhyID", "BCRsn", "BC Count");
763 for (idx
= 0; idx
< bcount
; idx
++) {
764 (void) printf("\t%7s %5s %5s %8s\n",
765 bdp
->sbd_broadcast_type
, bdp
->sbd_phy_identifier
,
766 bdp
->sbd_broadcast_reason
,
767 bdp
->sbd_broadcast_count
);
774 (void) printf("Response: (len %d)\n", smp_resp_len
);
775 for (i
= 0; i
< smp_resp_len
; i
+= 8) {
776 (void) printf("%02x: ", i
);
777 for (j
= i
; j
< i
+ 8; j
++)
778 if (j
< smp_resp_len
)
779 (void) printf("%02x ", smp_resp
[j
]);
782 for (j
= i
; j
< i
+ 8; j
++)
784 j
< smp_resp_len
&& isprint(smp_resp
[j
]) ?
785 smp_resp
[j
] : j
< smp_resp_len
? '.' :