]>
git.proxmox.com Git - mirror_spl.git/blob - include/sys/sunddi.h
2 * This file is part of the SPL: Solaris Porting Layer.
4 * Copyright (c) 2008 Lawrence Livermore National Security, LLC.
5 * Produced at Lawrence Livermore National Laboratory
7 * Brian Behlendorf <behlendorf1@llnl.gov>,
8 * Herb Wartens <wartens2@llnl.gov>,
9 * Jim Garlick <garlick@llnl.gov>
12 * This is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <sys/sunldi.h>
33 #include <sys/mutex.h>
34 #include <sys/u8_textprep.h>
35 #include <sys/vnode.h>
36 #include <linux/kdev_t.h>
38 #include <linux/cdev.h>
39 #include <linux/list.h>
40 #include <spl-device.h>
42 #define DDI_MAX_NAME_LEN 32
44 typedef int ddi_devid_t
;
47 DDI_INFO_DEVT2DEVINFO
= 0,
48 DDI_INFO_DEVT2INSTANCE
= 1
61 DDI_HOTPLUG_DETACH
= 3
70 PROP_LEN_AND_VAL_BUF
= 1,
71 PROP_LEN_AND_VAL_ALLOC
= 2,
75 typedef void *devmap_cookie_t
;
80 typedef struct pollhead
{
81 struct polldat
*ph_list
;
84 typedef struct dev_info
{
86 char di_name
[DDI_MAX_NAME_LEN
];
87 struct dev_ops
*di_ops
;
90 spl_device
*di_device
;
96 struct list_head di_list
;
99 typedef struct cb_ops
{
100 int (*cb_open
)(dev_t
*devp
, int flag
, int otyp
, cred_t
*credp
);
101 int (*cb_close
)(dev_t dev
, int flag
, int otyp
, cred_t
*credp
);
102 int (*cb_strategy
)(void *bp
);
103 int (*cb_print
)(dev_t dev
, char *str
);
104 int (*cb_dump
)(dev_t dev
, caddr_t addr
, daddr_t blkno
, int nblk
);
105 int (*cb_read
)(dev_t dev
, struct uio
*uiop
, cred_t
*credp
);
106 int (*cb_write
)(dev_t dev
, struct uio
*uiop
, cred_t
*credp
);
107 int (*cb_ioctl
)(dev_t dev
, int cmd
, intptr_t arg
, int mode
,
108 cred_t
*credp
, int *rvalp
);
109 int (*cb_devmap
)(dev_t dev
, devmap_cookie_t dhp
, offset_t off
,
110 size_t len
, size_t *maplen
, uint_t model
);
111 int (*cb_mmap
)(dev_t dev
, off_t off
, int prot
);
112 int (*cb_segmap
)(dev_t dev
, off_t off
, struct as
*asp
,
113 caddr_t
*addrp
, off_t len
, unsigned int prot
,
114 unsigned int maxprot
, unsigned int flags
,
116 int (*cb_chpoll
)(dev_t dev
, short events
, int anyyet
,
117 short *reventsp
, struct pollhead
**phpp
);
118 int (*cb_prop_op
)(dev_t dev
, dev_info_t
*dip
,
119 ddi_prop_op_t prop_op
, int mod_flags
,
120 char *name
, caddr_t valuep
, int *length
);
121 struct streamtab
*cb_str
;
124 int (*cb_aread
)(dev_t dev
, struct aio_req
*aio
, cred_t
*credp
);
125 int (*cb_awrite
)(dev_t dev
, struct aio_req
*aio
, cred_t
*credp
);
128 typedef struct dev_ops
{
132 int (*devo_getinfo
)(dev_info_t
*dip
,
133 ddi_info_cmd_t infocmd
, void *arg
, void **result
);
134 int (*devo_identify
)(dev_info_t
*dip
);
135 int (*devo_probe
)(dev_info_t
*dip
);
136 int (*devo_attach
)(dev_info_t
*dip
, ddi_attach_cmd_t cmd
);
137 int (*devo_detach
)(dev_info_t
*dip
, ddi_detach_cmd_t cmd
);
138 int (*devo_reset
)(dev_info_t
*dip
, ddi_reset_cmd_t cmd
);
140 struct cb_ops
*devo_cb_ops
;
141 struct bus_ops
*devo_bus_ops
;
142 int (*devo_power
)(dev_info_t
*dip
, int component
, int level
);
143 int (*devo_quiesce
)(dev_info_t
*dip
);
146 typedef struct mod_ops
{
147 int (*modm_install
)(void);
148 int (*modm_remove
)(void);
149 int (*modm_info
)(void);
152 typedef struct modldrv
{
153 struct mod_ops
*drv_modops
;
155 struct dev_ops
*drv_dev_ops
;
156 struct dev_info
*drv_dev_info
;
163 #define D_64BIT 0x200
168 #define DDI_SUCCESS 0
169 #define DDI_FAILURE -1
171 #define DDI_PSEUDO "ddi_pseudo"
174 #define nochpoll NULL
176 #define mod_driverops NULL
177 #define ddi_prop_op NULL
179 #define getminor(x) (x)
180 #define getmajor(x) (x)
181 #define ddi_driver_major(di) getmajor(di->di_dev)
183 #define DDI_DEV_T_NONE ((dev_t)-1)
184 #define DDI_DEV_T_ANY ((dev_t)-2)
185 #define DDI_MAJOR_T_UNKNOWN ((major_t)0)
187 #define DDI_PROP_DONTPASS 0x0001
188 #define DDI_PROP_CANSLEEP 0x0002
190 #define GLOBAL_DEV 0x02
191 #define NODEBOUND_DEV 0x04
192 #define NODESPECIFIC_DEV 0x06
193 #define ENUMERATED_DEV 0x08
195 #define ddi_prop_lookup_string(x1,x2,x3,x4,x5) (*x5 = NULL)
196 #define ddi_prop_free(x) (void)0
197 #define ddi_root_node() (void)0
199 #define mod_install(x) 0
200 #define mod_remove(x) 0
202 extern int __ddi_create_minor_node(dev_info_t
*dip
, char *name
, int spec_type
,
203 minor_t minor_num
, char *node_type
,
204 int flags
, struct module
*mod
);
205 extern void __ddi_remove_minor_node(dev_info_t
*dip
, char *name
);
206 extern int ddi_quiesce_not_needed(dev_info_t
*dip
);
207 extern int __mod_install(struct modlinkage
*modlp
);
208 extern int __mod_remove(struct modlinkage
*modlp
);
209 extern int __mod_mknod(char *name
, char *type
, int major
, int minor
);
211 extern int ddi_strtoul(const char *, char **, int, unsigned long *);
212 extern int ddi_strtol(const char *, char **, int, long *);
213 extern int ddi_strtoull(const char *, char **, int, unsigned long long *);
214 extern int ddi_strtoll(const char *, char **, int, long long *);
216 extern int ddi_copyin(const void *from
, void *to
, size_t len
, int flags
);
217 extern int ddi_copyout(const void *from
, void *to
, size_t len
, int flags
);
219 static __inline__
void ddi_report_dev(dev_info_t
*d
) { }
220 static __inline__
void ddi_prop_remove_all(dev_info_t
*dip
) { }
222 static __inline__
void
223 ddi_remove_minor_node(dev_info_t
*di
, char *name
)
225 #ifdef HAVE_GPL_ONLY_SYMBOLS
226 /* Cleanup udev (GPL-only symbols required). This is performed as
227 * part of an inline function to ensure that these symbols are not
228 * linked against the SPL which is GPL'ed. But instead they are
229 * linked against the package building against the SPL to ensure
230 * its license allows linking with GPL-only symbols. */
232 spl_device_destroy(di
->di_class
, di
->di_device
, di
->di_dev
);
233 spl_class_destroy(di
->di_class
);
238 /* When we do not have access to the GPL-only device interfaces we
239 * are forced to do something crude. We unlink the special device
240 * file in /dev/ ourselves from within the kernel. On the upside we
241 * are already providing this functionality for Solaris, and it is
242 * easy to leverage the Solaris API to perform the unlink. */
243 if (strlen(di
->di_name
) > 0)
244 vn_remove(di
->di_name
, UIO_SYSSPACE
, RMFILE
);
246 #endif /* HAVE_GPL_ONLY_SYMBOLS */
248 __ddi_remove_minor_node(di
, name
);
251 static __inline__
int
252 ddi_create_minor_node(dev_info_t
*di
, char *name
, int spec_type
,
253 minor_t minor_num
, char *node_type
, int flags
)
257 rc
= __ddi_create_minor_node(di
, name
, spec_type
, minor_num
,
258 node_type
, flags
, THIS_MODULE
);
262 #ifdef HAVE_GPL_ONLY_SYMBOLS
263 /* Setup udev (GPL-only symbols required). This is performed as
264 * part of an inline function to ensure that these symbols are not
265 * linked against the SPL which is GPL'ed. But instead they are
266 * linked against the package building against the SPL to ensure
267 * its license allows linking with GPL-only symbols. */
268 di
->di_class
= spl_class_create(THIS_MODULE
, name
);
269 if (IS_ERR(di
->di_class
)) {
270 rc
= PTR_ERR(di
->di_class
);
272 ddi_remove_minor_node(di
, name
);
273 CERROR("Error creating %s class, %d\n", name
, rc
);
277 /* Do not append a 0 to devices with minor nums of 0 */
278 di
->di_device
= spl_device_create(di
->di_class
, NULL
, di
->di_dev
, NULL
,
279 (di
->di_minor
== 0) ? "%s" : "%s%d",
282 /* When we do not have access to the GPL-only device interfaces we
283 * are forced to do something horible. We use a user mode helper to
284 * create the special device file in /dev/. By futher extending the
285 * Solaris vnode implementation we could potentially do a vn_create()
286 * from within the kernel but that's still a hack. */
288 rc
= __mod_mknod(di
->di_name
, "c", di
->di_major
, di
->di_minor
);
290 CERROR("Error mknod %s, %d\n", di
->di_name
, rc
);
291 ddi_remove_minor_node(di
, name
);
295 #endif /* HAVE_GPL_ONLY_SYMBOLS */
303 #define mod_install __mod_install
304 #define mod_remove __mod_remove
306 #endif /* SPL_SUNDDI_H */