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