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