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