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 */ 59struct dev_ops *devops_p, warlock_dev_ops = { 60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 61}; 62 63struct 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 67struct 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. */ 73int 74mod_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. */ 79int 80physio( 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 */ 95timeout_id_t 96timeout(void (*fp)(void *), void *a, clock_t b) 97{ 98 thread_create(0, 0, (void (*)())fp, 0, 0, 0, 0, 0); 99} 100 101int 102ddi_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 108int 109ddi_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 116int 117ddi_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 123int 124ddi_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 130int 131ddi_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 147int 148ddi_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 162void 163ddi_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 171int 172ddi_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 180int 181ddi_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 187int 188ddi_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 194int 195ddi_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 202int 203ddi_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 211int 212ddi_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 220int 221ddi_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} 228