add two ioctl's
[unix-history] / usr / src / sys / vax / uba / rx.c
CommitLineData
89435dd5 1/* rx.c 4.4 83/02/21 */
63e51da2
SL
2
3#include "rx.h"
4#if NFX > 0
5/*
6 * RX02 floppy disk device driver
7 *
9246378c 8 * WARNING, UNTESTED
63e51da2 9 */
9246378c
SL
10#include "../machine/pte.h"
11
63e51da2 12#include "../h/param.h"
63e51da2 13#include "../h/buf.h"
9246378c 14#include "../h/systm.h"
63e51da2 15#include "../h/conf.h"
95c06320
HS
16#include "../h/errno.h"
17#include "../h/time.h"
9246378c
SL
18#include "../h/kernel.h"
19#include "../h/uio.h"
95c06320 20#include "../h/file.h"
63e51da2 21
9246378c 22#include "../vax/cpu.h"
63e51da2
SL
23#include "../vax/nexus.h"
24#include "../vaxuba/ubavar.h"
25#include "../vaxuba/ubareg.h"
26#include "../vaxuba/rxreg.h"
27
28/* per-controller data */
29struct rx_ctlr {
30 int rxc_state; /* controller state */
31#define RXS_READ 1 /* read started */
32#define RXS_EMPTY 2 /* empty started */
33#define RXS_FILL 3 /* fill started */
34#define RXS_WRITE 4 /* write started */
35#define RXS_FORMAT 5 /* format started */
36#define RXS_RDSTAT 6 /* status read started */
37#define RXS_RDERR 7 /* error read started */
9246378c 38#define RXS_IDLE 8 /* device is idle */
63e51da2
SL
39 u_short rxc_rxcs; /* extended error status */
40 u_short rxc_rxdb;
41 u_short rxc_rxxt[4];
9246378c 42#define RX_MAXTIMEOUT 30 /* # seconds to wait before giving up */
63e51da2
SL
43} rx_ctlr[NFX];
44struct buf rrxbuf[NFX]; /* buffer for I/O */
45struct buf erxbuf[NFX]; /* buffer for reading error status */
46
47/* per-drive data */
48struct rx_softc {
9246378c 49 int sc_flags; /* drive status flags */
63e51da2
SL
50#define RXF_DBLDEN 0x01 /* use double density */
51#define RXF_DIRECT 0x02 /* use direct sector mapping */
52#define RXF_TRKZERO 0x04 /* start mapping on track 0 */
53#define RXF_DEVTYPE 0x07 /* density and mapping flags */
54#define RXF_OPEN 0x10 /* open */
55#define RXF_DDMK 0x20 /* deleted-data mark detected */
56#define RXF_USEWDDS 0x40 /* write deleted-data sector */
9246378c
SL
57 int sc_csbits; /* constant bits for CS register */
58 int sc_tocnt; /* for watchdog routine */
63e51da2
SL
59} rx_softc[NRX];
60
9246378c
SL
61struct rxerr {
62 short rxcs;
63 short rxdb;
64 short rxxt[4]; /* error code dump from controller */
65} rxerr[NFX];
66
63e51da2
SL
67struct uba_device *rxdinfo[NRX];
68struct uba_ctlr *rxminfo[NFX];
69int rxprobe(), rxslave(), rxattach(), rxdgo(), rxintr();
70int rxwatch(), rxphys();
71u_short rxstd[] = { 0177170, 0177150, 0 };
72struct uba_driver fxdriver =
73 { rxprobe, rxslave, rxattach, rxdgo, rxstd, "rx", rxdinfo, "fx", rxminfo };
74
75int rxwstart;
76#define RXUNIT(dev) (minor(dev)>>4)
77
63e51da2
SL
78/* constants related to floppy data capacity */
79#define RXSECS 2002 /* # sectors on a floppy */
9246378c 80#define DDSTATE (sc->sc_flags&RXF_DBLDEN)
63e51da2
SL
81#define NBPS (DDSTATE ? 256 : 128) /* # bytes per sector */
82#define NWPS (DDSTATE ? 128 : 64) /* # words per sector */
83#define RXSIZE (DDSTATE ? 512512 : 256256) /* # bytes per disk */
84#define SECSHFT (DDSTATE ? 8 : 7) /* # bits to shift for sctr # */
85#define SECMASK (DDSTATE ? 0xff : 0x7f) /* shifted-out bits of offset */
86
9246378c 87#define B_CTRL 0x80000000 /* control (format) request */
63e51da2
SL
88
89/*ARGSUSED*/
90rxprobe (reg)
91 caddr_t reg;
92{
9246378c 93 register int br, cvec; /* value-result */
63e51da2
SL
94 struct rxdevice *rxaddr = (struct rxdevice *)reg;
95
96#ifdef lint
97 br = 0; cvec = br; br = cvec;
9246378c 98 rxintr(0);
63e51da2
SL
99#endif lint
100 rxaddr->rxcs = RX_INTR;
101 DELAY(10);
102 rxaddr->rxcs = 0;
103 return (sizeof (*rxaddr));
104}
105
106rxslave(ui,reg)
107 struct uba_device *ui;
108 caddr_t reg;
109{
110
111 ui->ui_dk = 1;
112 return (ui->ui_slave == 0 || ui->ui_slave == 1);
113}
114
115/*ARGSUSED*/
116rxattach(ui)
117 struct uba_device *ui;
118{
119
120}
121
122/*ARGSUSED1*/
123rxopen(dev, flag)
124 dev_t dev;
125 int flag;
126{
127 register int unit = RXUNIT(dev);
128 register struct rx_softc *sc;
129 register struct uba_device *ui;
130
9246378c
SL
131 if (unit >= NRX || (minor(dev) & 0x8) ||
132 (ui = rxdinfo[unit]) == 0 || ui->ui_alive == 0)
133 return (ENXIO);
63e51da2 134 sc = &rx_softc[unit];
9246378c
SL
135 if (sc->sc_flags & RXF_OPEN)
136 return (EBUSY);
137 sc->sc_flags = RXF_OPEN | (minor(dev) & RXF_DEVTYPE);
138 sc->sc_csbits = RX_INTR;
139 sc->sc_csbits |= ui->ui_slave == 0 ? RX_DRV0 : RX_DRV1;
140 sc->sc_csbits |= minor(dev) & RXF_DBLDEN ? RX_DDEN : RX_SDEN;
141 return (0);
63e51da2
SL
142}
143
144/*ARGSUSED1*/
145rxclose(dev, flag)
146 dev_t dev;
147 int flag;
148{
149 register struct rx_softc *sc = &rx_softc[RXUNIT(dev)];
150
151 sc->sc_flags &= ~RXF_OPEN;
152 sc->sc_csbits = 0;
153}
154
155rxstrategy(bp)
156 register struct buf *bp;
157{
158 struct uba_device *ui;
159 register struct rx_softc *sc;
160 register struct uba_ctlr *um;
9246378c 161 int s;
63e51da2
SL
162
163 ui = rxdinfo[RXUNIT(bp->b_dev)];
164 if (ui == 0 || ui->ui_alive == 0) {
165 bp->b_flags |= B_ERROR;
166 iodone(bp);
167 return;
168 }
63e51da2
SL
169 um = ui->ui_mi;
170 bp->b_actf = NULL;
9246378c 171 s = spl5();
63e51da2
SL
172 if (um->um_tab.b_actf->b_actf == NULL)
173 um->um_tab.b_actf->b_actf = bp;
174 else
175 um->um_tab.b_actf->b_actl->b_forw = bp;
176 um->um_tab.b_actf->b_actl = bp;
177 bp = um->um_tab.b_actf;
9246378c
SL
178 if (!um->um_tab.b_active && bp->b_actf)
179 rxstart(um);
63e51da2
SL
180 splx(s);
181}
182
183/*
184 * Sector mapping routine.
185 * Two independent sets of choices are available:
186 *
187 * (a) The first logical sector may either be on track 1 or track 0.
188 * (b) The sectors on a track may either be taken in 2-for-1 interleaved
189 * fashion or directly.
190 * This gives a total of four possible mapping schemes.
191 *
192 * Physical tracks on the RX02 are numbered 0-76. Physical sectors on
193 * each track are numbered 1-26.
194 *
195 * When interleaving is used, sectors on the first logical track are
196 * taken in the order 1, 3, 5, ..., 25, 2, 4, 6, ..., 26. A skew of
197 * six sectors per track is also used (to allow time for the heads to
198 * move); hence, the sectors on the second logical track are taken in
199 * the order 7, 9, 11, ..., 25, 1, 3, 5, 8, 10, 12, ..., 26, 2, 4, 6;
200 * the third logical track starts with sector 13; and so on.
201 *
202 * When the mapping starts with track 1, track 0 is the last logical
203 * track, and this track is always handled directly (without inter-
204 * leaving), even when the rest of the disk is interleaved. (This is
205 * still compatible with DEC RT-11, which does not use track 0 at all.)
206 */
9246378c
SL
207rxmap(bp, psector, ptrack)
208 struct buf *bp;
209 int *psector, *ptrack;
63e51da2
SL
210{
211 register int lt, ls, ptoff;
9246378c 212 struct rx_softc *sc = &rx_softc[RXUNIT(bp->b_dev)];
63e51da2 213
95c06320 214 ls = bp->b_blkno * (NBPS / DEV_BSIZE);
9246378c
SL
215 lt = ls / 26;
216 ls %= 26;
63e51da2
SL
217 /*
218 * The "physical track offset" (ptoff) takes the
219 * starting physical track (0 or 1) and the desired
220 * interleaving into account. If lt+ptoff >= 77,
221 * then interleaving is not performed.
222 */
223 ptoff = 0;
9246378c
SL
224 if (sc->sc_flags&RXF_DIRECT)
225 ptoff = 77;
226 if (sc->sc_flags&RXF_TRKZERO)
63e51da2
SL
227 ptoff++;
228 if (lt + ptoff < 77)
229 ls = ((ls << 1) + (ls >= 13) + (6*lt)) % 26;
9246378c
SL
230 *ptrack = (lt + ptoff) % 77;
231 *psector = ls + 1;
63e51da2
SL
232}
233
234rxstart(um)
235 register struct uba_ctlr *um;
236{
237 register struct rxdevice *rxaddr;
238 register struct rx_ctlr *rxc;
239 register struct rx_softc *sc;
240 struct buf *bp;
9246378c 241 int unit, sector, track;
63e51da2 242
9246378c 243 if (um->um_tab.b_active || (bp = um->um_tab.b_actf->b_actf) == NULL)
63e51da2 244 return;
9246378c 245 um->um_tab.b_active++;
63e51da2
SL
246 unit = RXUNIT(bp->b_dev);
247 sc = &rx_softc[unit];
63e51da2
SL
248 rxaddr = (struct rxdevice *)um->um_addr;
249 rxc = &rx_ctlr[um->um_ctlr];
9246378c
SL
250 rxtimo(bp->b_dev); /* start watchdog */
251 if (bp->b_flags&B_CTRL) { /* format */
63e51da2
SL
252 rxc->rxc_state = RXS_FORMAT;
253 rxaddr->rxcs = RX_FORMAT | sc->sc_csbits;
9246378c 254 while ((rxaddr->rxcs&RX_TREQ) == 0)
63e51da2
SL
255 ;
256 rxaddr->rxdb = 'I';
257 return;
258 }
9246378c
SL
259 if (bp->b_flags&B_READ) { /* read */
260 rxmap(bp, &sector, &track);
63e51da2
SL
261 rxc->rxc_state = RXS_READ;
262 rxaddr->rxcs = RX_READ | sc->sc_csbits;
9246378c 263 while ((rxaddr->rxcs&RX_TREQ) == 0)
63e51da2 264 ;
9246378c
SL
265 rxaddr->rxdb = (u_short)sector;
266 while ((rxaddr->rxcs&RX_TREQ) == 0)
63e51da2 267 ;
9246378c 268 rxaddr->rxdb = (u_short)track;
63e51da2
SL
269 return;
270 }
9246378c 271 rxc->rxc_state = RXS_FILL; /* write */
63e51da2
SL
272 um->um_cmd = RX_FILL;
273 (void) ubago(rxdinfo[unit]);
274}
275
276rxdgo(um)
277 struct uba_ctlr *um;
278{
279 register struct rxdevice *rxaddr = (struct rxdevice *)um->um_addr;
280 int ubinfo = um->um_ubinfo;
281 struct buf *bp = &rrxbuf[um->um_ctlr];
282 struct rx_softc *sc = &rx_softc[RXUNIT(bp->b_dev)];
283 struct rx_ctlr *rxc = &rx_ctlr[um->um_ctlr];
284
285 bp = um->um_tab.b_actf;
9246378c 286 sc->sc_tocnt = 0;
63e51da2 287 if (rxc->rxc_state != RXS_RDERR) {
9246378c 288 while ((rxaddr->rxcs&RX_TREQ) == 0)
63e51da2 289 ;
9246378c 290 rxaddr->rxdb = bp->b_bcount >> 1;
63e51da2 291 }
9246378c 292 while ((rxaddr->rxcs&RX_TREQ) == 0)
63e51da2 293 ;
9246378c 294 rxaddr->rxdb = ubinfo;
63e51da2
SL
295 rxaddr->rxcs = um->um_cmd | ((ubinfo & 0x30000) >> 4) | sc->sc_csbits;
296}
297
9246378c
SL
298rxintr(dev)
299 dev_t dev;
63e51da2 300{
9246378c
SL
301 int unit = RXUNIT(dev), sector, track;
302 struct uba_ctlr *um = rxminfo[unit];
303 register struct rxdevice *rxaddr;
304 register struct buf *bp;
63e51da2
SL
305 register struct rx_softc *sc = &rx_softc[unit];
306 struct uba_device *ui = rxdinfo[unit];
9246378c
SL
307 struct rxerr *er;
308 register struct rx_ctlr *rxc;
309
310 sc->sc_tocnt = 0;
311 if (!um->um_tab.b_active)
63e51da2 312 return;
9246378c
SL
313 rxaddr = (struct rxdevice *)um->um_addr;
314 rxc = &rx_ctlr[um->um_ctlr];
315 er = &rxerr[um->um_ctlr];
316 bp = um->um_tab.b_actf->b_actf;
317 if ((rxaddr->rxcs & RX_ERR) &&
318 rxc->rxc_state != RXS_RDSTAT && rxc->rxc_state != RXS_RDERR)
319 goto error;
63e51da2
SL
320 switch (rxc->rxc_state) {
321
9246378c
SL
322 /*
323 * Incomplete commands. Perform next step
324 * and return. Note that b_active is set on
325 * entrance and, therefore, also on exit.
326 */
63e51da2
SL
327 case RXS_READ:
328 if (rxaddr->rxdb & RXES_DDMARK)
329 sc->sc_flags |= RXF_DDMK;
330 else
331 sc->sc_flags &= ~RXF_DDMK;
332 rxc->rxc_state = RXS_EMPTY;
333 um->um_cmd = RX_EMPTY;
334 (void) ubago(ui);
335 return;
336
337 case RXS_FILL:
338 rxc->rxc_state = RXS_WRITE;
339 if (sc->sc_flags & RXF_USEWDDS) {
340 rxaddr->rxcs = RX_WDDS | sc->sc_csbits;
341 sc->sc_flags &= ~RXF_USEWDDS;
342 } else
343 rxaddr->rxcs = RX_WRITE | sc->sc_csbits;
9246378c 344 while ((rxaddr->rxcs&RX_TREQ) == 0)
63e51da2 345 ;
9246378c
SL
346 rxmap(bp, &sector, &track);
347 rxaddr->rxdb = sector;
348 while ((rxaddr->rxcs&RX_TREQ) == 0)
63e51da2 349 ;
9246378c 350 rxaddr->rxdb = track;
63e51da2
SL
351 return;
352
9246378c
SL
353 /*
354 * Possibly completed command.
355 */
63e51da2 356 case RXS_RDSTAT:
9246378c 357 if (rxaddr->rxdb&RXES_READY)
63e51da2
SL
358 goto rderr;
359 bp->b_error = EBUSY;
360 bp->b_flags |= B_ERROR;
9246378c
SL
361 goto done;
362
363 /*
364 * Command completed.
365 */
366 case RXS_EMPTY:
367 case RXS_WRITE:
368 case RXS_FORMAT:
369 goto done;
63e51da2
SL
370
371 case RXS_RDERR:
9246378c
SL
372 rxmap(bp, &sector, &track);
373 printf("rx%d: hard error, lsn%d (trk %d psec %d) ",
95c06320 374 unit, bp->b_blkno * (NBPS / DEV_BSIZE),
9246378c
SL
375 track, sector);
376 printf("cs=%b, db=%b, err=%x\n", er->rxcs,
377 RXCS_BITS, er->rxdb, RXES_BITS, er->rxxt[0]);
378 goto done;
63e51da2
SL
379
380 default:
9246378c
SL
381 printf("rx%d: state %d (reset)", unit, rxc->rxc_state);
382 rxreset(um->um_ubanum);
63e51da2
SL
383 printf("\n");
384 return;
385 }
63e51da2
SL
386error:
387 /*
388 * In case of an error:
389 * (a) Give up now if a format (ioctl) was in progress, or if a
390 * density error was detected.
391 * (b) Retry up to nine times if a CRC (data) error was detected,
392 * then give up if the error persists.
393 * (c) In all other cases, reinitialize the drive and try the
394 * operation once more before giving up.
395 */
9246378c 396 if (rxc->rxc_state == RXS_FORMAT || (rxaddr->rxdb&RXES_DENERR))
63e51da2
SL
397 goto giveup;
398 if (rxaddr->rxdb & RXES_CRCERR) {
63e51da2
SL
399 if (++bp->b_errcnt >= 10)
400 goto giveup;
401 goto retry;
402 }
403 bp->b_errcnt += 9;
404 if (bp->b_errcnt >= 10)
405 goto giveup;
406 rxaddr->rxcs = RX_INIT;
407 /* no way to get an interrupt for "init done", so just wait */
9246378c 408 while ((rxaddr->rxdb&RX_DONE) == 0)
63e51da2
SL
409 ;
410retry:
9246378c
SL
411 /*
412 * In case we already have UNIBUS resources, give
413 * them back since we reallocate things in rxstart.
414 */
415 if (um->um_ubinfo)
416 ubadone(um);
417 rxstart(um);
63e51da2 418 return;
9246378c 419
63e51da2
SL
420giveup:
421 /*
422 * Hard I/O error --
9246378c
SL
423 * Density errors are not noted on the console since the
424 * only way to determine the density of an unknown disk
425 * is to try one density or the other at random and see
426 * which one doesn't give a density error.
63e51da2
SL
427 */
428 if (rxaddr->rxdb & RXES_DENERR) {
9246378c 429 bp->b_error = EIO;
63e51da2
SL
430 bp->b_flags |= B_ERROR;
431 goto done;
432 }
433 rxc->rxc_state = RXS_RDSTAT;
434 rxaddr->rxcs = RX_RDSTAT | sc->sc_csbits;
435 return;
9246378c 436
63e51da2
SL
437rderr:
438 /*
439 * A hard error (other than not ready or density) has occurred.
440 * Read the extended error status information.
441 * Before doing this, save the current CS and DB register values,
442 * because the read error status operation may modify them.
9246378c 443 * Insert buffer with request at the head of the queue.
63e51da2
SL
444 */
445 bp->b_error = EIO;
446 bp->b_flags |= B_ERROR;
447 ubadone(um);
448 er->rxcs = rxaddr->rxcs;
449 er->rxdb = rxaddr->rxdb;
95c06320 450 bp = &erxbuf[unit];
63e51da2
SL
451 bp->b_un.b_addr = (caddr_t)er->rxxt;
452 bp->b_bcount = sizeof (er->rxxt);
453 bp->b_flags &= ~(B_DIRTY|B_UAREA|B_PHYS|B_PAGET);
9246378c
SL
454 if (um->um_tab.b_actf->b_actf == NULL)
455 um->um_tab.b_actf->b_actl = bp;
456 bp->b_forw = um->um_tab.b_actf->b_actf;
457 um->um_tab.b_actf->b_actf = bp;
63e51da2
SL
458 rxc->rxc_state = RXS_RDERR;
459 um->um_cmd = RX_RDERR;
460 (void) ubago(ui);
9246378c
SL
461 return;
462done:
463 um->um_tab.b_active = 0;
464 um->um_tab.b_actf->b_actf = bp->b_forw;
465 bp->b_resid = 0;
466 iodone(bp);
467 rxc->rxc_state = RXS_IDLE;
468 ubadone(um);
469 /*
470 * If this unit has more work to do,
471 * start it up right away
472 */
95c06320
HS
473 if (um->um_tab.b_actf->b_actf)
474 rxstart(um);
63e51da2
SL
475}
476
477/*ARGSUSED*/
478minrxphys(bp)
479 struct buf *bp;
480{
95c06320 481 struct rx_softc *sc = &rx_softc[RXUNIT(bp->b_dev)];
63e51da2
SL
482
483 if (bp->b_bcount > NBPS)
484 bp->b_bcount = NBPS;
485}
486
9246378c
SL
487rxtimo(dev)
488 dev_t dev;
63e51da2
SL
489{
490 register struct rx_softc *sc = &rx_softc[RXUNIT(dev)];
491
9246378c
SL
492 if (sc->sc_flags & RXF_OPEN)
493 timeout(rxtimo, (caddr_t)dev, hz);
63e51da2
SL
494 if (++sc->sc_tocnt < RX_MAXTIMEOUT)
495 return;
63e51da2
SL
496 rxintr(dev);
497}
498
499rxreset(uban)
500 int uban;
501{
502 register struct uba_ctlr *um;
503 register struct rxdevice *rxaddr;
504 register int ctlr;
505
506 for (ctlr = 0; ctlr < NFX; ctlr++) {
507 if ((um = rxminfo[ctlr]) == 0 || um->um_ubanum != uban ||
508 um->um_alive == 0)
509 continue;
510 printf(" fx%d", ctlr);
511 if (um->um_ubinfo) {
512 printf("<%d>", (um->um_ubinfo>>28)&0xf);
9246378c 513 um->um_ubinfo = 0;
63e51da2
SL
514 }
515 rx_ctlr[ctlr].rxc_state = RXS_IDLE;
516 rxaddr = (struct rxdevice *)um->um_addr;
9246378c
SL
517 rxaddr->rxcs = RX_INIT;
518 while ((rxaddr->rxdb&RX_DONE) == 0)
63e51da2 519 ;
9246378c 520 rxstart(um);
63e51da2
SL
521 }
522}
523
9246378c 524rxread(dev, uio)
63e51da2 525 dev_t dev;
9246378c 526 struct uio *uio;
63e51da2
SL
527{
528 int unit = RXUNIT(dev), ctlr = rxdinfo[unit]->ui_ctlr;
95c06320 529 struct rx_softc *sc = &rx_softc[RXUNIT(dev)];
63e51da2 530
9246378c
SL
531 if (uio->uio_offset + uio->uio_resid > RXSIZE)
532 return (ENXIO);
533 if (uio->uio_offset < 0 || (uio->uio_offset & SECMASK) != 0)
534 return (EIO);
535 return (physio(rxstrategy, &rrxbuf[ctlr], dev, B_READ, minrxphys));
63e51da2
SL
536}
537
9246378c 538rxwrite(dev, uio)
63e51da2 539 dev_t dev;
9246378c 540 struct uio *uio;
63e51da2
SL
541{
542 int unit = RXUNIT(dev), ctlr = rxdinfo[unit]->ui_ctlr;
95c06320 543 struct rx_softc *sc = &rx_softc[RXUNIT(dev)];
63e51da2 544
9246378c
SL
545 if (uio->uio_offset + uio->uio_resid > RXSIZE)
546 return (ENXIO);
547 if (uio->uio_offset < 0 || (uio->uio_offset & SECMASK) != 0)
548 return (EIO);
549 return (physio(rxstrategy, &rrxbuf[ctlr], dev, B_WRITE, minrxphys));
63e51da2
SL
550}
551
552/*
553 * Control routine:
554 * processes three kinds of requests:
555 *
556 * (1) Set density according to that specified by the open device.
557 * (2) Arrange for the next sector to be written with a deleted-
558 * data mark.
559 * (3) Report whether the last sector read had a deleted-data mark
560 * (by returning with an EIO error code if it did).
561 *
562 * Requests relating to deleted-data marks can be handled right here.
563 * A "set density" request, however, must additionally be processed
564 * through "rxstart", just like a read or write request.
63e51da2
SL
565 */
566/*ARGSUSED3*/
9246378c 567rxioctl(dev, cmd, data, flag)
63e51da2
SL
568 dev_t dev;
569 int cmd;
9246378c 570 caddr_t data;
63e51da2
SL
571 int flag;
572{
573 int unit = RXUNIT(dev);
574 struct rx_softc *sc = &rx_softc[unit];
63e51da2
SL
575
576 switch (cmd) {
577
9246378c 578 case RXIOC_FORMAT:
63e51da2 579 if ((flag&FWRITE) == 0)
9246378c 580 return (EBADF);
95c06320 581 return (rxformat(dev));
63e51da2 582
9246378c
SL
583 case RXIOC_WDDS:
584 sc->sc_flags |= RXF_USEWDDS;
585 return (0);
63e51da2 586
9246378c
SL
587 case RXIOC_RDDSMK:
588 *(int *)data = sc->sc_flags & RXF_DDMK;
589 return (0);
63e51da2 590 }
9246378c
SL
591 return (ENXIO);
592}
593
594/*
595 * Initiate a format command.
596 */
95c06320
HS
597rxformat(dev)
598 dev_t dev;
9246378c 599{
95c06320 600 int ctlr = rxdinfo[RXUNIT(dev)]->ui_mi->um_ctlr;
9246378c 601 struct buf *bp;
95c06320 602 struct rx_softc *sc = &rx_softc[RXUNIT(dev)];
9246378c 603 int s, error = 0;
63e51da2 604
63e51da2
SL
605 bp = &rrxbuf[ctlr];
606 s = spl5();
607 while (bp->b_flags & B_BUSY)
608 sleep(bp, PRIBIO);
609 bp->b_flags = B_BUSY | B_CTRL;
610 splx(s);
9246378c 611 sc->sc_flags = RXS_FORMAT;
63e51da2
SL
612 bp->b_dev = dev;
613 bp->b_error = 0;
9246378c 614 bp->b_resid = 0;
63e51da2
SL
615 rxstrategy (bp);
616 iowait(bp);
9246378c
SL
617 if (bp->b_flags & B_ERROR)
618 error = bp->b_error;
63e51da2 619 bp->b_flags &= ~B_BUSY;
9246378c
SL
620 wakeup((caddr_t)bp);
621 return (error);
63e51da2
SL
622}
623#endif