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