Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / SOLARIS / osi_ioctl.c
1 /*
2 * Copyright 2010, Sine Nomine Associates and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13 /* ioctl-based emulation for the AFS syscall, for Solaris 11 and onwards. */
14
15 #ifdef AFS_SUN511_ENV
16
17 #include "afs/sysincludes.h" /* Standard vendor system headers */
18 #include "afsincludes.h" /* Afs-based standard headers */
19
20 #include <sys/types.h>
21 #include <sys/file.h>
22 #include <sys/errno.h>
23 #include <sys/open.h>
24 #include <sys/cred.h>
25 #include <sys/ddi.h>
26 #include <sys/sunddi.h>
27
28 #define DEVAFS_MINOR 0
29
30 static int
31 devafs_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
32 {
33 if (getminor(*devp) != DEVAFS_MINOR) {
34 return EINVAL;
35 }
36 if (otyp != OTYP_CHR) {
37 return EINVAL;
38 }
39 return 0;
40 }
41
42 static int
43 devafs_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
44 {
45 if (getminor(dev) != DEVAFS_MINOR) {
46 return EINVAL;
47 }
48 if (otyp != OTYP_CHR) {
49 return EINVAL;
50 }
51 return 0;
52 }
53
54 static int
55 devafs_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
56 int *rval_p)
57 {
58 int error;
59 struct afssysa ua;
60 rval_t rv;
61
62 if (getminor(dev) != DEVAFS_MINOR) {
63 return EINVAL;
64 }
65
66 switch (cmd) {
67 case VIOC_SYSCALL: {
68 struct afssysargs sargs;
69 error = ddi_copyin((const void *)arg, &sargs, sizeof(sargs), mode);
70 if (error) {
71 return EFAULT;
72 }
73 ua.syscall = sargs.syscall;
74 ua.parm1 = sargs.param1;
75 ua.parm2 = sargs.param2;
76 ua.parm3 = sargs.param3;
77 ua.parm4 = sargs.param4;
78 ua.parm5 = sargs.param5;
79 ua.parm6 = sargs.param6;
80
81 break;
82 }
83 case VIOC_SYSCALL32: {
84 struct afssysargs32 sargs32;
85 error = ddi_copyin((const void *)arg, &sargs32, sizeof(sargs32), mode);
86 if (error) {
87 return EFAULT;
88 }
89 ua.syscall = sargs32.syscall;
90 ua.parm1 = sargs32.param1;
91 ua.parm2 = sargs32.param2;
92 ua.parm3 = sargs32.param3;
93 ua.parm4 = sargs32.param4;
94 ua.parm5 = sargs32.param5;
95 ua.parm6 = sargs32.param6;
96
97 break;
98 }
99 default:
100 return EINVAL;
101 }
102
103 rv.r_val1 = 0;
104 error = Afs_syscall(&ua, &rv);
105
106 if (!error) {
107 error = rv.r_val1;
108 }
109
110 return error;
111 }
112
113 static struct cb_ops devafs_cb_ops = {
114 /* .cb_open = */ devafs_open,
115 /* .cb_close = */ devafs_close,
116 /* .cb_strategy = */ nodev,
117 /* .cb_print = */ nodev,
118 /* .cb_dump = */ nodev,
119 /* .cb_read = */ nodev,
120 /* .cb_write = */ nodev,
121 /* .cb_ioctl = */ devafs_ioctl,
122 /* .cb_devmap = */ nodev,
123 /* .cb_mmap = */ nodev,
124 /* .cb_segmap = */ nodev,
125 /* .cb_chpoll = */ nochpoll,
126 /* .cb_prop_op = */ ddi_prop_op,
127 /* .cb_str = */ NULL,
128 /* .cb_flag = */ D_NEW | D_MP | D_64BIT,
129 /* .cb_rev = */ CB_REV,
130 /* .cb_aread = */ nodev,
131 /* .cb_awrite = */ nodev,
132 };
133
134 static dev_info_t *devafs_dip = NULL;
135
136 static int
137 devafs_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
138 {
139 switch (cmd) {
140 case DDI_INFO_DEVT2DEVINFO:
141 *resultp = devafs_dip;
142 return DDI_SUCCESS;
143 case DDI_INFO_DEVT2INSTANCE:
144 *resultp = 0; /* we only have one instance */
145 return DDI_SUCCESS;
146 default:
147 return DDI_FAILURE;
148 }
149 }
150
151 static int
152 devafs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
153 {
154 int error;
155 switch (cmd) {
156 case DDI_ATTACH:
157 osi_Assert(devafs_dip == NULL);
158
159 error = ddi_create_minor_node(dip, "afs", S_IFCHR, DEVAFS_MINOR,
160 DDI_PSEUDO, 0);
161 if (error != DDI_SUCCESS) {
162 return DDI_FAILURE;
163 }
164
165 devafs_dip = dip;
166
167 ddi_report_dev(dip);
168
169 return DDI_SUCCESS;
170 case DDI_RESUME:
171 return DDI_FAILURE;
172 default:
173 return DDI_FAILURE;
174 }
175 }
176
177 static int
178 devafs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
179 {
180 switch (cmd) {
181 case DDI_DETACH:
182 osi_Assert(devafs_dip != NULL);
183
184 devafs_dip = NULL;
185
186 ddi_prop_remove_all(dip);
187 ddi_remove_minor_node(dip, NULL);
188
189 return DDI_SUCCESS;
190 case DDI_SUSPEND:
191 return DDI_FAILURE;
192 default:
193 return DDI_FAILURE;
194 }
195 }
196
197 static struct dev_ops afs_devops = {
198 /* .devo_rev = */ DEVO_REV,
199 /* .devo_refcnt = */ 0,
200 /* .devo_getinfo = */ devafs_getinfo,
201 /* .devo_identify = */ nulldev,
202 /* .devo_probe = */ nulldev,
203 /* .devo_attach = */ devafs_attach,
204 /* .devo_detach = */ devafs_detach,
205 /* .devo_reset = */ nodev,
206 /* .devo_cb_ops = */ &devafs_cb_ops,
207 /* .devo_bus_ops = */ NULL,
208 /* .devo_power = */ NULL,
209 /* .devo_quiesce = */ ddi_quiesce_not_needed,
210 };
211
212 extern struct mod_ops mod_driverops;
213
214 struct modldrv afs_modldrv = {
215 &mod_driverops,
216 "/dev/afs driver",
217 &afs_devops,
218 };
219
220 #endif /* AFS_SUN511_ENV */