1 /* $OpenBSD: uperf.c,v 1.9 2022/10/16 01:22:39 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/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/errno.h> 38 #include <sys/device.h> 39 #include <sys/malloc.h> 40 #include <sys/ioctl.h> 41 #include <sys/conf.h> 42 43 #include <machine/conf.h> 44 45 #include <dev/sun/uperfio.h> 46 #include <arch/sparc64/dev/uperfvar.h> 47 48 struct cfdriver uperf_cd = { 49 NULL, "uperf", DV_DULL 50 }; 51 52 int uperf_getcntsrc(struct uperf_softc *, struct uperf_io *); 53 int uperf_findbyval(struct uperf_softc *, int, u_int, int *); 54 int uperf_findbysrc(struct uperf_softc *, int, int, u_int32_t *); 55 int uperf_setcntsrc(struct uperf_softc *, struct uperf_io *); 56 57 int 58 uperfopen(dev_t dev, int flags, int mode, struct proc *p) 59 { 60 if (minor(dev) >= uperf_cd.cd_ndevs) 61 return (ENXIO); 62 if (uperf_cd.cd_devs[minor(dev)] == NULL) 63 return (ENXIO); 64 return (0); 65 } 66 67 int 68 uperfclose(dev_t dev, int flags, int mode, struct proc *p) 69 { 70 return (0); 71 } 72 73 int 74 uperfioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 75 { 76 struct uperf_softc *usc = uperf_cd.cd_devs[minor(dev)]; 77 struct uperf_io *io = (struct uperf_io *)data; 78 int error = EINVAL; 79 80 switch (cmd) { 81 case UPIO_GCNTSRC: 82 error = uperf_getcntsrc(usc, io); 83 break; 84 case UPIO_SCNTSRC: 85 error = uperf_setcntsrc(usc, io); 86 break; 87 case UPIO_CLRCNT: 88 error = usc->usc_clrcnt(usc->usc_cookie, io->cnt_flags); 89 break; 90 case UPIO_GETCNT: 91 error = usc->usc_getcnt(usc->usc_cookie, io->cnt_flags, 92 &io->cnt_val0, &io->cnt_val1); 93 break; 94 } 95 96 return (error); 97 } 98 99 int 100 uperf_getcntsrc(struct uperf_softc *usc, struct uperf_io *io) 101 { 102 u_int cnt0_src, cnt1_src; 103 int error; 104 105 error = usc->usc_getcntsrc(usc->usc_cookie, io->cnt_flags, 106 &cnt0_src, &cnt1_src); 107 if (error) 108 return (error); 109 110 if (io->cnt_flags & UPERF_CNT0) { 111 error = uperf_findbyval(usc, UPERF_CNT0, 112 cnt0_src, &io->cnt_src0); 113 if (error) 114 return (error); 115 } 116 117 if (io->cnt_flags & UPERF_CNT1) { 118 error = uperf_findbyval(usc, UPERF_CNT1, 119 cnt1_src, &io->cnt_src1); 120 if (error) 121 return (error); 122 } 123 return (0); 124 } 125 126 int 127 uperf_findbyval(struct uperf_softc *usc, int cnt, u_int uval, int *rval) 128 { 129 struct uperf_src *srcs = usc->usc_srcs; 130 131 if (srcs->us_src == 0) 132 return (EINVAL); 133 134 while (srcs->us_src != -1) { 135 if (srcs->us_val == uval && srcs->us_flags & cnt) { 136 *rval = srcs->us_src; 137 return (0); 138 } 139 srcs++; 140 } 141 return (EINVAL); 142 } 143 144 int 145 uperf_setcntsrc(struct uperf_softc *usc, struct uperf_io *io) 146 { 147 u_int32_t cnt0_src, cnt1_src; 148 int error; 149 150 cnt0_src = cnt1_src = 0; 151 152 if (io->cnt_flags & UPERF_CNT0) { 153 error = uperf_findbysrc(usc, UPERF_CNT0, 154 io->cnt_src0, &cnt0_src); 155 if (error) 156 return (error); 157 } 158 if (io->cnt_flags & UPERF_CNT1) { 159 error = uperf_findbysrc(usc, UPERF_CNT1, 160 io->cnt_src1, &cnt1_src); 161 if (error) 162 return (error); 163 } 164 return ((usc->usc_setcntsrc)(usc->usc_cookie, io->cnt_flags, 165 cnt0_src, cnt1_src)); 166 } 167 168 int 169 uperf_findbysrc(struct uperf_softc *usc, int cnt, int src, u_int32_t *rval) 170 { 171 struct uperf_src *srcs = usc->usc_srcs; 172 173 if (srcs->us_src == 0) 174 return (EINVAL); 175 176 while (srcs->us_src != -1) { 177 if (srcs->us_src == src && srcs->us_flags & cnt) { 178 *rval = srcs->us_val; 179 return (0); 180 } 181 srcs++; 182 } 183 return (EINVAL); 184 } 185