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
45int warlock_dummy(void);
46int _init(void);
47int _fini(void);
48int _info(struct modinfo *a);
49int scsi_init(void);
50
51int 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 */
141int
142pm_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
148int
149pm_raise_power(dev_info_t *dip, int comp, int level) {
150	(*devops_p->devo_power)(0, 0, 0);
151}
152
153int
154pm_lower_power(dev_info_t *dip, int comp, int level) {
155	(*devops_p->devo_power)(0, 0, 0);
156}
157
158static kmutex_t mutex;
159static kcondvar_t cv;
160
161void
162delay(clock_t ticks)
163{
164	mutex_enter(&mutex);
165	cv_wait(&cv, &mutex);
166	mutex_exit(&mutex);
167}
168
169void
170putnext(queue_t *q, mblk_t *mp)
171{
172	mutex_enter(&mutex);
173	cv_wait(&cv, &mutex);
174	mutex_exit(&mutex);
175}
176
177int
178ndi_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
188int
189ndi_devi_online(dev_info_t *dip, uint_t flags) {
190	(*busops_p->bus_config)(0, 0, 0, 0, 0);
191}
192