Home | History | Annotate | Line # | Download | only in qbus
rf.c revision 1.1
      1  1.1  ragge /*	$NetBSD: rf.c,v 1.1 2003/03/23 11:01:16 ragge Exp $	*/
      2  1.1  ragge /*
      3  1.1  ragge  * Copyright (c) 2002 Jochen Kunz.
      4  1.1  ragge  * All rights reserved.
      5  1.1  ragge  *
      6  1.1  ragge  * Redistribution and use in source and binary forms, with or without
      7  1.1  ragge  * modification, are permitted provided that the following conditions
      8  1.1  ragge  * are met:
      9  1.1  ragge  * 1. Redistributions of source code must retain the above copyright
     10  1.1  ragge  *    notice, this list of conditions and the following disclaimer.
     11  1.1  ragge  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  ragge  *    notice, this list of conditions and the following disclaimer in the
     13  1.1  ragge  *    documentation and/or other materials provided with the distribution.
     14  1.1  ragge  * 3. The name of Jochen Kunz may not be used to endorse or promote
     15  1.1  ragge  *    products derived from this software without specific prior
     16  1.1  ragge  *    written permission.
     17  1.1  ragge  *
     18  1.1  ragge  * THIS SOFTWARE IS PROVIDED BY JOCHEN KUNZ
     19  1.1  ragge  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     20  1.1  ragge  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     21  1.1  ragge  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL JOCHEN KUNZ
     22  1.1  ragge  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     23  1.1  ragge  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     24  1.1  ragge  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     25  1.1  ragge  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     26  1.1  ragge  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     27  1.1  ragge  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     28  1.1  ragge  * POSSIBILITY OF SUCH DAMAGE.
     29  1.1  ragge  */
     30  1.1  ragge 
     31  1.1  ragge /*
     32  1.1  ragge TODO:
     33  1.1  ragge - Better LBN bound checking, block padding for SD disks.
     34  1.1  ragge - Formating / "Set Density"
     35  1.1  ragge - Better error handling / detaild error reason reportnig.
     36  1.1  ragge */
     37  1.1  ragge 
     38  1.1  ragge /* autoconfig stuff */
     39  1.1  ragge #include <sys/param.h>
     40  1.1  ragge #include <sys/device.h>
     41  1.1  ragge #include <sys/conf.h>
     42  1.1  ragge #include "locators.h"
     43  1.1  ragge #include "ioconf.h"
     44  1.1  ragge 
     45  1.1  ragge /* bus_space / bus_dma */
     46  1.1  ragge #include <machine/bus.h>
     47  1.1  ragge 
     48  1.1  ragge /* UniBus / QBus specific stuff */
     49  1.1  ragge #include <dev/qbus/ubavar.h>
     50  1.1  ragge 
     51  1.1  ragge /* disk interface */
     52  1.1  ragge #include <sys/types.h>
     53  1.1  ragge #include <sys/disklabel.h>
     54  1.1  ragge #include <sys/disk.h>
     55  1.1  ragge 
     56  1.1  ragge /* general system data and functions */
     57  1.1  ragge #include <sys/systm.h>
     58  1.1  ragge #include <sys/ioctl.h>
     59  1.1  ragge #include <sys/ioccom.h>
     60  1.1  ragge 
     61  1.1  ragge /* physio / buffer handling */
     62  1.1  ragge #include <sys/buf.h>
     63  1.1  ragge 
     64  1.1  ragge /* tsleep / sleep / wakeup */
     65  1.1  ragge #include <sys/proc.h>
     66  1.1  ragge /* hz for above */
     67  1.1  ragge #include <sys/kernel.h>
     68  1.1  ragge 
     69  1.1  ragge /* bitdefinitions for RX211 */
     70  1.1  ragge #include <dev/qbus/rfreg.h>
     71  1.1  ragge 
     72  1.1  ragge 
     73  1.1  ragge #define	RFS_DENS	0x0001		/* single or double density */
     74  1.1  ragge #define	RFS_AD		0x0002		/* density auto detect */
     75  1.1  ragge #define	RFS_NOTINIT	0x0000		/* not initialized */
     76  1.1  ragge #define	RFS_PROBING	0x0010		/* density detect / verify started */
     77  1.1  ragge #define	RFS_FBUF	0x0020		/* Fill Buffer */
     78  1.1  ragge #define	RFS_EBUF	0x0030		/* Empty Buffer */
     79  1.1  ragge #define	RFS_WSEC	0x0040		/* Write Sector */
     80  1.1  ragge #define	RFS_RSEC	0x0050		/* Read Sector */
     81  1.1  ragge #define	RFS_SMD		0x0060		/* Set Media Density */
     82  1.1  ragge #define	RFS_RSTAT	0x0070		/* Read Status */
     83  1.1  ragge #define	RFS_WDDS	0x0080		/* Write Deleted Data Sector */
     84  1.1  ragge #define	RFS_REC		0x0090		/* Read Error Code */
     85  1.1  ragge #define	RFS_IDLE	0x00a0		/* controller is idle */
     86  1.1  ragge #define	RFS_CMDS	0x00f0		/* command mask */
     87  1.1  ragge #define	RFS_SETCMD(rf, state)	((rf) = ((rf) & ~RFS_CMDS) | (state))
     88  1.1  ragge 
     89  1.1  ragge 
     90  1.1  ragge 
     91  1.1  ragge /* autoconfig stuff */
     92  1.1  ragge static int rfc_match(struct device *, struct cfdata *, void *);
     93  1.1  ragge static void rfc_attach(struct device *, struct device *, void *);
     94  1.1  ragge static int rf_match(struct device *, struct cfdata *, void *);
     95  1.1  ragge static void rf_attach(struct device *, struct device *, void *);
     96  1.1  ragge static int rf_print(void *, const char *);
     97  1.1  ragge 
     98  1.1  ragge /* device interfce functions / interface to disk(9) */
     99  1.1  ragge dev_type_open(rfopen);
    100  1.1  ragge dev_type_close(rfclose);
    101  1.1  ragge dev_type_read(rfread);
    102  1.1  ragge dev_type_write(rfwrite);
    103  1.1  ragge dev_type_ioctl(rfioctl);
    104  1.1  ragge dev_type_strategy(rfstrategy);
    105  1.1  ragge dev_type_dump(rfdump);
    106  1.1  ragge dev_type_size(rfsize);
    107  1.1  ragge 
    108  1.1  ragge 
    109  1.1  ragge /* Entries in block and character major device number switch table. */
    110  1.1  ragge const struct bdevsw rf_bdevsw = {
    111  1.1  ragge 	rfopen,
    112  1.1  ragge 	rfclose,
    113  1.1  ragge 	rfstrategy,
    114  1.1  ragge 	rfioctl,
    115  1.1  ragge 	rfdump,
    116  1.1  ragge 	rfsize,
    117  1.1  ragge 	D_DISK
    118  1.1  ragge };
    119  1.1  ragge 
    120  1.1  ragge const struct cdevsw rf_cdevsw = {
    121  1.1  ragge 	rfopen,
    122  1.1  ragge 	rfclose,
    123  1.1  ragge 	rfread,
    124  1.1  ragge 	rfwrite,
    125  1.1  ragge 	rfioctl,
    126  1.1  ragge 	nostop,
    127  1.1  ragge 	notty,
    128  1.1  ragge 	nopoll,
    129  1.1  ragge 	nommap,
    130  1.1  ragge 	nokqfilter,
    131  1.1  ragge 	D_DISK
    132  1.1  ragge };
    133  1.1  ragge 
    134  1.1  ragge 
    135  1.1  ragge 
    136  1.1  ragge struct rfc_softc {
    137  1.1  ragge 	struct device sc_dev;		/* common device data */
    138  1.1  ragge 	struct device *sc_childs[2];	/* child devices */
    139  1.1  ragge 	struct evcnt sc_intr_count;	/* Interrupt counter for statistics */
    140  1.1  ragge 	struct buf *sc_curbuf;		/* buf that is currently in work */
    141  1.1  ragge 	bus_space_tag_t sc_iot;		/* bus_space IO tag */
    142  1.1  ragge 	bus_space_handle_t sc_ioh;	/* bus_space IO handle */
    143  1.1  ragge 	bus_dma_tag_t sc_dmat;		/* bus_dma DMA tag */
    144  1.1  ragge 	bus_dmamap_t sc_dmam;		/* bus_dma DMA map */
    145  1.1  ragge 	caddr_t sc_bufidx;		/* current position in buffer data */
    146  1.1  ragge 	int sc_curchild;		/* child whos bufq is in work */
    147  1.1  ragge 	int sc_bytesleft;		/* bytes left to transfer */
    148  1.1  ragge 	u_int8_t type;			/* controller type, 1 or 2 */
    149  1.1  ragge };
    150  1.1  ragge 
    151  1.1  ragge 
    152  1.1  ragge 
    153  1.1  ragge CFATTACH_DECL(
    154  1.1  ragge 	rfc,
    155  1.1  ragge 	sizeof(struct rfc_softc),
    156  1.1  ragge 	rfc_match,
    157  1.1  ragge 	rfc_attach,
    158  1.1  ragge 	NULL,
    159  1.1  ragge     	NULL
    160  1.1  ragge );
    161  1.1  ragge 
    162  1.1  ragge 
    163  1.1  ragge 
    164  1.1  ragge struct rf_softc {
    165  1.1  ragge 	struct device sc_dev;		/* common device data */
    166  1.1  ragge 	struct disk sc_disk;		/* common disk device data */
    167  1.1  ragge 	struct bufq_state sc_bufq;	/* queue of pending transfers */
    168  1.1  ragge 	int sc_state;			/* state of drive */
    169  1.1  ragge 	int sc_open;			/* simultaneous opens */
    170  1.1  ragge 	u_int8_t sc_dnum;		/* drive number, 0 or 1 */
    171  1.1  ragge };
    172  1.1  ragge 
    173  1.1  ragge 
    174  1.1  ragge 
    175  1.1  ragge CFATTACH_DECL(
    176  1.1  ragge 	rf,
    177  1.1  ragge 	sizeof(struct rf_softc),
    178  1.1  ragge 	rf_match,
    179  1.1  ragge 	rf_attach,
    180  1.1  ragge 	NULL,
    181  1.1  ragge 	NULL
    182  1.1  ragge );
    183  1.1  ragge 
    184  1.1  ragge 
    185  1.1  ragge 
    186  1.1  ragge struct rfc_attach_args {
    187  1.1  ragge 	u_int8_t type;		/* controller type, 1 or 2 */
    188  1.1  ragge 	u_int8_t dnum;		/* drive number, 0 or 1 */
    189  1.1  ragge };
    190  1.1  ragge 
    191  1.1  ragge 
    192  1.1  ragge 
    193  1.1  ragge struct dkdriver rfdkdriver = {
    194  1.1  ragge 	rfstrategy
    195  1.1  ragge };
    196  1.1  ragge 
    197  1.1  ragge 
    198  1.1  ragge 
    199  1.1  ragge /* helper functions */
    200  1.1  ragge int rfc_sendcmd(struct rfc_softc *, int, int, int);
    201  1.1  ragge static void rfc_intr(void *);
    202  1.1  ragge 
    203  1.1  ragge 
    204  1.1  ragge 
    205  1.1  ragge /*
    206  1.1  ragge  * Issue a reset command to the controller and look for the bits in
    207  1.1  ragge  * RX2CS and RX2ES.
    208  1.1  ragge  * RX2CS_RX02 and / or RX2CS_DD can be set,
    209  1.1  ragge  * RX2ES has to be set, all other bits must be 0
    210  1.1  ragge  */
    211  1.1  ragge int
    212  1.1  ragge rfc_match(struct device *parent, struct cfdata *match, void *aux)
    213  1.1  ragge {
    214  1.1  ragge 	struct uba_attach_args *ua = aux;
    215  1.1  ragge 	int i;
    216  1.1  ragge 
    217  1.1  ragge 	/* Issue reset command. */
    218  1.1  ragge 	bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS, RX2CS_INIT);
    219  1.1  ragge 	/* Wait for the controller to become ready, that is when
    220  1.1  ragge 	 * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set. */
    221  1.1  ragge 	for (i = 0 ; i < 20 ; i++) {
    222  1.1  ragge 		if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS)
    223  1.1  ragge 		    & RX2CS_DONE) != 0
    224  1.1  ragge 		    && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES)
    225  1.1  ragge 		    & (RX2ES_RDY | RX2ES_ID)) != 0)
    226  1.1  ragge 			break;
    227  1.1  ragge 		DELAY(100000);	/* wait 100ms */
    228  1.1  ragge 	}
    229  1.1  ragge 	/*
    230  1.1  ragge 	 * Give up if the timeout has elapsed
    231  1.1  ragge 	 * and the controller is not ready.
    232  1.1  ragge 	 */
    233  1.1  ragge 	if (i >= 20)
    234  1.1  ragge 		return(0);
    235  1.1  ragge 	/*
    236  1.1  ragge 	 * Issue a Read Status command with interrupt enabled.
    237  1.1  ragge 	 * The uba(4) driver wants to catch the interrupt to get the
    238  1.1  ragge 	 * interrupt vector and level of the device
    239  1.1  ragge 	 */
    240  1.1  ragge 	bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS,
    241  1.1  ragge 	    RX2CS_RSTAT | RX2CS_IE);
    242  1.1  ragge 	/*
    243  1.1  ragge 	 * Wait for command to finish, ignore errors and
    244  1.1  ragge 	 * abort if the controller does not respond within the timeout
    245  1.1  ragge 	 */
    246  1.1  ragge 	for (i = 0 ; i < 20 ; i++) {
    247  1.1  ragge 		if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS)
    248  1.1  ragge 		    & (RX2CS_DONE | RX2CS_IE)) != 0
    249  1.1  ragge 		    && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES)
    250  1.1  ragge 		    & RX2ES_RDY) != 0 )
    251  1.1  ragge 			return(1);
    252  1.1  ragge 		DELAY(100000);	/* wait 100ms */
    253  1.1  ragge 	}
    254  1.1  ragge 	return(0);
    255  1.1  ragge }
    256  1.1  ragge 
    257  1.1  ragge 
    258  1.1  ragge 
    259  1.1  ragge /* #define RX02_PROBE 1 */
    260  1.1  ragge #ifdef RX02_PROBE
    261  1.1  ragge /*
    262  1.1  ragge  * Probe the density of an inserted floppy disk.
    263  1.1  ragge  * This is done by reading a sector from disk.
    264  1.1  ragge  * Return -1 on error, 0 on SD and 1 on DD.
    265  1.1  ragge  */
    266  1.1  ragge int rfcprobedens(struct rfc_softc *, int);
    267  1.1  ragge int
    268  1.1  ragge rfcprobedens(struct rfc_softc *rfc_sc, int dnum)
    269  1.1  ragge {
    270  1.1  ragge 	int dens_flag;
    271  1.1  ragge 	int i;
    272  1.1  ragge 
    273  1.1  ragge 	dens_flag = 0;
    274  1.1  ragge 	do {
    275  1.1  ragge 		bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS,
    276  1.1  ragge 		    RX2CS_RSEC | (dens_flag == 0 ? 0 : RX2CS_DD)
    277  1.1  ragge 		    | (dnum == 0 ? 0 : RX2CS_US));
    278  1.1  ragge 		/*
    279  1.1  ragge 		 * Transfer request set?
    280  1.1  ragge 		 * Wait 50us, the controller needs this time to setle
    281  1.1  ragge 		 */
    282  1.1  ragge 		DELAY(50);
    283  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    284  1.1  ragge 		    & RX2CS_TR) == 0) {
    285  1.1  ragge 			printf("%s: did not respond to Read Sector CMD(1)\n",
    286  1.1  ragge 			    rfc_sc->sc_dev.dv_xname);
    287  1.1  ragge 			return(-1);
    288  1.1  ragge 		}
    289  1.1  ragge 		bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2SA, 1);
    290  1.1  ragge 		/* Wait 50us, the controller needs this time to setle */
    291  1.1  ragge 		DELAY(50);
    292  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    293  1.1  ragge 		    & RX2CS_TR) == 0) {
    294  1.1  ragge 			printf("%s: did not respond to Read Sector CMD(2)\n",
    295  1.1  ragge 			    rfc_sc->sc_dev.dv_xname);
    296  1.1  ragge 			return(-1);
    297  1.1  ragge 		}
    298  1.1  ragge 		bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2TA, 1);
    299  1.1  ragge 		/* Wait for the command to finish */
    300  1.1  ragge 		for (i = 0 ; i < 200 ; i++) {
    301  1.1  ragge 			if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
    302  1.1  ragge 			    RX2CS) & RX2CS_DONE) != 0)
    303  1.1  ragge 				break;
    304  1.1  ragge 			DELAY(10000);	/* wait 10ms */
    305  1.1  ragge 		}
    306  1.1  ragge 		if (i >= 200) {
    307  1.1  ragge 			printf("%s: did not respond to Read Sector CMD(3)\n",
    308  1.1  ragge 			    rfc_sc->sc_dev.dv_xname);
    309  1.1  ragge 			return(-1);
    310  1.1  ragge 		}
    311  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    312  1.1  ragge 		    & RX2CS_ERR) == 0)
    313  1.1  ragge 			return(dens_flag);
    314  1.1  ragge 	} while (rfc_sc->type == 2 && dens_flag++ == 0);
    315  1.1  ragge 	return(-1);
    316  1.1  ragge }
    317  1.1  ragge #endif /* RX02_PROBE */
    318  1.1  ragge 
    319  1.1  ragge 
    320  1.1  ragge 
    321  1.1  ragge void
    322  1.1  ragge rfc_attach(struct device *parent, struct device *self, void *aux)
    323  1.1  ragge {
    324  1.1  ragge 	struct rfc_softc *rfc_sc = (struct rfc_softc *)self;
    325  1.1  ragge 	struct uba_attach_args *ua = aux;
    326  1.1  ragge 	struct rfc_attach_args rfc_aa;
    327  1.1  ragge 	int i;
    328  1.1  ragge 
    329  1.1  ragge 	rfc_sc->sc_iot = ua->ua_iot;
    330  1.1  ragge 	rfc_sc->sc_ioh = ua->ua_ioh;
    331  1.1  ragge 	rfc_sc->sc_dmat = ua->ua_dmat;
    332  1.1  ragge 	rfc_sc->sc_curbuf = NULL;
    333  1.1  ragge 	/* Tell the QBus busdriver about our interrupt handler. */
    334  1.1  ragge 	uba_intr_establish(ua->ua_icookie, ua->ua_cvec, rfc_intr, rfc_sc,
    335  1.1  ragge 	    &rfc_sc->sc_intr_count);
    336  1.1  ragge 	/* Attach to the interrupt counter, see evcnt(9) */
    337  1.1  ragge 	evcnt_attach_dynamic(&rfc_sc->sc_intr_count, EVCNT_TYPE_INTR,
    338  1.1  ragge 	    ua->ua_evcnt, rfc_sc->sc_dev.dv_xname, "intr");
    339  1.1  ragge 	/* get a bus_dma(9) handle */
    340  1.1  ragge 	i = bus_dmamap_create(rfc_sc->sc_dmat, RX2_BYTE_DD, 1, RX2_BYTE_DD, 0,
    341  1.1  ragge 	    BUS_DMA_ALLOCNOW, &rfc_sc->sc_dmam);
    342  1.1  ragge 	if (i != 0) {
    343  1.1  ragge 		printf("rfc_attach: Error creating bus dma map: %d\n", i);
    344  1.1  ragge 		return;
    345  1.1  ragge 	}
    346  1.1  ragge 
    347  1.1  ragge 	/* Issue reset command. */
    348  1.1  ragge 	bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, RX2CS_INIT);
    349  1.1  ragge 	/*
    350  1.1  ragge 	 * Wait for the controller to become ready, that is when
    351  1.1  ragge 	 * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set.
    352  1.1  ragge 	 */
    353  1.1  ragge 	for (i = 0 ; i < 20 ; i++) {
    354  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    355  1.1  ragge 		    & RX2CS_DONE) != 0
    356  1.1  ragge 		    && (bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2ES)
    357  1.1  ragge 		    & (RX2ES_RDY | RX2ES_ID)) != 0)
    358  1.1  ragge 			break;
    359  1.1  ragge 		DELAY(100000);	/* wait 100ms */
    360  1.1  ragge 	}
    361  1.1  ragge 	/*
    362  1.1  ragge 	 * Give up if the timeout has elapsed
    363  1.1  ragge 	 * and the controller is not ready.
    364  1.1  ragge 	 */
    365  1.1  ragge 	if (i >= 20) {
    366  1.1  ragge 		printf(": did not respond to INIT CMD\n");
    367  1.1  ragge 		return;
    368  1.1  ragge 	}
    369  1.1  ragge 	/* Is ths a RX01 or a RX02? */
    370  1.1  ragge 	if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    371  1.1  ragge 	    & RX2CS_RX02) != 0) {
    372  1.1  ragge 		rfc_sc->type = 2;
    373  1.1  ragge 		rfc_aa.type = 2;
    374  1.1  ragge 	} else {
    375  1.1  ragge 		rfc_sc->type = 1;
    376  1.1  ragge 		rfc_aa.type = 1;
    377  1.1  ragge 	}
    378  1.1  ragge 	printf(": RX0%d\n", rfc_sc->type);
    379  1.1  ragge 
    380  1.1  ragge #ifndef RX02_PROBE
    381  1.1  ragge 	/*
    382  1.1  ragge 	 * Bouth disk drievs and the controller are one physical unit.
    383  1.1  ragge 	 * If we found the controller, there will be bouth disk drievs.
    384  1.1  ragge 	 * So attach them.
    385  1.1  ragge 	 */
    386  1.1  ragge 	rfc_aa.dnum = 0;
    387  1.1  ragge 	rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa,rf_print);
    388  1.1  ragge 	rfc_aa.dnum = 1;
    389  1.1  ragge 	rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa,rf_print);
    390  1.1  ragge #else /* RX02_PROBE */
    391  1.1  ragge 	/*
    392  1.1  ragge 	 * There are clones of the DEC RX system with standard shugart
    393  1.1  ragge 	 * interface. In this case we can not be sure that there are
    394  1.1  ragge 	 * bouth disk drievs. So we want to do a detection of attached
    395  1.1  ragge 	 * drives. This is done by reading a sector from disk. This means
    396  1.1  ragge 	 * that there must be a formated disk in the drive at boot time.
    397  1.1  ragge 	 * This is bad, but I did not find an other way to detect the
    398  1.1  ragge 	 * (non)existence of a floppy drive.
    399  1.1  ragge 	 */
    400  1.1  ragge 	if (rfcprobedens(rfc_sc, 0) >= 0) {
    401  1.1  ragge 		rfc_aa.dnum = 0;
    402  1.1  ragge 		rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa,
    403  1.1  ragge 		    rf_print);
    404  1.1  ragge 	} else
    405  1.1  ragge 		rfc_sc->sc_childs[0] = NULL;
    406  1.1  ragge 	if (rfcprobedens(rfc_sc, 1) >= 0) {
    407  1.1  ragge 		rfc_aa.dnum = 1;
    408  1.1  ragge 		rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa,
    409  1.1  ragge 		    rf_print);
    410  1.1  ragge 	} else
    411  1.1  ragge 		rfc_sc->sc_childs[1] = NULL;
    412  1.1  ragge #endif /* RX02_PROBE */
    413  1.1  ragge 	return;
    414  1.1  ragge }
    415  1.1  ragge 
    416  1.1  ragge 
    417  1.1  ragge 
    418  1.1  ragge int
    419  1.1  ragge rf_match(struct device *parent, struct cfdata *match, void *aux)
    420  1.1  ragge {
    421  1.1  ragge 	struct rfc_attach_args *rfc_aa = aux;
    422  1.1  ragge 
    423  1.1  ragge 	/*
    424  1.1  ragge 	 * Only attach if the locator is wildcarded or
    425  1.1  ragge 	 * if the specified locator addresses the current device.
    426  1.1  ragge 	 */
    427  1.1  ragge 	if (match->cf_loc[RFCCF_DRIVE] == RFCCF_DRIVE_DEFAULT ||
    428  1.1  ragge 	    match->cf_loc[RFCCF_DRIVE] == rfc_aa->dnum)
    429  1.1  ragge 		return(1);
    430  1.1  ragge 	return(0);
    431  1.1  ragge }
    432  1.1  ragge 
    433  1.1  ragge 
    434  1.1  ragge 
    435  1.1  ragge void
    436  1.1  ragge rf_attach(struct device *parent, struct device *self, void *aux)
    437  1.1  ragge {
    438  1.1  ragge 	struct rf_softc *rf_sc = (struct rf_softc *)self;
    439  1.1  ragge 	struct rfc_attach_args *rfc_aa = (struct rfc_attach_args *)aux;
    440  1.1  ragge 	struct rfc_softc *rfc_sc;
    441  1.1  ragge 	struct disklabel *dl;
    442  1.1  ragge 
    443  1.1  ragge 	rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
    444  1.1  ragge 	rf_sc->sc_dnum = rfc_aa->dnum;
    445  1.1  ragge 	rf_sc->sc_state = 0;
    446  1.1  ragge 	rf_sc->sc_open = 0;
    447  1.1  ragge 	rf_sc->sc_disk.dk_name = rf_sc->sc_dev.dv_xname;
    448  1.1  ragge 	rf_sc->sc_disk.dk_driver = &rfdkdriver;
    449  1.1  ragge 	disk_attach(&rf_sc->sc_disk);
    450  1.1  ragge 	dl = rf_sc->sc_disk.dk_label;
    451  1.1  ragge 	dl->d_type = DTYPE_FLOPPY;		/* drive type */
    452  1.1  ragge 	dl->d_magic = DISKMAGIC;		/* the magic number */
    453  1.1  ragge 	dl->d_magic2 = DISKMAGIC;
    454  1.1  ragge 	dl->d_typename[0] = 'R';
    455  1.1  ragge 	dl->d_typename[1] = 'X';
    456  1.1  ragge 	dl->d_typename[2] = '0';
    457  1.1  ragge 	dl->d_typename[3] = rfc_sc->type == 1 ? '1' : '2';	/* type name */
    458  1.1  ragge 	dl->d_typename[4] = '\0';
    459  1.1  ragge 	dl->d_secsize = DEV_BSIZE;		/* bytes per sector */
    460  1.1  ragge 	/*
    461  1.1  ragge 	 * Fill in some values to have a initialized data structure. Some
    462  1.1  ragge 	 * values will be reset by rfopen() depending on the actual density.
    463  1.1  ragge 	 */
    464  1.1  ragge 	dl->d_nsectors = RX2_SECTORS;		/* sectors per track */
    465  1.1  ragge 	dl->d_ntracks = 1;								/* tracks per cylinder */
    466  1.1  ragge 	dl->d_ncylinders = RX2_TRACKS;		/* cylinders per unit */
    467  1.1  ragge 	dl->d_secpercyl = RX2_SECTORS;		/* sectors per cylinder */
    468  1.1  ragge 	dl->d_secperunit = RX2_SECTORS * RX2_TRACKS;	/* sectors per unit */
    469  1.1  ragge 	dl->d_rpm = 360;			/* rotational speed */
    470  1.1  ragge 	dl->d_interleave = 1;			/* hardware sector interleave */
    471  1.1  ragge 	/* number of partitions in following */
    472  1.1  ragge 	dl->d_npartitions = MAXPARTITIONS;
    473  1.1  ragge 	dl->d_bbsize = 0;		/* size of boot area at sn0, bytes */
    474  1.1  ragge 	dl->d_sbsize = 0;		/* max size of fs superblock, bytes */
    475  1.1  ragge 	/* number of sectors in partition */
    476  1.1  ragge 	dl->d_partitions[0].p_size = 501;
    477  1.1  ragge 	dl->d_partitions[0].p_offset = 0;	/* starting sector */
    478  1.1  ragge 	dl->d_partitions[0].p_fsize = 0;	/* fs basic fragment size */
    479  1.1  ragge 	dl->d_partitions[0].p_fstype = 0;	/* fs type */
    480  1.1  ragge 	dl->d_partitions[0].p_frag = 0;		/* fs fragments per block */
    481  1.1  ragge 	dl->d_partitions[1].p_size = RX2_SECTORS * RX2_TRACKS / 2;
    482  1.1  ragge 	dl->d_partitions[1].p_offset = 0;	/* starting sector */
    483  1.1  ragge 	dl->d_partitions[1].p_fsize = 0;	/* fs basic fragment size */
    484  1.1  ragge 	dl->d_partitions[1].p_fstype = 0;	/* fs type */
    485  1.1  ragge 	dl->d_partitions[1].p_frag = 0;		/* fs fragments per block */
    486  1.1  ragge 	dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS;
    487  1.1  ragge 	dl->d_partitions[2].p_offset = 0;	/* starting sector */
    488  1.1  ragge 	dl->d_partitions[2].p_fsize = 0;	/* fs basic fragment size */
    489  1.1  ragge 	dl->d_partitions[2].p_fstype = 0;	/* fs type */
    490  1.1  ragge 	dl->d_partitions[2].p_frag = 0;		/* fs fragments per block */
    491  1.1  ragge 	bufq_alloc(&rf_sc->sc_bufq, BUFQ_DISKSORT | BUFQ_SORT_CYLINDER);
    492  1.1  ragge 	printf("\n");
    493  1.1  ragge 	return;
    494  1.1  ragge }
    495  1.1  ragge 
    496  1.1  ragge 
    497  1.1  ragge 
    498  1.1  ragge int
    499  1.1  ragge rf_print(void *aux, const char *name)
    500  1.1  ragge {
    501  1.1  ragge 	struct rfc_attach_args *rfc_aa = aux;
    502  1.1  ragge 
    503  1.1  ragge 	if (name != NULL)
    504  1.1  ragge 		aprint_normal("RX0%d at %s", rfc_aa->type, name);
    505  1.1  ragge 	aprint_normal(" drive %d", rfc_aa->dnum);
    506  1.1  ragge 	return(UNCONF);
    507  1.1  ragge }
    508  1.1  ragge 
    509  1.1  ragge 
    510  1.1  ragge 
    511  1.1  ragge /* Send a command to the controller */
    512  1.1  ragge int
    513  1.1  ragge rfc_sendcmd(struct rfc_softc *rfc_sc, int cmd, int data1, int data2)
    514  1.1  ragge {
    515  1.1  ragge 
    516  1.1  ragge 	/* Write command to CSR. */
    517  1.1  ragge 	bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, cmd);
    518  1.1  ragge 	/* Wait 50us, the controller needs this time to setle. */
    519  1.1  ragge 	DELAY(50);
    520  1.1  ragge 	/* Write parameter 1 to DBR */
    521  1.1  ragge 	if ((cmd & RX2CS_FC) != RX2CS_RSTAT) {
    522  1.1  ragge 		/* Transfer request set? */
    523  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    524  1.1  ragge 		    & RX2CS_TR) == 0) {
    525  1.1  ragge 			printf("%s: did not respond to CMD %x (1)\n",
    526  1.1  ragge 			    rfc_sc->sc_dev.dv_xname, cmd);
    527  1.1  ragge 			return(-1);
    528  1.1  ragge 		}
    529  1.1  ragge 		bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB,
    530  1.1  ragge 		    data1);
    531  1.1  ragge 	}
    532  1.1  ragge 	/* Write parameter 2 to DBR */
    533  1.1  ragge 	if ((cmd & RX2CS_FC) <= RX2CS_RSEC || (cmd & RX2CS_FC) == RX2CS_WDDS) {
    534  1.1  ragge 		/* Wait 50us, the controller needs this time to setle. */
    535  1.1  ragge 		DELAY(50);
    536  1.1  ragge 		/* Transfer request set? */
    537  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    538  1.1  ragge 		    & RX2CS_TR) == 0) {
    539  1.1  ragge 			printf("%s: did not respond to CMD %x (2)\n",
    540  1.1  ragge 			    rfc_sc->sc_dev.dv_xname, cmd);
    541  1.1  ragge 			return(-1);
    542  1.1  ragge 		}
    543  1.1  ragge 		bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB,
    544  1.1  ragge 		    data2);
    545  1.1  ragge 	}
    546  1.1  ragge 	return(1);
    547  1.1  ragge }
    548  1.1  ragge 
    549  1.1  ragge 
    550  1.1  ragge 
    551  1.1  ragge void
    552  1.1  ragge rfstrategy(struct buf *buf)
    553  1.1  ragge {
    554  1.1  ragge 	struct rf_softc *rf_sc;
    555  1.1  ragge 	struct rfc_softc *rfc_sc;
    556  1.1  ragge 	int i;
    557  1.1  ragge 
    558  1.1  ragge 	i = DISKUNIT(buf->b_dev);
    559  1.1  ragge 	if (i >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[i]) == NULL) {
    560  1.1  ragge 		buf->b_flags |= B_ERROR;
    561  1.1  ragge 		buf->b_error = ENXIO;
    562  1.1  ragge 		biodone(buf);
    563  1.1  ragge 		return;
    564  1.1  ragge 	}
    565  1.1  ragge 	rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
    566  1.1  ragge 	/* We are going to operate on a non open dev? PANIC! */
    567  1.1  ragge 	if (rf_sc->sc_open == 0)
    568  1.1  ragge 		panic("rfstrategy: can not operate on non-open drive %s (1)",
    569  1.1  ragge 		    rf_sc->sc_dev.dv_xname);
    570  1.1  ragge 	if (buf->b_bcount == 0) {
    571  1.1  ragge 		biodone(buf);
    572  1.1  ragge 		return;
    573  1.1  ragge 	}
    574  1.1  ragge 	/*
    575  1.1  ragge 	 * BUFQ_PUT() operates on b_rawblkno. rfstrategy() gets
    576  1.1  ragge 	 * only b_blkno that is partition relative. As a floppy does not
    577  1.1  ragge 	 * have partitions b_rawblkno == b_blkno.
    578  1.1  ragge 	 */
    579  1.1  ragge 	buf->b_rawblkno = buf->b_blkno;
    580  1.1  ragge 	/*
    581  1.1  ragge 	 * from sys/kern/subr_disk.c:
    582  1.1  ragge 	 * Seek sort for disks.  We depend on the driver which calls us using
    583  1.1  ragge 	 * b_resid as the current cylinder number.
    584  1.1  ragge 	 */
    585  1.1  ragge 	i = splbio();
    586  1.1  ragge 	if (rfc_sc->sc_curbuf == NULL) {
    587  1.1  ragge 		rfc_sc->sc_curchild = rf_sc->sc_dnum;
    588  1.1  ragge 		rfc_sc->sc_curbuf = buf;
    589  1.1  ragge 		rfc_sc->sc_bufidx = buf->b_un.b_addr;
    590  1.1  ragge 		rfc_sc->sc_bytesleft = buf->b_bcount;
    591  1.1  ragge 		rfc_intr(rfc_sc);
    592  1.1  ragge 	} else {
    593  1.1  ragge 		buf->b_resid = buf->b_blkno / RX2_SECTORS;
    594  1.1  ragge 		BUFQ_PUT(&rf_sc->sc_bufq, buf);
    595  1.1  ragge 		rfc_sc->sc_curbuf->b_resid = 0;
    596  1.1  ragge 	}
    597  1.1  ragge 	splx(i);
    598  1.1  ragge 	return;
    599  1.1  ragge }
    600  1.1  ragge 
    601  1.1  ragge 
    602  1.1  ragge 
    603  1.1  ragge void
    604  1.1  ragge rfc_intr(void *intarg)
    605  1.1  ragge {
    606  1.1  ragge 	struct rfc_softc *rfc_sc = intarg;
    607  1.1  ragge 	struct rf_softc *rf_sc;
    608  1.1  ragge 	struct rf_softc *other_drive;
    609  1.1  ragge 	int i;
    610  1.1  ragge 
    611  1.1  ragge 	rf_sc = (struct rf_softc *)rfc_sc->sc_childs[rfc_sc->sc_curchild];
    612  1.1  ragge 	/*
    613  1.1  ragge 	 * First clean up from previous command...
    614  1.1  ragge 	 */
    615  1.1  ragge 	switch (rf_sc->sc_state & RFS_CMDS) {
    616  1.1  ragge 	case RFS_PROBING:	/* density detect / verify started */
    617  1.1  ragge 		disk_unbusy(&rf_sc->sc_disk, 0, 1);
    618  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    619  1.1  ragge 		    & RX2CS_ERR) == 0) {
    620  1.1  ragge 			RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
    621  1.1  ragge 			wakeup(rf_sc);
    622  1.1  ragge 		} else {
    623  1.1  ragge 			if (rfc_sc->type == 2
    624  1.1  ragge 			    && (rf_sc->sc_state & RFS_DENS) == 0
    625  1.1  ragge 			    && (rf_sc->sc_state & RFS_AD) != 0) {
    626  1.1  ragge 				/* retry at DD */
    627  1.1  ragge 				rf_sc->sc_state |= RFS_DENS;
    628  1.1  ragge 				disk_busy(&rf_sc->sc_disk);
    629  1.1  ragge 				if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
    630  1.1  ragge 				    | RX2CS_DD | (rf_sc->sc_dnum == 0
    631  1.1  ragge 				    ? 0 : RX2CS_US), 1, 1) < 0) {
    632  1.1  ragge 					rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    633  1.1  ragge 					RFS_SETCMD(rf_sc->sc_state,
    634  1.1  ragge 					    RFS_NOTINIT);
    635  1.1  ragge 					wakeup(rf_sc);
    636  1.1  ragge 				}
    637  1.1  ragge 			} else {
    638  1.1  ragge 				printf("%s: density error.\n",
    639  1.1  ragge 				    rf_sc->sc_dev.dv_xname);
    640  1.1  ragge 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    641  1.1  ragge 				RFS_SETCMD(rf_sc->sc_state, RFS_NOTINIT);
    642  1.1  ragge 				wakeup(rf_sc);
    643  1.1  ragge 			}
    644  1.1  ragge 		}
    645  1.1  ragge 		return;
    646  1.1  ragge 	case RFS_IDLE:	/* controller is idle */
    647  1.1  ragge 		if (rfc_sc->sc_curbuf->b_bcount
    648  1.1  ragge 		    % ((rf_sc->sc_state & RFS_DENS) == 0
    649  1.1  ragge 		    ? RX2_BYTE_SD : RX2_BYTE_DD) != 0) {
    650  1.1  ragge 			/*
    651  1.1  ragge 			 * can only handle blocks that are a multiple of the
    652  1.1  ragge 			 * physical block size
    653  1.1  ragge 			 */
    654  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    655  1.1  ragge 			break;
    656  1.1  ragge 		}
    657  1.1  ragge 		RFS_SETCMD(rf_sc->sc_state, (rfc_sc->sc_curbuf->b_flags
    658  1.1  ragge 		    & B_READ) != 0 ? RFS_RSEC : RFS_FBUF);
    659  1.1  ragge 		break;
    660  1.1  ragge 	case RFS_RSEC:	/* Read Sector */
    661  1.1  ragge 		disk_unbusy(&rf_sc->sc_disk, 0, 1);
    662  1.1  ragge 		/* check for errors */
    663  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    664  1.1  ragge 		    & RX2CS_ERR) != 0) {
    665  1.1  ragge 			/* should do more verbose error reporting */
    666  1.1  ragge 			printf("rfc_intr: Error while reading secotr: %x\n",
    667  1.1  ragge 			    bus_space_read_2(rfc_sc->sc_iot,
    668  1.1  ragge 			    rfc_sc->sc_ioh, RX2ES) );
    669  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    670  1.1  ragge 			break;
    671  1.1  ragge 		}
    672  1.1  ragge 		RFS_SETCMD(rf_sc->sc_state, RFS_EBUF);
    673  1.1  ragge 		break;
    674  1.1  ragge 	case RFS_WSEC:	/* Write Sector */
    675  1.1  ragge 		i = (rf_sc->sc_state & RFS_DENS) == 0
    676  1.1  ragge 			? RX2_BYTE_SD : RX2_BYTE_DD;
    677  1.1  ragge 		disk_unbusy(&rf_sc->sc_disk, i, 0);
    678  1.1  ragge 		/* check for errors */
    679  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    680  1.1  ragge 		    & RX2CS_ERR) != 0) {
    681  1.1  ragge 			/* should do more verbose error reporting */
    682  1.1  ragge 			printf("rfc_intr: Error while writing secotr: %x\n",
    683  1.1  ragge 			    bus_space_read_2(rfc_sc->sc_iot,
    684  1.1  ragge 			    rfc_sc->sc_ioh, RX2ES) );
    685  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    686  1.1  ragge 			break;
    687  1.1  ragge 		}
    688  1.1  ragge 		if (rfc_sc->sc_bytesleft > i) {
    689  1.1  ragge 			rfc_sc->sc_bytesleft -= i;
    690  1.1  ragge 			rfc_sc->sc_bufidx += i;
    691  1.1  ragge 		} else {
    692  1.1  ragge 			biodone(rfc_sc->sc_curbuf);
    693  1.1  ragge 			rfc_sc->sc_curbuf = BUFQ_GET(&rf_sc->sc_bufq);
    694  1.1  ragge 			if (rfc_sc->sc_curbuf != NULL) {
    695  1.1  ragge 				rfc_sc->sc_bufidx =
    696  1.1  ragge 				    rfc_sc->sc_curbuf->b_un.b_addr;
    697  1.1  ragge 				rfc_sc->sc_bytesleft =
    698  1.1  ragge 				    rfc_sc->sc_curbuf->b_bcount;
    699  1.1  ragge 			} else {
    700  1.1  ragge 				RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
    701  1.1  ragge 				/*
    702  1.1  ragge 				 * Switch to the other drive if there where
    703  1.1  ragge 				 * buffers queued while we where working on
    704  1.1  ragge 				 * the buffer queue of this drive
    705  1.1  ragge 				 */
    706  1.1  ragge 				other_drive = (struct rf_softc *)
    707  1.1  ragge 				    rfc_sc->sc_childs[
    708  1.1  ragge 				    rfc_sc->sc_curchild == 0 ? 1 : 0];
    709  1.1  ragge 				if (other_drive != NULL && BUFQ_PEEK(
    710  1.1  ragge 					&other_drive->sc_bufq) != NULL) {
    711  1.1  ragge 					rfc_sc->sc_curchild =
    712  1.1  ragge 					    rfc_sc->sc_curchild == 0 ? 1 : 0;
    713  1.1  ragge 					rf_sc = other_drive;
    714  1.1  ragge 					rfc_sc->sc_curbuf =
    715  1.1  ragge 					    BUFQ_GET(&rf_sc->sc_bufq);
    716  1.1  ragge 					rfc_sc->sc_bufidx =
    717  1.1  ragge 					    rfc_sc->sc_curbuf->b_un.b_addr;
    718  1.1  ragge 					rfc_sc->sc_bytesleft =
    719  1.1  ragge 					    rfc_sc->sc_curbuf->b_bcount;
    720  1.1  ragge 				} else
    721  1.1  ragge 					return;
    722  1.1  ragge 			}
    723  1.1  ragge 		}
    724  1.1  ragge 		RFS_SETCMD(rf_sc->sc_state,
    725  1.1  ragge 		    (rfc_sc->sc_curbuf->b_flags & B_READ) != 0
    726  1.1  ragge 		    ? RFS_RSEC : RFS_FBUF);
    727  1.1  ragge 		break;
    728  1.1  ragge 	case RFS_FBUF:	/* Fill Buffer */
    729  1.1  ragge 		disk_unbusy(&rf_sc->sc_disk, 0, 0);
    730  1.1  ragge 		/* check for errors */
    731  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    732  1.1  ragge 		    & RX2CS_ERR) != 0) {
    733  1.1  ragge 			/* should do more verbose error reporting */
    734  1.1  ragge 			printf("rfc_intr: Error while DMA: %x\n",
    735  1.1  ragge 			    bus_space_read_2(rfc_sc->sc_iot,
    736  1.1  ragge 			    rfc_sc->sc_ioh, RX2ES));
    737  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    738  1.1  ragge 		}
    739  1.1  ragge 		bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
    740  1.1  ragge 		RFS_SETCMD(rf_sc->sc_state, RFS_WSEC);
    741  1.1  ragge 		break;
    742  1.1  ragge 	case RFS_EBUF:	/* Empty Buffer */
    743  1.1  ragge 		i = (rf_sc->sc_state & RFS_DENS) == 0
    744  1.1  ragge 		    ? RX2_BYTE_SD : RX2_BYTE_DD;
    745  1.1  ragge 		disk_unbusy(&rf_sc->sc_disk, i, 1);
    746  1.1  ragge 		/* check for errors */
    747  1.1  ragge 		if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
    748  1.1  ragge 			& RX2CS_ERR) != 0) {
    749  1.1  ragge 			/* should do more verbose error reporting */
    750  1.1  ragge 			printf("rfc_intr: Error while DMA: %x\n",
    751  1.1  ragge 			    bus_space_read_2(rfc_sc->sc_iot,
    752  1.1  ragge 			    rfc_sc->sc_ioh, RX2ES));
    753  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    754  1.1  ragge 		}
    755  1.1  ragge 		bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
    756  1.1  ragge 		if (rfc_sc->sc_bytesleft > i) {
    757  1.1  ragge 			rfc_sc->sc_bytesleft -= i;
    758  1.1  ragge 			rfc_sc->sc_bufidx += i;
    759  1.1  ragge 		} else {
    760  1.1  ragge 			biodone(rfc_sc->sc_curbuf);
    761  1.1  ragge 			rfc_sc->sc_curbuf = BUFQ_GET(&rf_sc->sc_bufq);
    762  1.1  ragge 			if (rfc_sc->sc_curbuf != NULL) {
    763  1.1  ragge 				rfc_sc->sc_bufidx =
    764  1.1  ragge 				    rfc_sc->sc_curbuf->b_un.b_addr;
    765  1.1  ragge 				rfc_sc->sc_bytesleft =
    766  1.1  ragge 				    rfc_sc->sc_curbuf->b_bcount;
    767  1.1  ragge 			} else {
    768  1.1  ragge 				RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
    769  1.1  ragge 				/*
    770  1.1  ragge 				 * Switch to the other drive if there where
    771  1.1  ragge 				 * buffers queued while we where working on
    772  1.1  ragge 				 * the buffer queue of this drive
    773  1.1  ragge 				 */
    774  1.1  ragge 				other_drive = (struct rf_softc *)
    775  1.1  ragge 				    rfc_sc->sc_childs[
    776  1.1  ragge 				    rfc_sc->sc_curchild == 0 ? 1 : 0];
    777  1.1  ragge 				if (other_drive != NULL && BUFQ_PEEK(
    778  1.1  ragge 					&other_drive->sc_bufq) != NULL) {
    779  1.1  ragge 					rfc_sc->sc_curchild =
    780  1.1  ragge 					    rfc_sc->sc_curchild == 0 ? 1 : 0;
    781  1.1  ragge 					rf_sc = other_drive;
    782  1.1  ragge 					rfc_sc->sc_curbuf =
    783  1.1  ragge 					    BUFQ_GET(&rf_sc->sc_bufq);
    784  1.1  ragge 					rfc_sc->sc_bufidx =
    785  1.1  ragge 					    rfc_sc->sc_curbuf->b_un.b_addr;
    786  1.1  ragge 					rfc_sc->sc_bytesleft =
    787  1.1  ragge 					    rfc_sc->sc_curbuf->b_bcount;
    788  1.1  ragge 				} else
    789  1.1  ragge 					return;
    790  1.1  ragge 			}
    791  1.1  ragge 		}
    792  1.1  ragge 		RFS_SETCMD(rf_sc->sc_state,
    793  1.1  ragge 		    (rfc_sc->sc_curbuf->b_flags & B_READ) != 0
    794  1.1  ragge 		    ? RFS_RSEC : RFS_FBUF);
    795  1.1  ragge 		break;
    796  1.1  ragge 	case RFS_NOTINIT: /* Controller is idle and density is not detected. */
    797  1.1  ragge 	case RFS_SMD:	/* Set Media Density */
    798  1.1  ragge 	case RFS_RSTAT:	/* Read Status */
    799  1.1  ragge 	case RFS_WDDS:	/* Write Deleted Data Sector */
    800  1.1  ragge 	case RFS_REC:	/* Read Error Code */
    801  1.1  ragge 	default:
    802  1.1  ragge 		panic("Impossible state in rfc_intr(1).\n");
    803  1.1  ragge 	}
    804  1.1  ragge 
    805  1.1  ragge 	if ((rfc_sc->sc_curbuf->b_flags & B_ERROR) != 0) {
    806  1.1  ragge 		rfc_sc->sc_curbuf->b_error = EIO;
    807  1.1  ragge 		biodone(rfc_sc->sc_curbuf);
    808  1.1  ragge 		rfc_sc->sc_curbuf = NULL;
    809  1.1  ragge 		RFS_SETCMD(rf_sc->sc_state, RFS_NOTINIT);
    810  1.1  ragge 		return;
    811  1.1  ragge 	}
    812  1.1  ragge 
    813  1.1  ragge 	/*
    814  1.1  ragge 	 * ... then initiate next command.
    815  1.1  ragge 	 */
    816  1.1  ragge 	switch (rf_sc->sc_state & RFS_CMDS) {
    817  1.1  ragge 	case RFS_NOTINIT: /* Controller is idle and density is not detected. */
    818  1.1  ragge 	case RFS_PROBING: /* density detect / verify started */
    819  1.1  ragge 	case RFS_IDLE:	/* controller is idle */
    820  1.1  ragge 		panic("Impossible state in rfc_intr(2).\n");
    821  1.1  ragge 		break;
    822  1.1  ragge 	case RFS_EBUF:	/* Empty Buffer */
    823  1.1  ragge 		i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam,
    824  1.1  ragge 		    rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0
    825  1.1  ragge 		    ? RX2_BYTE_SD : RX2_BYTE_DD, rfc_sc->sc_curbuf->b_proc,
    826  1.1  ragge 		    BUS_DMA_NOWAIT);
    827  1.1  ragge 		if (i != 0) {
    828  1.1  ragge 			printf("rfc_intr: Error while loading bus dma map: "
    829  1.1  ragge 			    "%d\n", i);
    830  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    831  1.1  ragge 			break;
    832  1.1  ragge 		}
    833  1.1  ragge 		disk_busy(&rf_sc->sc_disk);
    834  1.1  ragge 		if (rfc_sendcmd(rfc_sc, RX2CS_EBUF | RX2CS_IE
    835  1.1  ragge 		    | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD)
    836  1.1  ragge 		    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
    837  1.1  ragge 		    | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0x30000)>>4),
    838  1.1  ragge 		    ((rf_sc->sc_state & RFS_DENS) == 0
    839  1.1  ragge 		    ? RX2_BYTE_SD : RX2_BYTE_DD) / 2,
    840  1.1  ragge 		    rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) {
    841  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    842  1.1  ragge 			bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
    843  1.1  ragge 		}
    844  1.1  ragge 		break;
    845  1.1  ragge 	case RFS_FBUF:	/* Fill Buffer */
    846  1.1  ragge 		i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam,
    847  1.1  ragge 		    rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0
    848  1.1  ragge 		    ? RX2_BYTE_SD : RX2_BYTE_DD,
    849  1.1  ragge 		    rfc_sc->sc_curbuf->b_proc, BUS_DMA_NOWAIT);
    850  1.1  ragge 		if (i != 0) {
    851  1.1  ragge 			printf("rfc_intr: Error while loading bus dma map: "
    852  1.1  ragge 			    "%d\n", i);
    853  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    854  1.1  ragge 			break;
    855  1.1  ragge 		}
    856  1.1  ragge 		disk_busy(&rf_sc->sc_disk);
    857  1.1  ragge 		if (rfc_sendcmd(rfc_sc, RX2CS_FBUF | RX2CS_IE
    858  1.1  ragge 		    | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD)
    859  1.1  ragge 		    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
    860  1.1  ragge 		    | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0x30000)>>4),
    861  1.1  ragge 		    ((rf_sc->sc_state & RFS_DENS) == 0
    862  1.1  ragge 		    ? RX2_BYTE_SD : RX2_BYTE_DD) / 2,
    863  1.1  ragge 		    rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) {
    864  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    865  1.1  ragge 			bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
    866  1.1  ragge 		}
    867  1.1  ragge 		break;
    868  1.1  ragge 	case RFS_WSEC:	/* Write Sector */
    869  1.1  ragge 		i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft
    870  1.1  ragge 		    + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) /
    871  1.1  ragge 		    ((rf_sc->sc_state & RFS_DENS) == 0
    872  1.1  ragge 		    ? RX2_BYTE_SD : RX2_BYTE_DD);
    873  1.1  ragge 		if (i > RX2_TRACKS * RX2_SECTORS) {
    874  1.1  ragge 			rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft;
    875  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    876  1.1  ragge 		}
    877  1.1  ragge 		disk_busy(&rf_sc->sc_disk);
    878  1.1  ragge 		if (rfc_sendcmd(rfc_sc, RX2CS_WSEC | RX2CS_IE
    879  1.1  ragge 		    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
    880  1.1  ragge 		    | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD),
    881  1.1  ragge 		    i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) {
    882  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    883  1.1  ragge 		}
    884  1.1  ragge 		break;
    885  1.1  ragge 	case RFS_RSEC:	/* Read Sector */
    886  1.1  ragge 		i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft
    887  1.1  ragge 		    + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) /
    888  1.1  ragge 		    ((rf_sc->sc_state & RFS_DENS) == 0
    889  1.1  ragge 		    ? RX2_BYTE_SD : RX2_BYTE_DD);
    890  1.1  ragge 		if (i > RX2_TRACKS * RX2_SECTORS) {
    891  1.1  ragge 			rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft;
    892  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    893  1.1  ragge 		}
    894  1.1  ragge 		disk_busy(&rf_sc->sc_disk);
    895  1.1  ragge 		if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
    896  1.1  ragge 		    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
    897  1.1  ragge 		    | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD),
    898  1.1  ragge 		    i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) {
    899  1.1  ragge 			rfc_sc->sc_curbuf->b_flags |= B_ERROR;
    900  1.1  ragge 		}
    901  1.1  ragge 		break;
    902  1.1  ragge 	case RFS_SMD:	/* Set Media Density */
    903  1.1  ragge 	case RFS_RSTAT:	/* Read Status */
    904  1.1  ragge 	case RFS_WDDS:	/* Write Deleted Data Sector */
    905  1.1  ragge 	case RFS_REC:	/* Read Error Code */
    906  1.1  ragge 	default:
    907  1.1  ragge 		panic("Impossible state in rfc_intr(3).\n");
    908  1.1  ragge 	}
    909  1.1  ragge 
    910  1.1  ragge 	if ((rfc_sc->sc_curbuf->b_flags & B_ERROR) != 0) {
    911  1.1  ragge 		rfc_sc->sc_curbuf->b_error = EIO;
    912  1.1  ragge 		biodone(rfc_sc->sc_curbuf);
    913  1.1  ragge 		rfc_sc->sc_curbuf = NULL;
    914  1.1  ragge 		RFS_SETCMD(rf_sc->sc_state, RFS_NOTINIT);
    915  1.1  ragge 	}
    916  1.1  ragge 	return;
    917  1.1  ragge }
    918  1.1  ragge 
    919  1.1  ragge 
    920  1.1  ragge 
    921  1.1  ragge int
    922  1.1  ragge rfdump(dev_t dev, daddr_t blkno, caddr_t va, size_t size)
    923  1.1  ragge {
    924  1.1  ragge 
    925  1.1  ragge 	/* A 0.5MB floppy is much to small to take a system dump... */
    926  1.1  ragge 	return(ENXIO);
    927  1.1  ragge }
    928  1.1  ragge 
    929  1.1  ragge 
    930  1.1  ragge 
    931  1.1  ragge int
    932  1.1  ragge rfsize(dev_t dev)
    933  1.1  ragge {
    934  1.1  ragge 
    935  1.1  ragge 	return(-1);
    936  1.1  ragge }
    937  1.1  ragge 
    938  1.1  ragge 
    939  1.1  ragge 
    940  1.1  ragge int
    941  1.1  ragge rfopen(dev_t dev, int oflags, int devtype, struct proc *p)
    942  1.1  ragge {
    943  1.1  ragge 	struct rf_softc *rf_sc;
    944  1.1  ragge 	struct rfc_softc *rfc_sc;
    945  1.1  ragge 	struct disklabel *dl;
    946  1.1  ragge 	int unit;
    947  1.1  ragge 
    948  1.1  ragge 	unit = DISKUNIT(dev);
    949  1.1  ragge 	if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
    950  1.1  ragge 		return(ENXIO);
    951  1.1  ragge 	}
    952  1.1  ragge 	rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
    953  1.1  ragge 	dl = rf_sc->sc_disk.dk_label;
    954  1.1  ragge 	switch (DISKPART(dev)) {
    955  1.1  ragge 		case 0:			/* Part. a is single density. */
    956  1.1  ragge 			rf_sc->sc_state &= ~RFS_DENS;
    957  1.1  ragge 			rf_sc->sc_state &= ~RFS_AD;
    958  1.1  ragge 		break;
    959  1.1  ragge 		case 1:			/* Part. b is double density. */
    960  1.1  ragge 			/*
    961  1.1  ragge 			 * Opening a singe density only drive
    962  1.1  ragge 			 * in double density is sensless.
    963  1.1  ragge 			 */
    964  1.1  ragge 			if (rfc_sc->type == 1) {
    965  1.1  ragge 				return(ENXIO);
    966  1.1  ragge 			}
    967  1.1  ragge 			rf_sc->sc_state |= RFS_DENS;
    968  1.1  ragge 			rf_sc->sc_state &= ~RFS_AD;
    969  1.1  ragge 		break;
    970  1.1  ragge 		case 2:			/* Part. c is auto density. */
    971  1.1  ragge 			rf_sc->sc_state |= RFS_AD;
    972  1.1  ragge 		break;
    973  1.1  ragge 		default:
    974  1.1  ragge 			return(ENXIO);
    975  1.1  ragge 		break;
    976  1.1  ragge 	}
    977  1.1  ragge 	if ((rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) {
    978  1.1  ragge 		rfc_sc->sc_curchild = rf_sc->sc_dnum;
    979  1.1  ragge 		/*
    980  1.1  ragge 		 * Controller is idle and density is not detected.
    981  1.1  ragge 		 * Start a density probe by issuing a read sector command
    982  1.1  ragge 		 * and sleep until the density probe finished.
    983  1.1  ragge 		 * Due to this it is imposible to open unformated media.
    984  1.1  ragge 		 * As the RX02/02 is not able to format its own media,
    985  1.1  ragge 		 * media must be purchased preformated. fsck DEC makreting!
    986  1.1  ragge 		 */
    987  1.1  ragge 		RFS_SETCMD(rf_sc->sc_state, RFS_PROBING);
    988  1.1  ragge 		disk_busy(&rf_sc->sc_disk);
    989  1.1  ragge 		if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
    990  1.1  ragge 		    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
    991  1.1  ragge 		    | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD),
    992  1.1  ragge 		    1, 1) < 0) {
    993  1.1  ragge 			rf_sc->sc_state = 0;
    994  1.1  ragge 			return(ENXIO);
    995  1.1  ragge 		}
    996  1.1  ragge 		/* wait max. 2 sec for density probe to finish */
    997  1.1  ragge 		if (tsleep(rf_sc, PRIBIO | PCATCH, "density probe", 2 * hz)
    998  1.1  ragge 		    != 0 || (rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) {
    999  1.1  ragge 			/* timeout elapsed and / or somthing went wrong */
   1000  1.1  ragge 			rf_sc->sc_state = 0;
   1001  1.1  ragge 			return(ENXIO);
   1002  1.1  ragge 		}
   1003  1.1  ragge 	}
   1004  1.1  ragge 	/* disklabel. We use different fake geometries for SD and DD. */
   1005  1.1  ragge 	if ((rf_sc->sc_state & RFS_DENS) == 0) {
   1006  1.1  ragge 		dl->d_nsectors = 10;		/* sectors per track */
   1007  1.1  ragge 		dl->d_secpercyl = 10;		/* sectors per cylinder */
   1008  1.1  ragge 		dl->d_ncylinders = 50;		/* cylinders per unit */
   1009  1.1  ragge 		dl->d_secperunit = 501; /* sectors per unit */
   1010  1.1  ragge 		/* number of sectors in partition */
   1011  1.1  ragge 		dl->d_partitions[2].p_size = 500;
   1012  1.1  ragge 	} else {
   1013  1.1  ragge 		dl->d_nsectors = RX2_SECTORS / 2;  /* sectors per track */
   1014  1.1  ragge 		dl->d_secpercyl = RX2_SECTORS / 2; /* sectors per cylinder */
   1015  1.1  ragge 		dl->d_ncylinders = RX2_TRACKS;     /* cylinders per unit */
   1016  1.1  ragge 		/* sectors per unit */
   1017  1.1  ragge 		dl->d_secperunit = RX2_SECTORS * RX2_TRACKS / 2;
   1018  1.1  ragge 		/* number of sectors in partition */
   1019  1.1  ragge 		dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS / 2;
   1020  1.1  ragge 	}
   1021  1.1  ragge 	rf_sc->sc_open++;
   1022  1.1  ragge 	return(0);
   1023  1.1  ragge }
   1024  1.1  ragge 
   1025  1.1  ragge 
   1026  1.1  ragge 
   1027  1.1  ragge int
   1028  1.1  ragge rfclose(dev_t dev, int fflag, int devtype, struct proc *p)
   1029  1.1  ragge {
   1030  1.1  ragge 	struct rf_softc *rf_sc;
   1031  1.1  ragge 	int unit;
   1032  1.1  ragge 
   1033  1.1  ragge 	unit = DISKUNIT(dev);
   1034  1.1  ragge 	if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
   1035  1.1  ragge 		return(ENXIO);
   1036  1.1  ragge 	}
   1037  1.1  ragge 	if (rf_sc->sc_open == 0) {
   1038  1.1  ragge 		panic("rfclose: can not close non-open drive %s",
   1039  1.1  ragge 		    rf_sc->sc_dev.dv_xname);
   1040  1.1  ragge 	} else {
   1041  1.1  ragge 		if (--rf_sc->sc_open == 0) {
   1042  1.1  ragge 			rf_sc->sc_state = 0;
   1043  1.1  ragge 		}
   1044  1.1  ragge 	}
   1045  1.1  ragge 	return(0);
   1046  1.1  ragge }
   1047  1.1  ragge 
   1048  1.1  ragge 
   1049  1.1  ragge 
   1050  1.1  ragge int
   1051  1.1  ragge rfread(dev_t dev, struct uio *uio, int ioflag)
   1052  1.1  ragge {
   1053  1.1  ragge 
   1054  1.1  ragge 	return(physio(rfstrategy, NULL, dev, B_READ, minphys, uio));
   1055  1.1  ragge }
   1056  1.1  ragge 
   1057  1.1  ragge 
   1058  1.1  ragge 
   1059  1.1  ragge int
   1060  1.1  ragge rfwrite(dev_t dev, struct uio *uio, int ioflag)
   1061  1.1  ragge {
   1062  1.1  ragge 
   1063  1.1  ragge 	return(physio(rfstrategy, NULL, dev, B_WRITE, minphys, uio));
   1064  1.1  ragge }
   1065  1.1  ragge 
   1066  1.1  ragge 
   1067  1.1  ragge 
   1068  1.1  ragge int
   1069  1.1  ragge rfioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
   1070  1.1  ragge {
   1071  1.1  ragge 	struct rf_softc *rf_sc;
   1072  1.1  ragge 	int unit;
   1073  1.1  ragge 
   1074  1.1  ragge 	unit = DISKUNIT(dev);
   1075  1.1  ragge 	if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
   1076  1.1  ragge 		return(ENXIO);
   1077  1.1  ragge 	}
   1078  1.1  ragge 	/* We are going to operate on a non open dev? PANIC! */
   1079  1.1  ragge 	if (rf_sc->sc_open == 0) {
   1080  1.1  ragge 		panic("rfstrategy: can not operate on non-open drive %s (2)",
   1081  1.1  ragge 		    rf_sc->sc_dev.dv_xname);
   1082  1.1  ragge 	}
   1083  1.1  ragge 	switch (cmd) {
   1084  1.1  ragge 	/* get and set disklabel; DIOCGPART used internally */
   1085  1.1  ragge 	case DIOCGDINFO: /* get */
   1086  1.1  ragge 		memcpy(data, rf_sc->sc_disk.dk_label,
   1087  1.1  ragge 		    sizeof(struct disklabel));
   1088  1.1  ragge 		return(0);
   1089  1.1  ragge 	case DIOCSDINFO: /* set */
   1090  1.1  ragge 		return(0);
   1091  1.1  ragge 	case DIOCWDINFO: /* set, update disk */
   1092  1.1  ragge 		return(0);
   1093  1.1  ragge 	case DIOCGPART:  /* get partition */
   1094  1.1  ragge 		((struct partinfo *)data)->disklab = rf_sc->sc_disk.dk_label;
   1095  1.1  ragge 		((struct partinfo *)data)->part =
   1096  1.1  ragge 		    &rf_sc->sc_disk.dk_label->d_partitions[DISKPART(dev)];
   1097  1.1  ragge 		return(0);
   1098  1.1  ragge 
   1099  1.1  ragge 	/* do format operation, read or write */
   1100  1.1  ragge 	case DIOCRFORMAT:
   1101  1.1  ragge 	break;
   1102  1.1  ragge 	case DIOCWFORMAT:
   1103  1.1  ragge 	break;
   1104  1.1  ragge 
   1105  1.1  ragge 	case DIOCSSTEP: /* set step rate */
   1106  1.1  ragge 	break;
   1107  1.1  ragge 	case DIOCSRETRIES: /* set # of retries */
   1108  1.1  ragge 	break;
   1109  1.1  ragge 	case DIOCKLABEL: /* keep/drop label on close? */
   1110  1.1  ragge 	break;
   1111  1.1  ragge 	case DIOCWLABEL: /* write en/disable label */
   1112  1.1  ragge 	break;
   1113  1.1  ragge 
   1114  1.1  ragge /*	case DIOCSBAD: / * set kernel dkbad */
   1115  1.1  ragge 	break; /* */
   1116  1.1  ragge 	case DIOCEJECT: /* eject removable disk */
   1117  1.1  ragge 	break;
   1118  1.1  ragge 	case ODIOCEJECT: /* eject removable disk */
   1119  1.1  ragge 	break;
   1120  1.1  ragge 	case DIOCLOCK: /* lock/unlock pack */
   1121  1.1  ragge 	break;
   1122  1.1  ragge 
   1123  1.1  ragge 	/* get default label, clear label */
   1124  1.1  ragge 	case DIOCGDEFLABEL:
   1125  1.1  ragge 	break;
   1126  1.1  ragge 	case DIOCCLRLABEL:
   1127  1.1  ragge 	break;
   1128  1.1  ragge 	default:
   1129  1.1  ragge 		return(ENOTTY);
   1130  1.1  ragge 	}
   1131  1.1  ragge 
   1132  1.1  ragge 	return(ENOTTY);
   1133  1.1  ragge }
   1134  1.1  ragge 
   1135  1.1  ragge 
   1136