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 2014 Garrett D'Amore <garrett@damore.org> 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_mctl(dev_info_t *a, dev_info_t *b, ddi_dma_handle_t c, 173 enum ddi_dma_ctlops d, off_t *e, size_t *f, caddr_t *g, 174 uint_t h) 175 { 176 struct bus_ops *ops; 177 (*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0); 178 } 179 180 int 181 ddi_dma_get_error(ddi_dma_handle_t h, uint_t len, caddr_t errblk) 182 { 183 struct bus_ops *ops; 184 (*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0); 185 } 186 187 int 188 ddi_dma_sync(ddi_dma_handle_t h, off_t o, size_t l, uint_t whom) 189 { 190 struct bus_ops *ops; 191 (*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0); 192 } 193 194 int 195 ddi_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags, 196 char *name, caddr_t valuep, int *lengthp) 197 { 198 struct bus_ops *ops; 199 (*ops->bus_prop_op)(0, 0, 0, 0, 0, 0, 0, 0); 200 } 201 202 int 203 ddi_add_event_handler(dev_info_t *dip, ddi_eventcookie_t event, 204 void (*handler)(dev_info_t *, ddi_eventcookie_t, void *, void *), 205 void *arg, ddi_callback_id_t *id) 206 { 207 struct bus_ops *ops; 208 return ((*ops->bus_add_eventcall)(dip, dip, event, handler, arg, id)); 209 } 210 211 int 212 ddi_remove_event_handler(ddi_callback_id_t id) 213 { 214 dev_info_t *dip; 215 struct bus_ops *ops; 216 return ((*ops->bus_remove_eventcall)(dip, id)); 217 } 218 219 220 int 221 ddi_get_eventcookie(dev_info_t *dip, char *name, 222 ddi_eventcookie_t *event_cookiep) 223 { 224 struct bus_ops *ops; 225 return ((*ops->bus_get_eventcookie)(dip, dip, 226 name, event_cookiep)); 227 }