1ac88567aSHyon Kim /* 2ac88567aSHyon Kim * CDDL HEADER START 3ac88567aSHyon Kim * 4ac88567aSHyon Kim * The contents of this file are subject to the terms of the 5ac88567aSHyon Kim * Common Development and Distribution License (the "License"). 6ac88567aSHyon Kim * You may not use this file except in compliance with the License. 7ac88567aSHyon Kim * 8ac88567aSHyon Kim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9ac88567aSHyon Kim * or http://www.opensolaris.org/os/licensing. 10ac88567aSHyon Kim * See the License for the specific language governing permissions 11ac88567aSHyon Kim * and limitations under the License. 12ac88567aSHyon Kim * 13ac88567aSHyon Kim * When distributing Covered Code, include this CDDL HEADER in each 14ac88567aSHyon Kim * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15ac88567aSHyon Kim * If applicable, add the following below this CDDL HEADER, with the 16ac88567aSHyon Kim * fields enclosed by brackets "[]" replaced with your own identifying 17ac88567aSHyon Kim * information: Portions Copyright [yyyy] [name of copyright owner] 18ac88567aSHyon Kim * 19ac88567aSHyon Kim * CDDL HEADER END 20ac88567aSHyon Kim */ 21ac88567aSHyon Kim 22ac88567aSHyon Kim /* 23ac88567aSHyon Kim * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24*24f5a376SRichard PALO * Copyright 2015 PALO, Richard 25ac88567aSHyon Kim */ 26ac88567aSHyon Kim #include <sys/types.h> 27ac88567aSHyon Kim #include <sys/scsi/generic/smp_frames.h> 28ac88567aSHyon Kim #include <sys/scsi/generic/commands.h> 29ac88567aSHyon Kim #include <sys/scsi/impl/commands.h> 30ac88567aSHyon Kim #include <sys/ccompile.h> 31d0698e0dSDavid Hollister #include <sys/byteorder.h> 32ac88567aSHyon Kim 33ac88567aSHyon Kim #include <stdarg.h> 34ac88567aSHyon Kim #include <stdio.h> 35ac88567aSHyon Kim #include <string.h> 36ac88567aSHyon Kim #include <unistd.h> 37ac88567aSHyon Kim #include <stdlib.h> 38ac88567aSHyon Kim #include <errno.h> 39ac88567aSHyon Kim #include <strings.h> 40ac88567aSHyon Kim #include <ctype.h> 41ac88567aSHyon Kim 42ac88567aSHyon Kim #include <scsi/libsmp.h> 43ac88567aSHyon Kim #include <scsi/libsmp_plugin.h> 44ac88567aSHyon Kim 45d0698e0dSDavid Hollister static char *yes = "Yes"; 46d0698e0dSDavid Hollister static char *no = "No"; 47d0698e0dSDavid Hollister 48ac88567aSHyon Kim static void fatal(int, const char *, ...) __NORETURN; 49ac88567aSHyon Kim 50d0698e0dSDavid Hollister static smp_target_t *tp = NULL; 51d0698e0dSDavid Hollister static smp_action_t *ap = NULL; 52d0698e0dSDavid Hollister static smp_function_t func; 53d0698e0dSDavid Hollister static smp_result_t result; 54d0698e0dSDavid Hollister static smp_target_def_t tdef; 55d0698e0dSDavid Hollister static uint8_t *smp_resp; 56d0698e0dSDavid Hollister static size_t smp_resp_len; 57d0698e0dSDavid Hollister 58ac88567aSHyon Kim static void 59ac88567aSHyon Kim fatal(int err, const char *fmt, ...) 60ac88567aSHyon Kim { 61ac88567aSHyon Kim va_list ap; 62ac88567aSHyon Kim 63ac88567aSHyon Kim va_start(ap, fmt); 64ac88567aSHyon Kim (void) vfprintf(stderr, fmt, ap); 65ac88567aSHyon Kim va_end(ap); 66ac88567aSHyon Kim 67ac88567aSHyon Kim (void) fprintf(stderr, "\n"); 68ac88567aSHyon Kim (void) fflush(stderr); 69ac88567aSHyon Kim 70ac88567aSHyon Kim _exit(err); 71ac88567aSHyon Kim } 72ac88567aSHyon Kim 73d0698e0dSDavid Hollister static char * 74d0698e0dSDavid Hollister smp_get_result(smp_result_t result) 75ac88567aSHyon Kim { 76d0698e0dSDavid Hollister switch (result) { 77d0698e0dSDavid Hollister case SMP_RES_FUNCTION_ACCEPTED: 78d0698e0dSDavid Hollister return ("Function accepted"); 79d0698e0dSDavid Hollister break; 80d0698e0dSDavid Hollister case SMP_RES_UNKNOWN_FUNCTION: 81d0698e0dSDavid Hollister return ("Unknown function"); 82d0698e0dSDavid Hollister break; 83d0698e0dSDavid Hollister case SMP_RES_FUNCTION_FAILED: 84d0698e0dSDavid Hollister return ("Function failed"); 85d0698e0dSDavid Hollister break; 86d0698e0dSDavid Hollister case SMP_RES_INVALID_REQUEST_FRAME_LENGTH: 87d0698e0dSDavid Hollister return ("Invalid request frame length"); 88d0698e0dSDavid Hollister break; 89d0698e0dSDavid Hollister case SMP_RES_INVALID_EXPANDER_CHANGE_COUNT: 90d0698e0dSDavid Hollister return ("Invalid expander change count"); 91d0698e0dSDavid Hollister break; 92d0698e0dSDavid Hollister case SMP_RES_BUSY: 93d0698e0dSDavid Hollister return ("Busy"); 94d0698e0dSDavid Hollister break; 95d0698e0dSDavid Hollister case SMP_RES_INCOMPLETE_DESCRIPTOR_LIST: 96d0698e0dSDavid Hollister return ("Incomplete descriptor list"); 97d0698e0dSDavid Hollister break; 98d0698e0dSDavid Hollister case SMP_RES_PHY_DOES_NOT_EXIST: 99d0698e0dSDavid Hollister return ("PHY does not exist"); 100d0698e0dSDavid Hollister break; 101d0698e0dSDavid Hollister case SMP_RES_INDEX_DOES_NOT_EXIST: 102d0698e0dSDavid Hollister return ("Index does not exist"); 103d0698e0dSDavid Hollister break; 104d0698e0dSDavid Hollister case SMP_RES_PHY_DOES_NOT_SUPPORT_SATA: 105d0698e0dSDavid Hollister return ("PHY does not support SATA"); 106d0698e0dSDavid Hollister break; 107d0698e0dSDavid Hollister case SMP_RES_UNKNOWN_PHY_OPERATION: 108d0698e0dSDavid Hollister return ("Unknown PHY operation"); 109d0698e0dSDavid Hollister break; 110d0698e0dSDavid Hollister case SMP_RES_UNKNOWN_PHY_TEST_FUNCTION: 111d0698e0dSDavid Hollister return ("Unknown PHY test function"); 112d0698e0dSDavid Hollister break; 113d0698e0dSDavid Hollister case SMP_RES_PHY_TEST_IN_PROGRESS: 114d0698e0dSDavid Hollister return ("PHY test in progress"); 115d0698e0dSDavid Hollister break; 116d0698e0dSDavid Hollister case SMP_RES_PHY_VACANT: 117d0698e0dSDavid Hollister return ("PHY vacant"); 118d0698e0dSDavid Hollister break; 119d0698e0dSDavid Hollister case SMP_RES_UNKNOWN_PHY_EVENT_SOURCE: 120d0698e0dSDavid Hollister return ("Unknown PHY event source"); 121d0698e0dSDavid Hollister break; 122d0698e0dSDavid Hollister case SMP_RES_UNKNOWN_DESCRIPTOR_TYPE: 123d0698e0dSDavid Hollister return ("Unknown descriptor type"); 124d0698e0dSDavid Hollister break; 125d0698e0dSDavid Hollister case SMP_RES_UNKNOWN_PHY_FILTER: 126d0698e0dSDavid Hollister return ("Unknown PHY filter"); 127d0698e0dSDavid Hollister break; 128d0698e0dSDavid Hollister case SMP_RES_AFFILIATION_VIOLATION: 129d0698e0dSDavid Hollister return ("Affiliation violation"); 130d0698e0dSDavid Hollister break; 131d0698e0dSDavid Hollister case SMP_RES_ZONE_VIOLATION: 132d0698e0dSDavid Hollister return ("Zone violation"); 133d0698e0dSDavid Hollister break; 134d0698e0dSDavid Hollister case SMP_RES_NO_MANAGEMENT_ACCESS_RIGHTS: 135d0698e0dSDavid Hollister return ("No management access rights"); 136d0698e0dSDavid Hollister break; 137d0698e0dSDavid Hollister case SMP_RES_UNKNOWN_ENABLE_DISABLE_ZONING: 138d0698e0dSDavid Hollister return ("Unknown enable/disable zoning value"); 139d0698e0dSDavid Hollister break; 140d0698e0dSDavid Hollister case SMP_RES_ZONE_LOCK_VIOLATION: 141d0698e0dSDavid Hollister return ("Zone lock violation"); 142d0698e0dSDavid Hollister break; 143d0698e0dSDavid Hollister case SMP_RES_NOT_ACTIVATED: 144d0698e0dSDavid Hollister return ("Not activated"); 145d0698e0dSDavid Hollister break; 146d0698e0dSDavid Hollister case SMP_RES_ZONE_GROUP_OUT_OF_RANGE: 147d0698e0dSDavid Hollister return ("Zone group out of range"); 148d0698e0dSDavid Hollister break; 149d0698e0dSDavid Hollister case SMP_RES_NO_PHYSICAL_PRESENCE: 150d0698e0dSDavid Hollister return ("No physical presence"); 151d0698e0dSDavid Hollister break; 152d0698e0dSDavid Hollister case SMP_RES_SAVING_NOT_SUPPORTED: 153d0698e0dSDavid Hollister return ("Saving not supported"); 154d0698e0dSDavid Hollister break; 155d0698e0dSDavid Hollister case SMP_RES_SOURCE_ZONE_GROUP_DNE: 156d0698e0dSDavid Hollister return ("Source zone group does not exist"); 157d0698e0dSDavid Hollister break; 158d0698e0dSDavid Hollister case SMP_RES_DISABLED_PW_NOT_SUPPORTED: 159d0698e0dSDavid Hollister return ("Disabled password not supported"); 160d0698e0dSDavid Hollister break; 161d0698e0dSDavid Hollister default: 162d0698e0dSDavid Hollister break; 163d0698e0dSDavid Hollister } 164d0698e0dSDavid Hollister 165d0698e0dSDavid Hollister return (NULL); 166d0698e0dSDavid Hollister } 167d0698e0dSDavid Hollister 168d0698e0dSDavid Hollister static void 169d0698e0dSDavid Hollister smp_execute() 170d0698e0dSDavid Hollister { 171d0698e0dSDavid Hollister if (smp_exec(ap, tp) != 0) { 172d0698e0dSDavid Hollister smp_close(tp); 173d0698e0dSDavid Hollister smp_action_free(ap); 174d0698e0dSDavid Hollister smp_fini(); 175d0698e0dSDavid Hollister fatal(-4, "exec failed: %s", smp_errmsg()); 176d0698e0dSDavid Hollister } 177d0698e0dSDavid Hollister } 178d0698e0dSDavid Hollister 179d0698e0dSDavid Hollister static void 180d0698e0dSDavid Hollister smp_cmd_failed(smp_result_t result) 181d0698e0dSDavid Hollister { 182d0698e0dSDavid Hollister char *smp_result_str = smp_get_result(result); 183d0698e0dSDavid Hollister 184*24f5a376SRichard PALO if (smp_result_str == NULL) { 185d0698e0dSDavid Hollister fatal(-5, "Command failed: Unknown result (0x%x)", 186d0698e0dSDavid Hollister result); 187d0698e0dSDavid Hollister } else { 188d0698e0dSDavid Hollister fatal(-5, "Command failed: %s", smp_result_str); 189d0698e0dSDavid Hollister } 190d0698e0dSDavid Hollister } 191d0698e0dSDavid Hollister 192d0698e0dSDavid Hollister static void 193d0698e0dSDavid Hollister smp_get_response(boolean_t close_on_fail) 194d0698e0dSDavid Hollister { 195d0698e0dSDavid Hollister smp_action_get_response(ap, &result, (void **)&smp_resp, &smp_resp_len); 196d0698e0dSDavid Hollister 197d0698e0dSDavid Hollister if (close_on_fail && (result != SMP_RES_FUNCTION_ACCEPTED)) { 198d0698e0dSDavid Hollister smp_close(tp); 199d0698e0dSDavid Hollister smp_action_free(ap); 200d0698e0dSDavid Hollister smp_fini(); 201d0698e0dSDavid Hollister smp_cmd_failed(result); 202d0698e0dSDavid Hollister } 203d0698e0dSDavid Hollister } 204d0698e0dSDavid Hollister 205d0698e0dSDavid Hollister static void 206d0698e0dSDavid Hollister smp_cleanup() 207d0698e0dSDavid Hollister { 208d0698e0dSDavid Hollister if (tp) { 209d0698e0dSDavid Hollister smp_close(tp); 210d0698e0dSDavid Hollister tp = NULL; 211d0698e0dSDavid Hollister } 212d0698e0dSDavid Hollister smp_action_free(ap); 213d0698e0dSDavid Hollister smp_fini(); 214d0698e0dSDavid Hollister } 215d0698e0dSDavid Hollister 216*24f5a376SRichard PALO /* ARGSUSED */ 217d0698e0dSDavid Hollister static void 218d0698e0dSDavid Hollister smp_handle_report_route_info(int argc, char *argv[]) 219d0698e0dSDavid Hollister { 220d0698e0dSDavid Hollister smp_report_route_info_req_t *rp; 221d0698e0dSDavid Hollister smp_report_route_info_resp_t *rirp; 222d0698e0dSDavid Hollister uint16_t route_indexes = smp_target_get_exp_route_indexes(tp); 223d0698e0dSDavid Hollister uint8_t num_phys = smp_target_get_number_of_phys(tp); 224d0698e0dSDavid Hollister uint16_t rt_idx_req, ri_idx, ri_end; 225d0698e0dSDavid Hollister uint8_t phy_id_req, pi_idx, pi_end; 226d0698e0dSDavid Hollister boolean_t enabled_entries = B_FALSE; 227d0698e0dSDavid Hollister 228d0698e0dSDavid Hollister /* 229d0698e0dSDavid Hollister * Verify the expander supports the PHY-based expander route table 230d0698e0dSDavid Hollister */ 231d0698e0dSDavid Hollister if (route_indexes == 0) { 232d0698e0dSDavid Hollister smp_cleanup(); 233d0698e0dSDavid Hollister fatal(-6, "Expander does not support PHY-based route table\n"); 234d0698e0dSDavid Hollister } 235d0698e0dSDavid Hollister 236d0698e0dSDavid Hollister rt_idx_req = strtol(argv[3], NULL, 0); 237d0698e0dSDavid Hollister phy_id_req = strtol(argv[4], NULL, 0); 238d0698e0dSDavid Hollister 239d0698e0dSDavid Hollister if (((int16_t)rt_idx_req == -1) && ((int8_t)phy_id_req == -1)) { 240d0698e0dSDavid Hollister ri_idx = 0; 241d0698e0dSDavid Hollister ri_end = route_indexes - 1; 242d0698e0dSDavid Hollister pi_idx = 0; 243d0698e0dSDavid Hollister pi_end = num_phys - 1; 244d0698e0dSDavid Hollister } else if (((int16_t)rt_idx_req < 0) || (rt_idx_req >= route_indexes) || 245d0698e0dSDavid Hollister ((int8_t)phy_id_req < 0) || (phy_id_req >= num_phys)) { 246d0698e0dSDavid Hollister smp_cleanup(); 247d0698e0dSDavid Hollister fatal(-1, "Invalid route index (%d) or PHY ID (%d)\n", 248d0698e0dSDavid Hollister rt_idx_req, phy_id_req); 249d0698e0dSDavid Hollister } else { 250d0698e0dSDavid Hollister ri_end = ri_idx = rt_idx_req; 251d0698e0dSDavid Hollister pi_end = pi_idx = phy_id_req; 252d0698e0dSDavid Hollister } 253d0698e0dSDavid Hollister 254d0698e0dSDavid Hollister (void) printf("%6s %6s %3s %14s\n", 255d0698e0dSDavid Hollister "RT Idx", "PHY ID", "DIS", "Routed SASAddr"); 256d0698e0dSDavid Hollister 257d0698e0dSDavid Hollister smp_action_get_request(ap, (void **)&rp, NULL); 258d0698e0dSDavid Hollister 259d0698e0dSDavid Hollister while (ri_idx <= ri_end) { 260d0698e0dSDavid Hollister while (pi_idx <= pi_end) { 261d0698e0dSDavid Hollister rp->srrir_phy_identifier = pi_idx; 262d0698e0dSDavid Hollister rp->srrir_exp_route_index = ri_idx; 263d0698e0dSDavid Hollister 264d0698e0dSDavid Hollister smp_execute(); 265d0698e0dSDavid Hollister smp_get_response(B_FALSE); 266d0698e0dSDavid Hollister 267d0698e0dSDavid Hollister if (result != SMP_RES_FUNCTION_ACCEPTED) { 268d0698e0dSDavid Hollister pi_idx++; 269d0698e0dSDavid Hollister continue; 270d0698e0dSDavid Hollister } 271d0698e0dSDavid Hollister 272d0698e0dSDavid Hollister rirp = (smp_report_route_info_resp_t *)smp_resp; 273d0698e0dSDavid Hollister 274d0698e0dSDavid Hollister if (rirp->srrir_exp_route_entry_disabled == 0) { 275d0698e0dSDavid Hollister enabled_entries = B_TRUE; 276d0698e0dSDavid Hollister (void) printf("%6d %6d %3d %016llx\n", 277d0698e0dSDavid Hollister rirp->srrir_exp_route_index, 278d0698e0dSDavid Hollister rirp->srrir_phy_identifier, 279d0698e0dSDavid Hollister rirp->srrir_exp_route_entry_disabled, 280d0698e0dSDavid Hollister BE_64(rirp->srrir_routed_sas_addr)); 281d0698e0dSDavid Hollister } 282d0698e0dSDavid Hollister 283d0698e0dSDavid Hollister pi_idx++; 284d0698e0dSDavid Hollister } 285d0698e0dSDavid Hollister 286d0698e0dSDavid Hollister ri_idx++; 287d0698e0dSDavid Hollister pi_idx = 0; 288d0698e0dSDavid Hollister } 289d0698e0dSDavid Hollister 290d0698e0dSDavid Hollister if (!enabled_entries) { 291d0698e0dSDavid Hollister (void) printf("No enabled entries in the table.\n"); 292d0698e0dSDavid Hollister } 293d0698e0dSDavid Hollister 294d0698e0dSDavid Hollister smp_cleanup(); 295d0698e0dSDavid Hollister exit(0); 296d0698e0dSDavid Hollister } 297d0698e0dSDavid Hollister 298d0698e0dSDavid Hollister static char * 299d0698e0dSDavid Hollister smp_phy_event_src_str(smp_phy_event_source_t src, boolean_t *peak_detector) 300d0698e0dSDavid Hollister { 301d0698e0dSDavid Hollister char *src_str; 302d0698e0dSDavid Hollister 303d0698e0dSDavid Hollister *peak_detector = B_FALSE; 304d0698e0dSDavid Hollister 305d0698e0dSDavid Hollister switch (src) { 306d0698e0dSDavid Hollister case SMP_PHY_EVENT_NO_EVENT: 307d0698e0dSDavid Hollister src_str = "No event"; 308d0698e0dSDavid Hollister break; 309d0698e0dSDavid Hollister case SMP_PHY_EVENT_INVALID_DWORD_COUNT: 310d0698e0dSDavid Hollister src_str = "Invalid DWORD count"; 311d0698e0dSDavid Hollister break; 312d0698e0dSDavid Hollister case SMP_PHY_EVENT_RUNNING_DISPARITY_ERROR_COUNT: 313d0698e0dSDavid Hollister src_str = "Running disparity error count"; 314d0698e0dSDavid Hollister break; 315d0698e0dSDavid Hollister case SMP_PHY_EVENT_LOSS_OF_DWORD_SYNC_COUNT: 316d0698e0dSDavid Hollister src_str = "Loss of DWORD sync count"; 317d0698e0dSDavid Hollister break; 318d0698e0dSDavid Hollister case SMP_PHY_EVENT_PHY_RESET_PROBLEM_COUNT: 319d0698e0dSDavid Hollister src_str = "PHY reset problem count"; 320d0698e0dSDavid Hollister break; 321d0698e0dSDavid Hollister case SMP_PHY_EVENT_ELASTICITY_BUFFER_OVERFLOW_COUNT: 322d0698e0dSDavid Hollister src_str = "Elasticity buffer overflow count"; 323d0698e0dSDavid Hollister break; 324d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_ERROR_COUNT: 325d0698e0dSDavid Hollister src_str = "Received ERROR count"; 326d0698e0dSDavid Hollister break; 327d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_ADDR_FRAME_ERROR_COUNT: 328d0698e0dSDavid Hollister src_str = "Received address frame error count"; 329d0698e0dSDavid Hollister break; 330d0698e0dSDavid Hollister case SMP_PHY_EVENT_TX_ABANDON_CLASS_OPEN_REJ_COUNT: 331d0698e0dSDavid Hollister src_str = "Transmitted abandon-class OPEN_REJECT count"; 332d0698e0dSDavid Hollister break; 333d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_ABANDON_CLASS_OPEN_REJ_COUNT: 334d0698e0dSDavid Hollister src_str = "Received abandon-class OPEN_REJECT count"; 335d0698e0dSDavid Hollister break; 336d0698e0dSDavid Hollister case SMP_PHY_EVENT_TX_RETRY_CLASS_OPEN_REJ_COUNT: 337d0698e0dSDavid Hollister src_str = "Transmitted retry-class OPEN_REJECT count"; 338d0698e0dSDavid Hollister break; 339d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_RETRY_CLASS_OPEN_REJ_COUNT: 340d0698e0dSDavid Hollister src_str = "Received retry-class OPEN_REJECT count"; 341d0698e0dSDavid Hollister break; 342d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_AIP_W_O_PARTIAL_COUNT: 343d0698e0dSDavid Hollister src_str = "Received AIP (WAITING ON PARTIAL) count"; 344d0698e0dSDavid Hollister break; 345d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_AIP_W_O_CONN_COUNT: 346d0698e0dSDavid Hollister src_str = "Received AIP (WAITING ON CONNECTION) count"; 347d0698e0dSDavid Hollister break; 348d0698e0dSDavid Hollister case SMP_PHY_EVENT_TX_BREAK_COUNT: 349d0698e0dSDavid Hollister src_str = "Transmitted BREAK count"; 350d0698e0dSDavid Hollister break; 351d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_BREAK_COUNT: 352d0698e0dSDavid Hollister src_str = "Received BREAK count"; 353d0698e0dSDavid Hollister break; 354d0698e0dSDavid Hollister case SMP_PHY_EVENT_BREAK_TIMEOUT_COUNT: 355d0698e0dSDavid Hollister src_str = "BREAK timeout count"; 356d0698e0dSDavid Hollister break; 357d0698e0dSDavid Hollister case SMP_PHY_EVENT_CONNECTION_COUNT: 358d0698e0dSDavid Hollister src_str = "Connection count"; 359d0698e0dSDavid Hollister break; 360d0698e0dSDavid Hollister case SMP_PHY_EVENT_PEAK_TX_PATHWAY_BLOCKED_COUNT: 361d0698e0dSDavid Hollister src_str = "Peak transmitted pathway blocked count"; 362d0698e0dSDavid Hollister *peak_detector = B_TRUE; 363d0698e0dSDavid Hollister break; 364d0698e0dSDavid Hollister case SMP_PHY_EVENT_PEAK_TX_ARB_WAIT_TIME: 365d0698e0dSDavid Hollister src_str = "Peak transmitted arbitration wait time"; 366d0698e0dSDavid Hollister *peak_detector = B_TRUE; 367d0698e0dSDavid Hollister break; 368d0698e0dSDavid Hollister case SMP_PHY_EVENT_PEAK_ARB_TIME: 369d0698e0dSDavid Hollister src_str = "Peak arbitration time"; 370d0698e0dSDavid Hollister *peak_detector = B_TRUE; 371d0698e0dSDavid Hollister break; 372d0698e0dSDavid Hollister case SMP_PHY_EVENT_PEAK_CONNECTION_TIME: 373d0698e0dSDavid Hollister src_str = "Peak connection time"; 374d0698e0dSDavid Hollister *peak_detector = B_TRUE; 375d0698e0dSDavid Hollister break; 376d0698e0dSDavid Hollister case SMP_PHY_EVENT_TX_SSP_FRAME_COUNT: 377d0698e0dSDavid Hollister src_str = "Transmitted SSP frame count"; 378d0698e0dSDavid Hollister break; 379d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_SSP_FRAME_COUNT: 380d0698e0dSDavid Hollister src_str = "Received SSP frame count"; 381d0698e0dSDavid Hollister break; 382d0698e0dSDavid Hollister case SMP_PHY_EVENT_TX_SSP_FRAME_ERROR_COUNT: 383d0698e0dSDavid Hollister src_str = "Transmitted SSP frame error count"; 384d0698e0dSDavid Hollister break; 385d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_SSP_FRAME_ERROR_COUNT: 386d0698e0dSDavid Hollister src_str = "Received SSP frame error count"; 387d0698e0dSDavid Hollister break; 388d0698e0dSDavid Hollister case SMP_PHY_EVENT_TX_CREDIT_BLOCKED_COUNT: 389d0698e0dSDavid Hollister src_str = "Transmitted CREDIT_BLOCKED count"; 390d0698e0dSDavid Hollister break; 391d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_CREDIT_BLOCKED_COUNT: 392d0698e0dSDavid Hollister src_str = "Received CREDIT_BLOCKED count"; 393d0698e0dSDavid Hollister break; 394d0698e0dSDavid Hollister case SMP_PHY_EVENT_TX_SATA_FRAME_COUNT: 395d0698e0dSDavid Hollister src_str = "Transmitted SATA frame count"; 396d0698e0dSDavid Hollister break; 397d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_SATA_FRAME_COUNT: 398d0698e0dSDavid Hollister src_str = "Received SATA frame count"; 399d0698e0dSDavid Hollister break; 400d0698e0dSDavid Hollister case SMP_PHY_EVENT_SATA_FLOW_CTRL_BUF_OVERFLOW_COUNT: 401d0698e0dSDavid Hollister src_str = "SATA flow control buffer overflow count"; 402d0698e0dSDavid Hollister break; 403d0698e0dSDavid Hollister case SMP_PHY_EVENT_TX_SMP_FRAME_COUNT: 404d0698e0dSDavid Hollister src_str = "Transmitted SMP frame count"; 405d0698e0dSDavid Hollister break; 406d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_SMP_FRAME_COUNT: 407d0698e0dSDavid Hollister src_str = "Received SMP frame count"; 408d0698e0dSDavid Hollister break; 409d0698e0dSDavid Hollister case SMP_PHY_EVENT_RX_SMP_FRAME_ERROR_COUNT: 410d0698e0dSDavid Hollister src_str = "Received SMP frame error count"; 411d0698e0dSDavid Hollister break; 412d0698e0dSDavid Hollister default: 413d0698e0dSDavid Hollister src_str = "<Unknown>"; 414d0698e0dSDavid Hollister break; 415d0698e0dSDavid Hollister } 416d0698e0dSDavid Hollister 417d0698e0dSDavid Hollister return (src_str); 418d0698e0dSDavid Hollister } 419d0698e0dSDavid Hollister 420d0698e0dSDavid Hollister static void 421d0698e0dSDavid Hollister smp_validate_args(int argc, char *argv[]) 422d0698e0dSDavid Hollister { 423d0698e0dSDavid Hollister errno = 0; 424ac88567aSHyon Kim 425ac88567aSHyon Kim if (argc < 3) 426ac88567aSHyon Kim fatal(-1, "Usage: %s <device> <function> ...\n", argv[0]); 427ac88567aSHyon Kim 428ac88567aSHyon Kim func = strtoul(argv[2], NULL, 0); 429d0698e0dSDavid Hollister 430ac88567aSHyon Kim if (errno != 0) 431ac88567aSHyon Kim fatal(-1, "Usage: %s <device> <function> ...\n", argv[0]); 432ac88567aSHyon Kim 433d0698e0dSDavid Hollister switch (func) { 434d0698e0dSDavid Hollister case SMP_FUNC_DISCOVER: 435d0698e0dSDavid Hollister case SMP_FUNC_REPORT_PHY_EVENT: 436d0698e0dSDavid Hollister case SMP_FUNC_REPORT_PHY_ERROR_LOG: { 437d0698e0dSDavid Hollister if (argc != 4) { 438d0698e0dSDavid Hollister fatal(-1, 439d0698e0dSDavid Hollister "Usage: %s <device> 0x%x <phy identifier>\n", 440d0698e0dSDavid Hollister argv[0], func); 441d0698e0dSDavid Hollister } 442d0698e0dSDavid Hollister break; 443d0698e0dSDavid Hollister } 444d0698e0dSDavid Hollister case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST: { 445d0698e0dSDavid Hollister if (argc < 4) { 446d0698e0dSDavid Hollister fatal(-1, 447d0698e0dSDavid Hollister "Usage: %s <device> 0x%x <SAS Address Index>\n", 448d0698e0dSDavid Hollister argv[0], func); 449d0698e0dSDavid Hollister } 450d0698e0dSDavid Hollister break; 451d0698e0dSDavid Hollister } 452d0698e0dSDavid Hollister case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD: { 453d0698e0dSDavid Hollister if (argc < 4) { 454d0698e0dSDavid Hollister fatal(-1, 455d0698e0dSDavid Hollister "Usage: %s <device> 0x%x <report type>\n", 456d0698e0dSDavid Hollister argv[0], func); 457d0698e0dSDavid Hollister } 458d0698e0dSDavid Hollister break; 459d0698e0dSDavid Hollister } 460d0698e0dSDavid Hollister case SMP_FUNC_ENABLE_DISABLE_ZONING: { 461d0698e0dSDavid Hollister if (argc != 4) { 462d0698e0dSDavid Hollister fatal(-1, 463d0698e0dSDavid Hollister "Usage: %s <device> 0x%x " 464d0698e0dSDavid Hollister "[0(no change) | 1(enable)| 2(disable)]\n", 465d0698e0dSDavid Hollister argv[0], func); 466d0698e0dSDavid Hollister } 467d0698e0dSDavid Hollister break; 468d0698e0dSDavid Hollister } 469d0698e0dSDavid Hollister case SMP_FUNC_REPORT_BROADCAST: { 470d0698e0dSDavid Hollister if (argc != 4) { 471d0698e0dSDavid Hollister fatal(-1, "Usage: %s <device> 0x%x <bcast type>\n", 472d0698e0dSDavid Hollister argv[0], func); 473d0698e0dSDavid Hollister } 474d0698e0dSDavid Hollister break; 475d0698e0dSDavid Hollister } 476d0698e0dSDavid Hollister case SMP_FUNC_REPORT_ROUTE_INFO: { 477d0698e0dSDavid Hollister if (argc != 5) { 478d0698e0dSDavid Hollister fatal(-1, 479d0698e0dSDavid Hollister "Usage: %s <device> 0x%x <exp_route_idx> " 480d0698e0dSDavid Hollister "<phy_identifier>\n", argv[0], func); 481d0698e0dSDavid Hollister } 482d0698e0dSDavid Hollister break; 483d0698e0dSDavid Hollister } 484d0698e0dSDavid Hollister case SMP_FUNC_PHY_CONTROL: { 485d0698e0dSDavid Hollister if (argc != 5) { 486d0698e0dSDavid Hollister fatal(-1, 487d0698e0dSDavid Hollister "Usage: %s <device> 0x%x <phy identifier> " 488d0698e0dSDavid Hollister " <phy operation>\n", 489d0698e0dSDavid Hollister argv[0], func); 490d0698e0dSDavid Hollister } 491d0698e0dSDavid Hollister break; 492d0698e0dSDavid Hollister } 493d0698e0dSDavid Hollister default: { 494d0698e0dSDavid Hollister fatal(-1, "Usage: %s <device> <function> ...\n", argv[0]); 495d0698e0dSDavid Hollister break; 496d0698e0dSDavid Hollister } 497d0698e0dSDavid Hollister } 498d0698e0dSDavid Hollister } 499d0698e0dSDavid Hollister 500d0698e0dSDavid Hollister int 501d0698e0dSDavid Hollister main(int argc, char *argv[]) 502d0698e0dSDavid Hollister { 503d0698e0dSDavid Hollister uint_t i, j; 504d0698e0dSDavid Hollister char *yesorno; 505d0698e0dSDavid Hollister uint16_t exp_change_count; 506d0698e0dSDavid Hollister 507d0698e0dSDavid Hollister /* 508d0698e0dSDavid Hollister * If the arguments are invalid, this function will not return. 509d0698e0dSDavid Hollister */ 510d0698e0dSDavid Hollister smp_validate_args(argc, argv); 511d0698e0dSDavid Hollister 512ac88567aSHyon Kim if (smp_init(LIBSMP_VERSION) != 0) 513ac88567aSHyon Kim fatal(-1, "libsmp initialization failed: %s", smp_errmsg()); 514ac88567aSHyon Kim 515ac88567aSHyon Kim bzero(&tdef, sizeof (smp_target_def_t)); 516ac88567aSHyon Kim tdef.std_def = argv[1]; 517ac88567aSHyon Kim 518ac88567aSHyon Kim if ((tp = smp_open(&tdef)) == NULL) { 519ac88567aSHyon Kim smp_fini(); 520ac88567aSHyon Kim fatal(-2, "failed to open %s: %s", argv[1], smp_errmsg()); 521ac88567aSHyon Kim } 522ac88567aSHyon Kim 523d0698e0dSDavid Hollister exp_change_count = smp_target_get_change_count(tp); 524d0698e0dSDavid Hollister 525d0698e0dSDavid Hollister (void) printf("%s\n", argv[0]); 526d0698e0dSDavid Hollister (void) printf("\tSAS Address: %016llx\n", smp_target_addr(tp)); 527d0698e0dSDavid Hollister (void) printf("\tVendor/Product/Revision: %s/%s/%s\n", 528d0698e0dSDavid Hollister smp_target_vendor(tp), smp_target_product(tp), 529d0698e0dSDavid Hollister smp_target_revision(tp)); 530d0698e0dSDavid Hollister (void) printf("\tExp Vendor/ID/Rev: %s/%04x/%02x\n", 531d0698e0dSDavid Hollister smp_target_component_vendor(tp), smp_target_component_id(tp), 532d0698e0dSDavid Hollister smp_target_component_revision(tp)); 533d0698e0dSDavid Hollister (void) printf("\tExpander change count: 0x%04x\n", exp_change_count); 534d0698e0dSDavid Hollister 535ac88567aSHyon Kim ap = smp_action_alloc(func, tp, 0); 536ac88567aSHyon Kim if (ap == NULL) { 537ac88567aSHyon Kim smp_close(tp); 538ac88567aSHyon Kim smp_fini(); 539ac88567aSHyon Kim fatal(-3, "failed to allocate action: %s", smp_errmsg()); 540ac88567aSHyon Kim } 541ac88567aSHyon Kim 542d0698e0dSDavid Hollister switch (func) { 543d0698e0dSDavid Hollister case SMP_FUNC_DISCOVER: { 544ac88567aSHyon Kim smp_discover_req_t *dp; 545ac88567aSHyon Kim 546ac88567aSHyon Kim smp_action_get_request(ap, (void **)&dp, NULL); 547ac88567aSHyon Kim dp->sdr_phy_identifier = strtoul(argv[3], NULL, 0); 548d0698e0dSDavid Hollister break; 549d0698e0dSDavid Hollister } 550d0698e0dSDavid Hollister case SMP_FUNC_REPORT_ROUTE_INFO: { 551d0698e0dSDavid Hollister smp_handle_report_route_info(argc, argv); 552d0698e0dSDavid Hollister break; 553d0698e0dSDavid Hollister } 554d0698e0dSDavid Hollister case SMP_FUNC_ENABLE_DISABLE_ZONING: { 555ac88567aSHyon Kim smp_enable_disable_zoning_req_t *rp; 556ac88567aSHyon Kim 557ac88567aSHyon Kim smp_action_get_request(ap, (void **)&rp, NULL); 558ac88567aSHyon Kim rp->sedzr_enable_disable_zoning = strtoul(argv[3], NULL, 0); 559d0698e0dSDavid Hollister break; 560d0698e0dSDavid Hollister } 561d0698e0dSDavid Hollister case SMP_FUNC_PHY_CONTROL: { 562ac88567aSHyon Kim smp_phy_control_req_t *rp; 563ac88567aSHyon Kim 564ac88567aSHyon Kim smp_action_get_request(ap, (void **)&rp, NULL); 565ac88567aSHyon Kim rp->spcr_phy_identifier = strtoul(argv[3], NULL, 0); 566ac88567aSHyon Kim rp->spcr_phy_operation = strtoul(argv[4], NULL, 0); 567d0698e0dSDavid Hollister break; 568d0698e0dSDavid Hollister } 569d0698e0dSDavid Hollister case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST: { 570ac88567aSHyon Kim smp_report_exp_route_table_list_req_t *rp; 571ac88567aSHyon Kim 572ac88567aSHyon Kim smp_action_get_request(ap, (void **)&rp, NULL); 573ac88567aSHyon Kim SCSI_WRITE16(&rp->srertlr_max_descrs, 64); 574ac88567aSHyon Kim SCSI_WRITE16(&rp->srertlr_starting_routed_sas_addr_index, 575ac88567aSHyon Kim strtoull(argv[3], NULL, 0)); 576ac88567aSHyon Kim rp->srertlr_starting_phy_identifier = 0; 577d0698e0dSDavid Hollister break; 578ac88567aSHyon Kim } 579d0698e0dSDavid Hollister case SMP_FUNC_REPORT_PHY_ERROR_LOG: { 580d0698e0dSDavid Hollister smp_report_phy_error_log_req_t *pelp; 581ac88567aSHyon Kim 582d0698e0dSDavid Hollister smp_action_get_request(ap, (void **)&pelp, NULL); 583d0698e0dSDavid Hollister pelp->srpelr_phy_identifier = strtoul(argv[3], NULL, 0); 584d0698e0dSDavid Hollister break; 585d0698e0dSDavid Hollister } 586d0698e0dSDavid Hollister case SMP_FUNC_REPORT_PHY_EVENT: { 587d0698e0dSDavid Hollister smp_report_phy_event_req_t *rpep; 588ac88567aSHyon Kim 589d0698e0dSDavid Hollister smp_action_get_request(ap, (void **)&rpep, NULL); 590d0698e0dSDavid Hollister rpep->srper_phy_identifier = strtoul(argv[3], NULL, 0); 591d0698e0dSDavid Hollister break; 592d0698e0dSDavid Hollister } 593d0698e0dSDavid Hollister case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD: { 594d0698e0dSDavid Hollister smp_report_zone_mgr_password_req_t *rzmprp; 595d0698e0dSDavid Hollister 596d0698e0dSDavid Hollister smp_action_get_request(ap, (void **)&rzmprp, NULL); 597d0698e0dSDavid Hollister rzmprp->srzmpr_rpt_type = strtoul(argv[3], NULL, 0); 598d0698e0dSDavid Hollister break; 599d0698e0dSDavid Hollister } 600d0698e0dSDavid Hollister case SMP_FUNC_REPORT_BROADCAST: { 601d0698e0dSDavid Hollister smp_report_broadcast_req_t *rbrp; 602d0698e0dSDavid Hollister 603d0698e0dSDavid Hollister smp_action_get_request(ap, (void **)&rbrp, NULL); 604d0698e0dSDavid Hollister rbrp->srbr_broadcast_type = strtoul(argv[3], NULL, 0); 605d0698e0dSDavid Hollister break; 606d0698e0dSDavid Hollister } 607d0698e0dSDavid Hollister default: 608ac88567aSHyon Kim smp_close(tp); 609ac88567aSHyon Kim smp_action_free(ap); 610ac88567aSHyon Kim smp_fini(); 611d0698e0dSDavid Hollister smp_cmd_failed(result); 612ac88567aSHyon Kim } 613ac88567aSHyon Kim 614d0698e0dSDavid Hollister smp_execute(); 615d0698e0dSDavid Hollister smp_get_response(B_TRUE); 616ac88567aSHyon Kim 617d0698e0dSDavid Hollister switch (func) { 618d0698e0dSDavid Hollister case SMP_FUNC_DISCOVER: { 619d0698e0dSDavid Hollister smp_discover_resp_t *rp = (smp_discover_resp_t *)smp_resp; 620ac88567aSHyon Kim (void) printf("Addr: %016llx Phy: %02x\n", 621ac88567aSHyon Kim SCSI_READ64(&rp->sdr_sas_addr), rp->sdr_phy_identifier); 622ac88567aSHyon Kim (void) printf("Peer: %016llx Phy: %02x\n", 623ac88567aSHyon Kim SCSI_READ64(&rp->sdr_attached_sas_addr), 624ac88567aSHyon Kim rp->sdr_attached_phy_identifier); 625ac88567aSHyon Kim (void) printf("Device type: %01x\n", 626ac88567aSHyon Kim rp->sdr_attached_device_type); 627d0698e0dSDavid Hollister break; 628d0698e0dSDavid Hollister } 629d0698e0dSDavid Hollister case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD: { 630d0698e0dSDavid Hollister smp_report_zone_mgr_password_resp_t *rp = 631d0698e0dSDavid Hollister (smp_report_zone_mgr_password_resp_t *)smp_resp; 632d0698e0dSDavid Hollister char *rpt_type = NULL; 633d0698e0dSDavid Hollister int idx; 634d0698e0dSDavid Hollister switch (rp->srzmpr_rpt_type) { 635d0698e0dSDavid Hollister case SMP_ZMP_TYPE_CURRENT: 636d0698e0dSDavid Hollister rpt_type = "Current"; 637d0698e0dSDavid Hollister break; 638d0698e0dSDavid Hollister case SMP_ZMP_TYPE_SAVED: 639d0698e0dSDavid Hollister rpt_type = "Saved"; 640d0698e0dSDavid Hollister break; 641d0698e0dSDavid Hollister case SMP_ZMP_TYPE_DEFAULT: 642d0698e0dSDavid Hollister rpt_type = "Default"; 643d0698e0dSDavid Hollister break; 644d0698e0dSDavid Hollister default: 645d0698e0dSDavid Hollister rpt_type = "(Unknown Type)"; 646d0698e0dSDavid Hollister break; 647d0698e0dSDavid Hollister } 648d0698e0dSDavid Hollister (void) printf("%s zone manager password: 0x", rpt_type); 649d0698e0dSDavid Hollister for (idx = 0; idx < 32; idx++) { 650d0698e0dSDavid Hollister (void) printf("%02x", 651d0698e0dSDavid Hollister rp->srzmpr_zone_mgr_password[idx]); 652d0698e0dSDavid Hollister } 653d0698e0dSDavid Hollister (void) printf("\n"); 654d0698e0dSDavid Hollister break; 655d0698e0dSDavid Hollister } 656d0698e0dSDavid Hollister case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST: { 657d0698e0dSDavid Hollister smp_report_exp_route_table_list_resp_t *rtlr = 658d0698e0dSDavid Hollister (smp_report_exp_route_table_list_resp_t *)smp_resp; 659d0698e0dSDavid Hollister smp_route_table_descr_t *descp = &rtlr->srertlr_descrs[0]; 660d0698e0dSDavid Hollister int idx, idxx, ndescrs, zoning, startnum; 661d0698e0dSDavid Hollister 662d0698e0dSDavid Hollister (void) printf("Expander change count: 0x%04x\n", 663d0698e0dSDavid Hollister BE_16(rtlr->srertlr_exp_change_count)); 664d0698e0dSDavid Hollister (void) printf("Expander route table change count: 0x%04x\n", 665d0698e0dSDavid Hollister BE_16(rtlr->srertlr_route_table_change_count)); 666d0698e0dSDavid Hollister 667d0698e0dSDavid Hollister if (rtlr->srertlr_zoning_enabled) { 668d0698e0dSDavid Hollister yesorno = yes; 669d0698e0dSDavid Hollister zoning = 1; 670d0698e0dSDavid Hollister } else { 671d0698e0dSDavid Hollister yesorno = no; 672d0698e0dSDavid Hollister zoning = 0; 673d0698e0dSDavid Hollister } 674d0698e0dSDavid Hollister (void) printf("Zoning enabled: %s\n", yesorno); 675d0698e0dSDavid Hollister 676d0698e0dSDavid Hollister if (rtlr->srertlr_configuring) { 677d0698e0dSDavid Hollister yesorno = yes; 678d0698e0dSDavid Hollister } else { 679d0698e0dSDavid Hollister yesorno = no; 680d0698e0dSDavid Hollister } 681d0698e0dSDavid Hollister (void) printf("Configuring: %s\n", yesorno); 682d0698e0dSDavid Hollister 683d0698e0dSDavid Hollister ndescrs = rtlr->srertlr_n_descrs; 684d0698e0dSDavid Hollister (void) printf("Number of descriptors: %d\n", ndescrs); 685d0698e0dSDavid Hollister startnum = BE_16(rtlr->srertlr_first_routed_sas_addr_index); 686d0698e0dSDavid Hollister (void) printf("First/Last routed SAS address index: %d/%d\n", 687d0698e0dSDavid Hollister startnum, BE_16(rtlr->srertlr_last_routed_sas_addr_index)); 688d0698e0dSDavid Hollister (void) printf("Starting PHY identifier: %d\n", 689d0698e0dSDavid Hollister rtlr->srertlr_starting_phy_identifier); 690d0698e0dSDavid Hollister 691d0698e0dSDavid Hollister for (idx = 0; idx < ndescrs; idx++, descp++) { 692d0698e0dSDavid Hollister (void) printf("#%03d: Routed SAS addr: %016llx ", 693d0698e0dSDavid Hollister idx + startnum, BE_64(descp->srtd_routed_sas_addr)); 694d0698e0dSDavid Hollister (void) printf("PHY bitmap: 0x"); 695d0698e0dSDavid Hollister for (idxx = 0; idxx < 6; idxx++) { 696d0698e0dSDavid Hollister (void) printf("%02x", 697d0698e0dSDavid Hollister descp->srtd_phy_bitmap[idxx]); 698d0698e0dSDavid Hollister } 699d0698e0dSDavid Hollister (void) printf("\n"); 700d0698e0dSDavid Hollister if (zoning) { 701d0698e0dSDavid Hollister (void) printf("\tZone group: %d\n", 702d0698e0dSDavid Hollister descp->srtd_zone_group); 703d0698e0dSDavid Hollister } 704ac88567aSHyon Kim } 705ac88567aSHyon Kim 706d0698e0dSDavid Hollister (void) printf("\n"); 707d0698e0dSDavid Hollister break; 708d0698e0dSDavid Hollister } 709d0698e0dSDavid Hollister case SMP_FUNC_REPORT_PHY_ERROR_LOG: { 710d0698e0dSDavid Hollister smp_report_phy_error_log_resp_t *pelr = 711d0698e0dSDavid Hollister (smp_report_phy_error_log_resp_t *)smp_resp; 712d0698e0dSDavid Hollister (void) printf("PHY error log for PHY %d:\n", 713d0698e0dSDavid Hollister pelr->srpelr_phy_identifier); 714d0698e0dSDavid Hollister (void) printf("\tInvalid DWORD count: %d\n", 715d0698e0dSDavid Hollister BE_32(pelr->srpelr_invalid_dword_count)); 716d0698e0dSDavid Hollister (void) printf("\tRunning disparity error count: %d\n", 717d0698e0dSDavid Hollister BE_32(pelr->srpelr_running_disparity_error_count)); 718d0698e0dSDavid Hollister (void) printf("\tLoss of DWORD sync count: %d\n", 719d0698e0dSDavid Hollister BE_32(pelr->srpelr_loss_dword_sync_count)); 720d0698e0dSDavid Hollister (void) printf("\tPHY reset problem count: %d\n", 721d0698e0dSDavid Hollister BE_32(pelr->srpelr_phy_reset_problem_count)); 722d0698e0dSDavid Hollister break; 723d0698e0dSDavid Hollister } 724d0698e0dSDavid Hollister case SMP_FUNC_REPORT_PHY_EVENT: { 725d0698e0dSDavid Hollister smp_report_phy_event_resp_t *rper = 726d0698e0dSDavid Hollister (smp_report_phy_event_resp_t *)smp_resp; 727d0698e0dSDavid Hollister smp_phy_event_report_descr_t *perd = 728d0698e0dSDavid Hollister &rper->srper_phy_event_descrs[0]; 729d0698e0dSDavid Hollister boolean_t peak; 730d0698e0dSDavid Hollister int idx; 731ac88567aSHyon Kim 732d0698e0dSDavid Hollister (void) printf("PHY event for PHY %d:\n", 733d0698e0dSDavid Hollister rper->srper_phy_identifier); 734d0698e0dSDavid Hollister (void) printf("Number of PHY event descriptors: %d\n", 735d0698e0dSDavid Hollister rper->srper_n_phy_event_descrs); 736d0698e0dSDavid Hollister 737d0698e0dSDavid Hollister for (idx = 0; idx < rper->srper_n_phy_event_descrs; idx++) { 738d0698e0dSDavid Hollister (void) printf("%50s : %d\n", 739d0698e0dSDavid Hollister smp_phy_event_src_str(perd->sped_phy_event_source, 740d0698e0dSDavid Hollister &peak), BE_32(perd->sped_phy_event)); 741d0698e0dSDavid Hollister if (peak) { 742d0698e0dSDavid Hollister (void) printf("\tPeak value detector " 743d0698e0dSDavid Hollister "threshold: %d\n", 744d0698e0dSDavid Hollister BE_32(perd->sped_peak_detector_threshold)); 745d0698e0dSDavid Hollister } 746d0698e0dSDavid Hollister perd++; 747d0698e0dSDavid Hollister } 748d0698e0dSDavid Hollister 749d0698e0dSDavid Hollister break; 750d0698e0dSDavid Hollister } 751d0698e0dSDavid Hollister case SMP_FUNC_REPORT_BROADCAST: { 752d0698e0dSDavid Hollister smp_report_broadcast_resp_t *brp = 753d0698e0dSDavid Hollister (smp_report_broadcast_resp_t *)smp_resp; 754d0698e0dSDavid Hollister smp_broadcast_descr_t *bdp = &brp->srbr_descrs[0]; 755d0698e0dSDavid Hollister uint16_t bcount, idx; 756d0698e0dSDavid Hollister 757d0698e0dSDavid Hollister bcount = brp->srbr_number_broadcast_descrs; 758d0698e0dSDavid Hollister 759d0698e0dSDavid Hollister (void) printf("\tNumber of broadcast descriptors: %d\n", 760d0698e0dSDavid Hollister bcount); 761d0698e0dSDavid Hollister (void) printf("\t%7s %5s %5s %8s\n", 762d0698e0dSDavid Hollister "BCType", "PhyID", "BCRsn", "BC Count"); 763d0698e0dSDavid Hollister for (idx = 0; idx < bcount; idx++) { 764d0698e0dSDavid Hollister (void) printf("\t%7s %5s %5s %8s\n", 765d0698e0dSDavid Hollister bdp->sbd_broadcast_type, bdp->sbd_phy_identifier, 766d0698e0dSDavid Hollister bdp->sbd_broadcast_reason, 767d0698e0dSDavid Hollister bdp->sbd_broadcast_count); 768d0698e0dSDavid Hollister bdp++; 769d0698e0dSDavid Hollister } 770d0698e0dSDavid Hollister 771d0698e0dSDavid Hollister break; 772d0698e0dSDavid Hollister } 773d0698e0dSDavid Hollister default: 774d0698e0dSDavid Hollister (void) printf("Response: (len %d)\n", smp_resp_len); 775d0698e0dSDavid Hollister for (i = 0; i < smp_resp_len; i += 8) { 776d0698e0dSDavid Hollister (void) printf("%02x: ", i); 777d0698e0dSDavid Hollister for (j = i; j < i + 8; j++) 778d0698e0dSDavid Hollister if (j < smp_resp_len) 779d0698e0dSDavid Hollister (void) printf("%02x ", smp_resp[j]); 780d0698e0dSDavid Hollister else 781d0698e0dSDavid Hollister (void) printf(" "); 782d0698e0dSDavid Hollister for (j = i; j < i + 8; j++) 783d0698e0dSDavid Hollister (void) printf("%c", 784d0698e0dSDavid Hollister j < smp_resp_len && isprint(smp_resp[j]) ? 785d0698e0dSDavid Hollister smp_resp[j] : j < smp_resp_len ? '.' : 786d0698e0dSDavid Hollister '\0'); 787d0698e0dSDavid Hollister (void) printf("\n"); 788d0698e0dSDavid Hollister } 789d0698e0dSDavid Hollister break; 790d0698e0dSDavid Hollister } 791d0698e0dSDavid Hollister 792d0698e0dSDavid Hollister smp_cleanup(); 793ac88567aSHyon Kim return (0); 794ac88567aSHyon Kim } 795