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