Thu Jul 28 03:42:21 2011 UTC ()
dev_t is uint64_t; use PRIx64 to print it.  Fix DEBUG build.


(uebayasi)
diff -r1.42 -r1.43 src/sys/arch/hp300/dev/ppi.c
diff -r1.90 -r1.91 src/sys/arch/hp300/dev/rd.c

cvs diff -r1.42 -r1.43 src/sys/arch/hp300/dev/ppi.c (switch to unified diff)

--- src/sys/arch/hp300/dev/ppi.c 2008/06/18 12:25:13 1.42
+++ src/sys/arch/hp300/dev/ppi.c 2011/07/28 03:42:20 1.43
@@ -1,499 +1,499 @@ @@ -1,499 +1,499 @@
1/* $NetBSD: ppi.c,v 1.42 2008/06/18 12:25:13 tsutsui Exp $ */ 1/* $NetBSD: ppi.c,v 1.43 2011/07/28 03:42:20 uebayasi Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997 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 Jason R. Thorpe. 8 * by Jason R. Thorpe.
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/* 32/*
33 * Copyright (c) 1982, 1990, 1993 33 * Copyright (c) 1982, 1990, 1993
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors 44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 * 59 *
60 * @(#)ppi.c 8.1 (Berkeley) 6/16/93 60 * @(#)ppi.c 8.1 (Berkeley) 6/16/93
61 */ 61 */
62 62
63/* 63/*
64 * Printer/Plotter HPIB interface 64 * Printer/Plotter HPIB interface
65 */ 65 */
66 66
67#include <sys/cdefs.h> 67#include <sys/cdefs.h>
68__KERNEL_RCSID(0, "$NetBSD: ppi.c,v 1.42 2008/06/18 12:25:13 tsutsui Exp $"); 68__KERNEL_RCSID(0, "$NetBSD: ppi.c,v 1.43 2011/07/28 03:42:20 uebayasi Exp $");
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/systm.h> 71#include <sys/systm.h>
72#include <sys/callout.h> 72#include <sys/callout.h>
73#include <sys/conf.h> 73#include <sys/conf.h>
74#include <sys/device.h> 74#include <sys/device.h>
75#include <sys/errno.h> 75#include <sys/errno.h>
76#include <sys/malloc.h> 76#include <sys/malloc.h>
77#include <sys/proc.h> 77#include <sys/proc.h>
78#include <sys/uio.h> 78#include <sys/uio.h>
79 79
80#include <hp300/dev/hpibvar.h> 80#include <hp300/dev/hpibvar.h>
81 81
82#include <hp300/dev/ppiioctl.h> 82#include <hp300/dev/ppiioctl.h>
83 83
84#include "ioconf.h" 84#include "ioconf.h"
85 85
86struct ppi_softc { 86struct ppi_softc {
87 device_t sc_dev; 87 device_t sc_dev;
88 int sc_flags; 88 int sc_flags;
89 struct hpibqueue sc_hq; /* HP-IB job queue entry */ 89 struct hpibqueue sc_hq; /* HP-IB job queue entry */
90 struct ppiparam sc_param; 90 struct ppiparam sc_param;
91#define sc_burst sc_param.burst 91#define sc_burst sc_param.burst
92#define sc_timo sc_param.timo 92#define sc_timo sc_param.timo
93#define sc_delay sc_param.delay 93#define sc_delay sc_param.delay
94 int sc_sec; 94 int sc_sec;
95 int sc_slave; /* HP-IB slave address */ 95 int sc_slave; /* HP-IB slave address */
96 struct callout sc_timo_ch; 96 struct callout sc_timo_ch;
97 struct callout sc_start_ch; 97 struct callout sc_start_ch;
98}; 98};
99 99
100/* sc_flags values */ 100/* sc_flags values */
101#define PPIF_ALIVE 0x01 101#define PPIF_ALIVE 0x01
102#define PPIF_OPEN 0x02 102#define PPIF_OPEN 0x02
103#define PPIF_UIO 0x04 103#define PPIF_UIO 0x04
104#define PPIF_TIMO 0x08 104#define PPIF_TIMO 0x08
105#define PPIF_DELAY 0x10 105#define PPIF_DELAY 0x10
106 106
107static int ppimatch(device_t, cfdata_t, void *); 107static int ppimatch(device_t, cfdata_t, void *);
108static void ppiattach(device_t, device_t, void *); 108static void ppiattach(device_t, device_t, void *);
109 109
110CFATTACH_DECL_NEW(ppi, sizeof(struct ppi_softc), 110CFATTACH_DECL_NEW(ppi, sizeof(struct ppi_softc),
111 ppimatch, ppiattach, NULL, NULL); 111 ppimatch, ppiattach, NULL, NULL);
112 112
113static dev_type_open(ppiopen); 113static dev_type_open(ppiopen);
114static dev_type_close(ppiclose); 114static dev_type_close(ppiclose);
115static dev_type_read(ppiread); 115static dev_type_read(ppiread);
116static dev_type_write(ppiwrite); 116static dev_type_write(ppiwrite);
117static dev_type_ioctl(ppiioctl); 117static dev_type_ioctl(ppiioctl);
118 118
119const struct cdevsw ppi_cdevsw = { 119const struct cdevsw ppi_cdevsw = {
120 ppiopen, ppiclose, ppiread, ppiwrite, ppiioctl, 120 ppiopen, ppiclose, ppiread, ppiwrite, ppiioctl,
121 nostop, notty, nopoll, nommap, nokqfilter, 121 nostop, notty, nopoll, nommap, nokqfilter,
122}; 122};
123 123
124static void ppistart(void *); 124static void ppistart(void *);
125static void ppinoop(void *); 125static void ppinoop(void *);
126 126
127static void ppitimo(void *); 127static void ppitimo(void *);
128static int ppirw(dev_t, struct uio *); 128static int ppirw(dev_t, struct uio *);
129static int ppihztoms(int); 129static int ppihztoms(int);
130static int ppimstohz(int); 130static int ppimstohz(int);
131 131
132#define UNIT(x) minor(x) 132#define UNIT(x) minor(x)
133 133
134#ifdef DEBUG 134#ifdef DEBUG
135int ppidebug = 0x80; 135int ppidebug = 0x80;
136#define PDB_FOLLOW 0x01 136#define PDB_FOLLOW 0x01
137#define PDB_IO 0x02 137#define PDB_IO 0x02
138#define PDB_NOCHECK 0x80 138#define PDB_NOCHECK 0x80
139#endif 139#endif
140 140
141static int 141static int
142ppimatch(device_t parent, cfdata_t cf, void *aux) 142ppimatch(device_t parent, cfdata_t cf, void *aux)
143{ 143{
144 struct hpibbus_attach_args *ha = aux; 144 struct hpibbus_attach_args *ha = aux;
145 145
146 /* 146 /*
147 * The printer/plotter doesn't return an ID tag. 147 * The printer/plotter doesn't return an ID tag.
148 * The check below prevents us from matching a CS80 148 * The check below prevents us from matching a CS80
149 * device by mistake. 149 * device by mistake.
150 */ 150 */
151 if (ha->ha_id & 0x200) 151 if (ha->ha_id & 0x200)
152 return 0; 152 return 0;
153 153
154 /* 154 /*
155 * To prevent matching all unused slots on the bus, we 155 * To prevent matching all unused slots on the bus, we
156 * don't allow wildcarded locators. 156 * don't allow wildcarded locators.
157 */ 157 */
158 if (cf->hpibbuscf_slave == HPIBBUSCF_SLAVE_DEFAULT || 158 if (cf->hpibbuscf_slave == HPIBBUSCF_SLAVE_DEFAULT ||
159 cf->hpibbuscf_punit == HPIBBUSCF_PUNIT_DEFAULT) 159 cf->hpibbuscf_punit == HPIBBUSCF_PUNIT_DEFAULT)
160 return 0; 160 return 0;
161 161
162 return 1; 162 return 1;
163} 163}
164 164
165static void 165static void
166ppiattach(device_t parent, device_t self, void *aux) 166ppiattach(device_t parent, device_t self, void *aux)
167{ 167{
168 struct ppi_softc *sc = device_private(self); 168 struct ppi_softc *sc = device_private(self);
169 struct hpibbus_attach_args *ha = aux; 169 struct hpibbus_attach_args *ha = aux;
170 170
171 sc->sc_dev = self; 171 sc->sc_dev = self;
172 aprint_normal("\n"); 172 aprint_normal("\n");
173 173
174 sc->sc_slave = ha->ha_slave; 174 sc->sc_slave = ha->ha_slave;
175 175
176 callout_init(&sc->sc_timo_ch, 0); 176 callout_init(&sc->sc_timo_ch, 0);
177 callout_init(&sc->sc_start_ch, 0); 177 callout_init(&sc->sc_start_ch, 0);
178 178
179 /* Initialize the hpib queue entry. */ 179 /* Initialize the hpib queue entry. */
180 sc->sc_hq.hq_softc = sc; 180 sc->sc_hq.hq_softc = sc;
181 sc->sc_hq.hq_slave = sc->sc_slave; 181 sc->sc_hq.hq_slave = sc->sc_slave;
182 sc->sc_hq.hq_start = ppistart; 182 sc->sc_hq.hq_start = ppistart;
183 sc->sc_hq.hq_go = ppinoop; 183 sc->sc_hq.hq_go = ppinoop;
184 sc->sc_hq.hq_intr = ppinoop; 184 sc->sc_hq.hq_intr = ppinoop;
185 185
186 sc->sc_flags = PPIF_ALIVE; 186 sc->sc_flags = PPIF_ALIVE;
187} 187}
188 188
189static void 189static void
190ppinoop(void *arg) 190ppinoop(void *arg)
191{ 191{
192 /* Noop! */ 192 /* Noop! */
193} 193}
194 194
195int 195int
196ppiopen(dev_t dev, int flags, int fmt, struct lwp *l) 196ppiopen(dev_t dev, int flags, int fmt, struct lwp *l)
197{ 197{
198 struct ppi_softc *sc; 198 struct ppi_softc *sc;
199 199
200 sc = device_lookup_private(&ppi_cd,UNIT(dev)); 200 sc = device_lookup_private(&ppi_cd,UNIT(dev));
201 if (sc == NULL) 201 if (sc == NULL)
202 return ENXIO; 202 return ENXIO;
203 203
204 if ((sc->sc_flags & PPIF_ALIVE) == 0) 204 if ((sc->sc_flags & PPIF_ALIVE) == 0)
205 return ENXIO; 205 return ENXIO;
206 206
207#ifdef DEBUG 207#ifdef DEBUG
208 if (ppidebug & PDB_FOLLOW) 208 if (ppidebug & PDB_FOLLOW)
209 printf("ppiopen(%x, %x): flags %x\n", 209 printf("ppiopen(%"PRIx64", %x): flags %x\n",
210 dev, flags, sc->sc_flags); 210 dev, flags, sc->sc_flags);
211#endif 211#endif
212 if (sc->sc_flags & PPIF_OPEN) 212 if (sc->sc_flags & PPIF_OPEN)
213 return EBUSY; 213 return EBUSY;
214 sc->sc_flags |= PPIF_OPEN; 214 sc->sc_flags |= PPIF_OPEN;
215 sc->sc_burst = PPI_BURST; 215 sc->sc_burst = PPI_BURST;
216 sc->sc_timo = ppimstohz(PPI_TIMO); 216 sc->sc_timo = ppimstohz(PPI_TIMO);
217 sc->sc_delay = ppimstohz(PPI_DELAY); 217 sc->sc_delay = ppimstohz(PPI_DELAY);
218 sc->sc_sec = -1; 218 sc->sc_sec = -1;
219 return 0; 219 return 0;
220} 220}
221 221
222static int 222static int
223ppiclose(dev_t dev, int flags, int fmt, struct lwp *l) 223ppiclose(dev_t dev, int flags, int fmt, struct lwp *l)
224{ 224{
225 struct ppi_softc *sc = device_lookup_private(&ppi_cd, UNIT(dev)); 225 struct ppi_softc *sc = device_lookup_private(&ppi_cd, UNIT(dev));
226 226
227#ifdef DEBUG 227#ifdef DEBUG
228 if (ppidebug & PDB_FOLLOW) 228 if (ppidebug & PDB_FOLLOW)
229 printf("ppiclose(%x, %x): flags %x\n", 229 printf("ppiclose(%"PRIx64", %x): flags %x\n",
230 dev, flags, sc->sc_flags); 230 dev, flags, sc->sc_flags);
231#endif 231#endif
232 sc->sc_flags &= ~PPIF_OPEN; 232 sc->sc_flags &= ~PPIF_OPEN;
233 return 0; 233 return 0;
234} 234}
235 235
236static void 236static void
237ppistart(void *arg) 237ppistart(void *arg)
238{ 238{
239 struct ppi_softc *sc = arg; 239 struct ppi_softc *sc = arg;
240 240
241#ifdef DEBUG 241#ifdef DEBUG
242 if (ppidebug & PDB_FOLLOW) 242 if (ppidebug & PDB_FOLLOW)
243 printf("ppistart(%x)\n", device_unit(sc->sc_dev)); 243 printf("ppistart(%x)\n", device_unit(sc->sc_dev));
244#endif 244#endif
245 sc->sc_flags &= ~PPIF_DELAY; 245 sc->sc_flags &= ~PPIF_DELAY;
246 wakeup(sc); 246 wakeup(sc);
247} 247}
248 248
249static void 249static void
250ppitimo(void *arg) 250ppitimo(void *arg)
251{ 251{
252 struct ppi_softc *sc = arg; 252 struct ppi_softc *sc = arg;
253 253
254#ifdef DEBUG 254#ifdef DEBUG
255 if (ppidebug & PDB_FOLLOW) 255 if (ppidebug & PDB_FOLLOW)
256 printf("ppitimo(%x)\n", device_unit(sc->sc_dev)); 256 printf("ppitimo(%x)\n", device_unit(sc->sc_dev));
257#endif 257#endif
258 sc->sc_flags &= ~(PPIF_UIO|PPIF_TIMO); 258 sc->sc_flags &= ~(PPIF_UIO|PPIF_TIMO);
259 wakeup(sc); 259 wakeup(sc);
260} 260}
261 261
262static int 262static int
263ppiread(dev_t dev, struct uio *uio, int flags) 263ppiread(dev_t dev, struct uio *uio, int flags)
264{ 264{
265 265
266#ifdef DEBUG 266#ifdef DEBUG
267 if (ppidebug & PDB_FOLLOW) 267 if (ppidebug & PDB_FOLLOW)
268 printf("ppiread(%x, %p)\n", dev, uio); 268 printf("ppiread(%"PRIx64", %p)\n", dev, uio);
269#endif 269#endif
270 return ppirw(dev, uio); 270 return ppirw(dev, uio);
271} 271}
272 272
273static int 273static int
274ppiwrite(dev_t dev, struct uio *uio, int flags) 274ppiwrite(dev_t dev, struct uio *uio, int flags)
275{ 275{
276 276
277#ifdef DEBUG 277#ifdef DEBUG
278 if (ppidebug & PDB_FOLLOW) 278 if (ppidebug & PDB_FOLLOW)
279 printf("ppiwrite(%x, %p)\n", dev, uio); 279 printf("ppiwrite(%"PRIx64", %p)\n", dev, uio);
280#endif 280#endif
281 return ppirw(dev, uio); 281 return ppirw(dev, uio);
282} 282}
283 283
284static int 284static int
285ppirw(dev_t dev, struct uio *uio) 285ppirw(dev_t dev, struct uio *uio)
286{ 286{
287 struct ppi_softc *sc = device_lookup_private(&ppi_cd, UNIT(dev)); 287 struct ppi_softc *sc = device_lookup_private(&ppi_cd, UNIT(dev));
288 int s, s2, len, cnt; 288 int s, s2, len, cnt;
289 char *cp; 289 char *cp;
290 int error = 0, gotdata = 0; 290 int error = 0, gotdata = 0;
291 int buflen, ctlr, slave; 291 int buflen, ctlr, slave;
292 char *buf; 292 char *buf;
293 293
294 if (uio->uio_resid == 0) 294 if (uio->uio_resid == 0)
295 return 0; 295 return 0;
296 296
297 ctlr = device_unit(device_parent(sc->sc_dev)); 297 ctlr = device_unit(device_parent(sc->sc_dev));
298 slave = sc->sc_slave; 298 slave = sc->sc_slave;
299 299
300#ifdef DEBUG 300#ifdef DEBUG
301 if (ppidebug & (PDB_FOLLOW|PDB_IO)) 301 if (ppidebug & (PDB_FOLLOW|PDB_IO))
302 printf("ppirw(%x, %p, %c): burst %d, timo %d, resid %x\n", 302 printf("ppirw(%"PRIx64", %p, %c): burst %d, timo %d, resid %x\n",
303 dev, uio, uio->uio_rw == UIO_READ ? 'R' : 'W', 303 dev, uio, uio->uio_rw == UIO_READ ? 'R' : 'W',
304 sc->sc_burst, sc->sc_timo, uio->uio_resid); 304 sc->sc_burst, sc->sc_timo, uio->uio_resid);
305#endif 305#endif
306 buflen = min(sc->sc_burst, uio->uio_resid); 306 buflen = min(sc->sc_burst, uio->uio_resid);
307 buf = (char *)malloc(buflen, M_DEVBUF, M_WAITOK); 307 buf = (char *)malloc(buflen, M_DEVBUF, M_WAITOK);
308 sc->sc_flags |= PPIF_UIO; 308 sc->sc_flags |= PPIF_UIO;
309 if (sc->sc_timo > 0) { 309 if (sc->sc_timo > 0) {
310 sc->sc_flags |= PPIF_TIMO; 310 sc->sc_flags |= PPIF_TIMO;
311 callout_reset(&sc->sc_timo_ch, sc->sc_timo, ppitimo, sc); 311 callout_reset(&sc->sc_timo_ch, sc->sc_timo, ppitimo, sc);
312 } 312 }
313 len = cnt = 0; 313 len = cnt = 0;
314 while (uio->uio_resid > 0) { 314 while (uio->uio_resid > 0) {
315 len = min(buflen, uio->uio_resid); 315 len = min(buflen, uio->uio_resid);
316 cp = buf; 316 cp = buf;
317 if (uio->uio_rw == UIO_WRITE) { 317 if (uio->uio_rw == UIO_WRITE) {
318 error = uiomove(cp, len, uio); 318 error = uiomove(cp, len, uio);
319 if (error) 319 if (error)
320 break; 320 break;
321 } 321 }
322again: 322again:
323 s = splsoftclock(); 323 s = splsoftclock();
324 s2 = splbio(); 324 s2 = splbio();
325 if ((sc->sc_flags & PPIF_UIO) && 325 if ((sc->sc_flags & PPIF_UIO) &&
326 hpibreq(device_parent(sc->sc_dev), &sc->sc_hq) == 0) 326 hpibreq(device_parent(sc->sc_dev), &sc->sc_hq) == 0)
327 (void) tsleep(sc, PRIBIO + 1, "ppirw", 0); 327 (void) tsleep(sc, PRIBIO + 1, "ppirw", 0);
328 /* 328 /*
329 * Check if we timed out during sleep or uiomove 329 * Check if we timed out during sleep or uiomove
330 */ 330 */
331 splx(s2); 331 splx(s2);
332 if ((sc->sc_flags & PPIF_UIO) == 0) { 332 if ((sc->sc_flags & PPIF_UIO) == 0) {
333#ifdef DEBUG 333#ifdef DEBUG
334 if (ppidebug & PDB_IO) 334 if (ppidebug & PDB_IO)
335 printf("ppirw: uiomove/sleep timo, flags %x\n", 335 printf("ppirw: uiomove/sleep timo, flags %x\n",
336 sc->sc_flags); 336 sc->sc_flags);
337#endif 337#endif
338 if (sc->sc_flags & PPIF_TIMO) { 338 if (sc->sc_flags & PPIF_TIMO) {
339 callout_stop(&sc->sc_timo_ch); 339 callout_stop(&sc->sc_timo_ch);
340 sc->sc_flags &= ~PPIF_TIMO; 340 sc->sc_flags &= ~PPIF_TIMO;
341 } 341 }
342 splx(s); 342 splx(s);
343 break; 343 break;
344 } 344 }
345 splx(s); 345 splx(s);
346 /* 346 /*
347 * Perform the operation 347 * Perform the operation
348 */ 348 */
349 if (uio->uio_rw == UIO_WRITE) 349 if (uio->uio_rw == UIO_WRITE)
350 cnt = hpibsend(ctlr, slave, sc->sc_sec, cp, len); 350 cnt = hpibsend(ctlr, slave, sc->sc_sec, cp, len);
351 else 351 else
352 cnt = hpibrecv(ctlr, slave, sc->sc_sec, cp, len); 352 cnt = hpibrecv(ctlr, slave, sc->sc_sec, cp, len);
353 s = splbio(); 353 s = splbio();
354 hpibfree(device_parent(sc->sc_dev), &sc->sc_hq); 354 hpibfree(device_parent(sc->sc_dev), &sc->sc_hq);
355#ifdef DEBUG 355#ifdef DEBUG
356 if (ppidebug & PDB_IO) 356 if (ppidebug & PDB_IO)
357 printf("ppirw: %s(%d, %d, %x, %p, %d) -> %d\n", 357 printf("ppirw: %s(%d, %d, %x, %p, %d) -> %d\n",
358 uio->uio_rw == UIO_READ ? "recv" : "send", 358 uio->uio_rw == UIO_READ ? "recv" : "send",
359 ctlr, slave, sc->sc_sec, cp, len, cnt); 359 ctlr, slave, sc->sc_sec, cp, len, cnt);
360#endif 360#endif
361 splx(s); 361 splx(s);
362 if (uio->uio_rw == UIO_READ) { 362 if (uio->uio_rw == UIO_READ) {
363 if (cnt) { 363 if (cnt) {
364 error = uiomove(cp, cnt, uio); 364 error = uiomove(cp, cnt, uio);
365 if (error) 365 if (error)
366 break; 366 break;
367 gotdata++; 367 gotdata++;
368 } 368 }
369 /* 369 /*
370 * Didn't get anything this time, but did in the past. 370 * Didn't get anything this time, but did in the past.
371 * Consider us done. 371 * Consider us done.
372 */ 372 */
373 else if (gotdata) 373 else if (gotdata)
374 break; 374 break;
375 } 375 }
376 s = splsoftclock(); 376 s = splsoftclock();
377 /* 377 /*
378 * Operation timeout (or non-blocking), quit now. 378 * Operation timeout (or non-blocking), quit now.
379 */ 379 */
380 if ((sc->sc_flags & PPIF_UIO) == 0) { 380 if ((sc->sc_flags & PPIF_UIO) == 0) {
381#ifdef DEBUG 381#ifdef DEBUG
382 if (ppidebug & PDB_IO) 382 if (ppidebug & PDB_IO)
383 printf("ppirw: timeout/done\n"); 383 printf("ppirw: timeout/done\n");
384#endif 384#endif
385 splx(s); 385 splx(s);
386 break; 386 break;
387 } 387 }
388 /* 388 /*
389 * Implement inter-read delay 389 * Implement inter-read delay
390 */ 390 */
391 if (sc->sc_delay > 0) { 391 if (sc->sc_delay > 0) {
392 sc->sc_flags |= PPIF_DELAY; 392 sc->sc_flags |= PPIF_DELAY;
393 callout_reset(&sc->sc_start_ch, sc->sc_delay, 393 callout_reset(&sc->sc_start_ch, sc->sc_delay,
394 ppistart, sc); 394 ppistart, sc);
395 error = tsleep(sc, (PCATCH|PZERO) + 1, "hpib", 0); 395 error = tsleep(sc, (PCATCH|PZERO) + 1, "hpib", 0);
396 if (error) { 396 if (error) {
397 splx(s); 397 splx(s);
398 break; 398 break;
399 } 399 }
400 } 400 }
401 splx(s); 401 splx(s);
402 /* 402 /*
403 * Must not call uiomove again til we've used all data 403 * Must not call uiomove again til we've used all data
404 * that we already grabbed. 404 * that we already grabbed.
405 */ 405 */
406 if (uio->uio_rw == UIO_WRITE && cnt != len) { 406 if (uio->uio_rw == UIO_WRITE && cnt != len) {
407 cp += cnt; 407 cp += cnt;
408 len -= cnt; 408 len -= cnt;
409 cnt = 0; 409 cnt = 0;
410 goto again; 410 goto again;
411 } 411 }
412 } 412 }
413 s = splsoftclock(); 413 s = splsoftclock();
414 if (sc->sc_flags & PPIF_TIMO) { 414 if (sc->sc_flags & PPIF_TIMO) {
415 callout_stop(&sc->sc_timo_ch); 415 callout_stop(&sc->sc_timo_ch);
416 sc->sc_flags &= ~PPIF_TIMO; 416 sc->sc_flags &= ~PPIF_TIMO;
417 } 417 }
418 if (sc->sc_flags & PPIF_DELAY) { 418 if (sc->sc_flags & PPIF_DELAY) {
419 callout_stop(&sc->sc_start_ch); 419 callout_stop(&sc->sc_start_ch);
420 sc->sc_flags &= ~PPIF_DELAY; 420 sc->sc_flags &= ~PPIF_DELAY;
421 } 421 }
422 splx(s); 422 splx(s);
423 /* 423 /*
424 * Adjust for those chars that we uiomove'ed but never wrote 424 * Adjust for those chars that we uiomove'ed but never wrote
425 */ 425 */
426 if (uio->uio_rw == UIO_WRITE && cnt != len) { 426 if (uio->uio_rw == UIO_WRITE && cnt != len) {
427 uio->uio_resid += (len - cnt); 427 uio->uio_resid += (len - cnt);
428#ifdef DEBUG 428#ifdef DEBUG
429 if (ppidebug & PDB_IO) 429 if (ppidebug & PDB_IO)
430 printf("ppirw: short write, adjust by %d\n", 430 printf("ppirw: short write, adjust by %d\n",
431 len-cnt); 431 len-cnt);
432#endif 432#endif
433 } 433 }
434 free(buf, M_DEVBUF); 434 free(buf, M_DEVBUF);
435#ifdef DEBUG 435#ifdef DEBUG
436 if (ppidebug & (PDB_FOLLOW|PDB_IO)) 436 if (ppidebug & (PDB_FOLLOW|PDB_IO))
437 printf("ppirw: return %d, resid %d\n", error, uio->uio_resid); 437 printf("ppirw: return %d, resid %d\n", error, uio->uio_resid);
438#endif 438#endif
439 return error; 439 return error;
440} 440}
441 441
442static int 442static int
443ppiioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 443ppiioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
444{ 444{
445 struct ppi_softc *sc = device_lookup_private(&ppi_cd,UNIT(dev)); 445 struct ppi_softc *sc = device_lookup_private(&ppi_cd,UNIT(dev));
446 struct ppiparam *pp, *upp; 446 struct ppiparam *pp, *upp;
447 int error = 0; 447 int error = 0;
448 448
449 switch (cmd) { 449 switch (cmd) {
450 case PPIIOCGPARAM: 450 case PPIIOCGPARAM:
451 pp = &sc->sc_param; 451 pp = &sc->sc_param;
452 upp = (struct ppiparam *)data; 452 upp = (struct ppiparam *)data;
453 upp->burst = pp->burst; 453 upp->burst = pp->burst;
454 upp->timo = ppihztoms(pp->timo); 454 upp->timo = ppihztoms(pp->timo);
455 upp->delay = ppihztoms(pp->delay); 455 upp->delay = ppihztoms(pp->delay);
456 break; 456 break;
457 case PPIIOCSPARAM: 457 case PPIIOCSPARAM:
458 pp = &sc->sc_param; 458 pp = &sc->sc_param;
459 upp = (struct ppiparam *)data; 459 upp = (struct ppiparam *)data;
460 if (upp->burst < PPI_BURST_MIN || upp->burst > PPI_BURST_MAX || 460 if (upp->burst < PPI_BURST_MIN || upp->burst > PPI_BURST_MAX ||
461 upp->delay < PPI_DELAY_MIN || upp->delay > PPI_DELAY_MAX) 461 upp->delay < PPI_DELAY_MIN || upp->delay > PPI_DELAY_MAX)
462 return EINVAL; 462 return EINVAL;
463 pp->burst = upp->burst; 463 pp->burst = upp->burst;
464 pp->timo = ppimstohz(upp->timo); 464 pp->timo = ppimstohz(upp->timo);
465 pp->delay = ppimstohz(upp->delay); 465 pp->delay = ppimstohz(upp->delay);
466 break; 466 break;
467 case PPIIOCSSEC: 467 case PPIIOCSSEC:
468 sc->sc_sec = *(int *)data; 468 sc->sc_sec = *(int *)data;
469 break; 469 break;
470 default: 470 default:
471 return EINVAL; 471 return EINVAL;
472 } 472 }
473 return error; 473 return error;
474} 474}
475 475
476static int 476static int
477ppihztoms(int h) 477ppihztoms(int h)
478{ 478{
479 extern int hz; 479 extern int hz;
480 int m = h; 480 int m = h;
481 481
482 if (m > 0) 482 if (m > 0)
483 m = m * 1000 / hz; 483 m = m * 1000 / hz;
484 return m; 484 return m;
485} 485}
486 486
487static int 487static int
488ppimstohz(int m) 488ppimstohz(int m)
489{ 489{
490 extern int hz; 490 extern int hz;
491 int h = m; 491 int h = m;
492 492
493 if (h > 0) { 493 if (h > 0) {
494 h = h * hz / 1000; 494 h = h * hz / 1000;
495 if (h == 0) 495 if (h == 0)
496 h = 1000 / hz; 496 h = 1000 / hz;
497 } 497 }
498 return h; 498 return h;
499} 499}

cvs diff -r1.90 -r1.91 src/sys/arch/hp300/dev/rd.c (switch to unified diff)

--- src/sys/arch/hp300/dev/rd.c 2011/02/08 20:20:13 1.90
+++ src/sys/arch/hp300/dev/rd.c 2011/07/28 03:42:20 1.91
@@ -1,1340 +1,1340 @@ @@ -1,1340 +1,1340 @@
1/* $NetBSD: rd.c,v 1.90 2011/02/08 20:20:13 rmind Exp $ */ 1/* $NetBSD: rd.c,v 1.91 2011/07/28 03:42:20 uebayasi Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997 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 Jason R. Thorpe. 8 * by Jason R. Thorpe.
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/* 32/*
33 * Copyright (c) 1988 University of Utah. 33 * Copyright (c) 1988 University of Utah.
34 * Copyright (c) 1982, 1990, 1993 34 * Copyright (c) 1982, 1990, 1993
35 * The Regents of the University of California. All rights reserved. 35 * The Regents of the University of California. All rights reserved.
36 * 36 *
37 * This code is derived from software contributed to Berkeley by 37 * This code is derived from software contributed to Berkeley by
38 * the Systems Programming Group of the University of Utah Computer 38 * the Systems Programming Group of the University of Utah Computer
39 * Science Department. 39 * Science Department.
40 * 40 *
41 * Redistribution and use in source and binary forms, with or without 41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions 42 * modification, are permitted provided that the following conditions
43 * are met: 43 * are met:
44 * 1. Redistributions of source code must retain the above copyright 44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer. 45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright 46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the 47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution. 48 * documentation and/or other materials provided with the distribution.
49 * 3. Neither the name of the University nor the names of its contributors 49 * 3. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software 50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission. 51 * without specific prior written permission.
52 * 52 *
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * from: Utah $Hdr: rd.c 1.44 92/12/26$ 65 * from: Utah $Hdr: rd.c 1.44 92/12/26$
66 * 66 *
67 * @(#)rd.c 8.2 (Berkeley) 5/19/94 67 * @(#)rd.c 8.2 (Berkeley) 5/19/94
68 */ 68 */
69 69
70/* 70/*
71 * CS80/SS80 disk driver 71 * CS80/SS80 disk driver
72 */ 72 */
73 73
74#include <sys/cdefs.h> 74#include <sys/cdefs.h>
75__KERNEL_RCSID(0, "$NetBSD: rd.c,v 1.90 2011/02/08 20:20:13 rmind Exp $"); 75__KERNEL_RCSID(0, "$NetBSD: rd.c,v 1.91 2011/07/28 03:42:20 uebayasi Exp $");
76 76
77#include "opt_useleds.h" 77#include "opt_useleds.h"
78#include "rnd.h" 78#include "rnd.h"
79 79
80#include <sys/param.h> 80#include <sys/param.h>
81#include <sys/systm.h> 81#include <sys/systm.h>
82#include <sys/buf.h> 82#include <sys/buf.h>
83#include <sys/bufq.h> 83#include <sys/bufq.h>
84#include <sys/conf.h> 84#include <sys/conf.h>
85#include <sys/device.h> 85#include <sys/device.h>
86#include <sys/disk.h> 86#include <sys/disk.h>
87#include <sys/disklabel.h> 87#include <sys/disklabel.h>
88#include <sys/fcntl.h> 88#include <sys/fcntl.h>
89#include <sys/ioctl.h> 89#include <sys/ioctl.h>
90#include <sys/proc.h> 90#include <sys/proc.h>
91#include <sys/stat.h> 91#include <sys/stat.h>
92 92
93#if NRND > 0 93#if NRND > 0
94#include <sys/rnd.h> 94#include <sys/rnd.h>
95#endif 95#endif
96 96
97#include <hp300/dev/hpibvar.h> 97#include <hp300/dev/hpibvar.h>
98 98
99#include <hp300/dev/rdreg.h> 99#include <hp300/dev/rdreg.h>
100#include <hp300/dev/rdvar.h> 100#include <hp300/dev/rdvar.h>
101 101
102#ifdef USELEDS 102#ifdef USELEDS
103#include <hp300/hp300/leds.h> 103#include <hp300/hp300/leds.h>
104#endif 104#endif
105 105
106#include "ioconf.h" 106#include "ioconf.h"
107 107
108int rderrthresh = RDRETRY-1; /* when to start reporting errors */ 108int rderrthresh = RDRETRY-1; /* when to start reporting errors */
109 109
110#ifdef DEBUG 110#ifdef DEBUG
111/* error message tables */ 111/* error message tables */
112static const char *err_reject[] = { 112static const char *err_reject[] = {
113 0, 0, 113 0, 0,
114 "channel parity error", /* 0x2000 */ 114 "channel parity error", /* 0x2000 */
115 0, 0, 115 0, 0,
116 "illegal opcode", /* 0x0400 */ 116 "illegal opcode", /* 0x0400 */
117 "module addressing", /* 0x0200 */ 117 "module addressing", /* 0x0200 */
118 "address bounds", /* 0x0100 */ 118 "address bounds", /* 0x0100 */
119 "parameter bounds", /* 0x0080 */ 119 "parameter bounds", /* 0x0080 */
120 "illegal parameter", /* 0x0040 */ 120 "illegal parameter", /* 0x0040 */
121 "message sequence", /* 0x0020 */ 121 "message sequence", /* 0x0020 */
122 0, 122 0,
123 "message length", /* 0x0008 */ 123 "message length", /* 0x0008 */
124 0, 0, 0 124 0, 0, 0
125}; 125};
126 126
127static const char *err_fault[] = { 127static const char *err_fault[] = {
128 0, 128 0,
129 "cross unit", /* 0x4000 */ 129 "cross unit", /* 0x4000 */
130 0, 130 0,
131 "controller fault", /* 0x1000 */ 131 "controller fault", /* 0x1000 */
132 0, 0, 132 0, 0,
133 "unit fault", /* 0x0200 */ 133 "unit fault", /* 0x0200 */
134 0, 134 0,
135 "diagnostic result", /* 0x0080 */ 135 "diagnostic result", /* 0x0080 */
136 0, 136 0,
137 "operator release request", /* 0x0020 */ 137 "operator release request", /* 0x0020 */
138 "diagnostic release request", /* 0x0010 */ 138 "diagnostic release request", /* 0x0010 */
139 "internal maintenance release request", /* 0x0008 */ 139 "internal maintenance release request", /* 0x0008 */
140 0, 140 0,
141 "power fail", /* 0x0002 */ 141 "power fail", /* 0x0002 */
142 "retransmit" /* 0x0001 */ 142 "retransmit" /* 0x0001 */
143}; 143};
144 144
145static const char *err_access[] = { 145static const char *err_access[] = {
146 "illegal parallel operation", /* 0x8000 */ 146 "illegal parallel operation", /* 0x8000 */
147 "uninitialized media", /* 0x4000 */ 147 "uninitialized media", /* 0x4000 */
148 "no spares available", /* 0x2000 */ 148 "no spares available", /* 0x2000 */
149 "not ready", /* 0x1000 */ 149 "not ready", /* 0x1000 */
150 "write protect", /* 0x0800 */ 150 "write protect", /* 0x0800 */
151 "no data found", /* 0x0400 */ 151 "no data found", /* 0x0400 */
152 0, 0, 152 0, 0,
153 "unrecoverable data overflow", /* 0x0080 */ 153 "unrecoverable data overflow", /* 0x0080 */
154 "unrecoverable data", /* 0x0040 */ 154 "unrecoverable data", /* 0x0040 */
155 0, 155 0,
156 "end of file", /* 0x0010 */ 156 "end of file", /* 0x0010 */
157 "end of volume", /* 0x0008 */ 157 "end of volume", /* 0x0008 */
158 0, 0, 0 158 0, 0, 0
159}; 159};
160 160
161static const char *err_info[] = { 161static const char *err_info[] = {
162 "operator release request", /* 0x8000 */ 162 "operator release request", /* 0x8000 */
163 "diagnostic release request", /* 0x4000 */ 163 "diagnostic release request", /* 0x4000 */
164 "internal maintenance release request", /* 0x2000 */ 164 "internal maintenance release request", /* 0x2000 */
165 "media wear", /* 0x1000 */ 165 "media wear", /* 0x1000 */
166 "latency induced", /* 0x0800 */ 166 "latency induced", /* 0x0800 */
167 0, 0, 167 0, 0,
168 "auto sparing invoked", /* 0x0100 */ 168 "auto sparing invoked", /* 0x0100 */
169 0, 169 0,
170 "recoverable data overflow", /* 0x0040 */ 170 "recoverable data overflow", /* 0x0040 */
171 "marginal data", /* 0x0020 */ 171 "marginal data", /* 0x0020 */
172 "recoverable data", /* 0x0010 */ 172 "recoverable data", /* 0x0010 */
173 0, 173 0,
174 "maintenance track overflow", /* 0x0004 */ 174 "maintenance track overflow", /* 0x0004 */
175 0, 0 175 0, 0
176}; 176};
177 177
178int rddebug = 0x80; 178int rddebug = 0x80;
179#define RDB_FOLLOW 0x01 179#define RDB_FOLLOW 0x01
180#define RDB_STATUS 0x02 180#define RDB_STATUS 0x02
181#define RDB_IDENT 0x04 181#define RDB_IDENT 0x04
182#define RDB_IO 0x08 182#define RDB_IO 0x08
183#define RDB_ASYNC 0x10 183#define RDB_ASYNC 0x10
184#define RDB_ERROR 0x80 184#define RDB_ERROR 0x80
185#endif 185#endif
186 186
187/* 187/*
188 * Misc. HW description, indexed by sc_type. 188 * Misc. HW description, indexed by sc_type.
189 * Nothing really critical here, could do without it. 189 * Nothing really critical here, could do without it.
190 */ 190 */
191static const struct rdidentinfo rdidentinfo[] = { 191static const struct rdidentinfo rdidentinfo[] = {
192 { RD7946AID, 0, "7945A", NRD7945ABPT, 192 { RD7946AID, 0, "7945A", NRD7945ABPT,
193 NRD7945ATRK, 968, 108416 }, 193 NRD7945ATRK, 968, 108416 },
194 194
195 { RD9134DID, 1, "9134D", NRD9134DBPT, 195 { RD9134DID, 1, "9134D", NRD9134DBPT,
196 NRD9134DTRK, 303, 29088 }, 196 NRD9134DTRK, 303, 29088 },
197 197
198 { RD9134LID, 1, "9122S", NRD9122SBPT, 198 { RD9134LID, 1, "9122S", NRD9122SBPT,
199 NRD9122STRK, 77, 1232 }, 199 NRD9122STRK, 77, 1232 },
200 200
201 { RD7912PID, 0, "7912P", NRD7912PBPT, 201 { RD7912PID, 0, "7912P", NRD7912PBPT,
202 NRD7912PTRK, 572, 128128 }, 202 NRD7912PTRK, 572, 128128 },
203 203
204 { RD7914PID, 0, "7914P", NRD7914PBPT, 204 { RD7914PID, 0, "7914P", NRD7914PBPT,
205 NRD7914PTRK, 1152, 258048 }, 205 NRD7914PTRK, 1152, 258048 },
206 206
207 { RD7958AID, 0, "7958A", NRD7958ABPT, 207 { RD7958AID, 0, "7958A", NRD7958ABPT,
208 NRD7958ATRK, 1013, 255276 }, 208 NRD7958ATRK, 1013, 255276 },
209 209
210 { RD7957AID, 0, "7957A", NRD7957ABPT, 210 { RD7957AID, 0, "7957A", NRD7957ABPT,
211 NRD7957ATRK, 1036, 159544 }, 211 NRD7957ATRK, 1036, 159544 },
212 212
213 { RD7933HID, 0, "7933H", NRD7933HBPT, 213 { RD7933HID, 0, "7933H", NRD7933HBPT,
214 NRD7933HTRK, 1321, 789958 }, 214 NRD7933HTRK, 1321, 789958 },
215 215
216 { RD9134LID, 1, "9134L", NRD9134LBPT, 216 { RD9134LID, 1, "9134L", NRD9134LBPT,
217 NRD9134LTRK, 973, 77840 }, 217 NRD9134LTRK, 973, 77840 },
218 218
219 { RD7936HID, 0, "7936H", NRD7936HBPT, 219 { RD7936HID, 0, "7936H", NRD7936HBPT,
220 NRD7936HTRK, 698, 600978 }, 220 NRD7936HTRK, 698, 600978 },
221 221
222 { RD7937HID, 0, "7937H", NRD7937HBPT, 222 { RD7937HID, 0, "7937H", NRD7937HBPT,
223 NRD7937HTRK, 698, 1116102 }, 223 NRD7937HTRK, 698, 1116102 },
224 224
225 { RD7914CTID, 0, "7914CT", NRD7914PBPT, 225 { RD7914CTID, 0, "7914CT", NRD7914PBPT,
226 NRD7914PTRK, 1152, 258048 }, 226 NRD7914PTRK, 1152, 258048 },
227 227
228 { RD7946AID, 0, "7946A", NRD7945ABPT, 228 { RD7946AID, 0, "7946A", NRD7945ABPT,
229 NRD7945ATRK, 968, 108416 }, 229 NRD7945ATRK, 968, 108416 },
230 230
231 { RD9134LID, 1, "9122D", NRD9122SBPT, 231 { RD9134LID, 1, "9122D", NRD9122SBPT,
232 NRD9122STRK, 77, 1232 }, 232 NRD9122STRK, 77, 1232 },
233 233
234 { RD7957BID, 0, "7957B", NRD7957BBPT, 234 { RD7957BID, 0, "7957B", NRD7957BBPT,
235 NRD7957BTRK, 1269, 159894 }, 235 NRD7957BTRK, 1269, 159894 },
236 236
237 { RD7958BID, 0, "7958B", NRD7958BBPT, 237 { RD7958BID, 0, "7958B", NRD7958BBPT,
238 NRD7958BTRK, 786, 297108 }, 238 NRD7958BTRK, 786, 297108 },
239 239
240 { RD7959BID, 0, "7959B", NRD7959BBPT, 240 { RD7959BID, 0, "7959B", NRD7959BBPT,
241 NRD7959BTRK, 1572, 594216 }, 241 NRD7959BTRK, 1572, 594216 },
242 242
243 { RD2200AID, 0, "2200A", NRD2200ABPT, 243 { RD2200AID, 0, "2200A", NRD2200ABPT,
244 NRD2200ATRK, 1449, 654948 }, 244 NRD2200ATRK, 1449, 654948 },
245 245
246 { RD2203AID, 0, "2203A", NRD2203ABPT, 246 { RD2203AID, 0, "2203A", NRD2203ABPT,
247 NRD2203ATRK, 1449, 1309896 } 247 NRD2203ATRK, 1449, 1309896 }
248}; 248};
249static const int numrdidentinfo = __arraycount(rdidentinfo); 249static const int numrdidentinfo = __arraycount(rdidentinfo);
250 250
251static int rdident(struct device *, struct rd_softc *, 251static int rdident(struct device *, struct rd_softc *,
252 struct hpibbus_attach_args *); 252 struct hpibbus_attach_args *);
253static void rdreset(struct rd_softc *); 253static void rdreset(struct rd_softc *);
254static void rdustart(struct rd_softc *); 254static void rdustart(struct rd_softc *);
255static int rdgetinfo(dev_t); 255static int rdgetinfo(dev_t);
256static void rdrestart(void *); 256static void rdrestart(void *);
257static struct buf *rdfinish(struct rd_softc *, struct buf *); 257static struct buf *rdfinish(struct rd_softc *, struct buf *);
258 258
259static void rdgetdefaultlabel(struct rd_softc *, struct disklabel *); 259static void rdgetdefaultlabel(struct rd_softc *, struct disklabel *);
260static void rdrestart(void *); 260static void rdrestart(void *);
261static void rdustart(struct rd_softc *); 261static void rdustart(struct rd_softc *);
262static struct buf *rdfinish(struct rd_softc *, struct buf *); 262static struct buf *rdfinish(struct rd_softc *, struct buf *);
263static void rdstart(void *); 263static void rdstart(void *);
264static void rdgo(void *); 264static void rdgo(void *);
265static void rdintr(void *); 265static void rdintr(void *);
266static int rdstatus(struct rd_softc *); 266static int rdstatus(struct rd_softc *);
267static int rderror(int); 267static int rderror(int);
268#ifdef DEBUG 268#ifdef DEBUG
269static void rdprinterr(const char *, short, const char **); 269static void rdprinterr(const char *, short, const char **);
270#endif 270#endif
271 271
272static int rdmatch(device_t, cfdata_t, void *); 272static int rdmatch(device_t, cfdata_t, void *);
273static void rdattach(device_t, device_t, void *); 273static void rdattach(device_t, device_t, void *);
274 274
275CFATTACH_DECL_NEW(rd, sizeof(struct rd_softc), 275CFATTACH_DECL_NEW(rd, sizeof(struct rd_softc),
276 rdmatch, rdattach, NULL, NULL); 276 rdmatch, rdattach, NULL, NULL);
277 277
278static dev_type_open(rdopen); 278static dev_type_open(rdopen);
279static dev_type_close(rdclose); 279static dev_type_close(rdclose);
280static dev_type_read(rdread); 280static dev_type_read(rdread);
281static dev_type_write(rdwrite); 281static dev_type_write(rdwrite);
282static dev_type_ioctl(rdioctl); 282static dev_type_ioctl(rdioctl);
283static dev_type_strategy(rdstrategy); 283static dev_type_strategy(rdstrategy);
284static dev_type_dump(rddump); 284static dev_type_dump(rddump);
285static dev_type_size(rdsize); 285static dev_type_size(rdsize);
286 286
287const struct bdevsw rd_bdevsw = { 287const struct bdevsw rd_bdevsw = {
288 rdopen, rdclose, rdstrategy, rdioctl, rddump, rdsize, D_DISK 288 rdopen, rdclose, rdstrategy, rdioctl, rddump, rdsize, D_DISK
289}; 289};
290 290
291const struct cdevsw rd_cdevsw = { 291const struct cdevsw rd_cdevsw = {
292 rdopen, rdclose, rdread, rdwrite, rdioctl, 292 rdopen, rdclose, rdread, rdwrite, rdioctl,
293 nostop, notty, nopoll, nommap, nokqfilter, D_DISK 293 nostop, notty, nopoll, nommap, nokqfilter, D_DISK
294}; 294};
295 295
296static int 296static int
297rdmatch(device_t parent, cfdata_t cf, void *aux) 297rdmatch(device_t parent, cfdata_t cf, void *aux)
298{ 298{
299 struct hpibbus_attach_args *ha = aux; 299 struct hpibbus_attach_args *ha = aux;
300 300
301 /* 301 /*
302 * Set punit if operator specified one in the kernel 302 * Set punit if operator specified one in the kernel
303 * configuration file. 303 * configuration file.
304 */ 304 */
305 if (cf->hpibbuscf_punit != HPIBBUSCF_PUNIT_DEFAULT && 305 if (cf->hpibbuscf_punit != HPIBBUSCF_PUNIT_DEFAULT &&
306 cf->hpibbuscf_punit < HPIB_NPUNITS) 306 cf->hpibbuscf_punit < HPIB_NPUNITS)
307 ha->ha_punit = cf->hpibbuscf_punit; 307 ha->ha_punit = cf->hpibbuscf_punit;
308 308
309 if (rdident(parent, NULL, ha) == 0) { 309 if (rdident(parent, NULL, ha) == 0) {
310 /* 310 /*
311 * XXX Some aging HP-IB drives are slow to 311 * XXX Some aging HP-IB drives are slow to
312 * XXX respond; give them a chance to catch 312 * XXX respond; give them a chance to catch
313 * XXX up and probe them again. 313 * XXX up and probe them again.
314 */ 314 */
315 delay(10000); 315 delay(10000);
316 ha->ha_id = hpibid(device_unit(parent), ha->ha_slave); 316 ha->ha_id = hpibid(device_unit(parent), ha->ha_slave);
317 return rdident(parent, NULL, ha); 317 return rdident(parent, NULL, ha);
318 } 318 }
319 return 1; 319 return 1;
320} 320}
321 321
322static void 322static void
323rdattach(device_t parent, device_t self, void *aux) 323rdattach(device_t parent, device_t self, void *aux)
324{ 324{
325 struct rd_softc *sc = device_private(self); 325 struct rd_softc *sc = device_private(self);
326 struct hpibbus_attach_args *ha = aux; 326 struct hpibbus_attach_args *ha = aux;
327 327
328 sc->sc_dev = self; 328 sc->sc_dev = self;
329 bufq_alloc(&sc->sc_tab, "disksort", BUFQ_SORT_RAWBLOCK); 329 bufq_alloc(&sc->sc_tab, "disksort", BUFQ_SORT_RAWBLOCK);
330 330
331 if (rdident(parent, sc, ha) == 0) { 331 if (rdident(parent, sc, ha) == 0) {
332 aprint_error(": didn't respond to describe command!\n"); 332 aprint_error(": didn't respond to describe command!\n");
333 return; 333 return;
334 } 334 }
335 335
336 /* 336 /*
337 * Initialize and attach the disk structure. 337 * Initialize and attach the disk structure.
338 */ 338 */
339 memset(&sc->sc_dkdev, 0, sizeof(sc->sc_dkdev)); 339 memset(&sc->sc_dkdev, 0, sizeof(sc->sc_dkdev));
340 disk_init(&sc->sc_dkdev, device_xname(sc->sc_dev), NULL); 340 disk_init(&sc->sc_dkdev, device_xname(sc->sc_dev), NULL);
341 disk_attach(&sc->sc_dkdev); 341 disk_attach(&sc->sc_dkdev);
342 342
343 sc->sc_slave = ha->ha_slave; 343 sc->sc_slave = ha->ha_slave;
344 sc->sc_punit = ha->ha_punit; 344 sc->sc_punit = ha->ha_punit;
345 345
346 callout_init(&sc->sc_restart_ch, 0); 346 callout_init(&sc->sc_restart_ch, 0);
347 347
348 /* Initialize the hpib job queue entry */ 348 /* Initialize the hpib job queue entry */
349 sc->sc_hq.hq_softc = sc; 349 sc->sc_hq.hq_softc = sc;
350 sc->sc_hq.hq_slave = sc->sc_slave; 350 sc->sc_hq.hq_slave = sc->sc_slave;
351 sc->sc_hq.hq_start = rdstart; 351 sc->sc_hq.hq_start = rdstart;
352 sc->sc_hq.hq_go = rdgo; 352 sc->sc_hq.hq_go = rdgo;
353 sc->sc_hq.hq_intr = rdintr; 353 sc->sc_hq.hq_intr = rdintr;
354 354
355 sc->sc_flags = RDF_ALIVE; 355 sc->sc_flags = RDF_ALIVE;
356#ifdef DEBUG 356#ifdef DEBUG
357 /* always report errors */ 357 /* always report errors */
358 if (rddebug & RDB_ERROR) 358 if (rddebug & RDB_ERROR)
359 rderrthresh = 0; 359 rderrthresh = 0;
360#endif 360#endif
361#if NRND > 0 361#if NRND > 0
362 /* 362 /*
363 * attach the device into the random source list 363 * attach the device into the random source list
364 */ 364 */
365 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 365 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
366 RND_TYPE_DISK, 0); 366 RND_TYPE_DISK, 0);
367#endif 367#endif
368} 368}
369 369
370static int 370static int
371rdident(device_t parent, struct rd_softc *sc, struct hpibbus_attach_args *ha) 371rdident(device_t parent, struct rd_softc *sc, struct hpibbus_attach_args *ha)
372{ 372{
373 struct rd_describe *desc = sc != NULL ? &sc->sc_rddesc : NULL; 373 struct rd_describe *desc = sc != NULL ? &sc->sc_rddesc : NULL;
374 u_char stat, cmd[3]; 374 u_char stat, cmd[3];
375 char name[7]; 375 char name[7];
376 int i, id, n, ctlr, slave; 376 int i, id, n, ctlr, slave;
377 377
378 ctlr = device_unit(parent); 378 ctlr = device_unit(parent);
379 slave = ha->ha_slave; 379 slave = ha->ha_slave;
380 380
381 /* Verify that we have a CS80 device. */ 381 /* Verify that we have a CS80 device. */
382 if ((ha->ha_id & 0x200) == 0) 382 if ((ha->ha_id & 0x200) == 0)
383 return 0; 383 return 0;
384 384
385 /* Is it one of the disks we support? */ 385 /* Is it one of the disks we support? */
386 for (id = 0; id < numrdidentinfo; id++) 386 for (id = 0; id < numrdidentinfo; id++)
387 if (ha->ha_id == rdidentinfo[id].ri_hwid) 387 if (ha->ha_id == rdidentinfo[id].ri_hwid)
388 break; 388 break;
389 if (id == numrdidentinfo || ha->ha_punit > rdidentinfo[id].ri_maxunum) 389 if (id == numrdidentinfo || ha->ha_punit > rdidentinfo[id].ri_maxunum)
390 return 0; 390 return 0;
391 391
392 /* 392 /*
393 * If we're just probing for the device, that's all the 393 * If we're just probing for the device, that's all the
394 * work we need to do. 394 * work we need to do.
395 */ 395 */
396 if (sc == NULL) 396 if (sc == NULL)
397 return 1; 397 return 1;
398 398
399 /* 399 /*
400 * Reset device and collect description 400 * Reset device and collect description
401 */ 401 */
402 rdreset(sc); 402 rdreset(sc);
403 cmd[0] = C_SUNIT(ha->ha_punit); 403 cmd[0] = C_SUNIT(ha->ha_punit);
404 cmd[1] = C_SVOL(0); 404 cmd[1] = C_SVOL(0);
405 cmd[2] = C_DESC; 405 cmd[2] = C_DESC;
406 hpibsend(ctlr, slave, C_CMD, cmd, sizeof(cmd)); 406 hpibsend(ctlr, slave, C_CMD, cmd, sizeof(cmd));
407 hpibrecv(ctlr, slave, C_EXEC, desc, 37); 407 hpibrecv(ctlr, slave, C_EXEC, desc, 37);
408 hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); 408 hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat));
409 memset(name, 0, sizeof(name)); 409 memset(name, 0, sizeof(name));
410 if (stat == 0) { 410 if (stat == 0) {
411 n = desc->d_name; 411 n = desc->d_name;
412 for (i = 5; i >= 0; i--) { 412 for (i = 5; i >= 0; i--) {
413 name[i] = (n & 0xf) + '0'; 413 name[i] = (n & 0xf) + '0';
414 n >>= 4; 414 n >>= 4;
415 } 415 }
416 } 416 }
417 417
418#ifdef DEBUG 418#ifdef DEBUG
419 if (rddebug & RDB_IDENT) { 419 if (rddebug & RDB_IDENT) {
420 aprint_debug("\n"); 420 aprint_debug("\n");
421 aprint_debug_dev(sc->sc_dev, "name: %x ('%s')\n", 421 aprint_debug_dev(sc->sc_dev, "name: %x ('%s')\n",
422 desc->d_name, name); 422 desc->d_name, name);
423 aprint_debug(" iuw %x, maxxfr %d, ctype %d\n", 423 aprint_debug(" iuw %x, maxxfr %d, ctype %d\n",
424 desc->d_iuw, desc->d_cmaxxfr, desc->d_ctype); 424 desc->d_iuw, desc->d_cmaxxfr, desc->d_ctype);
425 aprint_debug(" utype %d, bps %d, blkbuf %d, burst %d," 425 aprint_debug(" utype %d, bps %d, blkbuf %d, burst %d,"
426 " blktime %d\n", 426 " blktime %d\n",
427 desc->d_utype, desc->d_sectsize, 427 desc->d_utype, desc->d_sectsize,
428 desc->d_blkbuf, desc->d_burstsize, desc->d_blocktime); 428 desc->d_blkbuf, desc->d_burstsize, desc->d_blocktime);
429 aprint_debug(" avxfr %d, ort %d, atp %d, maxint %d, fv %x" 429 aprint_debug(" avxfr %d, ort %d, atp %d, maxint %d, fv %x"
430 ", rv %x\n", 430 ", rv %x\n",
431 desc->d_uavexfr, desc->d_retry, desc->d_access, 431 desc->d_uavexfr, desc->d_retry, desc->d_access,
432 desc->d_maxint, desc->d_fvbyte, desc->d_rvbyte); 432 desc->d_maxint, desc->d_fvbyte, desc->d_rvbyte);
433 aprint_debug(" maxcyl/head/sect %d/%d/%d, maxvsect %d," 433 aprint_debug(" maxcyl/head/sect %d/%d/%d, maxvsect %d,"
434 " inter %d\n", 434 " inter %d\n",
435 desc->d_maxcyl, desc->d_maxhead, desc->d_maxsect, 435 desc->d_maxcyl, desc->d_maxhead, desc->d_maxsect,
436 desc->d_maxvsectl, desc->d_interleave); 436 desc->d_maxvsectl, desc->d_interleave);
437 aprint_normal("%s", device_xname(sc->sc_dev)); 437 aprint_normal("%s", device_xname(sc->sc_dev));
438 } 438 }
439#endif 439#endif
440 440
441 /* 441 /*
442 * Take care of a couple of anomolies: 442 * Take care of a couple of anomolies:
443 * 1. 7945A and 7946A both return same HW id 443 * 1. 7945A and 7946A both return same HW id
444 * 2. 9122S and 9134D both return same HW id 444 * 2. 9122S and 9134D both return same HW id
445 * 3. 9122D and 9134L both return same HW id 445 * 3. 9122D and 9134L both return same HW id
446 */ 446 */
447 switch (ha->ha_id) { 447 switch (ha->ha_id) {
448 case RD7946AID: 448 case RD7946AID:
449 if (memcmp(name, "079450", 6) == 0) 449 if (memcmp(name, "079450", 6) == 0)
450 id = RD7945A; 450 id = RD7945A;
451 else 451 else
452 id = RD7946A; 452 id = RD7946A;
453 break; 453 break;
454 454
455 case RD9134LID: 455 case RD9134LID:
456 if (memcmp(name, "091340", 6) == 0) 456 if (memcmp(name, "091340", 6) == 0)
457 id = RD9134L; 457 id = RD9134L;
458 else 458 else
459 id = RD9122D; 459 id = RD9122D;
460 break; 460 break;
461 461
462 case RD9134DID: 462 case RD9134DID:
463 if (memcmp(name, "091220", 6) == 0) 463 if (memcmp(name, "091220", 6) == 0)
464 id = RD9122S; 464 id = RD9122S;
465 else 465 else
466 id = RD9134D; 466 id = RD9134D;
467 break; 467 break;
468 } 468 }
469 469
470 sc->sc_type = id; 470 sc->sc_type = id;
471 471
472 /* 472 /*
473 * XXX We use DEV_BSIZE instead of the sector size value pulled 473 * XXX We use DEV_BSIZE instead of the sector size value pulled
474 * XXX off the driver because all of this code assumes 512 byte 474 * XXX off the driver because all of this code assumes 512 byte
475 * XXX blocks. ICK! 475 * XXX blocks. ICK!
476 */ 476 */
477 aprint_normal(": %s\n", rdidentinfo[id].ri_desc); 477 aprint_normal(": %s\n", rdidentinfo[id].ri_desc);
478 aprint_normal_dev(sc->sc_dev, "%d cylinders, %d heads, %d blocks," 478 aprint_normal_dev(sc->sc_dev, "%d cylinders, %d heads, %d blocks,"
479 " %d bytes/block\n", 479 " %d bytes/block\n",
480 rdidentinfo[id].ri_ncyl, 480 rdidentinfo[id].ri_ncyl,
481 rdidentinfo[id].ri_ntpc, rdidentinfo[id].ri_nblocks, 481 rdidentinfo[id].ri_ntpc, rdidentinfo[id].ri_nblocks,
482 DEV_BSIZE); 482 DEV_BSIZE);
483 483
484 return 1; 484 return 1;
485} 485}
486 486
487static void 487static void
488rdreset(struct rd_softc *sc) 488rdreset(struct rd_softc *sc)
489{ 489{
490 int ctlr = device_unit(device_parent(sc->sc_dev)); 490 int ctlr = device_unit(device_parent(sc->sc_dev));
491 int slave = sc->sc_slave; 491 int slave = sc->sc_slave;
492 u_char stat; 492 u_char stat;
493 493
494 sc->sc_clear.c_unit = C_SUNIT(sc->sc_punit); 494 sc->sc_clear.c_unit = C_SUNIT(sc->sc_punit);
495 sc->sc_clear.c_cmd = C_CLEAR; 495 sc->sc_clear.c_cmd = C_CLEAR;
496 hpibsend(ctlr, slave, C_TCMD, &sc->sc_clear, sizeof(sc->sc_clear)); 496 hpibsend(ctlr, slave, C_TCMD, &sc->sc_clear, sizeof(sc->sc_clear));
497 hpibswait(ctlr, slave); 497 hpibswait(ctlr, slave);
498 hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); 498 hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat));
499 499
500 sc->sc_src.c_unit = C_SUNIT(RDCTLR); 500 sc->sc_src.c_unit = C_SUNIT(RDCTLR);
501 sc->sc_src.c_nop = C_NOP; 501 sc->sc_src.c_nop = C_NOP;
502 sc->sc_src.c_cmd = C_SREL; 502 sc->sc_src.c_cmd = C_SREL;
503 sc->sc_src.c_param = C_REL; 503 sc->sc_src.c_param = C_REL;
504 hpibsend(ctlr, slave, C_CMD, &sc->sc_src, sizeof(sc->sc_src)); 504 hpibsend(ctlr, slave, C_CMD, &sc->sc_src, sizeof(sc->sc_src));
505 hpibswait(ctlr, slave); 505 hpibswait(ctlr, slave);
506 hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); 506 hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat));
507 507
508 sc->sc_ssmc.c_unit = C_SUNIT(sc->sc_punit); 508 sc->sc_ssmc.c_unit = C_SUNIT(sc->sc_punit);
509 sc->sc_ssmc.c_cmd = C_SSM; 509 sc->sc_ssmc.c_cmd = C_SSM;
510 sc->sc_ssmc.c_refm = REF_MASK; 510 sc->sc_ssmc.c_refm = REF_MASK;
511 sc->sc_ssmc.c_fefm = FEF_MASK; 511 sc->sc_ssmc.c_fefm = FEF_MASK;
512 sc->sc_ssmc.c_aefm = AEF_MASK; 512 sc->sc_ssmc.c_aefm = AEF_MASK;
513 sc->sc_ssmc.c_iefm = IEF_MASK; 513 sc->sc_ssmc.c_iefm = IEF_MASK;
514 hpibsend(ctlr, slave, C_CMD, &sc->sc_ssmc, sizeof(sc->sc_ssmc)); 514 hpibsend(ctlr, slave, C_CMD, &sc->sc_ssmc, sizeof(sc->sc_ssmc));
515 hpibswait(ctlr, slave); 515 hpibswait(ctlr, slave);
516 hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); 516 hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat));
517#ifdef DEBUG 517#ifdef DEBUG
518 sc->sc_stats.rdresets++; 518 sc->sc_stats.rdresets++;
519#endif 519#endif
520} 520}
521 521
522/* 522/*
523 * Read or construct a disklabel 523 * Read or construct a disklabel
524 */ 524 */
525static int 525static int
526rdgetinfo(dev_t dev) 526rdgetinfo(dev_t dev)
527{ 527{
528 struct rd_softc *sc = device_lookup_private(&rd_cd, rdunit(dev)); 528 struct rd_softc *sc = device_lookup_private(&rd_cd, rdunit(dev));
529 struct disklabel *lp = sc->sc_dkdev.dk_label; 529 struct disklabel *lp = sc->sc_dkdev.dk_label;
530 struct partition *pi; 530 struct partition *pi;
531 const char *msg; 531 const char *msg;
532 532
533 /* 533 /*
534 * Set some default values to use while reading the label 534 * Set some default values to use while reading the label
535 * or to use if there isn't a label. 535 * or to use if there isn't a label.
536 */ 536 */
537 memset((void *)lp, 0, sizeof *lp); 537 memset((void *)lp, 0, sizeof *lp);
538 rdgetdefaultlabel(sc, lp); 538 rdgetdefaultlabel(sc, lp);
539 539
540 /* 540 /*
541 * Now try to read the disklabel 541 * Now try to read the disklabel
542 */ 542 */
543 msg = readdisklabel(rdlabdev(dev), rdstrategy, lp, NULL); 543 msg = readdisklabel(rdlabdev(dev), rdstrategy, lp, NULL);
544 if (msg == NULL) 544 if (msg == NULL)
545 return 0; 545 return 0;
546 546
547 pi = lp->d_partitions; 547 pi = lp->d_partitions;
548 printf("%s: WARNING: %s\n", device_xname(sc->sc_dev), msg); 548 printf("%s: WARNING: %s\n", device_xname(sc->sc_dev), msg);
549 549
550 pi[2].p_size = rdidentinfo[sc->sc_type].ri_nblocks; 550 pi[2].p_size = rdidentinfo[sc->sc_type].ri_nblocks;
551 /* XXX reset other info since readdisklabel screws with it */ 551 /* XXX reset other info since readdisklabel screws with it */
552 lp->d_npartitions = 3; 552 lp->d_npartitions = 3;
553 pi[0].p_size = 0; 553 pi[0].p_size = 0;
554 554
555 return 0; 555 return 0;
556} 556}
557 557
558static int 558static int
559rdopen(dev_t dev, int flags, int mode, struct lwp *l) 559rdopen(dev_t dev, int flags, int mode, struct lwp *l)
560{ 560{
561 struct rd_softc *sc; 561 struct rd_softc *sc;
562 int error, mask, part; 562 int error, mask, part;
563 563
564 sc = device_lookup_private(&rd_cd, rdunit(dev)); 564 sc = device_lookup_private(&rd_cd, rdunit(dev));
565 if (sc == NULL) 565 if (sc == NULL)
566 return ENXIO; 566 return ENXIO;
567 567
568 if ((sc->sc_flags & RDF_ALIVE) == 0) 568 if ((sc->sc_flags & RDF_ALIVE) == 0)
569 return ENXIO; 569 return ENXIO;
570 570
571 /* 571 /*
572 * Wait for any pending opens/closes to complete 572 * Wait for any pending opens/closes to complete
573 */ 573 */
574 while (sc->sc_flags & (RDF_OPENING|RDF_CLOSING)) 574 while (sc->sc_flags & (RDF_OPENING|RDF_CLOSING))
575 (void) tsleep(sc, PRIBIO, "rdopen", 0); 575 (void) tsleep(sc, PRIBIO, "rdopen", 0);
576 576
577 /* 577 /*
578 * On first open, get label and partition info. 578 * On first open, get label and partition info.
579 * We may block reading the label, so be careful 579 * We may block reading the label, so be careful
580 * to stop any other opens. 580 * to stop any other opens.
581 */ 581 */
582 if (sc->sc_dkdev.dk_openmask == 0) { 582 if (sc->sc_dkdev.dk_openmask == 0) {
583 sc->sc_flags |= RDF_OPENING; 583 sc->sc_flags |= RDF_OPENING;
584 error = rdgetinfo(dev); 584 error = rdgetinfo(dev);
585 sc->sc_flags &= ~RDF_OPENING; 585 sc->sc_flags &= ~RDF_OPENING;
586 wakeup((void *)sc); 586 wakeup((void *)sc);
587 if (error) 587 if (error)
588 return error; 588 return error;
589 } 589 }
590 590
591 part = rdpart(dev); 591 part = rdpart(dev);
592 mask = 1 << part; 592 mask = 1 << part;
593 593
594 /* Check that the partition exists. */ 594 /* Check that the partition exists. */
595 if (part != RAW_PART && 595 if (part != RAW_PART &&
596 (part > sc->sc_dkdev.dk_label->d_npartitions || 596 (part > sc->sc_dkdev.dk_label->d_npartitions ||
597 sc->sc_dkdev.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) 597 sc->sc_dkdev.dk_label->d_partitions[part].p_fstype == FS_UNUSED))
598 return ENXIO; 598 return ENXIO;
599 599
600 /* Ensure only one open at a time. */ 600 /* Ensure only one open at a time. */
601 switch (mode) { 601 switch (mode) {
602 case S_IFCHR: 602 case S_IFCHR:
603 sc->sc_dkdev.dk_copenmask |= mask; 603 sc->sc_dkdev.dk_copenmask |= mask;
604 break; 604 break;
605 case S_IFBLK: 605 case S_IFBLK:
606 sc->sc_dkdev.dk_bopenmask |= mask; 606 sc->sc_dkdev.dk_bopenmask |= mask;
607 break; 607 break;
608 } 608 }
609 sc->sc_dkdev.dk_openmask = 609 sc->sc_dkdev.dk_openmask =
610 sc->sc_dkdev.dk_copenmask | sc->sc_dkdev.dk_bopenmask; 610 sc->sc_dkdev.dk_copenmask | sc->sc_dkdev.dk_bopenmask;
611 611
612 return 0; 612 return 0;
613} 613}
614 614
615static int 615static int
616rdclose(dev_t dev, int flag, int mode, struct lwp *l) 616rdclose(dev_t dev, int flag, int mode, struct lwp *l)
617{ 617{
618 struct rd_softc *sc = device_lookup_private(&rd_cd, rdunit(dev)); 618 struct rd_softc *sc = device_lookup_private(&rd_cd, rdunit(dev));
619 struct disk *dk = &sc->sc_dkdev; 619 struct disk *dk = &sc->sc_dkdev;
620 int mask, s; 620 int mask, s;
621 621
622 mask = 1 << rdpart(dev); 622 mask = 1 << rdpart(dev);
623 if (mode == S_IFCHR) 623 if (mode == S_IFCHR)
624 dk->dk_copenmask &= ~mask; 624 dk->dk_copenmask &= ~mask;
625 else 625 else
626 dk->dk_bopenmask &= ~mask; 626 dk->dk_bopenmask &= ~mask;
627 dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask; 627 dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
628 /* 628 /*
629 * On last close, we wait for all activity to cease since 629 * On last close, we wait for all activity to cease since
630 * the label/parition info will become invalid. Since we 630 * the label/parition info will become invalid. Since we
631 * might sleep, we must block any opens while we are here. 631 * might sleep, we must block any opens while we are here.
632 * Note we don't have to about other closes since we know 632 * Note we don't have to about other closes since we know
633 * we are the last one. 633 * we are the last one.
634 */ 634 */
635 if (dk->dk_openmask == 0) { 635 if (dk->dk_openmask == 0) {
636 sc->sc_flags |= RDF_CLOSING; 636 sc->sc_flags |= RDF_CLOSING;
637 s = splbio(); 637 s = splbio();
638 while (sc->sc_active) { 638 while (sc->sc_active) {
639 sc->sc_flags |= RDF_WANTED; 639 sc->sc_flags |= RDF_WANTED;
640 (void) tsleep(&sc->sc_tab, PRIBIO, "rdclose", 0); 640 (void) tsleep(&sc->sc_tab, PRIBIO, "rdclose", 0);
641 } 641 }
642 splx(s); 642 splx(s);
643 sc->sc_flags &= ~(RDF_CLOSING|RDF_WLABEL); 643 sc->sc_flags &= ~(RDF_CLOSING|RDF_WLABEL);
644 wakeup((void *)sc); 644 wakeup((void *)sc);
645 } 645 }
646 return 0; 646 return 0;
647} 647}
648 648
649static void 649static void
650rdstrategy(struct buf *bp) 650rdstrategy(struct buf *bp)
651{ 651{
652 struct rd_softc *sc = device_lookup_private(&rd_cd, rdunit(bp->b_dev)); 652 struct rd_softc *sc = device_lookup_private(&rd_cd, rdunit(bp->b_dev));
653 struct partition *pinfo; 653 struct partition *pinfo;
654 daddr_t bn; 654 daddr_t bn;
655 int sz, s; 655 int sz, s;
656 int offset; 656 int offset;
657 657
658#ifdef DEBUG 658#ifdef DEBUG
659 if (rddebug & RDB_FOLLOW) 659 if (rddebug & RDB_FOLLOW)
660 printf("rdstrategy(%p): dev %x, bn %llx, bcount %x, %c\n", 660 printf("rdstrategy(%p): dev %"PRIx64", bn %llx, bcount %x, %c\n",
661 bp, bp->b_dev, bp->b_blkno, bp->b_bcount, 661 bp, bp->b_dev, bp->b_blkno, bp->b_bcount,
662 (bp->b_flags & B_READ) ? 'R' : 'W'); 662 (bp->b_flags & B_READ) ? 'R' : 'W');
663#endif 663#endif
664 bn = bp->b_blkno; 664 bn = bp->b_blkno;
665 sz = howmany(bp->b_bcount, DEV_BSIZE); 665 sz = howmany(bp->b_bcount, DEV_BSIZE);
666 pinfo = &sc->sc_dkdev.dk_label->d_partitions[rdpart(bp->b_dev)]; 666 pinfo = &sc->sc_dkdev.dk_label->d_partitions[rdpart(bp->b_dev)];
667 667
668 /* Don't perform partition translation on RAW_PART. */ 668 /* Don't perform partition translation on RAW_PART. */
669 offset = (rdpart(bp->b_dev) == RAW_PART) ? 0 : pinfo->p_offset; 669 offset = (rdpart(bp->b_dev) == RAW_PART) ? 0 : pinfo->p_offset;
670 670
671 if (rdpart(bp->b_dev) != RAW_PART) { 671 if (rdpart(bp->b_dev) != RAW_PART) {
672 /* 672 /*
673 * XXX This block of code belongs in 673 * XXX This block of code belongs in
674 * XXX bounds_check_with_label() 674 * XXX bounds_check_with_label()
675 */ 675 */
676 676
677 if (bn < 0 || bn + sz > pinfo->p_size) { 677 if (bn < 0 || bn + sz > pinfo->p_size) {
678 sz = pinfo->p_size - bn; 678 sz = pinfo->p_size - bn;
679 if (sz == 0) { 679 if (sz == 0) {
680 bp->b_resid = bp->b_bcount; 680 bp->b_resid = bp->b_bcount;
681 goto done; 681 goto done;
682 } 682 }
683 if (sz < 0) { 683 if (sz < 0) {
684 bp->b_error = EINVAL; 684 bp->b_error = EINVAL;
685 goto done; 685 goto done;
686 } 686 }
687 bp->b_bcount = dbtob(sz); 687 bp->b_bcount = dbtob(sz);
688 } 688 }
689 /* 689 /*
690 * Check for write to write protected label 690 * Check for write to write protected label
691 */ 691 */
692 if (bn + offset <= LABELSECTOR && 692 if (bn + offset <= LABELSECTOR &&
693#if LABELSECTOR != 0 693#if LABELSECTOR != 0
694 bn + offset + sz > LABELSECTOR && 694 bn + offset + sz > LABELSECTOR &&
695#endif 695#endif
696 !(bp->b_flags & B_READ) && !(sc->sc_flags & RDF_WLABEL)) { 696 !(bp->b_flags & B_READ) && !(sc->sc_flags & RDF_WLABEL)) {
697 bp->b_error = EROFS; 697 bp->b_error = EROFS;
698 goto done; 698 goto done;
699 } 699 }
700 } 700 }
701 bp->b_rawblkno = bn + offset; 701 bp->b_rawblkno = bn + offset;
702 s = splbio(); 702 s = splbio();
703 bufq_put(sc->sc_tab, bp); 703 bufq_put(sc->sc_tab, bp);
704 if (sc->sc_active == 0) { 704 if (sc->sc_active == 0) {
705 sc->sc_active = 1; 705 sc->sc_active = 1;
706 rdustart(sc); 706 rdustart(sc);
707 } 707 }
708 splx(s); 708 splx(s);
709 return; 709 return;
710done: 710done:
711 biodone(bp); 711 biodone(bp);
712} 712}
713 713
714/* 714/*
715 * Called from timeout() when handling maintenance releases 715 * Called from timeout() when handling maintenance releases
716 */ 716 */
717static void 717static void
718rdrestart(void *arg) 718rdrestart(void *arg)
719{ 719{
720 int s = splbio(); 720 int s = splbio();
721 rdustart((struct rd_softc *)arg); 721 rdustart((struct rd_softc *)arg);
722 splx(s); 722 splx(s);
723} 723}
724 724
725static void 725static void
726rdustart(struct rd_softc *sc) 726rdustart(struct rd_softc *sc)
727{ 727{
728 struct buf *bp; 728 struct buf *bp;
729 729
730 bp = bufq_peek(sc->sc_tab); 730 bp = bufq_peek(sc->sc_tab);
731 sc->sc_addr = bp->b_data; 731 sc->sc_addr = bp->b_data;
732 sc->sc_resid = bp->b_bcount; 732 sc->sc_resid = bp->b_bcount;
733 if (hpibreq(device_parent(sc->sc_dev), &sc->sc_hq)) 733 if (hpibreq(device_parent(sc->sc_dev), &sc->sc_hq))
734 rdstart(sc); 734 rdstart(sc);
735} 735}
736 736
737static struct buf * 737static struct buf *
738rdfinish(struct rd_softc *sc, struct buf *bp) 738rdfinish(struct rd_softc *sc, struct buf *bp)
739{ 739{
740 740
741 sc->sc_errcnt = 0; 741 sc->sc_errcnt = 0;
742 (void)bufq_get(sc->sc_tab); 742 (void)bufq_get(sc->sc_tab);
743 bp->b_resid = 0; 743 bp->b_resid = 0;
744 biodone(bp); 744 biodone(bp);
745 hpibfree(device_parent(sc->sc_dev), &sc->sc_hq); 745 hpibfree(device_parent(sc->sc_dev), &sc->sc_hq);
746 if ((bp = bufq_peek(sc->sc_tab)) != NULL) 746 if ((bp = bufq_peek(sc->sc_tab)) != NULL)
747 return bp; 747 return bp;
748 sc->sc_active = 0; 748 sc->sc_active = 0;
749 if (sc->sc_flags & RDF_WANTED) { 749 if (sc->sc_flags & RDF_WANTED) {
750 sc->sc_flags &= ~RDF_WANTED; 750 sc->sc_flags &= ~RDF_WANTED;
751 wakeup((void *)&sc->sc_tab); 751 wakeup((void *)&sc->sc_tab);
752 } 752 }
753 return NULL; 753 return NULL;
754} 754}
755 755
756static void 756static void
757rdstart(void *arg) 757rdstart(void *arg)
758{ 758{
759 struct rd_softc *sc = arg; 759 struct rd_softc *sc = arg;
760 struct buf *bp = bufq_peek(sc->sc_tab); 760 struct buf *bp = bufq_peek(sc->sc_tab);
761 int part, ctlr, slave; 761 int part, ctlr, slave;
762 762
763 ctlr = device_unit(device_parent(sc->sc_dev)); 763 ctlr = device_unit(device_parent(sc->sc_dev));
764 slave = sc->sc_slave; 764 slave = sc->sc_slave;
765 765
766again: 766again:
767#ifdef DEBUG 767#ifdef DEBUG
768 if (rddebug & RDB_FOLLOW) 768 if (rddebug & RDB_FOLLOW)
769 printf("rdstart(%s): bp %p, %c\n", device_xname(sc->sc_dev), bp, 769 printf("rdstart(%s): bp %p, %c\n", device_xname(sc->sc_dev), bp,
770 (bp->b_flags & B_READ) ? 'R' : 'W'); 770 (bp->b_flags & B_READ) ? 'R' : 'W');
771#endif 771#endif
772 part = rdpart(bp->b_dev); 772 part = rdpart(bp->b_dev);
773 sc->sc_flags |= RDF_SEEK; 773 sc->sc_flags |= RDF_SEEK;
774 sc->sc_ioc.c_unit = C_SUNIT(sc->sc_punit); 774 sc->sc_ioc.c_unit = C_SUNIT(sc->sc_punit);
775 sc->sc_ioc.c_volume = C_SVOL(0); 775 sc->sc_ioc.c_volume = C_SVOL(0);
776 sc->sc_ioc.c_saddr = C_SADDR; 776 sc->sc_ioc.c_saddr = C_SADDR;
777 sc->sc_ioc.c_hiaddr = 0; 777 sc->sc_ioc.c_hiaddr = 0;
778 sc->sc_ioc.c_addr = RDBTOS(bp->b_rawblkno); 778 sc->sc_ioc.c_addr = RDBTOS(bp->b_rawblkno);
779 sc->sc_ioc.c_nop2 = C_NOP; 779 sc->sc_ioc.c_nop2 = C_NOP;
780 sc->sc_ioc.c_slen = C_SLEN; 780 sc->sc_ioc.c_slen = C_SLEN;
781 sc->sc_ioc.c_len = sc->sc_resid; 781 sc->sc_ioc.c_len = sc->sc_resid;
782 sc->sc_ioc.c_cmd = bp->b_flags & B_READ ? C_READ : C_WRITE; 782 sc->sc_ioc.c_cmd = bp->b_flags & B_READ ? C_READ : C_WRITE;
783#ifdef DEBUG 783#ifdef DEBUG
784 if (rddebug & RDB_IO) 784 if (rddebug & RDB_IO)
785 printf("rdstart: hpibsend(%x, %x, %x, %p, %x)\n", 785 printf("rdstart: hpibsend(%x, %x, %x, %p, %x)\n",
786 ctlr, slave, C_CMD, 786 ctlr, slave, C_CMD,
787 &sc->sc_ioc.c_unit, sizeof(sc->sc_ioc) - 2); 787 &sc->sc_ioc.c_unit, sizeof(sc->sc_ioc) - 2);
788#endif 788#endif
789 if (hpibsend(ctlr, slave, C_CMD, &sc->sc_ioc.c_unit, 789 if (hpibsend(ctlr, slave, C_CMD, &sc->sc_ioc.c_unit,
790 sizeof(sc->sc_ioc) - 2) == sizeof(sc->sc_ioc) - 2) { 790 sizeof(sc->sc_ioc) - 2) == sizeof(sc->sc_ioc) - 2) {
791 791
792 /* Instrumentation. */ 792 /* Instrumentation. */
793 disk_busy(&sc->sc_dkdev); 793 disk_busy(&sc->sc_dkdev);
794 iostat_seek(sc->sc_dkdev.dk_stats); 794 iostat_seek(sc->sc_dkdev.dk_stats);
795 795
796#ifdef DEBUG 796#ifdef DEBUG
797 if (rddebug & RDB_IO) 797 if (rddebug & RDB_IO)
798 printf("rdstart: hpibawait(%x)\n", ctlr); 798 printf("rdstart: hpibawait(%x)\n", ctlr);
799#endif 799#endif
800 hpibawait(ctlr); 800 hpibawait(ctlr);
801 return; 801 return;
802 } 802 }
803 /* 803 /*
804 * Experience has shown that the hpibwait in this hpibsend will 804 * Experience has shown that the hpibwait in this hpibsend will
805 * occasionally timeout. It appears to occur mostly on old 7914 805 * occasionally timeout. It appears to occur mostly on old 7914
806 * drives with full maintenance tracks. We should probably 806 * drives with full maintenance tracks. We should probably
807 * integrate this with the backoff code in rderror. 807 * integrate this with the backoff code in rderror.
808 */ 808 */
809#ifdef DEBUG 809#ifdef DEBUG
810 if (rddebug & RDB_ERROR) 810 if (rddebug & RDB_ERROR)
811 printf("%s: rdstart: cmd %x adr %lx blk %lld len %d ecnt %d\n", 811 printf("%s: rdstart: cmd %x adr %lx blk %lld len %d ecnt %d\n",
812 device_xname(sc->sc_dev), 812 device_xname(sc->sc_dev),
813 sc->sc_ioc.c_cmd, sc->sc_ioc.c_addr, 813 sc->sc_ioc.c_cmd, sc->sc_ioc.c_addr,
814 bp->b_blkno, sc->sc_resid, sc->sc_errcnt); 814 bp->b_blkno, sc->sc_resid, sc->sc_errcnt);
815 sc->sc_stats.rdretries++; 815 sc->sc_stats.rdretries++;
816#endif 816#endif
817 sc->sc_flags &= ~RDF_SEEK; 817 sc->sc_flags &= ~RDF_SEEK;
818 rdreset(sc); 818 rdreset(sc);
819 if (sc->sc_errcnt++ < RDRETRY) 819 if (sc->sc_errcnt++ < RDRETRY)
820 goto again; 820 goto again;
821 printf("%s: rdstart err: cmd 0x%x sect %ld blk %" PRId64 " len %d\n", 821 printf("%s: rdstart err: cmd 0x%x sect %ld blk %" PRId64 " len %d\n",
822 device_xname(sc->sc_dev), sc->sc_ioc.c_cmd, sc->sc_ioc.c_addr, 822 device_xname(sc->sc_dev), sc->sc_ioc.c_cmd, sc->sc_ioc.c_addr,
823 bp->b_blkno, sc->sc_resid); 823 bp->b_blkno, sc->sc_resid);
824 bp->b_error = EIO; 824 bp->b_error = EIO;
825 bp = rdfinish(sc, bp); 825 bp = rdfinish(sc, bp);
826 if (bp) { 826 if (bp) {
827 sc->sc_addr = bp->b_data; 827 sc->sc_addr = bp->b_data;
828 sc->sc_resid = bp->b_bcount; 828 sc->sc_resid = bp->b_bcount;
829 if (hpibreq(device_parent(sc->sc_dev), &sc->sc_hq)) 829 if (hpibreq(device_parent(sc->sc_dev), &sc->sc_hq))
830 goto again; 830 goto again;
831 } 831 }
832} 832}
833 833
834static void 834static void
835rdgo(void *arg) 835rdgo(void *arg)
836{ 836{
837 struct rd_softc *sc = arg; 837 struct rd_softc *sc = arg;
838 struct buf *bp = bufq_peek(sc->sc_tab); 838 struct buf *bp = bufq_peek(sc->sc_tab);
839 int rw, ctlr, slave; 839 int rw, ctlr, slave;
840 840
841 ctlr = device_unit(device_parent(sc->sc_dev)); 841 ctlr = device_unit(device_parent(sc->sc_dev));
842 slave = sc->sc_slave; 842 slave = sc->sc_slave;
843 843
844 rw = bp->b_flags & B_READ; 844 rw = bp->b_flags & B_READ;
845 845
846 /* Instrumentation. */ 846 /* Instrumentation. */
847 disk_busy(&sc->sc_dkdev); 847 disk_busy(&sc->sc_dkdev);
848 848
849#ifdef USELEDS 849#ifdef USELEDS
850 ledcontrol(0, 0, LED_DISK); 850 ledcontrol(0, 0, LED_DISK);
851#endif 851#endif
852 hpibgo(ctlr, slave, C_EXEC, sc->sc_addr, sc->sc_resid, rw, rw != 0); 852 hpibgo(ctlr, slave, C_EXEC, sc->sc_addr, sc->sc_resid, rw, rw != 0);
853} 853}
854 854
855/* ARGSUSED */ 855/* ARGSUSED */
856static void 856static void
857rdintr(void *arg) 857rdintr(void *arg)
858{ 858{
859 struct rd_softc *sc = arg; 859 struct rd_softc *sc = arg;
860 int unit = device_unit(sc->sc_dev); 860 int unit = device_unit(sc->sc_dev);
861 struct buf *bp = bufq_peek(sc->sc_tab); 861 struct buf *bp = bufq_peek(sc->sc_tab);
862 u_char stat = 13; /* in case hpibrecv fails */ 862 u_char stat = 13; /* in case hpibrecv fails */
863 int rv, restart, ctlr, slave; 863 int rv, restart, ctlr, slave;
864 864
865 ctlr = device_unit(device_parent(sc->sc_dev)); 865 ctlr = device_unit(device_parent(sc->sc_dev));
866 slave = sc->sc_slave; 866 slave = sc->sc_slave;
867 867
868#ifdef DEBUG 868#ifdef DEBUG
869 if (rddebug & RDB_FOLLOW) 869 if (rddebug & RDB_FOLLOW)
870 printf("rdintr(%d): bp %p, %c, flags %x\n", unit, bp, 870 printf("rdintr(%d): bp %p, %c, flags %x\n", unit, bp,
871 (bp->b_flags & B_READ) ? 'R' : 'W', sc->sc_flags); 871 (bp->b_flags & B_READ) ? 'R' : 'W', sc->sc_flags);
872 if (bp == NULL) { 872 if (bp == NULL) {
873 printf("%s: bp == NULL\n", device_xname(sc->sc_dev)); 873 printf("%s: bp == NULL\n", device_xname(sc->sc_dev));
874 return; 874 return;
875 } 875 }
876#endif 876#endif
877 disk_unbusy(&sc->sc_dkdev, (bp->b_bcount - bp->b_resid), 877 disk_unbusy(&sc->sc_dkdev, (bp->b_bcount - bp->b_resid),
878 (bp->b_flags & B_READ)); 878 (bp->b_flags & B_READ));
879 879
880 if (sc->sc_flags & RDF_SEEK) { 880 if (sc->sc_flags & RDF_SEEK) {
881 sc->sc_flags &= ~RDF_SEEK; 881 sc->sc_flags &= ~RDF_SEEK;
882 if (hpibustart(ctlr)) 882 if (hpibustart(ctlr))
883 rdgo(sc); 883 rdgo(sc);
884 return; 884 return;
885 } 885 }
886 if ((sc->sc_flags & RDF_SWAIT) == 0) { 886 if ((sc->sc_flags & RDF_SWAIT) == 0) {
887#ifdef DEBUG 887#ifdef DEBUG
888 sc->sc_stats.rdpolltries++; 888 sc->sc_stats.rdpolltries++;
889#endif 889#endif
890 if (hpibpptest(ctlr, slave) == 0) { 890 if (hpibpptest(ctlr, slave) == 0) {
891#ifdef DEBUG 891#ifdef DEBUG
892 sc->sc_stats.rdpollwaits++; 892 sc->sc_stats.rdpollwaits++;
893#endif 893#endif
894 894
895 /* Instrumentation. */ 895 /* Instrumentation. */
896 disk_busy(&sc->sc_dkdev); 896 disk_busy(&sc->sc_dkdev);
897 sc->sc_flags |= RDF_SWAIT; 897 sc->sc_flags |= RDF_SWAIT;
898 hpibawait(ctlr); 898 hpibawait(ctlr);
899 return; 899 return;
900 } 900 }
901 } else 901 } else
902 sc->sc_flags &= ~RDF_SWAIT; 902 sc->sc_flags &= ~RDF_SWAIT;
903 rv = hpibrecv(ctlr, slave, C_QSTAT, &stat, 1); 903 rv = hpibrecv(ctlr, slave, C_QSTAT, &stat, 1);
904 if (rv != 1 || stat) { 904 if (rv != 1 || stat) {
905#ifdef DEBUG 905#ifdef DEBUG
906 if (rddebug & RDB_ERROR) 906 if (rddebug & RDB_ERROR)
907 printf("rdintr: recv failed or bad stat %d\n", stat); 907 printf("rdintr: recv failed or bad stat %d\n", stat);
908#endif 908#endif
909 restart = rderror(unit); 909 restart = rderror(unit);
910#ifdef DEBUG 910#ifdef DEBUG
911 sc->sc_stats.rdretries++; 911 sc->sc_stats.rdretries++;
912#endif 912#endif
913 if (sc->sc_errcnt++ < RDRETRY) { 913 if (sc->sc_errcnt++ < RDRETRY) {
914 if (restart) 914 if (restart)
915 rdstart(sc); 915 rdstart(sc);
916 return; 916 return;
917 } 917 }
918 bp->b_error = EIO; 918 bp->b_error = EIO;
919 } 919 }
920 if (rdfinish(sc, bp)) 920 if (rdfinish(sc, bp))
921 rdustart(sc); 921 rdustart(sc);
922#if NRND > 0 922#if NRND > 0
923 rnd_add_uint32(&sc->rnd_source, bp->b_blkno); 923 rnd_add_uint32(&sc->rnd_source, bp->b_blkno);
924#endif 924#endif
925} 925}
926 926
927static int 927static int
928rdstatus(struct rd_softc *sc) 928rdstatus(struct rd_softc *sc)
929{ 929{
930 int c, s; 930 int c, s;
931 u_char stat; 931 u_char stat;
932 int rv; 932 int rv;
933 933
934 c = device_unit(device_parent(sc->sc_dev)); 934 c = device_unit(device_parent(sc->sc_dev));
935 s = sc->sc_slave; 935 s = sc->sc_slave;
936 sc->sc_rsc.c_unit = C_SUNIT(sc->sc_punit); 936 sc->sc_rsc.c_unit = C_SUNIT(sc->sc_punit);
937 sc->sc_rsc.c_sram = C_SRAM; 937 sc->sc_rsc.c_sram = C_SRAM;
938 sc->sc_rsc.c_ram = C_RAM; 938 sc->sc_rsc.c_ram = C_RAM;
939 sc->sc_rsc.c_cmd = C_STATUS; 939 sc->sc_rsc.c_cmd = C_STATUS;
940 memset((void *)&sc->sc_stat, 0, sizeof(sc->sc_stat)); 940 memset((void *)&sc->sc_stat, 0, sizeof(sc->sc_stat));
941 rv = hpibsend(c, s, C_CMD, &sc->sc_rsc, sizeof(sc->sc_rsc)); 941 rv = hpibsend(c, s, C_CMD, &sc->sc_rsc, sizeof(sc->sc_rsc));
942 if (rv != sizeof(sc->sc_rsc)) { 942 if (rv != sizeof(sc->sc_rsc)) {
943#ifdef DEBUG 943#ifdef DEBUG
944 if (rddebug & RDB_STATUS) 944 if (rddebug & RDB_STATUS)
945 printf("rdstatus: send C_CMD failed %d != %d\n", 945 printf("rdstatus: send C_CMD failed %d != %d\n",
946 rv, sizeof(sc->sc_rsc)); 946 rv, sizeof(sc->sc_rsc));
947#endif 947#endif
948 return 1; 948 return 1;
949 } 949 }
950 rv = hpibrecv(c, s, C_EXEC, &sc->sc_stat, sizeof(sc->sc_stat)); 950 rv = hpibrecv(c, s, C_EXEC, &sc->sc_stat, sizeof(sc->sc_stat));
951 if (rv != sizeof(sc->sc_stat)) { 951 if (rv != sizeof(sc->sc_stat)) {
952#ifdef DEBUG 952#ifdef DEBUG
953 if (rddebug & RDB_STATUS) 953 if (rddebug & RDB_STATUS)
954 printf("rdstatus: send C_EXEC failed %d != %d\n", 954 printf("rdstatus: send C_EXEC failed %d != %d\n",
955 rv, sizeof(sc->sc_stat)); 955 rv, sizeof(sc->sc_stat));
956#endif 956#endif
957 return 1; 957 return 1;
958 } 958 }
959 rv = hpibrecv(c, s, C_QSTAT, &stat, 1); 959 rv = hpibrecv(c, s, C_QSTAT, &stat, 1);
960 if (rv != 1 || stat) { 960 if (rv != 1 || stat) {
961#ifdef DEBUG 961#ifdef DEBUG
962 if (rddebug & RDB_STATUS) 962 if (rddebug & RDB_STATUS)
963 printf("rdstatus: recv failed %d or bad stat %d\n", 963 printf("rdstatus: recv failed %d or bad stat %d\n",
964 rv, stat); 964 rv, stat);
965#endif 965#endif
966 return 1; 966 return 1;
967 } 967 }
968 return 0; 968 return 0;
969} 969}
970 970
971/* 971/*
972 * Deal with errors. 972 * Deal with errors.
973 * Returns 1 if request should be restarted, 973 * Returns 1 if request should be restarted,
974 * 0 if we should just quietly give up. 974 * 0 if we should just quietly give up.
975 */ 975 */
976static int 976static int
977rderror(int unit) 977rderror(int unit)
978{ 978{
979 struct rd_softc *sc = device_lookup_private(&rd_cd,unit); 979 struct rd_softc *sc = device_lookup_private(&rd_cd,unit);
980 struct rd_stat *sp; 980 struct rd_stat *sp;
981 struct buf *bp; 981 struct buf *bp;
982 daddr_t hwbn, pbn; 982 daddr_t hwbn, pbn;
983 char *hexstr(int, int); /* XXX */ 983 char *hexstr(int, int); /* XXX */
984 984
985 if (rdstatus(sc)) { 985 if (rdstatus(sc)) {
986#ifdef DEBUG 986#ifdef DEBUG
987 printf("%s: couldn't get status\n", device_xname(sc->sc_dev)); 987 printf("%s: couldn't get status\n", device_xname(sc->sc_dev));
988#endif 988#endif
989 rdreset(sc); 989 rdreset(sc);
990 return 1; 990 return 1;
991 } 991 }
992 sp = &sc->sc_stat; 992 sp = &sc->sc_stat;
993 if (sp->c_fef & FEF_REXMT) 993 if (sp->c_fef & FEF_REXMT)
994 return 1; 994 return 1;
995 if (sp->c_fef & FEF_PF) { 995 if (sp->c_fef & FEF_PF) {
996 rdreset(sc); 996 rdreset(sc);
997 return 1; 997 return 1;
998 } 998 }
999 /* 999 /*
1000 * Unit requests release for internal maintenance. 1000 * Unit requests release for internal maintenance.
1001 * We just delay awhile and try again later. Use expontially 1001 * We just delay awhile and try again later. Use expontially
1002 * increasing backoff ala ethernet drivers since we don't really 1002 * increasing backoff ala ethernet drivers since we don't really
1003 * know how long the maintenance will take. With RDWAITC and 1003 * know how long the maintenance will take. With RDWAITC and
1004 * RDRETRY as defined, the range is 1 to 32 seconds. 1004 * RDRETRY as defined, the range is 1 to 32 seconds.
1005 */ 1005 */
1006 if (sp->c_fef & FEF_IMR) { 1006 if (sp->c_fef & FEF_IMR) {
1007 extern int hz; 1007 extern int hz;
1008 int rdtimo = RDWAITC << sc->sc_errcnt; 1008 int rdtimo = RDWAITC << sc->sc_errcnt;
1009#ifdef DEBUG 1009#ifdef DEBUG
1010 printf("%s: internal maintenance, %d second timeout\n", 1010 printf("%s: internal maintenance, %d second timeout\n",
1011 device_xname(sc->sc_dev), rdtimo); 1011 device_xname(sc->sc_dev), rdtimo);
1012 sc->sc_stats.rdtimeouts++; 1012 sc->sc_stats.rdtimeouts++;
1013#endif 1013#endif
1014 hpibfree(device_parent(sc->sc_dev), &sc->sc_hq); 1014 hpibfree(device_parent(sc->sc_dev), &sc->sc_hq);
1015 callout_reset(&sc->sc_restart_ch, rdtimo * hz, rdrestart, sc); 1015 callout_reset(&sc->sc_restart_ch, rdtimo * hz, rdrestart, sc);
1016 return 0; 1016 return 0;
1017 } 1017 }
1018 /* 1018 /*
1019 * Only report error if we have reached the error reporting 1019 * Only report error if we have reached the error reporting
1020 * threshhold. By default, this will only report after the 1020 * threshhold. By default, this will only report after the
1021 * retry limit has been exceeded. 1021 * retry limit has been exceeded.
1022 */ 1022 */
1023 if (sc->sc_errcnt < rderrthresh) 1023 if (sc->sc_errcnt < rderrthresh)
1024 return 1; 1024 return 1;
1025 1025
1026 /* 1026 /*
1027 * First conjure up the block number at which the error occurred. 1027 * First conjure up the block number at which the error occurred.
1028 * Note that not all errors report a block number, in that case 1028 * Note that not all errors report a block number, in that case
1029 * we just use b_blkno. 1029 * we just use b_blkno.
1030 */ 1030 */
1031 bp = bufq_peek(sc->sc_tab); 1031 bp = bufq_peek(sc->sc_tab);
1032 pbn = sc->sc_dkdev.dk_label->d_partitions[rdpart(bp->b_dev)].p_offset; 1032 pbn = sc->sc_dkdev.dk_label->d_partitions[rdpart(bp->b_dev)].p_offset;
1033 if ((sp->c_fef & FEF_CU) || (sp->c_fef & FEF_DR) || 1033 if ((sp->c_fef & FEF_CU) || (sp->c_fef & FEF_DR) ||
1034 (sp->c_ief & IEF_RRMASK)) { 1034 (sp->c_ief & IEF_RRMASK)) {
1035 hwbn = RDBTOS(pbn + bp->b_blkno); 1035 hwbn = RDBTOS(pbn + bp->b_blkno);
1036 pbn = bp->b_blkno; 1036 pbn = bp->b_blkno;
1037 } else { 1037 } else {
1038 hwbn = sp->c_blk; 1038 hwbn = sp->c_blk;
1039 pbn = RDSTOB(hwbn) - pbn; 1039 pbn = RDSTOB(hwbn) - pbn;
1040 } 1040 }
1041 /* 1041 /*
1042 * Now output a generic message suitable for badsect. 1042 * Now output a generic message suitable for badsect.
1043 * Note that we don't use harderr cuz it just prints 1043 * Note that we don't use harderr cuz it just prints
1044 * out b_blkno which is just the beginning block number 1044 * out b_blkno which is just the beginning block number
1045 * of the transfer, not necessary where the error occurred. 1045 * of the transfer, not necessary where the error occurred.
1046 */ 1046 */
1047 printf("%s%c: hard error sn%" PRId64 "\n", device_xname(sc->sc_dev), 1047 printf("%s%c: hard error sn%" PRId64 "\n", device_xname(sc->sc_dev),
1048 'a'+rdpart(bp->b_dev), pbn); 1048 'a'+rdpart(bp->b_dev), pbn);
1049 /* 1049 /*
1050 * Now report the status as returned by the hardware with 1050 * Now report the status as returned by the hardware with
1051 * attempt at interpretation (unless debugging). 1051 * attempt at interpretation (unless debugging).
1052 */ 1052 */
1053 printf("%s %s error:", device_xname(sc->sc_dev), 1053 printf("%s %s error:", device_xname(sc->sc_dev),
1054 (bp->b_flags & B_READ) ? "read" : "write"); 1054 (bp->b_flags & B_READ) ? "read" : "write");
1055#ifdef DEBUG 1055#ifdef DEBUG
1056 if (rddebug & RDB_ERROR) { 1056 if (rddebug & RDB_ERROR) {
1057 /* status info */ 1057 /* status info */
1058 printf("\n volume: %d, unit: %d\n", 1058 printf("\n volume: %d, unit: %d\n",
1059 (sp->c_vu>>4)&0xF, sp->c_vu&0xF); 1059 (sp->c_vu>>4)&0xF, sp->c_vu&0xF);
1060 rdprinterr("reject", sp->c_ref, err_reject); 1060 rdprinterr("reject", sp->c_ref, err_reject);
1061 rdprinterr("fault", sp->c_fef, err_fault); 1061 rdprinterr("fault", sp->c_fef, err_fault);
1062 rdprinterr("access", sp->c_aef, err_access); 1062 rdprinterr("access", sp->c_aef, err_access);
1063 rdprinterr("info", sp->c_ief, err_info); 1063 rdprinterr("info", sp->c_ief, err_info);
1064 printf(" block: %lld, P1-P10: ", hwbn); 1064 printf(" block: %lld, P1-P10: ", hwbn);
1065 printf("0x%x", *(u_int *)&sp->c_raw[0]); 1065 printf("0x%x", *(u_int *)&sp->c_raw[0]);
1066 printf("0x%x", *(u_int *)&sp->c_raw[4]); 1066 printf("0x%x", *(u_int *)&sp->c_raw[4]);
1067 printf("0x%x\n", *(u_short *)&sp->c_raw[8]); 1067 printf("0x%x\n", *(u_short *)&sp->c_raw[8]);
1068 /* command */ 1068 /* command */
1069 printf(" ioc: "); 1069 printf(" ioc: ");
1070 printf("0x%x", *(u_int *)&sc->sc_ioc.c_pad); 1070 printf("0x%x", *(u_int *)&sc->sc_ioc.c_pad);
1071 printf("0x%x", *(u_short *)&sc->sc_ioc.c_hiaddr); 1071 printf("0x%x", *(u_short *)&sc->sc_ioc.c_hiaddr);
1072 printf("0x%x", *(u_int *)&sc->sc_ioc.c_addr); 1072 printf("0x%x", *(u_int *)&sc->sc_ioc.c_addr);
1073 printf("0x%x", *(u_short *)&sc->sc_ioc.c_nop2); 1073 printf("0x%x", *(u_short *)&sc->sc_ioc.c_nop2);
1074 printf("0x%x", *(u_int *)&sc->sc_ioc.c_len); 1074 printf("0x%x", *(u_int *)&sc->sc_ioc.c_len);
1075 printf("0x%x\n", *(u_short *)&sc->sc_ioc.c_cmd); 1075 printf("0x%x\n", *(u_short *)&sc->sc_ioc.c_cmd);
1076 return 1; 1076 return 1;
1077 } 1077 }
1078#endif 1078#endif
1079 printf(" v%d u%d, R0x%x F0x%x A0x%x I0x%x\n", 1079 printf(" v%d u%d, R0x%x F0x%x A0x%x I0x%x\n",
1080 (sp->c_vu>>4)&0xF, sp->c_vu&0xF, 1080 (sp->c_vu>>4)&0xF, sp->c_vu&0xF,
1081 sp->c_ref, sp->c_fef, sp->c_aef, sp->c_ief); 1081 sp->c_ref, sp->c_fef, sp->c_aef, sp->c_ief);
1082 printf("P1-P10: "); 1082 printf("P1-P10: ");
1083 printf("0x%x", *(u_int *)&sp->c_raw[0]); 1083 printf("0x%x", *(u_int *)&sp->c_raw[0]);
1084 printf("0x%x", *(u_int *)&sp->c_raw[4]); 1084 printf("0x%x", *(u_int *)&sp->c_raw[4]);
1085 printf("0x%x\n", *(u_short *)&sp->c_raw[8]); 1085 printf("0x%x\n", *(u_short *)&sp->c_raw[8]);
1086 return 1; 1086 return 1;
1087} 1087}
1088 1088
1089static int 1089static int
1090rdread(dev_t dev, struct uio *uio, int flags) 1090rdread(dev_t dev, struct uio *uio, int flags)
1091{ 1091{
1092 1092
1093 return physio(rdstrategy, NULL, dev, B_READ, minphys, uio); 1093 return physio(rdstrategy, NULL, dev, B_READ, minphys, uio);
1094} 1094}
1095 1095
1096static int 1096static int
1097rdwrite(dev_t dev, struct uio *uio, int flags) 1097rdwrite(dev_t dev, struct uio *uio, int flags)
1098{ 1098{
1099 1099
1100 return physio(rdstrategy, NULL, dev, B_WRITE, minphys, uio); 1100 return physio(rdstrategy, NULL, dev, B_WRITE, minphys, uio);
1101} 1101}
1102 1102
1103static int 1103static int
1104rdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 1104rdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
1105{ 1105{
1106 struct rd_softc *sc = device_lookup_private(&rd_cd, rdunit(dev)); 1106 struct rd_softc *sc = device_lookup_private(&rd_cd, rdunit(dev));
1107 struct disklabel *lp = sc->sc_dkdev.dk_label; 1107 struct disklabel *lp = sc->sc_dkdev.dk_label;
1108 int error, flags; 1108 int error, flags;
1109 1109
1110 switch (cmd) { 1110 switch (cmd) {
1111 case DIOCGDINFO: 1111 case DIOCGDINFO:
1112 *(struct disklabel *)data = *lp; 1112 *(struct disklabel *)data = *lp;
1113 return 0; 1113 return 0;
1114 1114
1115 case DIOCGPART: 1115 case DIOCGPART:
1116 ((struct partinfo *)data)->disklab = lp; 1116 ((struct partinfo *)data)->disklab = lp;
1117 ((struct partinfo *)data)->part = 1117 ((struct partinfo *)data)->part =
1118 &lp->d_partitions[rdpart(dev)]; 1118 &lp->d_partitions[rdpart(dev)];
1119 return 0; 1119 return 0;
1120 1120
1121 case DIOCWLABEL: 1121 case DIOCWLABEL:
1122 if ((flag & FWRITE) == 0) 1122 if ((flag & FWRITE) == 0)
1123 return EBADF; 1123 return EBADF;
1124 if (*(int *)data) 1124 if (*(int *)data)
1125 sc->sc_flags |= RDF_WLABEL; 1125 sc->sc_flags |= RDF_WLABEL;
1126 else 1126 else
1127 sc->sc_flags &= ~RDF_WLABEL; 1127 sc->sc_flags &= ~RDF_WLABEL;
1128 return 0; 1128 return 0;
1129 1129
1130 case DIOCSDINFO: 1130 case DIOCSDINFO:
1131 if ((flag & FWRITE) == 0) 1131 if ((flag & FWRITE) == 0)
1132 return EBADF; 1132 return EBADF;
1133 return setdisklabel(lp, (struct disklabel *)data, 1133 return setdisklabel(lp, (struct disklabel *)data,
1134 (sc->sc_flags & RDF_WLABEL) ? 0 : sc->sc_dkdev.dk_openmask, 1134 (sc->sc_flags & RDF_WLABEL) ? 0 : sc->sc_dkdev.dk_openmask,
1135 NULL); 1135 NULL);
1136 1136
1137 case DIOCWDINFO: 1137 case DIOCWDINFO:
1138 if ((flag & FWRITE) == 0) 1138 if ((flag & FWRITE) == 0)
1139 return EBADF; 1139 return EBADF;
1140 error = setdisklabel(lp, (struct disklabel *)data, 1140 error = setdisklabel(lp, (struct disklabel *)data,
1141 (sc->sc_flags & RDF_WLABEL) ? 0 : sc->sc_dkdev.dk_openmask, 1141 (sc->sc_flags & RDF_WLABEL) ? 0 : sc->sc_dkdev.dk_openmask,
1142 NULL); 1142 NULL);
1143 if (error) 1143 if (error)
1144 return error; 1144 return error;
1145 flags = sc->sc_flags; 1145 flags = sc->sc_flags;
1146 sc->sc_flags = RDF_ALIVE | RDF_WLABEL; 1146 sc->sc_flags = RDF_ALIVE | RDF_WLABEL;
1147 error = writedisklabel(rdlabdev(dev), rdstrategy, lp, NULL); 1147 error = writedisklabel(rdlabdev(dev), rdstrategy, lp, NULL);
1148 sc->sc_flags = flags; 1148 sc->sc_flags = flags;
1149 return error; 1149 return error;
1150 1150
1151 case DIOCGDEFLABEL: 1151 case DIOCGDEFLABEL:
1152 rdgetdefaultlabel(sc, (struct disklabel *)data); 1152 rdgetdefaultlabel(sc, (struct disklabel *)data);
1153 return 0; 1153 return 0;
1154 } 1154 }
1155 return EINVAL; 1155 return EINVAL;
1156} 1156}
1157 1157
1158static void 1158static void
1159rdgetdefaultlabel(struct rd_softc *sc, struct disklabel *lp) 1159rdgetdefaultlabel(struct rd_softc *sc, struct disklabel *lp)
1160{ 1160{
1161 int type = sc->sc_type; 1161 int type = sc->sc_type;
1162 1162
1163 memset((void *)lp, 0, sizeof(struct disklabel)); 1163 memset((void *)lp, 0, sizeof(struct disklabel));
1164 1164
1165 lp->d_type = DTYPE_HPIB; 1165 lp->d_type = DTYPE_HPIB;
1166 lp->d_secsize = DEV_BSIZE; 1166 lp->d_secsize = DEV_BSIZE;
1167 lp->d_nsectors = rdidentinfo[type].ri_nbpt; 1167 lp->d_nsectors = rdidentinfo[type].ri_nbpt;
1168 lp->d_ntracks = rdidentinfo[type].ri_ntpc; 1168 lp->d_ntracks = rdidentinfo[type].ri_ntpc;
1169 lp->d_ncylinders = rdidentinfo[type].ri_ncyl; 1169 lp->d_ncylinders = rdidentinfo[type].ri_ncyl;
1170 lp->d_secperunit = rdidentinfo[type].ri_nblocks; 1170 lp->d_secperunit = rdidentinfo[type].ri_nblocks;
1171 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; 1171 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
1172 1172
1173 strlcpy(lp->d_typename, rdidentinfo[type].ri_desc, 1173 strlcpy(lp->d_typename, rdidentinfo[type].ri_desc,
1174 sizeof(lp->d_typename)); 1174 sizeof(lp->d_typename));
1175 strlcpy(lp->d_packname, "fictitious", sizeof(lp->d_packname)); 1175 strlcpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
1176 lp->d_rpm = 3000; 1176 lp->d_rpm = 3000;
1177 lp->d_interleave = 1; 1177 lp->d_interleave = 1;
1178 lp->d_flags = 0; 1178 lp->d_flags = 0;
1179 1179
1180 lp->d_partitions[RAW_PART].p_offset = 0; 1180 lp->d_partitions[RAW_PART].p_offset = 0;
1181 lp->d_partitions[RAW_PART].p_size = 1181 lp->d_partitions[RAW_PART].p_size =
1182 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); 1182 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1183 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; 1183 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
1184 lp->d_npartitions = RAW_PART + 1; 1184 lp->d_npartitions = RAW_PART + 1;
1185 1185
1186 lp->d_magic = DISKMAGIC; 1186 lp->d_magic = DISKMAGIC;
1187 lp->d_magic2 = DISKMAGIC; 1187 lp->d_magic2 = DISKMAGIC;
1188 lp->d_checksum = dkcksum(lp); 1188 lp->d_checksum = dkcksum(lp);
1189} 1189}
1190 1190
1191int 1191int
1192rdsize(dev_t dev) 1192rdsize(dev_t dev)
1193{ 1193{
1194 struct rd_softc *sc; 1194 struct rd_softc *sc;
1195 int psize, didopen = 0; 1195 int psize, didopen = 0;
1196 1196
1197 sc = device_lookup_private(&rd_cd, rdunit(dev)); 1197 sc = device_lookup_private(&rd_cd, rdunit(dev));
1198 if (sc == NULL) 1198 if (sc == NULL)
1199 return ENXIO; 1199 return ENXIO;
1200 1200
1201 if ((sc->sc_flags & RDF_ALIVE) == 0) 1201 if ((sc->sc_flags & RDF_ALIVE) == 0)
1202 return ENXIO; 1202 return ENXIO;
1203 1203
1204 /* 1204 /*
1205 * We get called very early on (via swapconf) 1205 * We get called very early on (via swapconf)
1206 * without the device being open so we may need 1206 * without the device being open so we may need
1207 * to handle it here. 1207 * to handle it here.
1208 */ 1208 */
1209 if (sc->sc_dkdev.dk_openmask == 0) { 1209 if (sc->sc_dkdev.dk_openmask == 0) {
1210 if (rdopen(dev, FREAD|FWRITE, S_IFBLK, NULL)) 1210 if (rdopen(dev, FREAD|FWRITE, S_IFBLK, NULL))
1211 return -1; 1211 return -1;
1212 didopen = 1; 1212 didopen = 1;
1213 } 1213 }
1214 psize = sc->sc_dkdev.dk_label->d_partitions[rdpart(dev)].p_size * 1214 psize = sc->sc_dkdev.dk_label->d_partitions[rdpart(dev)].p_size *
1215 (sc->sc_dkdev.dk_label->d_secsize / DEV_BSIZE); 1215 (sc->sc_dkdev.dk_label->d_secsize / DEV_BSIZE);
1216 if (didopen) 1216 if (didopen)
1217 (void)rdclose(dev, FREAD|FWRITE, S_IFBLK, NULL); 1217 (void)rdclose(dev, FREAD|FWRITE, S_IFBLK, NULL);
1218 return psize; 1218 return psize;
1219} 1219}
1220 1220
1221#ifdef DEBUG 1221#ifdef DEBUG
1222static void 1222static void
1223rdprinterr(const char *str, short err, const char **tab) 1223rdprinterr(const char *str, short err, const char **tab)
1224{ 1224{
1225 int i; 1225 int i;
1226 int printed; 1226 int printed;
1227 1227
1228 if (err == 0) 1228 if (err == 0)
1229 return; 1229 return;
1230 printf(" %s error %d field:", str, err); 1230 printf(" %s error %d field:", str, err);
1231 printed = 0; 1231 printed = 0;
1232 for (i = 0; i < 16; i++) 1232 for (i = 0; i < 16; i++)
1233 if (err & (0x8000 >> i)) 1233 if (err & (0x8000 >> i))
1234 printf("%s%s", printed++ ? " + " : " ", tab[i]); 1234 printf("%s%s", printed++ ? " + " : " ", tab[i]);
1235 printf("\n"); 1235 printf("\n");
1236} 1236}
1237#endif 1237#endif
1238 1238
1239static int rddoingadump; /* simple mutex */ 1239static int rddoingadump; /* simple mutex */
1240 1240
1241/* 1241/*
1242 * Non-interrupt driven, non-DMA dump routine. 1242 * Non-interrupt driven, non-DMA dump routine.
1243 */ 1243 */
1244static int 1244static int
1245rddump(dev_t dev, daddr_t blkno, void *va, size_t size) 1245rddump(dev_t dev, daddr_t blkno, void *va, size_t size)
1246{ 1246{
1247 int sectorsize; /* size of a disk sector */ 1247 int sectorsize; /* size of a disk sector */
1248 int nsects; /* number of sectors in partition */ 1248 int nsects; /* number of sectors in partition */
1249 int sectoff; /* sector offset of partition */ 1249 int sectoff; /* sector offset of partition */
1250 int totwrt; /* total number of sectors left to write */ 1250 int totwrt; /* total number of sectors left to write */
1251 int nwrt; /* current number of sectors to write */ 1251 int nwrt; /* current number of sectors to write */
1252 int unit, part; 1252 int unit, part;
1253 int ctlr, slave; 1253 int ctlr, slave;
1254 struct rd_softc *sc; 1254 struct rd_softc *sc;
1255 struct disklabel *lp; 1255 struct disklabel *lp;
1256 char stat; 1256 char stat;
1257 1257
1258 /* Check for recursive dump; if so, punt. */ 1258 /* Check for recursive dump; if so, punt. */
1259 if (rddoingadump) 1259 if (rddoingadump)
1260 return EFAULT; 1260 return EFAULT;
1261 rddoingadump = 1; 1261 rddoingadump = 1;
1262 1262
1263 /* Decompose unit and partition. */ 1263 /* Decompose unit and partition. */
1264 unit = rdunit(dev); 1264 unit = rdunit(dev);
1265 part = rdpart(dev); 1265 part = rdpart(dev);
1266 1266
1267 /* Make sure dump device is ok. */ 1267 /* Make sure dump device is ok. */
1268 sc = device_lookup_private(&rd_cd, rdunit(dev)); 1268 sc = device_lookup_private(&rd_cd, rdunit(dev));
1269 if (sc == NULL) 1269 if (sc == NULL)
1270 return ENXIO; 1270 return ENXIO;
1271 1271
1272 if ((sc->sc_flags & RDF_ALIVE) == 0) 1272 if ((sc->sc_flags & RDF_ALIVE) == 0)
1273 return ENXIO; 1273 return ENXIO;
1274 1274
1275 ctlr = device_unit(device_parent(sc->sc_dev)); 1275 ctlr = device_unit(device_parent(sc->sc_dev));
1276 slave = sc->sc_slave; 1276 slave = sc->sc_slave;
1277 1277
1278 /* 1278 /*
1279 * Convert to disk sectors. Request must be a multiple of size. 1279 * Convert to disk sectors. Request must be a multiple of size.
1280 */ 1280 */
1281 lp = sc->sc_dkdev.dk_label; 1281 lp = sc->sc_dkdev.dk_label;
1282 sectorsize = lp->d_secsize; 1282 sectorsize = lp->d_secsize;
1283 if ((size % sectorsize) != 0) 1283 if ((size % sectorsize) != 0)
1284 return EFAULT; 1284 return EFAULT;
1285 totwrt = size / sectorsize; 1285 totwrt = size / sectorsize;
1286 blkno = dbtob(blkno) / sectorsize; /* blkno in DEV_BSIZE units */ 1286 blkno = dbtob(blkno) / sectorsize; /* blkno in DEV_BSIZE units */
1287 1287
1288 nsects = lp->d_partitions[part].p_size; 1288 nsects = lp->d_partitions[part].p_size;
1289 sectoff = lp->d_partitions[part].p_offset; 1289 sectoff = lp->d_partitions[part].p_offset;
1290 1290
1291 /* Check transfer bounds against partition size. */ 1291 /* Check transfer bounds against partition size. */
1292 if ((blkno < 0) || (blkno + totwrt) > nsects) 1292 if ((blkno < 0) || (blkno + totwrt) > nsects)
1293 return EINVAL; 1293 return EINVAL;
1294 1294
1295 /* Offset block number to start of partition. */ 1295 /* Offset block number to start of partition. */
1296 blkno += sectoff; 1296 blkno += sectoff;
1297 1297
1298 while (totwrt > 0) { 1298 while (totwrt > 0) {
1299 nwrt = totwrt; /* XXX */ 1299 nwrt = totwrt; /* XXX */
1300#ifndef RD_DUMP_NOT_TRUSTED 1300#ifndef RD_DUMP_NOT_TRUSTED
1301 /* 1301 /*
1302 * Fill out and send HPIB command. 1302 * Fill out and send HPIB command.
1303 */ 1303 */
1304 sc->sc_ioc.c_unit = C_SUNIT(sc->sc_punit); 1304 sc->sc_ioc.c_unit = C_SUNIT(sc->sc_punit);
1305 sc->sc_ioc.c_volume = C_SVOL(0); 1305 sc->sc_ioc.c_volume = C_SVOL(0);
1306 sc->sc_ioc.c_saddr = C_SADDR; 1306 sc->sc_ioc.c_saddr = C_SADDR;
1307 sc->sc_ioc.c_hiaddr = 0; 1307 sc->sc_ioc.c_hiaddr = 0;
1308 sc->sc_ioc.c_addr = RDBTOS(blkno); 1308 sc->sc_ioc.c_addr = RDBTOS(blkno);
1309 sc->sc_ioc.c_nop2 = C_NOP; 1309 sc->sc_ioc.c_nop2 = C_NOP;
1310 sc->sc_ioc.c_slen = C_SLEN; 1310 sc->sc_ioc.c_slen = C_SLEN;
1311 sc->sc_ioc.c_len = nwrt * sectorsize; 1311 sc->sc_ioc.c_len = nwrt * sectorsize;
1312 sc->sc_ioc.c_cmd = C_WRITE; 1312 sc->sc_ioc.c_cmd = C_WRITE;
1313 hpibsend(ctlr, slave, C_CMD, &sc->sc_ioc.c_unit, 1313 hpibsend(ctlr, slave, C_CMD, &sc->sc_ioc.c_unit,
1314 sizeof(sc->sc_ioc) - 2); 1314 sizeof(sc->sc_ioc) - 2);
1315 if (hpibswait(ctlr, slave)) 1315 if (hpibswait(ctlr, slave))
1316 return EIO; 1316 return EIO;
1317 1317
1318 /* 1318 /*
1319 * Send the data. 1319 * Send the data.
1320 */ 1320 */
1321 hpibsend(ctlr, slave, C_EXEC, va, nwrt * sectorsize); 1321 hpibsend(ctlr, slave, C_EXEC, va, nwrt * sectorsize);
1322 (void) hpibswait(ctlr, slave); 1322 (void) hpibswait(ctlr, slave);
1323 hpibrecv(ctlr, slave, C_QSTAT, &stat, 1); 1323 hpibrecv(ctlr, slave, C_QSTAT, &stat, 1);
1324 if (stat) 1324 if (stat)
1325 return EIO; 1325 return EIO;
1326#else /* RD_DUMP_NOT_TRUSTED */ 1326#else /* RD_DUMP_NOT_TRUSTED */
1327 /* Let's just talk about this first... */ 1327 /* Let's just talk about this first... */
1328 printf("%s: dump addr %p, blk %d\n", device_xname(sc->sc_dev), 1328 printf("%s: dump addr %p, blk %d\n", device_xname(sc->sc_dev),
1329 va, blkno); 1329 va, blkno);
1330 delay(500 * 1000); /* half a second */ 1330 delay(500 * 1000); /* half a second */
1331#endif /* RD_DUMP_NOT_TRUSTED */ 1331#endif /* RD_DUMP_NOT_TRUSTED */
1332 1332
1333 /* update block count */ 1333 /* update block count */
1334 totwrt -= nwrt; 1334 totwrt -= nwrt;
1335 blkno += nwrt; 1335 blkno += nwrt;
1336 va = (char *)va + sectorsize * nwrt; 1336 va = (char *)va + sectorsize * nwrt;
1337 } 1337 }
1338 rddoingadump = 0; 1338 rddoingadump = 0;
1339 return 0; 1339 return 0;
1340} 1340}