Sat Jan 21 16:49:26 2012 UTC ()
src/sys/dev/ic/mpu.c
fix assertions after audiomp.


(chs)
diff -r1.18 -r1.19 src/sys/dev/ic/mpu.c

cvs diff -r1.18 -r1.19 src/sys/dev/ic/mpu.c (switch to unified diff)

--- src/sys/dev/ic/mpu.c 2011/11/23 23:07:32 1.18
+++ src/sys/dev/ic/mpu.c 2012/01/21 16:49:26 1.19
@@ -1,280 +1,280 @@ @@ -1,280 +1,280 @@
1/* $NetBSD: mpu.c,v 1.18 2011/11/23 23:07:32 jmcneill Exp $ */ 1/* $NetBSD: mpu.c,v 1.19 2012/01/21 16:49:26 chs Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss@NetBSD.org) and by Andrew Doran. 8 * by Lennart Augustsson (augustss@NetBSD.org) and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: mpu.c,v 1.18 2011/11/23 23:07:32 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: mpu.c,v 1.19 2012/01/21 16:49:26 chs Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/errno.h> 37#include <sys/errno.h>
38#include <sys/ioctl.h> 38#include <sys/ioctl.h>
39#include <sys/syslog.h> 39#include <sys/syslog.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/proc.h> 41#include <sys/proc.h>
42#include <sys/buf.h> 42#include <sys/buf.h>
43 43
44#include <sys/cpu.h> 44#include <sys/cpu.h>
45#include <sys/intr.h> 45#include <sys/intr.h>
46#include <sys/bus.h> 46#include <sys/bus.h>
47 47
48#include <dev/midi_if.h> 48#include <dev/midi_if.h>
49 49
50#include <dev/ic/mpuvar.h> 50#include <dev/ic/mpuvar.h>
51 51
52#ifdef AUDIO_DEBUG 52#ifdef AUDIO_DEBUG
53#define DPRINTF(x) if (mpudebug) printf x 53#define DPRINTF(x) if (mpudebug) printf x
54#define DPRINTFN(n,x) if (mpudebug >= (n)) printf x 54#define DPRINTFN(n,x) if (mpudebug >= (n)) printf x
55int mpudebug = 0; 55int mpudebug = 0;
56#else 56#else
57#define DPRINTF(x) 57#define DPRINTF(x)
58#define DPRINTFN(n,x) 58#define DPRINTFN(n,x)
59#endif 59#endif
60 60
61#define MPU_DATA 0 61#define MPU_DATA 0
62#define MPU_COMMAND 1 62#define MPU_COMMAND 1
63#define MPU_RESET 0xff 63#define MPU_RESET 0xff
64#define MPU_UART_MODE 0x3f 64#define MPU_UART_MODE 0x3f
65#define MPU_ACK 0xfe 65#define MPU_ACK 0xfe
66#define MPU_STATUS 1 66#define MPU_STATUS 1
67#define MPU_OUTPUT_BUSY 0x40 67#define MPU_OUTPUT_BUSY 0x40
68#define MPU_INPUT_EMPTY 0x80 68#define MPU_INPUT_EMPTY 0x80
69 69
70#define MPU_MAXWAIT 10000 /* usec/10 to wait */ 70#define MPU_MAXWAIT 10000 /* usec/10 to wait */
71 71
72#define MPU_GETSTATUS(iot, ioh) (bus_space_read_1(iot, ioh, MPU_STATUS)) 72#define MPU_GETSTATUS(iot, ioh) (bus_space_read_1(iot, ioh, MPU_STATUS))
73 73
74static int mpu_reset(struct mpu_softc *); 74static int mpu_reset(struct mpu_softc *);
75static inline int mpu_waitready(struct mpu_softc *); 75static inline int mpu_waitready(struct mpu_softc *);
76static void mpu_readinput(struct mpu_softc *); 76static void mpu_readinput(struct mpu_softc *);
77 77
78static int mpu_open(void *, int, 78static int mpu_open(void *, int,
79 void (*iintr)(void *, int), 79 void (*iintr)(void *, int),
80 void (*ointr)(void *), void *arg); 80 void (*ointr)(void *), void *arg);
81static void mpu_close(void *); 81static void mpu_close(void *);
82static int mpu_output(void *, int); 82static int mpu_output(void *, int);
83static void mpu_getinfo(void *, struct midi_info *); 83static void mpu_getinfo(void *, struct midi_info *);
84static void mpu_get_locks(void *, kmutex_t **, kmutex_t **); 84static void mpu_get_locks(void *, kmutex_t **, kmutex_t **);
85 85
86const struct midi_hw_if mpu_midi_hw_if = { 86const struct midi_hw_if mpu_midi_hw_if = {
87 mpu_open, 87 mpu_open,
88 mpu_close, 88 mpu_close,
89 mpu_output, 89 mpu_output,
90 mpu_getinfo, 90 mpu_getinfo,
91 0, /* ioctl */ 91 0, /* ioctl */
92 mpu_get_locks, 92 mpu_get_locks,
93}; 93};
94 94
95int 95int
96mpu_find(struct mpu_softc *sc) 96mpu_find(struct mpu_softc *sc)
97{ 97{
98 if (MPU_GETSTATUS(sc->iot, sc->ioh) == 0xff) { 98 if (MPU_GETSTATUS(sc->iot, sc->ioh) == 0xff) {
99 DPRINTF(("%s: No status\n", __func__)); 99 DPRINTF(("%s: No status\n", __func__));
100 goto bad; 100 goto bad;
101 } 101 }
102 sc->open = 0; 102 sc->open = 0;
103 sc->intr = 0; 103 sc->intr = 0;
104 if (mpu_reset(sc) == 0) 104 if (mpu_reset(sc) == 0)
105 return 1; 105 return 1;
106bad: 106bad:
107 return 0; 107 return 0;
108} 108}
109 109
110void 110void
111mpu_attach(struct mpu_softc *sc) 111mpu_attach(struct mpu_softc *sc)
112{ 112{
113 113
114 if (sc->lock == NULL) { 114 if (sc->lock == NULL) {
115 panic("mpu_attach: no lock"); 115 panic("mpu_attach: no lock");
116 } 116 }
117 117
118 midi_attach_mi(&mpu_midi_hw_if, sc, sc->sc_dev); 118 midi_attach_mi(&mpu_midi_hw_if, sc, sc->sc_dev);
119} 119}
120 120
121static inline int 121static inline int
122mpu_waitready(struct mpu_softc *sc) 122mpu_waitready(struct mpu_softc *sc)
123{ 123{
124 int i; 124 int i;
125 125
126 KASSERT(mutex_owned(sc->lock)); 126 KASSERT(sc->lock == NULL || mutex_owned(sc->lock));
127 127
128 for(i = 0; i < MPU_MAXWAIT; i++) { 128 for (i = 0; i < MPU_MAXWAIT; i++) {
129 if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_OUTPUT_BUSY)) 129 if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_OUTPUT_BUSY))
130 return 0; 130 return 0;
131 delay(10); 131 delay(10);
132 } 132 }
133 return 1; 133 return 1;
134} 134}
135 135
136static int 136static int
137mpu_reset(struct mpu_softc *sc) 137mpu_reset(struct mpu_softc *sc)
138{ 138{
139 bus_space_tag_t iot = sc->iot; 139 bus_space_tag_t iot = sc->iot;
140 bus_space_handle_t ioh = sc->ioh; 140 bus_space_handle_t ioh = sc->ioh;
141 int i; 141 int i;
142 142
143 KASSERT(mutex_owned(sc->lock)); 143 KASSERT(sc->lock == NULL || mutex_owned(sc->lock));
144 144
145 if (mpu_waitready(sc)) { 145 if (mpu_waitready(sc)) {
146 DPRINTF(("%s: not ready\n", __func__)); 146 DPRINTF(("%s: not ready\n", __func__));
147 return EIO; 147 return EIO;
148 } 148 }
149 bus_space_write_1(iot, ioh, MPU_COMMAND, MPU_RESET); 149 bus_space_write_1(iot, ioh, MPU_COMMAND, MPU_RESET);
150 for(i = 0; i < 2*MPU_MAXWAIT; i++) { 150 for (i = 0; i < 2*MPU_MAXWAIT; i++) {
151 if (!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY) && 151 if (!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY) &&
152 bus_space_read_1(iot, ioh, MPU_DATA) == MPU_ACK) { 152 bus_space_read_1(iot, ioh, MPU_DATA) == MPU_ACK) {
153 return 0; 153 return 0;
154 } 154 }
155 } 155 }
156 DPRINTF(("%s: No ACK\n", __func__)); 156 DPRINTF(("%s: No ACK\n", __func__));
157 return EIO; 157 return EIO;
158} 158}
159 159
160static int 160static int
161mpu_open(void *addr, int flags, void (*iintr)(void *, int), 161mpu_open(void *addr, int flags, void (*iintr)(void *, int),
162 void (*ointr)(void *), void *arg) 162 void (*ointr)(void *), void *arg)
163{ 163{
164 struct mpu_softc *sc = addr; 164 struct mpu_softc *sc = addr;
165 165
166 DPRINTF(("%s: sc=%p\n", __func__, sc)); 166 DPRINTF(("%s: sc=%p\n", __func__, sc));
167 167
168 KASSERT(mutex_owned(sc->lock)); 168 KASSERT(mutex_owned(sc->lock));
169 169
170 if (sc->open) 170 if (sc->open)
171 return EBUSY; 171 return EBUSY;
172#ifndef AUDIO_NO_POWER_CTL 172#ifndef AUDIO_NO_POWER_CTL
173 if (sc->powerctl) 173 if (sc->powerctl)
174 sc->powerctl(sc->powerarg, 1); 174 sc->powerctl(sc->powerarg, 1);
175#endif 175#endif
176 if (mpu_reset(sc) != 0) { 176 if (mpu_reset(sc) != 0) {
177#ifndef AUDIO_NO_POWER_CTL 177#ifndef AUDIO_NO_POWER_CTL
178 if (sc->powerctl) 178 if (sc->powerctl)
179 sc->powerctl(sc->powerarg, 0); 179 sc->powerctl(sc->powerarg, 0);
180#endif 180#endif
181 return EIO; 181 return EIO;
182 } 182 }
183 183
184 bus_space_write_1(sc->iot, sc->ioh, MPU_COMMAND, MPU_UART_MODE); 184 bus_space_write_1(sc->iot, sc->ioh, MPU_COMMAND, MPU_UART_MODE);
185 sc->open = 1; 185 sc->open = 1;
186 sc->intr = iintr; 186 sc->intr = iintr;
187 sc->arg = arg; 187 sc->arg = arg;
188 return 0; 188 return 0;
189} 189}
190 190
191static void 191static void
192mpu_close(void *addr) 192mpu_close(void *addr)
193{ 193{
194 struct mpu_softc *sc = addr; 194 struct mpu_softc *sc = addr;
195 195
196 DPRINTF(("%s: sc=%p\n", __func__, sc)); 196 DPRINTF(("%s: sc=%p\n", __func__, sc));
197 197
198 KASSERT(mutex_owned(sc->lock)); 198 KASSERT(mutex_owned(sc->lock));
199 199
200 sc->open = 0; 200 sc->open = 0;
201 sc->intr = 0; 201 sc->intr = 0;
202 mpu_reset(sc); /* exit UART mode */ 202 mpu_reset(sc); /* exit UART mode */
203 203
204#ifndef AUDIO_NO_POWER_CTL 204#ifndef AUDIO_NO_POWER_CTL
205 if (sc->powerctl) 205 if (sc->powerctl)
206 sc->powerctl(sc->powerarg, 0); 206 sc->powerctl(sc->powerarg, 0);
207#endif 207#endif
208} 208}
209 209
210static void 210static void
211mpu_readinput(struct mpu_softc *sc) 211mpu_readinput(struct mpu_softc *sc)
212{ 212{
213 bus_space_tag_t iot = sc->iot; 213 bus_space_tag_t iot = sc->iot;
214 bus_space_handle_t ioh = sc->ioh; 214 bus_space_handle_t ioh = sc->ioh;
215 int data; 215 int data;
216 216
217 KASSERT(mutex_owned(sc->lock)); 217 KASSERT(mutex_owned(sc->lock));
218 218
219 while(!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY)) { 219 while(!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY)) {
220 data = bus_space_read_1(iot, ioh, MPU_DATA); 220 data = bus_space_read_1(iot, ioh, MPU_DATA);
221 DPRINTFN(3, ("%s: sc=%p 0x%02x\n", __func__, sc, data)); 221 DPRINTFN(3, ("%s: sc=%p 0x%02x\n", __func__, sc, data));
222 if (sc->intr) 222 if (sc->intr)
223 sc->intr(sc->arg, data); 223 sc->intr(sc->arg, data);
224 } 224 }
225} 225}
226 226
227static int 227static int
228mpu_output(void *addr, int d) 228mpu_output(void *addr, int d)
229{ 229{
230 struct mpu_softc *sc = addr; 230 struct mpu_softc *sc = addr;
231 231
232 KASSERT(mutex_owned(sc->lock)); 232 KASSERT(mutex_owned(sc->lock));
233 233
234 DPRINTFN(3, ("%s: sc=%p 0x%02x\n", __func__, sc, d)); 234 DPRINTFN(3, ("%s: sc=%p 0x%02x\n", __func__, sc, d));
235 if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY)) { 235 if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY)) {
236 mpu_readinput(sc); 236 mpu_readinput(sc);
237 } 237 }
238 if (mpu_waitready(sc)) { 238 if (mpu_waitready(sc)) {
239 DPRINTF(("%s:: not ready\n", __func__)); 239 DPRINTF(("%s:: not ready\n", __func__));
240 return EIO; 240 return EIO;
241 } 241 }
242 bus_space_write_1(sc->iot, sc->ioh, MPU_DATA, d); 242 bus_space_write_1(sc->iot, sc->ioh, MPU_DATA, d);
243 return 0; 243 return 0;
244} 244}
245 245
246static void 246static void
247mpu_getinfo(void *addr, struct midi_info *mi) 247mpu_getinfo(void *addr, struct midi_info *mi)
248{ 248{
249 struct mpu_softc *sc = addr; 249 struct mpu_softc *sc = addr;
250 250
251 KASSERT(mutex_owned(sc->lock)); 251 KASSERT(mutex_owned(sc->lock));
252 252
253 mi->name = sc->model; 253 mi->name = sc->model;
254 mi->props = 0; 254 mi->props = 0;
255} 255}
256 256
257static void 257static void
258mpu_get_locks(void *addr, kmutex_t **intr, kmutex_t **proc) 258mpu_get_locks(void *addr, kmutex_t **intr, kmutex_t **proc)
259{ 259{
260 struct mpu_softc *sc = addr; 260 struct mpu_softc *sc = addr;
261 261
262 *intr = sc->lock; 262 *intr = sc->lock;
263 *proc = NULL; 263 *proc = NULL;
264} 264}
265 265
266int 266int
267mpu_intr(void *addr) 267mpu_intr(void *addr)
268{ 268{
269 struct mpu_softc *sc = addr; 269 struct mpu_softc *sc = addr;
270 270
271 KASSERT(mutex_owned(sc->lock)); 271 KASSERT(mutex_owned(sc->lock));
272 272
273 if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY) { 273 if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY) {
274 DPRINTF(("%s: no data\n", __func__)); 274 DPRINTF(("%s: no data\n", __func__));
275 return 0; 275 return 0;
276 } else { 276 } else {
277 mpu_readinput(sc); 277 mpu_readinput(sc);
278 return 1; 278 return 1;
279 } 279 }
280} 280}