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