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