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