mscp_disk.c revision 1.42 1 1.42 agc /* $NetBSD: mscp_disk.c,v 1.42 2003/08/07 16:31:09 agc Exp $ */
2 1.1 ragge /*
3 1.1 ragge * Copyright (c) 1988 Regents of the University of California.
4 1.1 ragge * All rights reserved.
5 1.1 ragge *
6 1.1 ragge * This code is derived from software contributed to Berkeley by
7 1.1 ragge * Chris Torek.
8 1.1 ragge *
9 1.1 ragge * Redistribution and use in source and binary forms, with or without
10 1.1 ragge * modification, are permitted provided that the following conditions
11 1.1 ragge * are met:
12 1.1 ragge * 1. Redistributions of source code must retain the above copyright
13 1.1 ragge * notice, this list of conditions and the following disclaimer.
14 1.1 ragge * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 ragge * notice, this list of conditions and the following disclaimer in the
16 1.1 ragge * documentation and/or other materials provided with the distribution.
17 1.42 agc * 3. Neither the name of the University nor the names of its contributors
18 1.42 agc * may be used to endorse or promote products derived from this software
19 1.42 agc * without specific prior written permission.
20 1.42 agc *
21 1.42 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.42 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.42 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.42 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.42 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.42 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.42 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.42 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.42 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.42 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.42 agc * SUCH DAMAGE.
32 1.42 agc *
33 1.42 agc * @(#)uda.c 7.32 (Berkeley) 2/13/91
34 1.42 agc */
35 1.42 agc
36 1.42 agc /*
37 1.42 agc * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
38 1.42 agc *
39 1.42 agc * This code is derived from software contributed to Berkeley by
40 1.42 agc * Chris Torek.
41 1.42 agc *
42 1.42 agc * Redistribution and use in source and binary forms, with or without
43 1.42 agc * modification, are permitted provided that the following conditions
44 1.42 agc * are met:
45 1.42 agc * 1. Redistributions of source code must retain the above copyright
46 1.42 agc * notice, this list of conditions and the following disclaimer.
47 1.42 agc * 2. Redistributions in binary form must reproduce the above copyright
48 1.42 agc * notice, this list of conditions and the following disclaimer in the
49 1.42 agc * documentation and/or other materials provided with the distribution.
50 1.1 ragge * 3. All advertising materials mentioning features or use of this software
51 1.1 ragge * must display the following acknowledgement:
52 1.1 ragge * This product includes software developed by the University of
53 1.1 ragge * California, Berkeley and its contributors.
54 1.1 ragge * 4. Neither the name of the University nor the names of its contributors
55 1.1 ragge * may be used to endorse or promote products derived from this software
56 1.1 ragge * without specific prior written permission.
57 1.1 ragge *
58 1.1 ragge * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 1.1 ragge * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 1.1 ragge * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 1.1 ragge * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 1.1 ragge * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 1.1 ragge * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 1.1 ragge * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 1.1 ragge * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 1.1 ragge * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 1.1 ragge * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 1.1 ragge * SUCH DAMAGE.
69 1.1 ragge *
70 1.1 ragge * @(#)uda.c 7.32 (Berkeley) 2/13/91
71 1.1 ragge */
72 1.1 ragge
73 1.1 ragge /*
74 1.1 ragge * RA disk device driver
75 1.17 ragge * RX MSCP floppy disk device driver
76 1.1 ragge */
77 1.1 ragge
78 1.1 ragge /*
79 1.1 ragge * TODO
80 1.1 ragge * write bad block forwarding code
81 1.1 ragge */
82 1.30 lukem
83 1.30 lukem #include <sys/cdefs.h>
84 1.42 agc __KERNEL_RCSID(0, "$NetBSD: mscp_disk.c,v 1.42 2003/08/07 16:31:09 agc Exp $");
85 1.1 ragge
86 1.1 ragge #include <sys/param.h>
87 1.1 ragge #include <sys/buf.h>
88 1.1 ragge #include <sys/device.h>
89 1.2 ragge #include <sys/disk.h>
90 1.1 ragge #include <sys/disklabel.h>
91 1.2 ragge #include <sys/ioctl.h>
92 1.1 ragge #include <sys/stat.h>
93 1.2 ragge #include <sys/fcntl.h>
94 1.17 ragge #include <sys/reboot.h>
95 1.2 ragge #include <sys/proc.h>
96 1.2 ragge #include <sys/systm.h>
97 1.33 gehenna #include <sys/conf.h>
98 1.17 ragge
99 1.18 ragge #include <ufs/ufs/dinode.h>
100 1.17 ragge #include <ufs/ffs/fs.h>
101 1.10 ragge
102 1.21 ragge #include <machine/bus.h>
103 1.10 ragge #include <machine/cpu.h>
104 1.1 ragge
105 1.21 ragge #include <dev/mscp/mscp.h>
106 1.21 ragge #include <dev/mscp/mscpreg.h>
107 1.21 ragge #include <dev/mscp/mscpvar.h>
108 1.1 ragge
109 1.14 jtk #include "locators.h"
110 1.17 ragge #include "ioconf.h"
111 1.17 ragge #include "ra.h"
112 1.17 ragge
113 1.1 ragge /*
114 1.1 ragge * Drive status, per drive
115 1.1 ragge */
116 1.1 ragge struct ra_softc {
117 1.1 ragge struct device ra_dev; /* Autoconf struct */
118 1.1 ragge struct disk ra_disk;
119 1.1 ragge int ra_state; /* open/closed state */
120 1.1 ragge u_long ra_mediaid; /* media id */
121 1.1 ragge int ra_hwunit; /* Hardware unit number */
122 1.1 ragge int ra_havelabel; /* true if we have a label */
123 1.1 ragge int ra_wlabel; /* label sector is currently writable */
124 1.1 ragge };
125 1.1 ragge
126 1.17 ragge #define rx_softc ra_softc
127 1.17 ragge
128 1.17 ragge void rxattach __P((struct device *, struct device *, void *));
129 1.17 ragge int rx_putonline __P((struct rx_softc *));
130 1.17 ragge void rrmakelabel __P((struct disklabel *, long));
131 1.17 ragge
132 1.17 ragge #if NRA
133 1.17 ragge
134 1.16 ragge int ramatch __P((struct device *, struct cfdata *, void *));
135 1.2 ragge void raattach __P((struct device *, struct device *, void *));
136 1.2 ragge int ra_putonline __P((struct ra_softc *));
137 1.2 ragge
138 1.35 thorpej CFATTACH_DECL(ra, sizeof(struct ra_softc),
139 1.36 thorpej ramatch, rxattach, NULL, NULL);
140 1.15 thorpej
141 1.33 gehenna dev_type_open(raopen);
142 1.33 gehenna dev_type_close(raclose);
143 1.33 gehenna dev_type_read(raread);
144 1.33 gehenna dev_type_write(rawrite);
145 1.33 gehenna dev_type_ioctl(raioctl);
146 1.33 gehenna dev_type_strategy(rastrategy);
147 1.33 gehenna dev_type_dump(radump);
148 1.33 gehenna dev_type_size(rasize);
149 1.33 gehenna
150 1.33 gehenna const struct bdevsw ra_bdevsw = {
151 1.33 gehenna raopen, raclose, rastrategy, raioctl, radump, rasize, D_DISK
152 1.33 gehenna };
153 1.33 gehenna
154 1.33 gehenna const struct cdevsw ra_cdevsw = {
155 1.33 gehenna raopen, raclose, raread, rawrite, raioctl,
156 1.37 jdolecek nostop, notty, nopoll, nommap, nokqfilter, D_DISK
157 1.33 gehenna };
158 1.33 gehenna
159 1.1 ragge /*
160 1.1 ragge * More driver definitions, for generic MSCP code.
161 1.1 ragge */
162 1.1 ragge
163 1.1 ragge int
164 1.16 ragge ramatch(parent, cf, aux)
165 1.1 ragge struct device *parent;
166 1.16 ragge struct cfdata *cf;
167 1.16 ragge void *aux;
168 1.1 ragge {
169 1.2 ragge struct drive_attach_args *da = aux;
170 1.2 ragge struct mscp *mp = da->da_mp;
171 1.1 ragge
172 1.2 ragge if ((da->da_typ & MSCPBUS_DISK) == 0)
173 1.2 ragge return 0;
174 1.14 jtk if (cf->cf_loc[MSCPBUSCF_DRIVE] != MSCPBUSCF_DRIVE_DEFAULT &&
175 1.14 jtk cf->cf_loc[MSCPBUSCF_DRIVE] != mp->mscp_unit)
176 1.1 ragge return 0;
177 1.17 ragge /*
178 1.17 ragge * Check if this disk is a floppy; then don't configure it.
179 1.17 ragge * Seems to be a safe way to test it per Chris Torek.
180 1.17 ragge */
181 1.17 ragge if (MSCP_MID_ECH(1, mp->mscp_guse.guse_mediaid) == 'X' - '@')
182 1.17 ragge return 0;
183 1.1 ragge return 1;
184 1.1 ragge }
185 1.1 ragge
186 1.1 ragge /*
187 1.1 ragge * (Try to) put the drive online. This is done the first time the
188 1.1 ragge * drive is opened, or if it har fallen offline.
189 1.1 ragge */
190 1.1 ragge int
191 1.1 ragge ra_putonline(ra)
192 1.1 ragge struct ra_softc *ra;
193 1.1 ragge {
194 1.1 ragge struct disklabel *dl;
195 1.40 dsl const char *msg;
196 1.33 gehenna int maj;
197 1.1 ragge
198 1.17 ragge if (rx_putonline(ra) != MSCP_DONE)
199 1.1 ragge return MSCP_FAILED;
200 1.1 ragge
201 1.17 ragge dl = ra->ra_disk.dk_label;
202 1.1 ragge
203 1.17 ragge ra->ra_state = DK_RDLABEL;
204 1.5 christos printf("%s", ra->ra_dev.dv_xname);
205 1.33 gehenna maj = cdevsw_lookup_major(&ra_cdevsw);
206 1.33 gehenna if ((msg = readdisklabel(MAKEDISKDEV(maj, ra->ra_dev.dv_unit,
207 1.17 ragge RAW_PART), rastrategy, dl, NULL)) != NULL)
208 1.5 christos printf(": %s", msg);
209 1.17 ragge else {
210 1.1 ragge ra->ra_havelabel = 1;
211 1.17 ragge ra->ra_state = DK_OPEN;
212 1.17 ragge }
213 1.1 ragge
214 1.5 christos printf(": size %d sectors\n", dl->d_secperunit);
215 1.1 ragge
216 1.1 ragge return MSCP_DONE;
217 1.1 ragge }
218 1.17 ragge
219 1.1 ragge /*
220 1.1 ragge * Open a drive.
221 1.1 ragge */
222 1.1 ragge /*ARGSUSED*/
223 1.1 ragge int
224 1.1 ragge raopen(dev, flag, fmt, p)
225 1.1 ragge dev_t dev;
226 1.1 ragge int flag, fmt;
227 1.1 ragge struct proc *p;
228 1.1 ragge {
229 1.23 augustss struct ra_softc *ra;
230 1.2 ragge int part, unit, mask;
231 1.1 ragge /*
232 1.1 ragge * Make sure this is a reasonable open request.
233 1.1 ragge */
234 1.17 ragge unit = DISKUNIT(dev);
235 1.1 ragge if (unit >= ra_cd.cd_ndevs)
236 1.1 ragge return ENXIO;
237 1.1 ragge ra = ra_cd.cd_devs[unit];
238 1.1 ragge if (ra == 0)
239 1.1 ragge return ENXIO;
240 1.1 ragge
241 1.1 ragge /*
242 1.1 ragge * If this is the first open; we must first try to put
243 1.1 ragge * the disk online (and read the label).
244 1.1 ragge */
245 1.17 ragge if (ra->ra_state == DK_CLOSED)
246 1.1 ragge if (ra_putonline(ra) == MSCP_FAILED)
247 1.17 ragge return ENXIO;
248 1.1 ragge
249 1.11 ragge /* If the disk has no label; allow writing everywhere */
250 1.11 ragge if (ra->ra_havelabel == 0)
251 1.11 ragge ra->ra_wlabel = 1;
252 1.11 ragge
253 1.17 ragge part = DISKPART(dev);
254 1.17 ragge if (part >= ra->ra_disk.dk_label->d_npartitions)
255 1.17 ragge return ENXIO;
256 1.1 ragge
257 1.1 ragge /*
258 1.1 ragge * Wait for the state to settle
259 1.1 ragge */
260 1.1 ragge #if notyet
261 1.17 ragge while (ra->ra_state != DK_OPEN)
262 1.1 ragge if ((error = tsleep((caddr_t)ra, (PZERO + 1) | PCATCH,
263 1.1 ragge devopn, 0))) {
264 1.1 ragge splx(s);
265 1.1 ragge return (error);
266 1.1 ragge }
267 1.1 ragge #endif
268 1.1 ragge
269 1.1 ragge mask = 1 << part;
270 1.1 ragge
271 1.1 ragge switch (fmt) {
272 1.1 ragge case S_IFCHR:
273 1.1 ragge ra->ra_disk.dk_copenmask |= mask;
274 1.1 ragge break;
275 1.1 ragge case S_IFBLK:
276 1.1 ragge ra->ra_disk.dk_bopenmask |= mask;
277 1.1 ragge break;
278 1.1 ragge }
279 1.1 ragge ra->ra_disk.dk_openmask |= mask;
280 1.1 ragge return 0;
281 1.1 ragge }
282 1.1 ragge
283 1.1 ragge /* ARGSUSED */
284 1.1 ragge int
285 1.1 ragge raclose(dev, flags, fmt, p)
286 1.1 ragge dev_t dev;
287 1.1 ragge int flags, fmt;
288 1.1 ragge struct proc *p;
289 1.1 ragge {
290 1.23 augustss int unit = DISKUNIT(dev);
291 1.23 augustss struct ra_softc *ra = ra_cd.cd_devs[unit];
292 1.17 ragge int mask = (1 << DISKPART(dev));
293 1.1 ragge
294 1.1 ragge switch (fmt) {
295 1.1 ragge case S_IFCHR:
296 1.1 ragge ra->ra_disk.dk_copenmask &= ~mask;
297 1.1 ragge break;
298 1.1 ragge case S_IFBLK:
299 1.1 ragge ra->ra_disk.dk_bopenmask &= ~mask;
300 1.1 ragge break;
301 1.1 ragge }
302 1.1 ragge ra->ra_disk.dk_openmask =
303 1.1 ragge ra->ra_disk.dk_copenmask | ra->ra_disk.dk_bopenmask;
304 1.1 ragge
305 1.1 ragge /*
306 1.1 ragge * Should wait for I/O to complete on this partition even if
307 1.1 ragge * others are open, but wait for work on blkflush().
308 1.1 ragge */
309 1.11 ragge #if notyet
310 1.1 ragge if (ra->ra_openpart == 0) {
311 1.29 thorpej s = spluba();
312 1.31 hannken while (BUFQ_PEEK(&udautab[unit]) != NULL)
313 1.25 thorpej (void) tsleep(&udautab[unit], PZERO - 1,
314 1.25 thorpej "raclose", 0);
315 1.1 ragge splx(s);
316 1.1 ragge ra->ra_state = CLOSED;
317 1.1 ragge ra->ra_wlabel = 0;
318 1.1 ragge }
319 1.1 ragge #endif
320 1.1 ragge return (0);
321 1.1 ragge }
322 1.1 ragge
323 1.1 ragge /*
324 1.1 ragge * Queue a transfer request, and if possible, hand it to the controller.
325 1.1 ragge */
326 1.1 ragge void
327 1.1 ragge rastrategy(bp)
328 1.23 augustss struct buf *bp;
329 1.1 ragge {
330 1.23 augustss int unit;
331 1.23 augustss struct ra_softc *ra;
332 1.32 ragge int b;
333 1.32 ragge
334 1.1 ragge /*
335 1.1 ragge * Make sure this is a reasonable drive to use.
336 1.1 ragge */
337 1.17 ragge unit = DISKUNIT(bp->b_dev);
338 1.1 ragge if (unit > ra_cd.cd_ndevs || (ra = ra_cd.cd_devs[unit]) == NULL) {
339 1.1 ragge bp->b_error = ENXIO;
340 1.11 ragge bp->b_flags |= B_ERROR;
341 1.11 ragge goto done;
342 1.1 ragge }
343 1.1 ragge /*
344 1.1 ragge * If drive is open `raw' or reading label, let it at it.
345 1.1 ragge */
346 1.17 ragge if (ra->ra_state == DK_RDLABEL) {
347 1.32 ragge /* Make some statistics... /bqt */
348 1.32 ragge b = splbio();
349 1.32 ragge disk_busy(&ra->ra_disk);
350 1.32 ragge splx(b);
351 1.7 ragge mscp_strategy(bp, ra->ra_dev.dv_parent);
352 1.1 ragge return;
353 1.1 ragge }
354 1.17 ragge
355 1.17 ragge /* If disk is not online, try to put it online */
356 1.17 ragge if (ra->ra_state == DK_CLOSED)
357 1.17 ragge if (ra_putonline(ra) == MSCP_FAILED) {
358 1.17 ragge bp->b_flags |= B_ERROR;
359 1.17 ragge bp->b_error = EIO;
360 1.17 ragge goto done;
361 1.17 ragge }
362 1.1 ragge
363 1.1 ragge /*
364 1.1 ragge * Determine the size of the transfer, and make sure it is
365 1.1 ragge * within the boundaries of the partition.
366 1.1 ragge */
367 1.41 thorpej if (bounds_check_with_label(&ra->ra_disk, bp, ra->ra_wlabel) <= 0)
368 1.17 ragge goto done;
369 1.1 ragge
370 1.12 ragge /* Make some statistics... /bqt */
371 1.32 ragge b = splbio();
372 1.32 ragge disk_busy(&ra->ra_disk);
373 1.32 ragge splx(b);
374 1.7 ragge mscp_strategy(bp, ra->ra_dev.dv_parent);
375 1.1 ragge return;
376 1.1 ragge
377 1.7 ragge done:
378 1.1 ragge biodone(bp);
379 1.1 ragge }
380 1.1 ragge
381 1.1 ragge int
382 1.33 gehenna raread(dev, uio, flags)
383 1.17 ragge dev_t dev;
384 1.17 ragge struct uio *uio;
385 1.33 gehenna int flags;
386 1.1 ragge {
387 1.1 ragge
388 1.17 ragge return (physio(rastrategy, NULL, dev, B_READ, minphys, uio));
389 1.1 ragge }
390 1.1 ragge
391 1.1 ragge int
392 1.33 gehenna rawrite(dev, uio, flags)
393 1.17 ragge dev_t dev;
394 1.17 ragge struct uio *uio;
395 1.33 gehenna int flags;
396 1.1 ragge {
397 1.1 ragge
398 1.17 ragge return (physio(rastrategy, NULL, dev, B_WRITE, minphys, uio));
399 1.1 ragge }
400 1.1 ragge
401 1.1 ragge /*
402 1.1 ragge * I/O controls.
403 1.1 ragge */
404 1.1 ragge int
405 1.1 ragge raioctl(dev, cmd, data, flag, p)
406 1.1 ragge dev_t dev;
407 1.33 gehenna u_long cmd;
408 1.1 ragge caddr_t data;
409 1.1 ragge int flag;
410 1.1 ragge struct proc *p;
411 1.1 ragge {
412 1.23 augustss int unit = DISKUNIT(dev);
413 1.23 augustss struct disklabel *lp, *tp;
414 1.23 augustss struct ra_softc *ra = ra_cd.cd_devs[unit];
415 1.1 ragge int error = 0;
416 1.26 fvdl #ifdef __HAVE_OLD_DISKLABEL
417 1.26 fvdl struct disklabel newlabel;
418 1.26 fvdl #endif
419 1.1 ragge
420 1.1 ragge lp = ra->ra_disk.dk_label;
421 1.1 ragge
422 1.1 ragge switch (cmd) {
423 1.1 ragge
424 1.1 ragge case DIOCGDINFO:
425 1.1 ragge bcopy(lp, data, sizeof (struct disklabel));
426 1.1 ragge break;
427 1.26 fvdl #ifdef __HAVE_OLD_DISKLABEL
428 1.26 fvdl case ODIOCGDINFO:
429 1.26 fvdl bcopy(lp, &newlabel, sizeof disklabel);
430 1.26 fvdl if (newlabel.d_npartitions > OLDMAXPARTITIONS)
431 1.27 fvdl return ENOTTY;
432 1.26 fvdl bcopy(&newlabel, data, sizeof (struct olddisklabel));
433 1.26 fvdl break;
434 1.26 fvdl #endif
435 1.1 ragge
436 1.1 ragge case DIOCGPART:
437 1.1 ragge ((struct partinfo *)data)->disklab = lp;
438 1.1 ragge ((struct partinfo *)data)->part =
439 1.17 ragge &lp->d_partitions[DISKPART(dev)];
440 1.1 ragge break;
441 1.1 ragge
442 1.11 ragge case DIOCWDINFO:
443 1.1 ragge case DIOCSDINFO:
444 1.26 fvdl #ifdef __HAVE_OLD_DISKLABEL
445 1.26 fvdl case ODIOCWDINFO:
446 1.26 fvdl case ODIOCSDINFO:
447 1.26 fvdl if (cmd == ODIOCSDINFO || xfer == ODIOCWDINFO) {
448 1.26 fvdl memset(&newlabel, 0, sizeof newlabel);
449 1.26 fvdl memcpy(&newlabel, data, sizeof (struct olddisklabel));
450 1.26 fvdl tp = &newlabel;
451 1.26 fvdl } else
452 1.26 fvdl #endif
453 1.26 fvdl tp = (struct disklabel *)data;
454 1.26 fvdl
455 1.1 ragge if ((flag & FWRITE) == 0)
456 1.1 ragge error = EBADF;
457 1.11 ragge else {
458 1.26 fvdl error = setdisklabel(lp, tp, 0, 0);
459 1.26 fvdl if ((error == 0) && (cmd == DIOCWDINFO
460 1.26 fvdl #ifdef __HAVE_OLD_DISKLABEL
461 1.26 fvdl || cmd == ODIOCWDINFO
462 1.26 fvdl #else
463 1.26 fvdl )) {
464 1.26 fvdl #endif
465 1.11 ragge ra->ra_wlabel = 1;
466 1.11 ragge error = writedisklabel(dev, rastrategy, lp,0);
467 1.11 ragge ra->ra_wlabel = 0;
468 1.11 ragge }
469 1.11 ragge }
470 1.1 ragge break;
471 1.1 ragge
472 1.1 ragge case DIOCWLABEL:
473 1.1 ragge if ((flag & FWRITE) == 0)
474 1.1 ragge error = EBADF;
475 1.1 ragge else
476 1.1 ragge ra->ra_wlabel = 1;
477 1.1 ragge break;
478 1.1 ragge
479 1.17 ragge case DIOCGDEFLABEL:
480 1.26 fvdl #ifdef __HAVE_OLD_DISKLABEL
481 1.26 fvdl case ODIOCGDEFLABEL:
482 1.26 fvdl if (cmd == ODIOCGDEFLABEL)
483 1.26 fvdl tp = &newlabel;
484 1.26 fvdl else
485 1.26 fvdl #else
486 1.18 ragge tp = (struct disklabel *)data;
487 1.26 fvdl #endif
488 1.26 fvdl bzero(tp, sizeof(struct disklabel));
489 1.18 ragge tp->d_secsize = lp->d_secsize;
490 1.18 ragge tp->d_nsectors = lp->d_nsectors;
491 1.18 ragge tp->d_ntracks = lp->d_ntracks;
492 1.18 ragge tp->d_ncylinders = lp->d_ncylinders;
493 1.18 ragge tp->d_secpercyl = lp->d_secpercyl;
494 1.18 ragge tp->d_secperunit = lp->d_secperunit;
495 1.18 ragge tp->d_type = DTYPE_MSCP;
496 1.18 ragge tp->d_rpm = 3600;
497 1.18 ragge rrmakelabel(tp, ra->ra_mediaid);
498 1.26 fvdl #ifdef __HAVE_OLD_DISKLABEL
499 1.26 fvdl if (cmd == ODIOCGDEFLABEL) {
500 1.26 fvdl if (tp->d_npartitions > OLDMAXPARTITIONS)
501 1.27 fvdl return ENOTTY;
502 1.26 fvdl memcpy(data, tp, sizeof (struct olddisklabel));
503 1.26 fvdl }
504 1.26 fvdl #endif
505 1.18 ragge break;
506 1.18 ragge
507 1.1 ragge default:
508 1.1 ragge error = ENOTTY;
509 1.1 ragge break;
510 1.1 ragge }
511 1.1 ragge return (error);
512 1.1 ragge }
513 1.1 ragge
514 1.1 ragge
515 1.1 ragge int
516 1.1 ragge radump(dev, blkno, va, size)
517 1.1 ragge dev_t dev;
518 1.17 ragge daddr_t blkno;
519 1.17 ragge caddr_t va;
520 1.1 ragge size_t size;
521 1.1 ragge {
522 1.17 ragge return ENXIO;
523 1.1 ragge }
524 1.1 ragge
525 1.1 ragge /*
526 1.1 ragge * Return the size of a partition, if known, or -1 if not.
527 1.1 ragge */
528 1.1 ragge int
529 1.1 ragge rasize(dev)
530 1.1 ragge dev_t dev;
531 1.1 ragge {
532 1.23 augustss int unit = DISKUNIT(dev);
533 1.1 ragge struct ra_softc *ra;
534 1.1 ragge
535 1.1 ragge if (unit >= ra_cd.cd_ndevs || ra_cd.cd_devs[unit] == 0)
536 1.1 ragge return -1;
537 1.1 ragge
538 1.1 ragge ra = ra_cd.cd_devs[unit];
539 1.1 ragge
540 1.17 ragge if (ra->ra_state == DK_CLOSED)
541 1.1 ragge if (ra_putonline(ra) == MSCP_FAILED)
542 1.17 ragge return -1;
543 1.1 ragge
544 1.17 ragge return ra->ra_disk.dk_label->d_partitions[DISKPART(dev)].p_size *
545 1.13 thorpej (ra->ra_disk.dk_label->d_secsize / DEV_BSIZE);
546 1.17 ragge }
547 1.17 ragge
548 1.17 ragge #endif /* NRA */
549 1.17 ragge
550 1.17 ragge #if NRX
551 1.17 ragge
552 1.17 ragge int rxmatch __P((struct device *, struct cfdata *, void *));
553 1.17 ragge
554 1.35 thorpej CFATTACH_DECL(rx, sizeof(struct rx_softc),
555 1.36 thorpej rxmatch, rxattach, NULL, NULL);
556 1.17 ragge
557 1.33 gehenna dev_type_open(rxopen);
558 1.33 gehenna dev_type_read(rxread);
559 1.33 gehenna dev_type_write(rxwrite);
560 1.33 gehenna dev_type_ioctl(rxioctl);
561 1.33 gehenna dev_type_strategy(rxstrategy);
562 1.33 gehenna dev_type_dump(rxdump);
563 1.33 gehenna dev_type_size(rxsize);
564 1.33 gehenna
565 1.33 gehenna const struct bdevsw rx_bdevsw = {
566 1.33 gehenna rxopen, nullclose, rxstrategy, rxioctl, rxdump, rxsize, D_DISK
567 1.33 gehenna };
568 1.33 gehenna
569 1.33 gehenna const struct cdevsw rx_cdevsw = {
570 1.33 gehenna rxopen, nullclose, rxread, rxwrite, rxioctl,
571 1.37 jdolecek nostop, notty, nopoll, nommap, nokqfilter, D_DISK
572 1.33 gehenna };
573 1.33 gehenna
574 1.17 ragge /*
575 1.17 ragge * More driver definitions, for generic MSCP code.
576 1.17 ragge */
577 1.17 ragge
578 1.17 ragge int
579 1.17 ragge rxmatch(parent, cf, aux)
580 1.17 ragge struct device *parent;
581 1.17 ragge struct cfdata *cf;
582 1.17 ragge void *aux;
583 1.17 ragge {
584 1.17 ragge struct drive_attach_args *da = aux;
585 1.17 ragge struct mscp *mp = da->da_mp;
586 1.17 ragge
587 1.17 ragge if ((da->da_typ & MSCPBUS_DISK) == 0)
588 1.17 ragge return 0;
589 1.17 ragge if (cf->cf_loc[MSCPBUSCF_DRIVE] != MSCPBUSCF_DRIVE_DEFAULT &&
590 1.17 ragge cf->cf_loc[MSCPBUSCF_DRIVE] != mp->mscp_unit)
591 1.17 ragge return 0;
592 1.17 ragge /*
593 1.17 ragge * Check if this disk is a floppy; then configure it.
594 1.17 ragge * Seems to be a safe way to test it per Chris Torek.
595 1.17 ragge */
596 1.17 ragge if (MSCP_MID_ECH(1, mp->mscp_guse.guse_mediaid) == 'X' - '@')
597 1.17 ragge return 1;
598 1.17 ragge return 0;
599 1.17 ragge }
600 1.17 ragge
601 1.17 ragge #endif /* NRX */
602 1.17 ragge
603 1.17 ragge /*
604 1.17 ragge * The attach routine only checks and prints drive type.
605 1.17 ragge * Bringing the disk online is done when the disk is accessed
606 1.17 ragge * the first time.
607 1.17 ragge */
608 1.17 ragge void
609 1.17 ragge rxattach(parent, self, aux)
610 1.17 ragge struct device *parent, *self;
611 1.17 ragge void *aux;
612 1.17 ragge {
613 1.17 ragge struct rx_softc *rx = (void *)self;
614 1.17 ragge struct drive_attach_args *da = aux;
615 1.17 ragge struct mscp *mp = da->da_mp;
616 1.17 ragge struct mscp_softc *mi = (void *)parent;
617 1.17 ragge struct disklabel *dl;
618 1.17 ragge
619 1.17 ragge rx->ra_mediaid = mp->mscp_guse.guse_mediaid;
620 1.17 ragge rx->ra_state = DK_CLOSED;
621 1.17 ragge rx->ra_hwunit = mp->mscp_unit;
622 1.17 ragge mi->mi_dp[mp->mscp_unit] = self;
623 1.17 ragge
624 1.17 ragge rx->ra_disk.dk_name = rx->ra_dev.dv_xname;
625 1.17 ragge disk_attach((struct disk *)&rx->ra_disk);
626 1.17 ragge
627 1.17 ragge /* Fill in what we know. The actual size is gotten later */
628 1.17 ragge dl = rx->ra_disk.dk_label;
629 1.17 ragge
630 1.17 ragge dl->d_secsize = DEV_BSIZE;
631 1.17 ragge dl->d_nsectors = mp->mscp_guse.guse_nspt;
632 1.19 ragge dl->d_ntracks = mp->mscp_guse.guse_ngpc * mp->mscp_guse.guse_group;
633 1.17 ragge dl->d_secpercyl = dl->d_nsectors * dl->d_ntracks;
634 1.17 ragge disk_printtype(mp->mscp_unit, mp->mscp_guse.guse_mediaid);
635 1.19 ragge #ifdef DEBUG
636 1.19 ragge printf("%s: nspt %d group %d ngpc %d rct %d nrpt %d nrct %d\n",
637 1.19 ragge self->dv_xname, mp->mscp_guse.guse_nspt, mp->mscp_guse.guse_group,
638 1.19 ragge mp->mscp_guse.guse_ngpc, mp->mscp_guse.guse_rctsize,
639 1.19 ragge mp->mscp_guse.guse_nrpt, mp->mscp_guse.guse_nrct);
640 1.19 ragge #endif
641 1.17 ragge }
642 1.17 ragge
643 1.17 ragge /*
644 1.17 ragge * (Try to) put the drive online. This is done the first time the
645 1.17 ragge * drive is opened, or if it har fallen offline.
646 1.17 ragge */
647 1.17 ragge int
648 1.17 ragge rx_putonline(rx)
649 1.17 ragge struct rx_softc *rx;
650 1.17 ragge {
651 1.17 ragge struct mscp *mp;
652 1.17 ragge struct mscp_softc *mi = (struct mscp_softc *)rx->ra_dev.dv_parent;
653 1.17 ragge volatile int i;
654 1.17 ragge
655 1.17 ragge rx->ra_state = DK_CLOSED;
656 1.17 ragge mp = mscp_getcp(mi, MSCP_WAIT);
657 1.17 ragge mp->mscp_opcode = M_OP_ONLINE;
658 1.17 ragge mp->mscp_unit = rx->ra_hwunit;
659 1.17 ragge mp->mscp_cmdref = 1;
660 1.17 ragge *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
661 1.17 ragge
662 1.17 ragge /* Poll away */
663 1.21 ragge i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
664 1.17 ragge if (tsleep(&rx->ra_dev.dv_unit, PRIBIO, "rxonline", 100*100))
665 1.17 ragge rx->ra_state = DK_CLOSED;
666 1.17 ragge
667 1.17 ragge if (rx->ra_state == DK_CLOSED)
668 1.17 ragge return MSCP_FAILED;
669 1.17 ragge
670 1.17 ragge return MSCP_DONE;
671 1.17 ragge }
672 1.17 ragge
673 1.17 ragge #if NRX
674 1.17 ragge
675 1.17 ragge /*
676 1.17 ragge * Open a drive.
677 1.17 ragge */
678 1.17 ragge /*ARGSUSED*/
679 1.17 ragge int
680 1.17 ragge rxopen(dev, flag, fmt, p)
681 1.17 ragge dev_t dev;
682 1.17 ragge int flag, fmt;
683 1.17 ragge struct proc *p;
684 1.17 ragge {
685 1.23 augustss struct rx_softc *rx;
686 1.17 ragge int unit;
687 1.17 ragge
688 1.17 ragge /*
689 1.17 ragge * Make sure this is a reasonable open request.
690 1.17 ragge */
691 1.17 ragge unit = DISKUNIT(dev);
692 1.17 ragge if (unit >= rx_cd.cd_ndevs)
693 1.17 ragge return ENXIO;
694 1.17 ragge rx = rx_cd.cd_devs[unit];
695 1.17 ragge if (rx == 0)
696 1.17 ragge return ENXIO;
697 1.17 ragge
698 1.17 ragge /*
699 1.17 ragge * If this is the first open; we must first try to put
700 1.17 ragge * the disk online (and read the label).
701 1.17 ragge */
702 1.17 ragge if (rx->ra_state == DK_CLOSED)
703 1.17 ragge if (rx_putonline(rx) == MSCP_FAILED)
704 1.17 ragge return ENXIO;
705 1.17 ragge
706 1.17 ragge return 0;
707 1.17 ragge }
708 1.17 ragge
709 1.17 ragge /*
710 1.17 ragge * Queue a transfer request, and if possible, hand it to the controller.
711 1.17 ragge *
712 1.17 ragge * This routine is broken into two so that the internal version
713 1.17 ragge * udastrat1() can be called by the (nonexistent, as yet) bad block
714 1.17 ragge * revectoring routine.
715 1.17 ragge */
716 1.17 ragge void
717 1.17 ragge rxstrategy(bp)
718 1.23 augustss struct buf *bp;
719 1.17 ragge {
720 1.23 augustss int unit;
721 1.23 augustss struct rx_softc *rx;
722 1.32 ragge int b;
723 1.17 ragge
724 1.17 ragge /*
725 1.17 ragge * Make sure this is a reasonable drive to use.
726 1.17 ragge */
727 1.17 ragge unit = DISKUNIT(bp->b_dev);
728 1.17 ragge if (unit > rx_cd.cd_ndevs || (rx = rx_cd.cd_devs[unit]) == NULL) {
729 1.17 ragge bp->b_error = ENXIO;
730 1.17 ragge bp->b_flags |= B_ERROR;
731 1.17 ragge goto done;
732 1.17 ragge }
733 1.17 ragge
734 1.17 ragge /* If disk is not online, try to put it online */
735 1.17 ragge if (rx->ra_state == DK_CLOSED)
736 1.17 ragge if (rx_putonline(rx) == MSCP_FAILED) {
737 1.17 ragge bp->b_flags |= B_ERROR;
738 1.17 ragge bp->b_error = EIO;
739 1.17 ragge goto done;
740 1.17 ragge }
741 1.17 ragge
742 1.17 ragge /*
743 1.17 ragge * Determine the size of the transfer, and make sure it is
744 1.17 ragge * within the boundaries of the partition.
745 1.17 ragge */
746 1.17 ragge if (bp->b_blkno >= rx->ra_disk.dk_label->d_secperunit) {
747 1.17 ragge bp->b_resid = bp->b_bcount;
748 1.17 ragge goto done;
749 1.17 ragge }
750 1.17 ragge
751 1.17 ragge /* Make some statistics... /bqt */
752 1.32 ragge b = splbio();
753 1.32 ragge disk_busy(&rx->ra_disk);
754 1.32 ragge splx(b);
755 1.17 ragge mscp_strategy(bp, rx->ra_dev.dv_parent);
756 1.17 ragge return;
757 1.17 ragge
758 1.17 ragge done:
759 1.17 ragge biodone(bp);
760 1.17 ragge }
761 1.17 ragge
762 1.17 ragge int
763 1.33 gehenna rxread(dev, uio, flag)
764 1.17 ragge dev_t dev;
765 1.17 ragge struct uio *uio;
766 1.33 gehenna int flag;
767 1.17 ragge {
768 1.17 ragge
769 1.17 ragge return (physio(rxstrategy, NULL, dev, B_READ, minphys, uio));
770 1.17 ragge }
771 1.17 ragge
772 1.17 ragge int
773 1.33 gehenna rxwrite(dev, uio, flag)
774 1.17 ragge dev_t dev;
775 1.17 ragge struct uio *uio;
776 1.33 gehenna int flag;
777 1.17 ragge {
778 1.17 ragge
779 1.17 ragge return (physio(rxstrategy, NULL, dev, B_WRITE, minphys, uio));
780 1.17 ragge }
781 1.17 ragge
782 1.17 ragge /*
783 1.17 ragge * I/O controls.
784 1.17 ragge */
785 1.17 ragge int
786 1.17 ragge rxioctl(dev, cmd, data, flag, p)
787 1.17 ragge dev_t dev;
788 1.33 gehenna u_long cmd;
789 1.17 ragge caddr_t data;
790 1.17 ragge int flag;
791 1.17 ragge struct proc *p;
792 1.17 ragge {
793 1.23 augustss int unit = DISKUNIT(dev);
794 1.23 augustss struct disklabel *lp;
795 1.23 augustss struct rx_softc *rx = rx_cd.cd_devs[unit];
796 1.17 ragge int error = 0;
797 1.17 ragge
798 1.17 ragge lp = rx->ra_disk.dk_label;
799 1.17 ragge
800 1.17 ragge switch (cmd) {
801 1.17 ragge
802 1.17 ragge case DIOCGDINFO:
803 1.17 ragge bcopy(lp, data, sizeof (struct disklabel));
804 1.17 ragge break;
805 1.17 ragge
806 1.17 ragge case DIOCGPART:
807 1.17 ragge ((struct partinfo *)data)->disklab = lp;
808 1.17 ragge ((struct partinfo *)data)->part =
809 1.17 ragge &lp->d_partitions[DISKPART(dev)];
810 1.17 ragge break;
811 1.17 ragge
812 1.17 ragge
813 1.17 ragge case DIOCWDINFO:
814 1.17 ragge case DIOCSDINFO:
815 1.17 ragge case DIOCWLABEL:
816 1.17 ragge break;
817 1.17 ragge
818 1.17 ragge default:
819 1.17 ragge error = ENOTTY;
820 1.17 ragge break;
821 1.17 ragge }
822 1.17 ragge return (error);
823 1.17 ragge }
824 1.17 ragge
825 1.17 ragge int
826 1.17 ragge rxdump(dev, blkno, va, size)
827 1.17 ragge dev_t dev;
828 1.17 ragge daddr_t blkno;
829 1.17 ragge caddr_t va;
830 1.17 ragge size_t size;
831 1.17 ragge {
832 1.17 ragge
833 1.17 ragge /* Not likely. */
834 1.17 ragge return ENXIO;
835 1.17 ragge }
836 1.17 ragge
837 1.17 ragge int
838 1.17 ragge rxsize(dev)
839 1.17 ragge dev_t dev;
840 1.17 ragge {
841 1.17 ragge
842 1.17 ragge return -1;
843 1.17 ragge }
844 1.17 ragge
845 1.17 ragge #endif /* NRX */
846 1.17 ragge
847 1.17 ragge void rrdgram __P((struct device *, struct mscp *, struct mscp_softc *));
848 1.17 ragge void rriodone __P((struct device *, struct buf *));
849 1.17 ragge int rronline __P((struct device *, struct mscp *));
850 1.17 ragge int rrgotstatus __P((struct device *, struct mscp *));
851 1.17 ragge void rrreplace __P((struct device *, struct mscp *));
852 1.17 ragge int rrioerror __P((struct device *, struct mscp *, struct buf *));
853 1.17 ragge void rrfillin __P((struct buf *, struct mscp *));
854 1.17 ragge void rrbb __P((struct device *, struct mscp *, struct buf *));
855 1.17 ragge
856 1.17 ragge
857 1.17 ragge struct mscp_device ra_device = {
858 1.17 ragge rrdgram,
859 1.17 ragge rriodone,
860 1.17 ragge rronline,
861 1.17 ragge rrgotstatus,
862 1.17 ragge rrreplace,
863 1.17 ragge rrioerror,
864 1.17 ragge rrbb,
865 1.17 ragge rrfillin,
866 1.17 ragge };
867 1.17 ragge
868 1.17 ragge /*
869 1.17 ragge * Handle an error datagram.
870 1.17 ragge * This can come from an unconfigured drive as well.
871 1.17 ragge */
872 1.17 ragge void
873 1.17 ragge rrdgram(usc, mp, mi)
874 1.17 ragge struct device *usc;
875 1.17 ragge struct mscp *mp;
876 1.17 ragge struct mscp_softc *mi;
877 1.17 ragge {
878 1.17 ragge if (mscp_decodeerror(usc == NULL?"unconf disk" : usc->dv_xname, mp, mi))
879 1.17 ragge return;
880 1.17 ragge /*
881 1.17 ragge * SDI status information bytes 10 and 11 are the microprocessor
882 1.17 ragge * error code and front panel code respectively. These vary per
883 1.17 ragge * drive type and are printed purely for field service information.
884 1.17 ragge */
885 1.17 ragge if (mp->mscp_format == M_FM_SDI)
886 1.17 ragge printf("\tsdi uproc error code 0x%x, front panel code 0x%x\n",
887 1.17 ragge mp->mscp_erd.erd_sdistat[10],
888 1.17 ragge mp->mscp_erd.erd_sdistat[11]);
889 1.17 ragge }
890 1.17 ragge
891 1.17 ragge void
892 1.17 ragge rriodone(usc, bp)
893 1.17 ragge struct device *usc;
894 1.17 ragge struct buf *bp;
895 1.17 ragge {
896 1.32 ragge struct ra_softc *ra;
897 1.32 ragge int unit;
898 1.32 ragge
899 1.32 ragge /* We assume that this is a reasonable drive. ra_strategy should
900 1.32 ragge already have verified it. Thus, no checks here... /bqt */
901 1.32 ragge unit = DISKUNIT(bp->b_dev);
902 1.32 ragge ra = ra_cd.cd_devs[unit];
903 1.38 mrg disk_unbusy(&ra->ra_disk, bp->b_bcount, (bp->b_flags & B_READ));
904 1.17 ragge
905 1.17 ragge biodone(bp);
906 1.17 ragge }
907 1.17 ragge
908 1.17 ragge /*
909 1.17 ragge * A drive came on line. Check its type and size. Return DONE if
910 1.17 ragge * we think the drive is truly on line. In any case, awaken anyone
911 1.17 ragge * sleeping on the drive on-line-ness.
912 1.17 ragge */
913 1.17 ragge int
914 1.17 ragge rronline(usc, mp)
915 1.17 ragge struct device *usc;
916 1.17 ragge struct mscp *mp;
917 1.17 ragge {
918 1.17 ragge struct rx_softc *rx = (struct rx_softc *)usc;
919 1.17 ragge struct disklabel *dl;
920 1.17 ragge
921 1.17 ragge wakeup((caddr_t)&usc->dv_unit);
922 1.17 ragge if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
923 1.17 ragge printf("%s: attempt to bring on line failed: ", usc->dv_xname);
924 1.17 ragge mscp_printevent(mp);
925 1.17 ragge return (MSCP_FAILED);
926 1.17 ragge }
927 1.17 ragge
928 1.17 ragge rx->ra_state = DK_OPEN;
929 1.17 ragge
930 1.17 ragge dl = rx->ra_disk.dk_label;
931 1.17 ragge dl->d_secperunit = (daddr_t)mp->mscp_onle.onle_unitsize;
932 1.17 ragge
933 1.17 ragge if (dl->d_secpercyl) {
934 1.17 ragge dl->d_ncylinders = dl->d_secperunit/dl->d_secpercyl;
935 1.17 ragge dl->d_type = DTYPE_MSCP;
936 1.17 ragge dl->d_rpm = 3600;
937 1.17 ragge } else {
938 1.17 ragge dl->d_type = DTYPE_FLOPPY;
939 1.17 ragge dl->d_rpm = 300;
940 1.17 ragge }
941 1.17 ragge rrmakelabel(dl, rx->ra_mediaid);
942 1.17 ragge
943 1.17 ragge return (MSCP_DONE);
944 1.17 ragge }
945 1.17 ragge
946 1.17 ragge void
947 1.17 ragge rrmakelabel(dl, type)
948 1.17 ragge struct disklabel *dl;
949 1.17 ragge long type;
950 1.17 ragge {
951 1.17 ragge int n, p = 0;
952 1.17 ragge
953 1.17 ragge dl->d_bbsize = BBSIZE;
954 1.39 he dl->d_sbsize = SBLOCKSIZE;
955 1.17 ragge
956 1.17 ragge /* Create the disk name for disklabel. Phew... */
957 1.17 ragge dl->d_typename[p++] = MSCP_MID_CHAR(2, type);
958 1.17 ragge dl->d_typename[p++] = MSCP_MID_CHAR(1, type);
959 1.17 ragge if (MSCP_MID_ECH(0, type))
960 1.17 ragge dl->d_typename[p++] = MSCP_MID_CHAR(0, type);
961 1.17 ragge n = MSCP_MID_NUM(type);
962 1.17 ragge if (n > 99) {
963 1.17 ragge dl->d_typename[p++] = '1';
964 1.17 ragge n -= 100;
965 1.17 ragge }
966 1.17 ragge if (n > 9) {
967 1.17 ragge dl->d_typename[p++] = (n / 10) + '0';
968 1.17 ragge n %= 10;
969 1.17 ragge }
970 1.17 ragge dl->d_typename[p++] = n + '0';
971 1.17 ragge dl->d_typename[p] = 0;
972 1.17 ragge dl->d_npartitions = MAXPARTITIONS;
973 1.17 ragge dl->d_partitions[0].p_size = dl->d_partitions[2].p_size =
974 1.17 ragge dl->d_secperunit;
975 1.17 ragge dl->d_partitions[0].p_offset = dl->d_partitions[2].p_offset = 0;
976 1.17 ragge dl->d_interleave = dl->d_headswitch = 1;
977 1.17 ragge dl->d_magic = dl->d_magic2 = DISKMAGIC;
978 1.17 ragge dl->d_checksum = dkcksum(dl);
979 1.17 ragge }
980 1.17 ragge
981 1.17 ragge /*
982 1.17 ragge * We got some (configured) unit's status. Return DONE if it succeeded.
983 1.17 ragge */
984 1.17 ragge int
985 1.17 ragge rrgotstatus(usc, mp)
986 1.23 augustss struct device *usc;
987 1.23 augustss struct mscp *mp;
988 1.17 ragge {
989 1.17 ragge if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
990 1.17 ragge printf("%s: attempt to get status failed: ", usc->dv_xname);
991 1.17 ragge mscp_printevent(mp);
992 1.17 ragge return (MSCP_FAILED);
993 1.17 ragge }
994 1.17 ragge /* record for (future) bad block forwarding and whatever else */
995 1.17 ragge #ifdef notyet
996 1.17 ragge uda_rasave(ui->ui_unit, mp, 1);
997 1.17 ragge #endif
998 1.17 ragge return (MSCP_DONE);
999 1.17 ragge }
1000 1.17 ragge
1001 1.17 ragge /*
1002 1.17 ragge * A replace operation finished.
1003 1.17 ragge */
1004 1.17 ragge /*ARGSUSED*/
1005 1.17 ragge void
1006 1.17 ragge rrreplace(usc, mp)
1007 1.17 ragge struct device *usc;
1008 1.17 ragge struct mscp *mp;
1009 1.17 ragge {
1010 1.17 ragge
1011 1.17 ragge panic("udareplace");
1012 1.17 ragge }
1013 1.17 ragge
1014 1.17 ragge /*
1015 1.17 ragge * A transfer failed. We get a chance to fix or restart it.
1016 1.17 ragge * Need to write the bad block forwaring code first....
1017 1.17 ragge */
1018 1.17 ragge /*ARGSUSED*/
1019 1.17 ragge int
1020 1.17 ragge rrioerror(usc, mp, bp)
1021 1.23 augustss struct device *usc;
1022 1.23 augustss struct mscp *mp;
1023 1.17 ragge struct buf *bp;
1024 1.17 ragge {
1025 1.17 ragge struct ra_softc *ra = (void *)usc;
1026 1.17 ragge int code = mp->mscp_event;
1027 1.17 ragge
1028 1.17 ragge switch (code & M_ST_MASK) {
1029 1.17 ragge /* The unit has fallen offline. Try to figure out why. */
1030 1.17 ragge case M_ST_OFFLINE:
1031 1.17 ragge bp->b_flags |= B_ERROR;
1032 1.17 ragge bp->b_error = EIO;
1033 1.17 ragge ra->ra_state = DK_CLOSED;
1034 1.17 ragge if (code & M_OFFLINE_UNMOUNTED)
1035 1.17 ragge printf("%s: not mounted/spun down\n", usc->dv_xname);
1036 1.17 ragge if (code & M_OFFLINE_DUPLICATE)
1037 1.17 ragge printf("%s: duplicate unit number!!!\n", usc->dv_xname);
1038 1.17 ragge return MSCP_DONE;
1039 1.17 ragge
1040 1.17 ragge case M_ST_AVAILABLE:
1041 1.17 ragge ra->ra_state = DK_CLOSED; /* Force another online */
1042 1.17 ragge return MSCP_DONE;
1043 1.17 ragge
1044 1.17 ragge default:
1045 1.17 ragge printf("%s:", usc->dv_xname);
1046 1.17 ragge break;
1047 1.17 ragge }
1048 1.17 ragge return (MSCP_FAILED);
1049 1.17 ragge }
1050 1.17 ragge
1051 1.17 ragge /*
1052 1.17 ragge * Fill in disk addresses in a mscp packet waiting for transfer.
1053 1.17 ragge */
1054 1.17 ragge void
1055 1.17 ragge rrfillin(bp, mp)
1056 1.17 ragge struct buf *bp;
1057 1.17 ragge struct mscp *mp;
1058 1.17 ragge {
1059 1.17 ragge struct rx_softc *rx = 0; /* Wall */
1060 1.17 ragge struct disklabel *lp;
1061 1.17 ragge int unit = DISKUNIT(bp->b_dev);
1062 1.17 ragge int part = DISKPART(bp->b_dev);
1063 1.17 ragge
1064 1.17 ragge #if NRA
1065 1.33 gehenna if (cdevsw_lookup(bp->b_dev) == &ra_cdevsw)
1066 1.17 ragge rx = ra_cd.cd_devs[unit];
1067 1.17 ragge #endif
1068 1.17 ragge #if NRX
1069 1.33 gehenna if (cdevsw_lookup(bp->b_dev) == &rx_cdevsw)
1070 1.17 ragge rx = rx_cd.cd_devs[unit];
1071 1.17 ragge #endif
1072 1.17 ragge lp = rx->ra_disk.dk_label;
1073 1.17 ragge
1074 1.17 ragge mp->mscp_seq.seq_lbn = lp->d_partitions[part].p_offset + bp->b_blkno;
1075 1.17 ragge mp->mscp_unit = rx->ra_hwunit;
1076 1.17 ragge mp->mscp_seq.seq_bytecount = bp->b_bcount;
1077 1.17 ragge }
1078 1.17 ragge
1079 1.17 ragge /*
1080 1.17 ragge * A bad block related operation finished.
1081 1.17 ragge */
1082 1.17 ragge /*ARGSUSED*/
1083 1.17 ragge void
1084 1.17 ragge rrbb(usc, mp, bp)
1085 1.17 ragge struct device *usc;
1086 1.17 ragge struct mscp *mp;
1087 1.17 ragge struct buf *bp;
1088 1.17 ragge {
1089 1.17 ragge
1090 1.17 ragge panic("udabb");
1091 1.1 ragge }
1092