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