Home | History | Annotate | Download | only in sys
      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