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