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. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * ddi_dki_impl.c - A pseudo-kernel to use when analyzing drivers with warlock.
30 *
31 * The main idea here is to represent all of the ways that the kernel can
32 * call into the driver, so that warlock has the correct view of the call
33 * graph.
34 *
35 * This version differs from ddi_dki_spec.c in that it represents the
36 * current implementation of the DDI/DKI rather than the specification.
37 */
38 #include "ddi_dki_comm.inc"
39 #include <sys/esunddi.h>
40 #include <sys/sunndi.h>
41 #include <sys/ddi.h>
42 #include <sys/epm.h>
43 #include <sys/proc.h>
44
45 int warlock_dummy(void);
46 int _init(void);
47 int _fini(void);
48 int _info(struct modinfo *a);
49 int scsi_init(void);
50
main(void)51 int main(void) {
52
53 /*
54 * The following call will cause warlock to know about
55 * warlock_dummy as a func that can be used to satisfy
56 * unbound function pointers. It shouldn't be needed
57 * with the new warlock on suntools.
58 */
59 warlock_dummy();
60
61 /*
62 * When the following functions are called, there is never
63 * more than one thread running in the driver.
64 */
65 _init();
66 _fini();
67 _info(0);
68 (*devops_p->devo_identify)(0);
69 (*devops_p->devo_probe)(0);
70 (*devops_p->devo_attach)(0, 0);
71
72 /*
73 * When the following functions are called, there may be
74 * more than one thread running in the driver.
75 */
76 _NOTE(COMPETING_THREADS_NOW)
77
78
79 scsi_init();
80
81 (*devops_p->devo_getinfo)(0, 0, 0, 0);
82 (*devops_p->devo_reset)(0, 0);
83 (*devops_p->devo_power)(0, 0, 0);
84
85 (*cbops_p->cb_open)(0, 0, 0, 0);
86 (*cbops_p->cb_close)(0, 0, 0, 0);
87 (*cbops_p->cb_strategy)(0);
88 (*cbops_p->cb_print)(0, 0);
89 (*cbops_p->cb_dump)(0, 0, 0, 0);
90 (*cbops_p->cb_read)(0, 0, 0);
91 (*cbops_p->cb_write)(0, 0, 0);
92 (*cbops_p->cb_ioctl)(0, 0, 0, 0, 0, 0);
93 (*cbops_p->cb_devmap)(0, 0, 0, 0, 0, 0);
94 (*cbops_p->cb_mmap)(0, 0, 0);
95 (*cbops_p->cb_segmap)(0, 0, 0, 0, 0, 0, 0, 0, 0);
96 (*cbops_p->cb_chpoll)(0, 0, 0, 0, 0);
97 (*cbops_p->cb_prop_op)(0, 0, 0, 0, 0, 0, 0);
98 (*cbops_p->cb_aread)(0, 0, 0);
99 (*cbops_p->cb_awrite)(0, 0, 0);
100
101 (*busops_p->bus_map)(0, 0, 0, 0, 0, 0);
102 (*busops_p->bus_get_intrspec)(0, 0, 0);
103 (*busops_p->bus_add_intrspec)(0, 0, 0, 0, 0, 0, 0, 0);
104 (*busops_p->bus_remove_intrspec)(0, 0, 0, 0);
105 (*busops_p->bus_map_fault)(0, 0, 0, 0, 0, 0, 0, 0, 0);
106 (*busops_p->bus_dma_map)(0, 0, 0, 0);
107 (*busops_p->bus_dma_allochdl)(0, 0, 0, 0, 0, 0);
108 (*busops_p->bus_dma_freehdl)(0, 0, 0);
109 (*busops_p->bus_dma_bindhdl)(0, 0, 0, 0, 0, 0);
110 (*busops_p->bus_dma_unbindhdl)(0, 0, 0);
111 (*busops_p->bus_dma_flush)(0, 0, 0, 0, 0, 0);
112 (*busops_p->bus_dma_win)(0, 0, 0, 0, 0, 0, 0, 0);
113 (*busops_p->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
114 (*busops_p->bus_ctl)(0, 0, 0, 0, 0);
115 (*busops_p->bus_prop_op)(0, 0, 0, 0, 0, 0, 0, 0);
116
117 (*busops_p->bus_get_eventcookie)(0, 0, 0, 0);
118 (*busops_p->bus_add_eventcall)(0, 0, 0, 0, 0, 0);
119 (*busops_p->bus_remove_eventcall)(0, 0);
120 (*busops_p->bus_post_event)(0, 0, 0, 0);
121 (*busops_p->bus_intr_ctl)(0, 0, 0, 0, 0);
122
123 (*busops_p->bus_config)(0, 0, 0, 0, 0);
124 (*busops_p->bus_unconfig)(0, 0, 0, 0);
125
126 #ifndef __lock_lint
127 /* this causes warnings and it is unclear how to handle this */
128 (*busops_p->bus_fm_init)(0, 0, 0, 0);
129 (*busops_p->bus_fm_fini)(0, 0);
130 (*busops_p->bus_fm_access_enter)(0, 0);
131 (*busops_p->bus_fm_access_exit)(0, 0);
132 (*busops_p->bus_power)(0, 0, 0, 0, 0);
133 (*busops_p->bus_intr_op)(0, 0, 0, 0, 0);
134 #endif
135
136 ndi_devi_offline(0, 0);
137 _NOTE(NO_COMPETING_THREADS_NOW)
138 }
139
140 /* Power managment framework calls */
141 int
pm_set_power(dev_info_t * dip,int comp,int level,int direction,pm_canblock_t canblock,int scan,int * retp)142 pm_set_power(dev_info_t *dip, int comp, int level, int direction,
143 pm_canblock_t canblock, int scan, int *retp)
144 {
145 (*devops_p->devo_power)(0, 0, 0);
146 }
147
148 int
pm_raise_power(dev_info_t * dip,int comp,int level)149 pm_raise_power(dev_info_t *dip, int comp, int level) {
150 (*devops_p->devo_power)(0, 0, 0);
151 }
152
153 int
pm_lower_power(dev_info_t * dip,int comp,int level)154 pm_lower_power(dev_info_t *dip, int comp, int level) {
155 (*devops_p->devo_power)(0, 0, 0);
156 }
157
158 static kmutex_t mutex;
159 static kcondvar_t cv;
160
161 void
delay(clock_t ticks)162 delay(clock_t ticks)
163 {
164 mutex_enter(&mutex);
165 cv_wait(&cv, &mutex);
166 mutex_exit(&mutex);
167 }
168
169 void
putnext(queue_t * q,mblk_t * mp)170 putnext(queue_t *q, mblk_t *mp)
171 {
172 mutex_enter(&mutex);
173 cv_wait(&cv, &mutex);
174 mutex_exit(&mutex);
175 }
176
177 int
ndi_devi_offline(dev_info_t * dip,uint_t flags)178 ndi_devi_offline(dev_info_t *dip, uint_t flags) {
179 (*busops_p->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
180 (*busops_p->bus_ctl)(0, 0, 0, 0, 0);
181 (*busops_p->bus_get_eventcookie)(0, 0, 0, 0);
182 (*busops_p->bus_add_eventcall)(0, 0, 0, 0, 0, 0);
183 (*busops_p->bus_remove_eventcall)(0, 0);
184 (*busops_p->bus_post_event)(0, 0, 0, 0);
185 (*busops_p->bus_unconfig)(0, 0, 0, 0);
186 }
187
188 int
ndi_devi_online(dev_info_t * dip,uint_t flags)189 ndi_devi_online(dev_info_t *dip, uint_t flags) {
190 (*busops_p->bus_config)(0, 0, 0, 0, 0);
191 }
192