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