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