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