Home | History | Annotate | Line # | Download | only in mscp
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