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