Home | History | Annotate | Download | only in warlock
      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 2007 Sun Microsystems, Inc.
     23  * All rights reserved.  Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 /*
     29  * ddi_dki_comm.inc - Part of a pseudo-kernel to use when analyzing drivers
     30  * with warlock.
     31  *
     32  * The main idea here is to represent all of the ways that the kernel can
     33  * call into the driver, so that warlock has the correct view of the call
     34  * graph.
     35  *
     36  * This file represents the stuff in common between the DDI/DKI spec and
     37  * the current implementation.	It is included by both ddi_dki_{spec,impl}.c
     38  *
     39  * This is a SPARC version; some functions (e.g. ddi_dma_nextwin) should
     40  * be changed for an x86 version.
     41  */
     42 
     43 #include <sys/note.h>
     44 #include <sys/devops.h>
     45 #include <sys/ddi.h>
     46 #include <sys/sunddi.h>
     47 #include <sys/proc.h>
     48 
     49 _NOTE(DATA_READABLE_WITHOUT_LOCK( dev_ops cb_ops bus_ops ))
     50 
     51 /*
     52  * Now define a dev_ops, a cb_ops, and a bus_ops with 0 for each
     53  * entry point, so that warlock doesn't complain that these
     54  * function pointers have no bindings.
     55  *	1  2  3  4  5  6  7  8	9 10 11 12 13 14 15 16 17 18 19 20 21 22
     56  */
     57 struct dev_ops *devops_p, warlock_dev_ops = {
     58 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
     59 };
     60 
     61 struct cb_ops *cbops_p, warlock_cb_ops = {
     62 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
     63 };
     64 
     65 struct bus_ops *busops_p, warlock_bus_ops = {
     66 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
     67 };
     68 
     69 
     70 /* This rendition of mod_remove() tells warlock that it calls detach. */
     71 int
     72 mod_remove(struct modlinkage *a) {
     73 	(*devops_p->devo_detach)(NULL, 0);
     74 }
     75 
     76 /* This rendition of physio() shows that it calls its func ptr args. */
     77 int
     78 physio(
     79 	int (*strategy)(struct buf *),
     80 	struct buf *a,
     81 	dev_t b,
     82 	int c,
     83 	void (*mincnt)(struct buf *),
     84 	struct uio *d)
     85 {
     86 	(*strategy)(0);
     87 	(*mincnt)(0);
     88 }
     89 
     90 /*
     91  * Tell warlock that args to some funcs get called back as separate threads.
     92  */
     93 timeout_id_t
     94 timeout(void (*fp)(void *), void *a, clock_t b)
     95 {
     96 	thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
     97 }
     98 
     99 int
    100 ddi_add_intr(dev_info_t *a, uint_t b, ddi_iblock_cookie_t *c,
    101 	ddi_idevice_cookie_t *d, uint_t (*fp)(caddr_t), caddr_t e)
    102 {
    103 	thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
    104 }
    105 
    106 int
    107 ddi_add_softintr(dev_info_t *a, int b, ddi_softintr_t *c,
    108     ddi_iblock_cookie_t *d, ddi_idevice_cookie_t *e, uint_t (*fp)(caddr_t),
    109     caddr_t f)
    110 {
    111 	thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
    112 }
    113 
    114 int
    115 ddi_intr_add_handler(ddi_intr_handle_t h, ddi_intr_handler_t inthandler,
    116     void *arg1, void *arg2)
    117 {
    118 	thread_create(0, 0, (void (*)())inthandler, 0, 0, 0, 0, 0);
    119 }
    120 
    121 int
    122 ddi_intr_add_softint(dev_info_t *dip, ddi_softint_handle_t *h_p, int soft_pri,
    123     ddi_intr_handler_t handler, void *arg1)
    124 {
    125 	thread_create(0, 0, (void (*)())handler, 0, 0, 0, 0, 0);
    126 }
    127 
    128 int
    129 ddi_dma_addr_setup(
    130 	dev_info_t *a,
    131 	struct as *b,
    132 	caddr_t c,
    133 	size_t d,
    134 	uint_t e,
    135 	int (*fp)(void),
    136 	caddr_t f,
    137 	ddi_dma_lim_t *g,
    138 	ddi_dma_handle_t *h)
    139 {
    140 	struct bus_ops *ops;
    141 	(*ops->bus_dma_map)(0, 0, 0, 0);
    142 	thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
    143 }
    144 
    145 int
    146 ddi_dma_buf_setup(
    147 	dev_info_t *a,
    148 	struct buf *b,
    149 	uint_t c,
    150 	int (*fp)(void),
    151 	caddr_t d,
    152 	ddi_dma_lim_t *e,
    153 	ddi_dma_handle_t *f)
    154 {
    155 	struct bus_ops *ops;
    156 	(*ops->bus_dma_map)(0, 0, 0, 0);
    157 	thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
    158 }
    159 
    160 void
    161 ddi_set_callback(
    162 	int (*fp)(caddr_t),
    163 	caddr_t a,
    164 	uintptr_t *b)
    165 {
    166 	thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
    167 }
    168 
    169 int
    170 ddi_dma_map(
    171 	dev_info_t *a,
    172 	dev_info_t *b,
    173 	struct ddi_dma_req *c,
    174 	ddi_dma_handle_t *d)
    175 {
    176 	struct bus_ops *ops;
    177 	(*ops->bus_dma_map)(0, 0, 0, 0);
    178 }
    179 
    180 int
    181 ddi_dma_setup(
    182 	dev_info_t *a,
    183 	struct ddi_dma_req *b,
    184 	ddi_dma_handle_t *c)
    185 {
    186 	struct bus_ops *ops;
    187 	(*ops->bus_dma_map)(0, 0, 0, 0);
    188 }
    189 
    190 int
    191 ddi_dma_pp_setup(
    192 	dev_info_t *a,
    193 	struct page *b,
    194 	off_t c,
    195 	uint_t d,
    196 	uint_t e,
    197 	int (*fp)(),
    198 	caddr_t f,
    199 	ddi_dma_lim_t *g,
    200 	ddi_dma_handle_t *h)
    201 {
    202 	struct bus_ops *ops;
    203 	(*ops->bus_dma_map)(0, 0, 0, 0);
    204 }
    205 
    206 int
    207 ddi_dma_mctl(dev_info_t *a, dev_info_t *b, ddi_dma_handle_t c,
    208 	enum ddi_dma_ctlops d, off_t *e, size_t *f, caddr_t *g,
    209 	uint_t h)
    210 {
    211 	struct bus_ops *ops;
    212 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    213 }
    214 
    215 int
    216 ddi_dma_kvaddrp(ddi_dma_handle_t h, off_t off, size_t len, caddr_t *kp)
    217 {
    218 	struct bus_ops *ops;
    219 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    220 }
    221 
    222 int
    223 ddi_dma_htoc(ddi_dma_handle_t h, off_t o, ddi_dma_cookie_t *c)
    224 {
    225 	struct bus_ops *ops;
    226 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    227 }
    228 
    229 int
    230 ddi_dma_coff(ddi_dma_handle_t h, ddi_dma_cookie_t *c, off_t *o)
    231 {
    232 	struct bus_ops *ops;
    233 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    234 }
    235 
    236 int
    237 ddi_dma_movwin(ddi_dma_handle_t h, off_t *o, size_t *l, ddi_dma_cookie_t *c)
    238 {
    239 	struct bus_ops *ops;
    240 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    241 }
    242 
    243 int
    244 ddi_dma_curwin(ddi_dma_handle_t h, off_t *o, size_t *l)
    245 {
    246 	struct bus_ops *ops;
    247 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    248 }
    249 
    250 int
    251 ddi_dma_nextwin(register ddi_dma_handle_t h, ddi_dma_win_t win,
    252     ddi_dma_win_t *nwin)
    253 {
    254 	struct bus_ops *ops;
    255 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    256 }
    257 
    258 int
    259 ddi_dma_nextseg(ddi_dma_win_t win, ddi_dma_seg_t seg, ddi_dma_seg_t *nseg)
    260 {
    261 	struct bus_ops *ops;
    262 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    263 }
    264 
    265 int
    266 ddi_dma_get_error(ddi_dma_handle_t h, uint_t len, caddr_t errblk)
    267 {
    268 	struct bus_ops *ops;
    269 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    270 }
    271 
    272 int
    273 ddi_dma_segtocookie(ddi_dma_seg_t seg, off_t *o, off_t *l,
    274     ddi_dma_cookie_t *cookiep)
    275 {
    276 	struct bus_ops *ops;
    277 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    278 }
    279 
    280 int
    281 ddi_dma_sync(ddi_dma_handle_t h, off_t o, size_t l, uint_t whom)
    282 {
    283 	struct bus_ops *ops;
    284 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    285 }
    286 
    287 int
    288 ddi_dma_free(ddi_dma_handle_t h)
    289 {
    290 	struct bus_ops *ops;
    291 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    292 }
    293 
    294 int
    295 ddi_iopb_alloc(dev_info_t *dip, ddi_dma_lim_t *limp, uint_t len, caddr_t *iopbp)
    296 {
    297 	struct bus_ops *ops;
    298 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    299 }
    300 
    301 void
    302 ddi_iopb_free(caddr_t iopb)
    303 {
    304 	struct bus_ops *ops;
    305 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    306 }
    307 
    308 int
    309 ddi_mem_alloc(dev_info_t *dip, ddi_dma_lim_t *limits, uint_t length,
    310 	uint_t flags, caddr_t *kaddrp, uint_t *real_length)
    311 {
    312 	struct bus_ops *ops;
    313 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    314 }
    315 
    316 void
    317 ddi_mem_free(caddr_t kaddr)
    318 {
    319 	struct bus_ops *ops;
    320 	(*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    321 }
    322 
    323 int
    324 ddi_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
    325     char *name, caddr_t valuep, int *lengthp)
    326 {
    327 	struct bus_ops *ops;
    328 	(*ops->bus_prop_op)(0, 0, 0, 0, 0, 0, 0, 0);
    329 }
    330 
    331 int
    332 ddi_add_event_handler(dev_info_t *dip, ddi_eventcookie_t event,
    333     void (*handler)(dev_info_t *, ddi_eventcookie_t, void *, void *),
    334     void *arg, ddi_callback_id_t *id)
    335 {
    336 	struct bus_ops *ops;
    337 	return ((*ops->bus_add_eventcall)(dip, dip, event, handler, arg, id));
    338 }
    339 
    340 int
    341 ddi_remove_event_handler(ddi_callback_id_t id)
    342 {
    343 	dev_info_t *dip;
    344 	struct bus_ops *ops;
    345 	return ((*ops->bus_remove_eventcall)(dip, id));
    346 }
    347 
    348 
    349 int
    350 ddi_get_eventcookie(dev_info_t *dip, char *name,
    351     ddi_eventcookie_t *event_cookiep)
    352 {
    353 	struct bus_ops *ops;
    354 	return ((*ops->bus_get_eventcookie)(dip, dip,
    355 	    name, event_cookiep));
    356 }
    357