Home | History | Annotate | Download | only in warlock
      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.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 /*
     29  * ddi_dki_impl.c - A pseudo-kernel to use when analyzing drivers with warlock.
     30  *
     31  * The main idea here is to represent all of the ways that the kernel can
     32  * call into the driver, so that warlock has the correct view of the call
     33  * graph.
     34  *
     35  * This version differs from ddi_dki_spec.c in that it represents the
     36  * current implementation of the DDI/DKI rather than the specification.
     37  */
     38 #include "ddi_dki_comm.inc"
     39 #include <sys/esunddi.h>
     40 #include <sys/sunndi.h>
     41 #include <sys/ddi.h>
     42 #include <sys/epm.h>
     43 #include <sys/proc.h>
     44 
     45 int warlock_dummy(void);
     46 int _init(void);
     47 int _fini(void);
     48 int _info(struct modinfo *a);
     49 int scsi_init(void);
     50 
     51 int main(void) {
     52 
     53 	/*
     54 	 * The following call will cause warlock to know about
     55 	 * warlock_dummy as a func that can be used to satisfy
     56 	 * unbound function pointers.  It shouldn't be needed
     57 	 * with the new warlock on suntools.
     58 	 */
     59 	warlock_dummy();
     60 
     61 	/*
     62 	 * When the following functions are called, there is never
     63 	 * more than one thread running in the driver.
     64 	 */
     65 	_init();
     66 	_fini();
     67 	_info(0);
     68 	(*devops_p->devo_identify)(0);
     69 	(*devops_p->devo_probe)(0);
     70 	(*devops_p->devo_attach)(0, 0);
     71 
     72 	/*
     73 	 * When the following functions are called, there may be
     74 	 * more than one thread running in the driver.
     75 	 */
     76 	_NOTE(COMPETING_THREADS_NOW)
     77 
     78 
     79 	scsi_init();
     80 
     81 	(*devops_p->devo_getinfo)(0, 0, 0, 0);
     82 	(*devops_p->devo_reset)(0, 0);
     83 	(*devops_p->devo_power)(0, 0, 0);
     84 
     85 	(*cbops_p->cb_open)(0, 0, 0, 0);
     86 	(*cbops_p->cb_close)(0, 0, 0, 0);
     87 	(*cbops_p->cb_strategy)(0);
     88 	(*cbops_p->cb_print)(0, 0);
     89 	(*cbops_p->cb_dump)(0, 0, 0, 0);
     90 	(*cbops_p->cb_read)(0, 0, 0);
     91 	(*cbops_p->cb_write)(0, 0, 0);
     92 	(*cbops_p->cb_ioctl)(0, 0, 0, 0, 0, 0);
     93 	(*cbops_p->cb_devmap)(0, 0, 0, 0, 0, 0);
     94 	(*cbops_p->cb_mmap)(0, 0, 0);
     95 	(*cbops_p->cb_segmap)(0, 0, 0, 0, 0, 0, 0, 0, 0);
     96 	(*cbops_p->cb_chpoll)(0, 0, 0, 0, 0);
     97 	(*cbops_p->cb_prop_op)(0, 0, 0, 0, 0, 0, 0);
     98 	(*cbops_p->cb_aread)(0, 0, 0);
     99 	(*cbops_p->cb_awrite)(0, 0, 0);
    100 
    101 	(*busops_p->bus_map)(0, 0, 0, 0, 0, 0);
    102 	(*busops_p->bus_get_intrspec)(0, 0, 0);
    103 	(*busops_p->bus_add_intrspec)(0, 0, 0, 0, 0, 0, 0, 0);
    104 	(*busops_p->bus_remove_intrspec)(0, 0, 0, 0);
    105 	(*busops_p->bus_map_fault)(0, 0, 0, 0, 0, 0, 0, 0, 0);
    106 	(*busops_p->bus_dma_map)(0, 0, 0, 0);
    107 	(*busops_p->bus_dma_allochdl)(0, 0, 0, 0, 0, 0);
    108 	(*busops_p->bus_dma_freehdl)(0, 0, 0);
    109 	(*busops_p->bus_dma_bindhdl)(0, 0, 0, 0, 0, 0);
    110 	(*busops_p->bus_dma_unbindhdl)(0, 0, 0);
    111 	(*busops_p->bus_dma_flush)(0, 0, 0, 0, 0, 0);
    112 	(*busops_p->bus_dma_win)(0, 0, 0, 0, 0, 0, 0, 0);
    113 	(*busops_p->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    114 	(*busops_p->bus_ctl)(0, 0, 0, 0, 0);
    115 	(*busops_p->bus_prop_op)(0, 0, 0, 0, 0, 0, 0, 0);
    116 
    117 	(*busops_p->bus_get_eventcookie)(0, 0, 0, 0);
    118 	(*busops_p->bus_add_eventcall)(0, 0, 0, 0, 0, 0);
    119 	(*busops_p->bus_remove_eventcall)(0, 0);
    120 	(*busops_p->bus_post_event)(0, 0, 0, 0);
    121 	(*busops_p->bus_intr_ctl)(0, 0, 0, 0, 0);
    122 
    123 	(*busops_p->bus_config)(0, 0, 0, 0, 0);
    124 	(*busops_p->bus_unconfig)(0, 0, 0, 0);
    125 
    126 #ifndef __lock_lint
    127 /* this causes warnings and it is unclear how to handle this */
    128 	(*busops_p->bus_fm_init)(0, 0, 0, 0);
    129 	(*busops_p->bus_fm_fini)(0, 0);
    130 	(*busops_p->bus_fm_access_enter)(0, 0);
    131 	(*busops_p->bus_fm_access_exit)(0, 0);
    132 	(*busops_p->bus_power)(0, 0, 0, 0, 0);
    133 	(*busops_p->bus_intr_op)(0, 0, 0, 0, 0);
    134 #endif
    135 
    136 	ndi_devi_offline(0, 0);
    137 	_NOTE(NO_COMPETING_THREADS_NOW)
    138 }
    139 
    140 	/* Power managment framework calls */
    141 int
    142 pm_set_power(dev_info_t *dip, int comp, int level, int direction,
    143     pm_canblock_t canblock, int scan, int *retp)
    144 {
    145 	(*devops_p->devo_power)(0, 0, 0);
    146 }
    147 
    148 int
    149 pm_raise_power(dev_info_t *dip, int comp, int level) {
    150 	(*devops_p->devo_power)(0, 0, 0);
    151 }
    152 
    153 int
    154 pm_lower_power(dev_info_t *dip, int comp, int level) {
    155 	(*devops_p->devo_power)(0, 0, 0);
    156 }
    157 
    158 static kmutex_t mutex;
    159 static kcondvar_t cv;
    160 
    161 void
    162 delay(clock_t ticks)
    163 {
    164 	mutex_enter(&mutex);
    165 	cv_wait(&cv, &mutex);
    166 	mutex_exit(&mutex);
    167 }
    168 
    169 void
    170 putnext(queue_t *q, mblk_t *mp)
    171 {
    172 	mutex_enter(&mutex);
    173 	cv_wait(&cv, &mutex);
    174 	mutex_exit(&mutex);
    175 }
    176 
    177 int
    178 ndi_devi_offline(dev_info_t *dip, uint_t flags) {
    179 	(*busops_p->bus_dma_ctl)(0, 0, 0, 0, 0, 0, 0, 0);
    180 	(*busops_p->bus_ctl)(0, 0, 0, 0, 0);
    181 	(*busops_p->bus_get_eventcookie)(0, 0, 0, 0);
    182 	(*busops_p->bus_add_eventcall)(0, 0, 0, 0, 0, 0);
    183 	(*busops_p->bus_remove_eventcall)(0, 0);
    184 	(*busops_p->bus_post_event)(0, 0, 0, 0);
    185 	(*busops_p->bus_unconfig)(0, 0, 0, 0);
    186 }
    187 
    188 int
    189 ndi_devi_online(dev_info_t *dip, uint_t flags) {
    190 	(*busops_p->bus_config)(0, 0, 0, 0, 0);
    191 }
    192