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