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