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 }