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 /*
27 * Copyright 2012 Garrett D'Amore <garrett@damore.org>.
28 * Copyright 2014 Pluribus Networks, Inc.
29 */
30
31 /*
32 * ddi_dki_comm.inc - Part of a pseudo-kernel to use when analyzing drivers
33 * with warlock.
34 *
35 * The main idea here is to represent all of the ways that the kernel can
36 * call into the driver, so that warlock has the correct view of the call
37 * graph.
38 *
39 * This file represents the stuff in common between the DDI/DKI spec and
40 * the current implementation. It is included by both ddi_dki_{spec,impl}.c
41 *
42 * This is a SPARC version; some functions (e.g. ddi_dma_nextwin) should
43 * be changed for an x86 version.
44 */
45
46 #include <sys/note.h>
47 #include <sys/devops.h>
48 #include <sys/ddi.h>
49 #include <sys/sunddi.h>
50 #include <sys/proc.h>
51
52 _NOTE(DATA_READABLE_WITHOUT_LOCK( dev_ops cb_ops bus_ops ))
53
54 /*
55 * Now define a dev_ops, a cb_ops, and a bus_ops with 0 for each
56 * entry point, so that warlock doesn't complain that these
57 * function pointers have no bindings.
58 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
59 */
60 struct dev_ops *devops_p, warlock_dev_ops = {
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
62 };
63
64 struct cb_ops *cbops_p, warlock_cb_ops = {
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
66 };
67
68 struct bus_ops *busops_p, warlock_bus_ops = {
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
70 };
71
72
73 /* This rendition of mod_remove() tells warlock that it calls detach. */
74 int
75 mod_remove(struct modlinkage *a) {
76 (*devops_p->devo_detach)(NULL, 0);
77 }
78
79 /* This rendition of physio() shows that it calls its func ptr args. */
80 int
81 physio(
82 int (*strategy)(struct buf *),
83 struct buf *a,
84 dev_t b,
85 int c,
86 void (*mincnt)(struct buf *),
87 struct uio *d)
88 {
89 (*strategy)(0);
90 (*mincnt)(0);
91 }
92
93 /*
94 * Tell warlock that args to some funcs get called back as separate threads.
95 */
96 timeout_id_t
97 timeout(void (*fp)(void *), void *a, clock_t b)
98 {
99 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
100 }
101
102 int
103 ddi_add_intr(dev_info_t *a, uint_t b, ddi_iblock_cookie_t *c,
104 ddi_idevice_cookie_t *d, uint_t (*fp)(caddr_t), caddr_t e)
105 {
106 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
107 }
108
109 int
110 ddi_add_softintr(dev_info_t *a, int b, ddi_softintr_t *c,
111 ddi_iblock_cookie_t *d, ddi_idevice_cookie_t *e, uint_t (*fp)(caddr_t),
112 caddr_t f)
113 {
114 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
115 }
116
117 int
118 ddi_intr_add_handler(ddi_intr_handle_t h, ddi_intr_handler_t inthandler,
119 void *arg1, void *arg2)
120 {
121 thread_create(0, 0, (void (*)())inthandler, 0, 0, 0, 0, 0);
122 }
123
124 int
125 ddi_intr_add_softint(dev_info_t *dip, ddi_softint_handle_t *h_p, int soft_pri,
126 ddi_intr_handler_t handler, void *arg1)
127 {
128 thread_create(0, 0, (void (*)())handler, 0, 0, 0, 0, 0);
129 }
130
131 void
132 ddi_set_callback(
133 int (*fp)(caddr_t),
134 caddr_t a,
135 uintptr_t *b)
136 {
137 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0);
138 }
139
140 int
141 ddi_dma_map(
142 dev_info_t *a,
143 dev_info_t *b,
144 struct ddi_dma_req *c,
145 ddi_dma_handle_t *d)
146 {
147 struct bus_ops *ops;
148 (*ops->bus_dma_map)(0, 0, 0, 0);
149 }
150
151 int
152 ddi_dma_mctl(dev_info_t *a, dev_info_t *b, ddi_dma_handle_t c,
153 enum ddi_dma_ctlops d, off_t *e, size_t *f, caddr_t *g,
154 uint_t h)
155 {
156 struct bus_ops *ops;
157 (*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
158 }
159
160 int
161 ddi_dma_sync(ddi_dma_handle_t h, off_t o, size_t l, uint_t whom)
162 {
163 struct bus_ops *ops;
164 (*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
165 }
166
167 int
168 ddi_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
169 char *name, caddr_t valuep, int *lengthp)
170 {
171 struct bus_ops *ops;
172 (*ops->bus_prop_op)(0, 0, 0, 0, 0, 0, 0, 0);
173 }
174
175 int
176 ddi_add_event_handler(dev_info_t *dip, ddi_eventcookie_t event,
177 void (*handler)(dev_info_t *, ddi_eventcookie_t, void *, void *),
178 void *arg, ddi_callback_id_t *id)
179 {
180 struct bus_ops *ops;
181 return ((*ops->bus_add_eventcall)(dip, dip, event, handler, arg, id));
182 }
183
184 int
185 ddi_remove_event_handler(ddi_callback_id_t id)
186 {
187 dev_info_t *dip;
188 struct bus_ops *ops;
189 return ((*ops->bus_remove_eventcall)(dip, id));
190 }
191
192
193 int
194 ddi_get_eventcookie(dev_info_t *dip, char *name,
195 ddi_eventcookie_t *event_cookiep)
196 {
197 struct bus_ops *ops;
198 return ((*ops->bus_get_eventcookie)(dip, dip,
199 name, event_cookiep));
200 }