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 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 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 149 pm_raise_power(dev_info_t *dip, int comp, int level) { 150 (*devops_p->devo_power)(0, 0, 0); 151 } 152 153 int 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 162 delay(clock_t ticks) 163 { 164 mutex_enter(&mutex); 165 cv_wait(&cv, &mutex); 166 mutex_exit(&mutex); 167 } 168 169 void 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 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 189 ndi_devi_online(dev_info_t *dip, uint_t flags) { 190 (*busops_p->bus_config)(0, 0, 0, 0, 0); 191 } 192