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>. 28 * Copyright 2014 Pluribus Networks, Inc. 29 */ 30 31 /* 32 * ddi_dki_comm.inc - Part of a pseudo-kernel to use when analyzing drivers 33 * with warlock. 34 * 35 * The main idea here is to represent all of the ways that the kernel can 36 * call into the driver, so that warlock has the correct view of the call 37 * graph. 38 * 39 * This file represents the stuff in common between the DDI/DKI spec and 40 * the current implementation. It is included by both ddi_dki_{spec,impl}.c 41 * 42 * This is a SPARC version; some functions (e.g. ddi_dma_nextwin) should 43 * be changed for an x86 version. 44 */ 45 46 #include <sys/note.h> 47 #include <sys/devops.h> 48 #include <sys/ddi.h> 49 #include <sys/sunddi.h> 50 #include <sys/proc.h> 51 52 _NOTE(DATA_READABLE_WITHOUT_LOCK( dev_ops cb_ops bus_ops )) 53 54 /* 55 * Now define a dev_ops, a cb_ops, and a bus_ops with 0 for each 56 * entry point, so that warlock doesn't complain that these 57 * function pointers have no bindings. 58 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 59 */ 60 struct dev_ops *devops_p, warlock_dev_ops = { 61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 62 }; 63 64 struct cb_ops *cbops_p, warlock_cb_ops = { 65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 66 }; 67 68 struct bus_ops *busops_p, warlock_bus_ops = { 69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 70 }; 71 72 73 /* This rendition of mod_remove() tells warlock that it calls detach. */ 74 int 75 mod_remove(struct modlinkage *a) { 76 (*devops_p->devo_detach)(NULL, 0); 77 } 78 79 /* This rendition of physio() shows that it calls its func ptr args. */ 80 int 81 physio( 82 int (*strategy)(struct buf *), 83 struct buf *a, 84 dev_t b, 85 int c, 86 void (*mincnt)(struct buf *), 87 struct uio *d) 88 { 89 (*strategy)(0); 90 (*mincnt)(0); 91 } 92 93 /* 94 * Tell warlock that args to some funcs get called back as separate threads. 95 */ 96 timeout_id_t 97 timeout(void (*fp)(void *), void *a, clock_t b) 98 { 99 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0); 100 } 101 102 int 103 ddi_add_intr(dev_info_t *a, uint_t b, ddi_iblock_cookie_t *c, 104 ddi_idevice_cookie_t *d, uint_t (*fp)(caddr_t), caddr_t e) 105 { 106 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0); 107 } 108 109 int 110 ddi_add_softintr(dev_info_t *a, int b, ddi_softintr_t *c, 111 ddi_iblock_cookie_t *d, ddi_idevice_cookie_t *e, uint_t (*fp)(caddr_t), 112 caddr_t f) 113 { 114 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0); 115 } 116 117 int 118 ddi_intr_add_handler(ddi_intr_handle_t h, ddi_intr_handler_t inthandler, 119 void *arg1, void *arg2) 120 { 121 thread_create(0, 0, (void (*)())inthandler, 0, 0, 0, 0, 0); 122 } 123 124 int 125 ddi_intr_add_softint(dev_info_t *dip, ddi_softint_handle_t *h_p, int soft_pri, 126 ddi_intr_handler_t handler, void *arg1) 127 { 128 thread_create(0, 0, (void (*)())handler, 0, 0, 0, 0, 0); 129 } 130 131 void 132 ddi_set_callback( 133 int (*fp)(caddr_t), 134 caddr_t a, 135 uintptr_t *b) 136 { 137 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0); 138 } 139 140 int 141 ddi_dma_map( 142 dev_info_t *a, 143 dev_info_t *b, 144 struct ddi_dma_req *c, 145 ddi_dma_handle_t *d) 146 { 147 struct bus_ops *ops; 148 (*ops->bus_dma_map)(0, 0, 0, 0); 149 } 150 151 int 152 ddi_dma_mctl(dev_info_t *a, dev_info_t *b, ddi_dma_handle_t c, 153 enum ddi_dma_ctlops d, off_t *e, size_t *f, caddr_t *g, 154 uint_t h) 155 { 156 struct bus_ops *ops; 157 (*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0); 158 } 159 160 int 161 ddi_dma_sync(ddi_dma_handle_t h, off_t o, size_t l, uint_t whom) 162 { 163 struct bus_ops *ops; 164 (*ops->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0); 165 } 166 167 int 168 ddi_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags, 169 char *name, caddr_t valuep, int *lengthp) 170 { 171 struct bus_ops *ops; 172 (*ops->bus_prop_op)(0, 0, 0, 0, 0, 0, 0, 0); 173 } 174 175 int 176 ddi_add_event_handler(dev_info_t *dip, ddi_eventcookie_t event, 177 void (*handler)(dev_info_t *, ddi_eventcookie_t, void *, void *), 178 void *arg, ddi_callback_id_t *id) 179 { 180 struct bus_ops *ops; 181 return ((*ops->bus_add_eventcall)(dip, dip, event, handler, arg, id)); 182 } 183 184 int 185 ddi_remove_event_handler(ddi_callback_id_t id) 186 { 187 dev_info_t *dip; 188 struct bus_ops *ops; 189 return ((*ops->bus_remove_eventcall)(dip, id)); 190 } 191 192 193 int 194 ddi_get_eventcookie(dev_info_t *dip, char *name, 195 ddi_eventcookie_t *event_cookiep) 196 { 197 struct bus_ops *ops; 198 return ((*ops->bus_get_eventcookie)(dip, dip, 199 name, event_cookiep)); 200 }