1 /* $OpenBSD: uperf.c,v 1.7 2016/12/20 13:47:38 jsg Exp $ */ 2 3 /* 4 * Copyright (c) 2002 Jason L. Wright (jason@thought.net) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Effort sponsored in part by the Defense Advanced Research Projects 29 * Agency (DARPA) and Air Force Research Laboratory, Air Force 30 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 31 * 32 */ 33 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/errno.h> 39 #include <sys/device.h> 40 #include <sys/malloc.h> 41 #include <sys/ioctl.h> 42 #include <sys/conf.h> 43 44 #include <machine/conf.h> 45 46 #include <dev/sun/uperfio.h> 47 #include <arch/sparc64/dev/uperfvar.h> 48 49 struct cfdriver uperf_cd = { 50 NULL, "uperf", DV_DULL 51 }; 52 53 int uperf_getcntsrc(struct uperf_softc *, struct uperf_io *); 54 int uperf_findbyval(struct uperf_softc *, int, u_int, int *); 55 int uperf_findbysrc(struct uperf_softc *, int, int, u_int32_t *); 56 int uperf_setcntsrc(struct uperf_softc *, struct uperf_io *); 57 58 int 59 uperfopen(dev, flags, mode, p) 60 dev_t dev; 61 int flags, mode; 62 struct proc *p; 63 { 64 if (minor(dev) >= uperf_cd.cd_ndevs) 65 return (ENXIO); 66 if (uperf_cd.cd_devs[minor(dev)] == NULL) 67 return (ENXIO); 68 return (0); 69 } 70 71 int 72 uperfclose(dev, flags, mode, p) 73 dev_t dev; 74 int flags, mode; 75 struct proc *p; 76 { 77 return (0); 78 } 79 80 int 81 uperfioctl(dev, cmd, data, flags, p) 82 dev_t dev; 83 u_long cmd; 84 caddr_t data; 85 int flags; 86 struct proc *p; 87 { 88 struct uperf_softc *usc = uperf_cd.cd_devs[minor(dev)]; 89 struct uperf_io *io = (struct uperf_io *)data; 90 int error = EINVAL; 91 92 switch (cmd) { 93 case UPIO_GCNTSRC: 94 error = uperf_getcntsrc(usc, io); 95 break; 96 case UPIO_SCNTSRC: 97 error = uperf_setcntsrc(usc, io); 98 break; 99 case UPIO_CLRCNT: 100 error = usc->usc_clrcnt(usc->usc_cookie, io->cnt_flags); 101 break; 102 case UPIO_GETCNT: 103 error = usc->usc_getcnt(usc->usc_cookie, io->cnt_flags, 104 &io->cnt_val0, &io->cnt_val1); 105 break; 106 } 107 108 return (error); 109 } 110 111 int 112 uperf_getcntsrc(usc, io) 113 struct uperf_softc *usc; 114 struct uperf_io *io; 115 { 116 u_int cnt0_src, cnt1_src; 117 int error; 118 119 error = usc->usc_getcntsrc(usc->usc_cookie, io->cnt_flags, 120 &cnt0_src, &cnt1_src); 121 if (error) 122 return (error); 123 124 if (io->cnt_flags & UPERF_CNT0) { 125 error = uperf_findbyval(usc, UPERF_CNT0, 126 cnt0_src, &io->cnt_src0); 127 if (error) 128 return (error); 129 } 130 131 if (io->cnt_flags & UPERF_CNT1) { 132 error = uperf_findbyval(usc, UPERF_CNT1, 133 cnt1_src, &io->cnt_src1); 134 if (error) 135 return (error); 136 } 137 return (0); 138 } 139 140 int 141 uperf_findbyval(usc, cnt, uval, rval) 142 struct uperf_softc *usc; 143 int cnt; 144 u_int uval; 145 int *rval; 146 { 147 struct uperf_src *srcs = usc->usc_srcs; 148 149 if (srcs->us_src == 0) 150 return (EINVAL); 151 152 while (srcs->us_src != -1) { 153 if (srcs->us_val == uval && srcs->us_flags & cnt) { 154 *rval = srcs->us_src; 155 return (0); 156 } 157 srcs++; 158 } 159 return (EINVAL); 160 } 161 162 int 163 uperf_setcntsrc(usc, io) 164 struct uperf_softc *usc; 165 struct uperf_io *io; 166 { 167 u_int32_t cnt0_src, cnt1_src; 168 int error; 169 170 cnt0_src = cnt1_src = 0; 171 172 if (io->cnt_flags & UPERF_CNT0) { 173 error = uperf_findbysrc(usc, UPERF_CNT0, 174 io->cnt_src0, &cnt0_src); 175 if (error) 176 return (error); 177 } 178 if (io->cnt_flags & UPERF_CNT1) { 179 error = uperf_findbysrc(usc, UPERF_CNT1, 180 io->cnt_src1, &cnt1_src); 181 if (error) 182 return (error); 183 } 184 return ((usc->usc_setcntsrc)(usc->usc_cookie, io->cnt_flags, 185 cnt0_src, cnt1_src)); 186 } 187 188 int 189 uperf_findbysrc(usc, cnt, src, rval) 190 struct uperf_softc *usc; 191 int cnt, src; 192 u_int32_t *rval; 193 { 194 struct uperf_src *srcs = usc->usc_srcs; 195 196 if (srcs->us_src == 0) 197 return (EINVAL); 198 199 while (srcs->us_src != -1) { 200 if (srcs->us_src == src && srcs->us_flags & cnt) { 201 *rval = srcs->us_val; 202 return (0); 203 } 204 srcs++; 205 } 206 return (EINVAL); 207 } 208