4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
24 /* All Rights Reserved */
27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
32 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
36 * kTLI variant of t_optmgmt(3NSL)
37 * Returns 0 on success or an errno value.
38 * Similar to libnsl t_optmgmt.c
40 * Note: This expects the caller's struct t_optmgmt to contain the
41 * XTI version of struct T_opthdr (used with T_OPTMGMT_REQ == 27)
42 * not the old "struct opthdr" (used with T_SVR4_OPTMGMT_REQ == 9)
45 #include <sys/param.h>
46 #include <sys/types.h>
50 #include <sys/vnode.h>
51 #include <sys/errno.h>
52 #include <sys/stream.h>
53 #include <sys/ioctl.h>
54 #include <sys/stropts.h>
55 #include <sys/strsubr.h>
56 #define _SUN_TPI_VERSION 2
57 #include <sys/tihdr.h>
58 #include <sys/timod.h>
59 #include <sys/tiuser.h>
60 #include <sys/t_kuser.h>
64 t_koptmgmt(TIUSER
*tiptr
, struct t_optmgmt
*req
, struct t_optmgmt
*ret
)
66 struct strioctl strioc
;
67 struct T_optmgmt_req
*opt_req
;
68 struct T_optmgmt_ack
*opt_ack
;
81 optlen
= req
->opt
.len
;
83 if (req
->opt
.buf
== NULL
)
85 if (optlen
< (t_scalar_t
)sizeof (struct T_opthdr
)) {
86 /* option buffer should atleast have an t_opthdr */
95 ctlsize
= sizeof (*opt_req
) + optlen
;
96 ctlbuf
= kmem_alloc(ctlsize
, KM_SLEEP
);
98 /* LINTED E_BAD_PTR_CAST_ALIGN */
99 opt_req
= (struct T_optmgmt_req
*)ctlbuf
;
100 opt_req
->PRIM_type
= T_OPTMGMT_REQ
;
101 opt_req
->MGMT_flags
= req
->flags
;
102 opt_req
->OPT_length
= optlen
;
103 opt_req
->OPT_offset
= sizeof (*opt_req
);
105 opt_data
= ctlbuf
+ sizeof (*opt_req
);
106 bcopy(req
->opt
.buf
, opt_data
, optlen
);
109 strioc
.ic_cmd
= TI_OPTMGMT
;
110 strioc
.ic_timout
= 0;
111 strioc
.ic_dp
= ctlbuf
;
112 strioc
.ic_len
= ctlsize
;
114 error
= strdoioctl(vp
->v_stream
, &strioc
, FNATIVE
, K_TO_K
,
115 fp
->f_cred
, &retval
);
120 if ((retval
& 0xff) == TSYSERR
)
121 error
= (retval
>> 8) & 0xff;
123 error
= t_tlitosyserr(retval
& 0xff);
127 if (strioc
.ic_len
< sizeof (struct T_optmgmt_ack
)) {
132 /* LINTED pointer cast */
133 opt_ack
= (struct T_optmgmt_ack
*)ctlbuf
;
134 if (opt_ack
->PRIM_type
!= T_OPTMGMT_ACK
) {
139 if (ret
->opt
.maxlen
> 0) {
140 if (opt_ack
->OPT_length
> ret
->opt
.maxlen
) {
144 ret
->opt
.len
= opt_ack
->OPT_offset
;
145 opt_data
= ctlbuf
+ opt_ack
->OPT_offset
;
146 bcopy(opt_data
, ret
->opt
.buf
, ret
->opt
.len
);
148 ret
->flags
= opt_ack
->MGMT_flags
;
152 kmem_free(ctlbuf
, ctlsize
);