xref: /illumos-gate/usr/src/uts/common/sys/devops.h (revision 8b80e8cb6855118d46f605e91b5ed4ce83417395)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_SYS_DEVOPS_H
27 #define	_SYS_DEVOPS_H
28 
29 
30 #include <sys/types.h>
31 #include <sys/cred.h>
32 #include <sys/uio.h>
33 #include <sys/buf.h>
34 #include <sys/poll.h>
35 #include <vm/as.h>
36 
37 #include <sys/dditypes.h>
38 #include <sys/ddidmareq.h>
39 #include <sys/ddimapreq.h>
40 #include <sys/ddipropdefs.h>
41 #include <sys/ddidevmap.h>
42 #include <sys/ddifm.h>
43 #include <sys/nexusdefs.h>
44 #include <sys/ddi_intr.h>
45 #include <sys/aio_req.h>
46 #include <vm/page.h>
47 
48 #ifdef	__cplusplus
49 extern "C" {
50 #endif
51 
52 #ifdef	_KERNEL
53 
54 /*
55  * cb_ops:	Leaf device drivers or bus nexus drivers supporting
56  *		direct user process access (open/close/etc).
57  *
58  * This is an OR of cdevsw and bdevsw fields for drivers that
59  * support both character and block entry points.
60  *
61  * For streams stuff, see also sys/stream.h.
62  *
63  * The following DDI/DKI or DKI only or DDI only functions are
64  * provided in the character/block driver operations structure.
65  *
66  *	block/char	Function	description
67  *	b/c		XXopen		DDI/DKI
68  *	b/c		XXclose		DDI/DKI
69  *	b		XXstrategy	DDI/DKI
70  *	b  		XXprint		DDI/DKI
71  *	b  		XXdump		DDI(Sun)
72  *	  c		XXread		DDI/DKI
73  *	  c		XXwrite		DDI/DKI
74  *	  c		XXioctl		DDI/DKI
75  *	  c		XXdevmap	DDI(Sun)
76  *	  c		XXmmap		DKI
77  *	  c		XXsegmap	DKI
78  *	  c		XXchpoll	DDI/DKI
79  *	  c		XXprop_op	DDI(Sun)
80  */
81 
82 struct cb_ops  {
83 	int	(*cb_open)(dev_t *devp, int flag, int otyp, cred_t *credp);
84 	int	(*cb_close)(dev_t dev, int flag, int otyp, cred_t *credp);
85 	int	(*cb_strategy)(struct buf *bp);
86 	int	(*cb_print)(dev_t dev, char *str);
87 	int	(*cb_dump)(dev_t dev, caddr_t addr, daddr_t blkno, int nblk);
88 	int	(*cb_read)(dev_t dev, struct uio *uiop, cred_t *credp);
89 	int	(*cb_write)(dev_t dev, struct uio *uiop, cred_t *credp);
90 	int	(*cb_ioctl)(dev_t dev, int cmd, intptr_t arg, int mode,
91 		    cred_t *credp, int *rvalp);
92 	int	(*cb_devmap)(dev_t dev, devmap_cookie_t dhp, offset_t off,
93 			size_t len, size_t *maplen, uint_t model);
94 	int	(*cb_mmap)(dev_t dev, off_t off, int prot);
95 	int	(*cb_segmap)(dev_t dev, off_t off, struct as *asp,
96 		    caddr_t *addrp, off_t len, unsigned int prot,
97 		    unsigned int maxprot, unsigned int flags, cred_t *credp);
98 	int	(*cb_chpoll)(dev_t dev, short events, int anyyet,
99 		    short *reventsp, struct pollhead **phpp);
100 	int	(*cb_prop_op)(dev_t dev, dev_info_t *dip,
101 		    ddi_prop_op_t prop_op, int mod_flags,
102 		    char *name, caddr_t valuep, int *length);
103 
104 	struct streamtab *cb_str;	/* streams information */
105 
106 	/*
107 	 * The cb_flag fields are here to tell the system a
108 	 * bit about the device. The bit definitions are
109 	 * in <sys/conf.h>.
110 	 */
111 	int	cb_flag;		/* driver compatibility flag */
112 	int	cb_rev;			/* cb_ops version number */
113 	int	(*cb_aread)(dev_t dev, struct aio_req *aio, cred_t *credp);
114 	int	(*cb_awrite)(dev_t dev, struct aio_req *aio, cred_t *credp);
115 };
116 
117 /*
118  * bus_ops:	bus nexus drivers only.
119  *
120  * These functions are used to implement the Sun DDI functions
121  * described elsewhere.
122  *
123  * Only nexus drivers support these entry points.
124  *
125  * The following bus nexus functions are provided in the bus nexus
126  * driver operations structure.  Note that all functions take both
127  * their dip and the requesters dip except for the child functions since
128  * they will be called from outside the ddi.
129  *
130  *	bus_map			-  Map/unmap/control IU -> device mappings.
131  *	bus_get_intrspec	-  get interrupt specification by number
132  *	bus_add_intrspec	-  add interrupt specification, return cookie
133  *	bus_remove_intrspec	-  remove interrupt specification
134  *	bus_map_fault		-  bus fault handler
135  *	bus_dma_map		-  setup dma mapping
136  *	bus_dma_mapctl		-  control (and free) dma mapping
137  *	bus_ctl			-  generic control operations
138  *	bus_prop_op		_  request for property
139  */
140 
141 #define	BUSO_REV_3	3
142 #define	BUSO_REV_4	4
143 #define	BUSO_REV_5	5
144 #define	BUSO_REV_6	6
145 #define	BUSO_REV_7	7
146 #define	BUSO_REV_8	8
147 #define	BUSO_REV_9	9
148 #define	BUSO_REV	BUSO_REV_9
149 
150 
151 struct bus_ops  {
152 	int		busops_rev;	/* rev of this structure */
153 	int		(*bus_map)(dev_info_t *dip, dev_info_t *rdip,
154 			    ddi_map_req_t *mp, off_t offset, off_t len,
155 			    caddr_t *vaddrp);
156 
157 	/*
158 	 * NOTE: the following 3 busops entrypoints are obsoleted with
159 	 * version 9 or greater. Use bus_intr_op interface in place of
160 	 * these obsolete interfaces.
161 	 */
162 	ddi_intrspec_t	(*bus_get_intrspec)(dev_info_t *dip, dev_info_t *rdip,
163 			    uint_t inumber);
164 	int		(*bus_add_intrspec)(dev_info_t *dip,
165 			    dev_info_t *rdip, ddi_intrspec_t intrspec,
166 			    ddi_iblock_cookie_t *ibcp,
167 			    ddi_idevice_cookie_t *idcp,
168 			    uint_t (*int_handler)(caddr_t intr_handler_arg),
169 			    caddr_t intr_handler_arg, int kind);
170 	void		(*bus_remove_intrspec)(dev_info_t *dip,
171 			    dev_info_t *rdip, ddi_intrspec_t intrspec,
172 			    ddi_iblock_cookie_t iblock_cookie);
173 
174 	int		(*bus_map_fault)(dev_info_t *dip, dev_info_t *rdip,
175 			    struct hat *hat, struct seg *seg, caddr_t addr,
176 			    struct devpage *dp, pfn_t pfn, uint_t prot,
177 			    uint_t lock);
178 	int		(*bus_dma_map)(dev_info_t *dip, dev_info_t *rdip,
179 			    struct ddi_dma_req *dmareq,
180 			    ddi_dma_handle_t *handlep);
181 	int		(*bus_dma_allochdl)(dev_info_t *dip, dev_info_t *rdip,
182 			    ddi_dma_attr_t *attr, int (*waitfp)(caddr_t),
183 			    caddr_t arg, ddi_dma_handle_t *handlep);
184 	int		(*bus_dma_freehdl)(dev_info_t *dip, dev_info_t *rdip,
185 			    ddi_dma_handle_t handle);
186 	int		(*bus_dma_bindhdl)(dev_info_t *dip, dev_info_t *rdip,
187 			    ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
188 			    ddi_dma_cookie_t *, uint_t *);
189 	int		(*bus_dma_unbindhdl)(dev_info_t *dip, dev_info_t *rdip,
190 			    ddi_dma_handle_t handle);
191 	int		(*bus_dma_flush)(dev_info_t *dip, dev_info_t *rdip,
192 			    ddi_dma_handle_t handle, off_t off,
193 			    size_t len, uint_t cache_flags);
194 	int		(*bus_dma_win)(dev_info_t *dip, dev_info_t *rdip,
195 			    ddi_dma_handle_t handle, uint_t win, off_t *offp,
196 			    size_t *lenp, ddi_dma_cookie_t *cookiep,
197 			    uint_t *ccountp);
198 	int		(*bus_dma_ctl)(dev_info_t *dip, dev_info_t *rdip,
199 			    ddi_dma_handle_t handle,
200 			    enum ddi_dma_ctlops request, off_t *offp,
201 			    size_t *lenp, caddr_t *objp, uint_t flags);
202 	int		(*bus_ctl)(dev_info_t *dip, dev_info_t *rdip,
203 			    ddi_ctl_enum_t ctlop, void *arg, void *result);
204 	int		(*bus_prop_op)(dev_t dev, dev_info_t *dip,
205 			    dev_info_t *child_dip, ddi_prop_op_t prop_op,
206 			    int mod_flags, char *name, caddr_t valuep,
207 			    int *length);
208 	/*
209 	 * NOTE: the following 4 busops entrypoints are only available
210 	 * with version 3 or greater.  Due to interface modifications, these
211 	 * entrypoints can only be used with version 6 or greater.
212 	 */
213 
214 	int		(*bus_get_eventcookie)(dev_info_t *dip,
215 			    dev_info_t *rdip, char *eventname,
216 			    ddi_eventcookie_t *cookiep);
217 	int		(*bus_add_eventcall)(dev_info_t *dip, dev_info_t *rdip,
218 			    ddi_eventcookie_t eventid,
219 			    void (*event_hdlr)(dev_info_t *dip,
220 			    ddi_eventcookie_t event, void *arg,
221 			    void *bus_impldata), void *arg,
222 			    ddi_callback_id_t *cb_id);
223 	int		(*bus_remove_eventcall)(dev_info_t *devi,
224 			    ddi_callback_id_t cb_id);
225 	int		(*bus_post_event)(dev_info_t *dip, dev_info_t *rdip,
226 			    ddi_eventcookie_t event, void *impl_data);
227 
228 	/*
229 	 * NOTE: the following bus_intr_ctl entrypoint is obsoleted with
230 	 * version 9 or greater. Use bus_intr_op interface in place of
231 	 * this obsolete interface.
232 	 */
233 	int		(*bus_intr_ctl)(dev_info_t *dip, dev_info_t *rdip,
234 			    ddi_intr_ctlop_t ctlop, void * arg, void * result);
235 	/*
236 	 * NOTE: the following busop entrypoints are available with version
237 	 * 5 or greater.
238 	 */
239 	int		(*bus_config)(dev_info_t *parent, uint_t flags,
240 			    ddi_bus_config_op_t op, void *arg,
241 			    dev_info_t **childp);
242 	int		(*bus_unconfig)(dev_info_t *parent, uint_t flags,
243 			    ddi_bus_config_op_t op, void *arg);
244 
245 	/*
246 	 * NOTE: the following busop entrypoints are available with version
247 	 * 6 or greater.
248 	 */
249 	int		(*bus_fm_init)(dev_info_t *dip, dev_info_t *tdip,
250 			    int cap, ddi_iblock_cookie_t *ibc);
251 	void		(*bus_fm_fini)(dev_info_t *dip, dev_info_t *tdip);
252 	void		(*bus_fm_access_enter)(dev_info_t *dip,
253 			    ddi_acc_handle_t handle);
254 	void		(*bus_fm_access_exit)(dev_info_t *dip,
255 			    ddi_acc_handle_t handle);
256 
257 	/*
258 	 * NOTE: the following busop entrypoint is available with version
259 	 * 7 or greater.
260 	 */
261 	int		(*bus_power)(dev_info_t *dip, void *impl_arg,
262 			    pm_bus_power_op_t op, void *arg, void *result);
263 
264 	/*
265 	 * NOTE: the following busop entrypoint is available with version
266 	 * 9 or greater.
267 	 */
268 	int		(*bus_intr_op)(dev_info_t *dip, dev_info_t *rdip,
269 			    ddi_intr_op_t op, ddi_intr_handle_impl_t *hdlp,
270 			    void *result);
271 };
272 
273 /*
274  * REV 1 bus ops structure
275  */
276 
277 struct bus_ops_rev1 {
278 	int		(*bus_map)(dev_info_t *dip, dev_info_t *rdip,
279 			    ddi_map_req_t *mp, off_t offset, off_t len,
280 			    caddr_t *vaddrp);
281 	ddi_intrspec_t	(*bus_get_intrspec)(dev_info_t *dip, dev_info_t *rdip,
282 			    uint_t inumber);
283 	int		(*bus_add_intrspec)(dev_info_t *dip,
284 			    dev_info_t *rdip, ddi_intrspec_t intrspec,
285 			    ddi_iblock_cookie_t *ibcp,
286 			    ddi_idevice_cookie_t *idcp,
287 			    uint_t (*int_handler)(caddr_t intr_handler_arg),
288 			    caddr_t intr_handler_arg, int kind);
289 	void		(*bus_remove_intrspec)(dev_info_t *dip,
290 			    dev_info_t *rdip, ddi_intrspec_t intrspec,
291 			    ddi_iblock_cookie_t iblock_cookie);
292 	int		(*bus_map_fault)(dev_info_t *dip, dev_info_t *rdip,
293 			    struct hat *hat, struct seg *seg, caddr_t addr,
294 			    struct devpage *dp, pfn_t pfn, uint_t prot,
295 			    uint_t lock);
296 	int		(*bus_dma_map)(dev_info_t *dip, dev_info_t *rdip,
297 			    struct ddi_dma_req *dmareq,
298 			    ddi_dma_handle_t *handlep);
299 	int		(*bus_dma_ctl)(dev_info_t *dip, dev_info_t *rdip,
300 			    ddi_dma_handle_t handle,
301 			    enum ddi_dma_ctlops request, off_t *offp,
302 			    uint_t *lenp, caddr_t *objp, uint_t flags);
303 	int		(*bus_ctl)(dev_info_t *dip, dev_info_t *rdip,
304 			    ddi_ctl_enum_t ctlop, void *arg, void *result);
305 	int		(*bus_prop_op)(dev_t dev, dev_info_t *dip,
306 			    dev_info_t *child_dip, ddi_prop_op_t prop_op,
307 			    int mod_flags, char *name, caddr_t valuep,
308 			    int *length);
309 };
310 
311 /*
312  * dev_ops:	Contains driver common fields and pointers
313  *		to the bus_ops and/or cb_ops parts.
314  *
315  * Drivers should set devo_rev to DEVO_REV at compile time.
316  * All drivers should support these entry points.
317  *
318  * the following device functions are provided in the device operations
319  * structure.
320  *
321  *	devo_getinfo		-  Device handle conversion
322  *	devo_identify		-  Obsolete, set to nulldev
323  *	devo_probe		-  Probe for device's existence
324  *	devo_attach		-  Attach driver to dev_info
325  *	devo_detach		-  Detach/prepare driver to unload
326  *	devo_reset		-  Reset device
327  *	devo_quiesce		-  Quiesce device
328  */
329 
330 #define		DEVO_REV		4
331 #define		CB_REV			1
332 
333 /*
334  * Return from driver's devo_probe function:
335  */
336 
337 #define	DDI_PROBE_FAILURE	ENXIO	/* matches nodev return */
338 #define	DDI_PROBE_DONTCARE	0	/* matches nulldev return */
339 #define	DDI_PROBE_PARTIAL	1
340 #define	DDI_PROBE_SUCCESS	2
341 
342 /*
343  * Typedefs for the info, attach, detach and reset routines.
344  * These are mostly placeholders for now.
345  *
346  * NOTE: DDI_INFO_DEVT2DEVINFO is deprecated
347  */
348 typedef enum {
349 	DDI_INFO_DEVT2DEVINFO = 0,	/* Convert a dev_t to a dev_info_t */
350 	DDI_INFO_DEVT2INSTANCE = 1	/* Convert a dev_t to an instance # */
351 } ddi_info_cmd_t;
352 
353 typedef enum {
354 	DDI_ATTACH = 0,
355 	DDI_RESUME = 1,
356 	DDI_PM_RESUME = 2
357 } ddi_attach_cmd_t;
358 
359 typedef enum {
360 	DDI_DETACH = 0,
361 	DDI_SUSPEND = 1,
362 	DDI_PM_SUSPEND = 2,
363 	DDI_HOTPLUG_DETACH = 3		/* detach, don't try to auto-unconfig */
364 } ddi_detach_cmd_t;
365 
366 typedef enum {
367 	DDI_RESET_FORCE = 0
368 } ddi_reset_cmd_t;
369 
370 struct dev_ops  {
371 	int		devo_rev;	/* Driver build version		*/
372 	int		devo_refcnt;	/* device reference count	*/
373 
374 	int		(*devo_getinfo)(dev_info_t *dip,
375 			    ddi_info_cmd_t infocmd, void *arg, void **result);
376 	int		(*devo_identify)(dev_info_t *dip);
377 	int		(*devo_probe)(dev_info_t *dip);
378 	int		(*devo_attach)(dev_info_t *dip, ddi_attach_cmd_t cmd);
379 	int		(*devo_detach)(dev_info_t *dip, ddi_detach_cmd_t cmd);
380 	int		(*devo_reset)(dev_info_t *dip, ddi_reset_cmd_t cmd);
381 
382 	struct cb_ops	*devo_cb_ops;	/* cb_ops pointer for leaf drivers   */
383 	struct bus_ops	*devo_bus_ops;	/* bus_ops pointer for nexus drivers */
384 	int		(*devo_power)(dev_info_t *dip, int component,
385 			    int level);
386 	int		(*devo_quiesce)(dev_info_t *dip);
387 };
388 
389 /*
390  * Create a dev_ops suitable for a streams driver:
391  *
392  * XXX: Note:  Since this is a macro, it is NOT supported as
393  * XXX: part of the Sun DDI.  It is not a documented Sun DDI interface.
394  *
395  * STR_OPS(name, identify, probe, attach, detach, reset,
396  *	info, flag, stream_tab);
397  *
398  *	XXname is the name of the dev_ops structure.
399  *	XXidentify must be set to nulldev
400  *	XXprobe is the name of the probe routine, or nulldev
401  *	XXattach is the name of the attach routine
402  *	XXdetach is the name of the detach routine, or nodev
403  *	XXreset is the name of the reset routine, or nodev
404  *	XXinfo is the name of the info routine
405  *	XXflag is driver flag (cb_flag) in cb_ops,
406  *	XXstream_tab is the obvious.
407  *	XXquiesce is the name of the quiesce routine. It must be implemented
408  *		for fast reboot to succeed.
409  *	cb_##XXname is the name of the internally defined cb_ops struct.
410  *
411  * uses cb_XXname as name of static cb_ops structure.
412  */
413 
414 /*
415  * This file is included by genassym.c now and I couldn't get it to take the
416  * next line if it was broken into two lines joined by a '\'.  So, don't try
417  * to reformat it to satisfy Cstyle because genassym.c won't compile.
418  */
419 /* CSTYLED */
420 #define	DDI_DEFINE_STREAM_OPS(XXname, XXidentify, XXprobe, XXattach, XXdetach, XXreset, XXgetinfo, XXflag, XXstream_tab, XXquiesce) \
421 static struct cb_ops cb_##XXname = {					\
422 	nulldev,		/* cb_open */				\
423 	nulldev,		/* cb_close */				\
424 	nodev,			/* cb_strategy */			\
425 	nodev,			/* cb_print */				\
426 	nodev,			/* cb_dump */				\
427 	nodev,			/* cb_read */				\
428 	nodev,			/* cb_write */				\
429 	nodev,			/* cb_ioctl */				\
430 	nodev,			/* cb_devmap */				\
431 	nodev,			/* cb_mmap */				\
432 	nodev,			/* cb_segmap */				\
433 	nochpoll,		/* cb_chpoll */				\
434 	ddi_prop_op,		/* cb_prop_op */			\
435 	(XXstream_tab),		/* cb_stream */				\
436 	(int)(XXflag),		/* cb_flag */				\
437 	CB_REV,			/* cb_rev */				\
438 	nodev,			/* cb_aread */				\
439 	nodev,			/* cb_awrite */				\
440 };									\
441 									\
442 static struct dev_ops XXname = {					\
443 	DEVO_REV,		/* devo_rev */				\
444 	0,			/* devo_refcnt */			\
445 	(XXgetinfo),		/* devo_getinfo */			\
446 	(XXidentify),		/* devo_identify */			\
447 	(XXprobe),		/* devo_probe */			\
448 	(XXattach),		/* devo_attach */			\
449 	(XXdetach),		/* devo_detach */			\
450 	(XXreset),		/* devo_reset */			\
451 	&(cb_##XXname),		/* devo_cb_ops */			\
452 	(struct bus_ops *)NULL,	/* devo_bus_ops */			\
453 	NULL,			/* devo_power */			\
454 	(XXquiesce)		/* devo_quiesce */			\
455 }
456 
457 #endif	/* _KERNEL */
458 
459 #ifdef	__cplusplus
460 }
461 #endif
462 
463 #endif	/* _SYS_DEVOPS_H */
464