]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/pc98/cbus/fdc.c
Fix style nits. No md5 changes in .o's. ;-)
[FreeBSD/FreeBSD.git] / sys / pc98 / cbus / fdc.c
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Don Ahn.
7  *
8  * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)
9  * aided by the Linux floppy driver modifications from David Bateman
10  * (dbateman@eng.uts.edu.au).
11  *
12  * Copyright (c) 1993, 1994 by
13  *  jc@irbs.UUCP (John Capo)
14  *  vak@zebub.msk.su (Serge Vakulenko)
15  *  ache@astral.msk.su (Andrew A. Chernov)
16  *
17  * Copyright (c) 1993, 1994, 1995 by
18  *  joerg_wunsch@uriah.sax.de (Joerg Wunsch)
19  *  dufault@hda.com (Peter Dufault)
20  *
21  * Copyright (c) 2001 Joerg Wunsch,
22  *  joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch)
23  *
24  * Redistribution and use in source and binary forms, with or without
25  * modification, are permitted provided that the following conditions
26  * are met:
27  * 1. Redistributions of source code must retain the above copyright
28  *    notice, this list of conditions and the following disclaimer.
29  * 2. Redistributions in binary form must reproduce the above copyright
30  *    notice, this list of conditions and the following disclaimer in the
31  *    documentation and/or other materials provided with the distribution.
32  * 3. All advertising materials mentioning features or use of this software
33  *    must display the following acknowledgement:
34  *      This product includes software developed by the University of
35  *      California, Berkeley and its contributors.
36  * 4. Neither the name of the University nor the names of its contributors
37  *    may be used to endorse or promote products derived from this software
38  *    without specific prior written permission.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  *      from:   @(#)fd.c        7.4 (Berkeley) 5/25/91
53  * $FreeBSD$
54  */
55
56 #include "opt_fdc.h"
57
58 #include <sys/param.h>
59 #include <sys/bio.h>
60 #include <sys/bus.h>
61 #include <sys/devicestat.h>
62 #include <sys/disk.h>
63 #include <sys/fcntl.h>
64 #include <sys/fdcio.h>
65 #include <sys/filio.h>
66 #include <sys/kernel.h>
67 #include <sys/lock.h>
68 #include <sys/malloc.h>
69 #include <sys/module.h>
70 #include <sys/mutex.h>
71 #include <sys/proc.h>
72 #include <sys/rman.h>
73 #include <sys/systm.h>
74
75 #include <machine/bus.h>
76 #include <machine/stdarg.h>
77
78 #ifdef PC98
79 #include <isa/isavar.h>
80 #include <pc98/cbus/fdcreg.h>
81 #include <pc98/cbus/fdcvar.h>
82 #include <pc98/pc98/pc98_machdep.h>
83 #else
84 #include <isa/isavar.h>
85 #include <isa/isareg.h>
86 #include <dev/fdc/fdcreg.h>
87 #include <dev/fdc/fdcvar.h>
88 #include <isa/rtc.h>
89 #endif
90
91 #define FDBIO_FORMAT    BIO_CMD2
92
93 /* configuration flags for fdc */
94 #define FDC_NO_FIFO     (1 << 2)        /* do not enable FIFO  */
95
96 /*
97  * Stop retrying after this many DMA overruns.  Since each retry takes
98  * one revolution, with 300 rpm., 25 retries take approximately 5
99  * seconds which the read attempt will block in case the DMA overrun
100  * is persistent.
101  */
102 #define FDC_DMAOV_MAX   25
103
104 /*
105  * Timeout value for the PIO loops to wait until the FDC main status
106  * register matches our expectations (request for master, direction
107  * bit).  This is supposed to be a number of microseconds, although
108  * timing might actually not be very accurate.
109  *
110  * Timeouts of 100 msec are believed to be required for some broken
111  * (old) hardware.
112  */
113 #define FDSTS_TIMEOUT   100000
114
115 /*
116  * Number of subdevices that can be used for different density types.
117  */
118 #ifdef PC98
119 #define NUMDENS         12
120 #else
121 #define NUMDENS         16
122 #endif
123
124 #define FDBIO_RDSECTID  BIO_CMD1
125
126 /*
127  * List of native drive densities.  Order must match enum fd_drivetype
128  * in <sys/fdcio.h>.  Upon attaching the drive, each of the
129  * programmable subdevices is initialized with the native density
130  * definition.
131  */
132 #ifdef PC98
133 static struct fd_type fd_native_types[] =
134 {
135 { 0 },                                          /* FDT_NONE */
136 { 0 },                                          /* FDT_360K */
137 { 15,2,0xFF,0x1B,80,2400,0,2,0x54,1,0,FL_MFM }, /* FDT_12M  */
138 { 0 },                                          /* FDT_720K */
139 { 18,2,0xFF,0x1B,80,2880,2,2,0x54,1,0,FL_MFM }, /* FDT_144M */
140 { 0 },                                          /* FDT_288M */
141 };
142
143 static struct fd_type fd_searchlist_12m[] = {
144 { 15,2,0xFF,0x1B,80,2400,0,2,0x54,1,0,FL_MFM }, /* 1.2M */
145 #if 0
146 { 10,2,0xFF,0x10,82,1640,1,2,0x30,1,0,FL_MFM }, /* 820K */
147 { 10,2,0xFF,0x10,80,1600,1,2,0x30,1,0,FL_MFM }, /* 800K */
148 #endif
149 {  9,2,0xFF,0x20,80,1440,1,2,0x50,1,0,FL_MFM }, /* 720K */
150 {  9,2,0xFF,0x20,40, 720,1,2,0x50,1,0,FL_MFM|FL_2STEP },/* 360K */
151 {  8,2,0xFF,0x2A,80,1280,1,2,0x50,1,0,FL_MFM }, /* 640K */
152 {  8,3,0xFF,0x35,77,1232,0,2,0x74,1,0,FL_MFM }, /* 1.23M 1024/sec */
153 #if 0
154 {  8,3,0xFF,0x35,80,1280,0,2,0x74,1,0,FL_MFM }, /* 1.28M 1024/sec */
155 #endif
156 };
157 static struct fd_type fd_searchlist_144m[] = {
158 #if 0
159 { 21,2,0xFF,0x04,82,3444,2,2,0x0C,2,0,FL_MFM }, /* 1.72M in 3mode */
160 { 18,2,0xFF,0x1B,82,2952,2,2,0x54,1,0,FL_MFM }, /* 1.48M in 3mode */
161 #endif
162 { 18,2,0xFF,0x1B,80,2880,2,2,0x54,1,0,FL_MFM }, /* 1.44M in 3mode */
163 { 15,2,0xFF,0x1B,80,2400,0,2,0x54,1,0,FL_MFM }, /* 1.2M */
164 #if 0
165 { 10,2,0xFF,0x10,82,1640,1,2,0x30,1,0,FL_MFM }, /* 820K */
166 { 10,2,0xFF,0x10,80,1600,1,2,0x30,1,0,FL_MFM }, /* 800K */
167 #endif
168 {  9,2,0xFF,0x20,80,1440,1,2,0x50,1,0,FL_MFM }, /* 720K */
169 {  9,2,0xFF,0x20,40, 720,1,2,0x50,1,0,FL_MFM|FL_2STEP },/* 360K */
170 {  8,2,0xFF,0x2A,80,1280,1,2,0x50,1,0,FL_MFM }, /* 640K */
171 {  8,3,0xFF,0x35,77,1232,0,2,0x74,1,0,FL_MFM }, /* 1.23M 1024/sec */
172 #if 0
173 {  8,3,0xFF,0x35,80,1280,0,2,0x74,1,0,FL_MFM }, /* 1.28M 1024/sec */
174 {  9,3,0xFF,0x35,82,1476,0,2,0x47,1,0,FL_MFM }, /* 1.48M 1024/sec 9sec */
175 { 10,3,0xFF,0x1B,82,1640,2,2,0x54,1,0,FL_MFM }, /* 1.64M in 3mode - Reserve */
176 #endif
177 };
178 #else /* PC98 */
179 static struct fd_type fd_native_types[] =
180 {
181 { 0 },                          /* FDT_NONE */
182 {  9,2,0xFF,0x2A,40, 720,FDC_250KBPS,2,0x50,1,0,FL_MFM }, /* FDT_360K */
183 { 15,2,0xFF,0x1B,80,2400,FDC_500KBPS,2,0x54,1,0,FL_MFM }, /* FDT_12M  */
184 {  9,2,0xFF,0x20,80,1440,FDC_250KBPS,2,0x50,1,0,FL_MFM }, /* FDT_720K */
185 { 18,2,0xFF,0x1B,80,2880,FDC_500KBPS,2,0x6C,1,0,FL_MFM }, /* FDT_144M */
186 #if 0                           /* we currently don't handle 2.88 MB */
187 { 36,2,0xFF,0x1B,80,5760,FDC_1MBPS,  2,0x4C,1,1,FL_MFM|FL_PERPND } /*FDT_288M*/
188 #else
189 { 18,2,0xFF,0x1B,80,2880,FDC_500KBPS,2,0x6C,1,0,FL_MFM }, /* FDT_144M */
190 #endif
191 };
192
193 /*
194  * 360 KB 5.25" and 720 KB 3.5" drives don't have automatic density
195  * selection, they just start out with their native density (or lose).
196  * So 1.2 MB 5.25", 1.44 MB 3.5", and 2.88 MB 3.5" drives have their
197  * respective lists of densities to search for.
198  */
199 static struct fd_type fd_searchlist_12m[] = {
200 { 15,2,0xFF,0x1B,80,2400,FDC_500KBPS,2,0x54,1,0,FL_MFM }, /* 1.2M */
201 {  9,2,0xFF,0x23,40, 720,FDC_300KBPS,2,0x50,1,0,FL_MFM|FL_2STEP }, /* 360K */
202 {  9,2,0xFF,0x20,80,1440,FDC_300KBPS,2,0x50,1,0,FL_MFM }, /* 720K */
203 };
204
205 static struct fd_type fd_searchlist_144m[] = {
206 { 18,2,0xFF,0x1B,80,2880,FDC_500KBPS,2,0x6C,1,0,FL_MFM }, /* 1.44M */
207 {  9,2,0xFF,0x20,80,1440,FDC_250KBPS,2,0x50,1,0,FL_MFM }, /* 720K */
208 };
209
210 /* We search for 1.44M first since this is the most common case. */
211 static struct fd_type fd_searchlist_288m[] = {
212 { 18,2,0xFF,0x1B,80,2880,FDC_500KBPS,2,0x6C,1,0,FL_MFM }, /* 1.44M */
213 #if 0
214 { 36,2,0xFF,0x1B,80,5760,FDC_1MBPS,  2,0x4C,1,1,FL_MFM|FL_PERPND } /* 2.88M */
215 #endif
216 {  9,2,0xFF,0x20,80,1440,FDC_250KBPS,2,0x50,1,0,FL_MFM }, /* 720K */
217 };
218 #endif /* PC98 */
219
220 #define MAX_SEC_SIZE    (128 << 3)
221 #define MAX_CYLINDER    85      /* some people really stress their drives
222                                  * up to cyl 82 */
223 #define MAX_HEAD        1
224
225 devclass_t fdc_devclass;
226
227 /*
228  * Per drive structure (softc).
229  */
230 struct fd_data {
231         struct  fdc_data *fdc;  /* pointer to controller structure */
232         int     fdsu;           /* this units number on this controller */
233         enum    fd_drivetype type; /* drive type */
234         struct  fd_type *ft;    /* pointer to current type descriptor */
235         struct  fd_type fts[NUMDENS]; /* type descriptors */
236         int     flags;
237 #define FD_OPEN         0x01    /* it's open            */
238 #define FD_NONBLOCK     0x02    /* O_NONBLOCK set       */
239 #define FD_ACTIVE       0x04    /* it's active          */
240 #define FD_MOTOR        0x08    /* motor should be on   */
241 #define FD_MOTOR_WAIT   0x10    /* motor coming up      */
242 #define FD_UA           0x20    /* force unit attention */
243         int     skip;
244         int     hddrv;
245 #define FD_NO_TRACK -2
246         int     track;          /* where we think the head is */
247         int     options;        /* user configurable options, see fdcio.h */
248         struct  callout_handle toffhandle;
249         struct  callout_handle tohandle;
250         struct  devstat *device_stats;
251         struct cdev *masterdev;
252         device_t dev;
253         fdu_t   fdu;
254 #ifdef PC98
255         int     pc98_trans;
256 #endif
257 };
258
259 struct fdc_ivars {
260         int     fdunit;
261         int     fdtype;
262 };
263
264 static devclass_t fd_devclass;
265
266 /* configuration flags for fd */
267 #define FD_TYPEMASK     0x0f    /* drive type, matches enum
268                                  * fd_drivetype; on i386 machines, if
269                                  * given as 0, use RTC type for fd0
270                                  * and fd1 */
271 #define FD_DTYPE(flags) ((flags) & FD_TYPEMASK)
272 #define FD_NO_CHLINE    0x10    /* drive does not support changeline
273                                  * aka. unit attention */
274 #define FD_NO_PROBE     0x20    /* don't probe drive (seek test), just
275                                  * assume it is there */
276
277 /*
278  * Throughout this file the following conventions will be used:
279  *
280  * fd is a pointer to the fd_data struct for the drive in question
281  * fdc is a pointer to the fdc_data struct for the controller
282  * fdu is the floppy drive unit number
283  * fdcu is the floppy controller unit number
284  * fdsu is the floppy drive unit number on that controller. (sub-unit)
285  */
286
287 /*
288  * Function declarations, same (chaotic) order as they appear in the
289  * file.  Re-ordering is too late now, it would only obfuscate the
290  * diffs against old and offspring versions (like the PC98 one).
291  *
292  * Anyone adding functions here, please keep this sequence the same
293  * as below -- makes locating a particular function in the body much
294  * easier.
295  */
296 static u_int8_t fdsts_rd(fdc_p);
297 static void fddata_wr(fdc_p, u_int8_t);
298 static u_int8_t fddata_rd(fdc_p);
299 static int fdc_err(struct fdc_data *, const char *);
300 static int enable_fifo(fdc_p fdc);
301 static int fd_sense_drive_status(fdc_p, int *);
302 static int fd_sense_int(fdc_p, int *, int *);
303 static int fd_read_status(fdc_p);
304 static int fd_probe(device_t);
305 static int fd_attach(device_t);
306 static int fd_detach(device_t);
307 static void set_motor(struct fdc_data *, int, int);
308 #  define TURNON 1
309 #  define TURNOFF 0
310 static timeout_t fd_turnoff;
311 static timeout_t fd_motor_on;
312 static void fd_turnon(struct fd_data *);
313 static void fdc_reset(fdc_p);
314 static int fd_in(struct fdc_data *, int *);
315 static int out_fdc(struct fdc_data *, int);
316 static  d_open_t        fdopen;
317 static  d_close_t       fdclose;
318 static  d_strategy_t    fdstrategy;
319 static void fdstart(struct fdc_data *);
320 static timeout_t fd_iotimeout;
321 static timeout_t fd_pseudointr;
322 static driver_intr_t fdc_intr;
323 static int fdcpio(fdc_p, long, caddr_t, u_int);
324 static int fdautoselect(struct cdev *);
325 static int fdstate(struct fdc_data *);
326 static int retrier(struct fdc_data *);
327 static void fdbiodone(struct bio *);
328 static int fdmisccmd(struct cdev *, u_int, void *);
329 static  d_ioctl_t       fdioctl;
330
331 static int fifo_threshold = 8;  /* XXX: should be accessible via sysctl */
332
333 #ifdef  FDC_DEBUG
334 /* CAUTION: fd_debug causes huge amounts of logging output */
335 static int volatile fd_debug = 0;
336 #define TRACE0(arg) do { if (fd_debug) printf(arg); } while (0)
337 #define TRACE1(arg1, arg2) do { if (fd_debug) printf(arg1, arg2); } while (0)
338 #else /* FDC_DEBUG */
339 #define TRACE0(arg) do { } while (0)
340 #define TRACE1(arg1, arg2) do { } while (0)
341 #endif /* FDC_DEBUG */
342
343 /*
344  * Bus space handling (access to low-level IO).
345  */
346 #ifndef PC98
347 void
348 fdout_wr(fdc_p fdc, u_int8_t v)
349 {
350         bus_space_write_1(fdc->portt, fdc->porth, FDOUT+fdc->port_off, v);
351 }
352 #endif
353
354 static u_int8_t
355 fdsts_rd(fdc_p fdc)
356 {
357         return bus_space_read_1(fdc->portt, fdc->porth, FDSTS+fdc->port_off);
358 }
359
360 static void
361 fddata_wr(fdc_p fdc, u_int8_t v)
362 {
363         bus_space_write_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off, v);
364 }
365
366 static u_int8_t
367 fddata_rd(fdc_p fdc)
368 {
369         return bus_space_read_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off);
370 }
371
372 #ifdef PC98
373 static void
374 fdctl_wr(fdc_p fdc, u_int8_t v)
375 {
376         bus_space_write_1(fdc->portt, fdc->porth, FDCTL, v);
377 }
378 #endif
379
380 #ifndef PC98
381 static u_int8_t
382 fdin_rd(fdc_p fdc)
383 {
384         return bus_space_read_1(fdc->portt, fdc->porth, FDIN);
385 }
386 #endif /* PC98 */
387
388 static struct cdevsw fd_cdevsw = {
389         .d_version =    D_VERSION,
390         .d_open =       fdopen,
391         .d_close =      fdclose,
392         .d_read =       physread,
393         .d_write =      physwrite,
394         .d_ioctl =      fdioctl,
395         .d_strategy =   fdstrategy,
396         .d_name =       "fd",
397         .d_flags =      D_DISK | D_NEEDGIANT,
398 };
399
400 /*
401  * Auxiliary functions.  Well, some only.  Others are scattered
402  * throughout the entire file.
403  */
404 static int
405 fdc_err(struct fdc_data *fdc, const char *s)
406 {
407         fdc->fdc_errs++;
408         if (s) {
409                 if (fdc->fdc_errs < FDC_ERRMAX)
410                         device_printf(fdc->fdc_dev, "%s", s);
411                 else if (fdc->fdc_errs == FDC_ERRMAX)
412                         device_printf(fdc->fdc_dev, "too many errors, not "
413                                                     "logging any more\n");
414         }
415
416         return FD_FAILED;
417 }
418
419 /*
420  * fd_cmd: Send a command to the chip.  Takes a varargs with this structure:
421  * Unit number,
422  * # of output bytes, output bytes as ints ...,
423  * # of input bytes, input bytes as ints ...
424  */
425 int
426 fd_cmd(struct fdc_data *fdc, int n_out, ...)
427 {
428         u_char cmd;
429         int n_in;
430         int n;
431         va_list ap;
432
433         va_start(ap, n_out);
434         cmd = (u_char)(va_arg(ap, int));
435         va_end(ap);
436         va_start(ap, n_out);
437         for (n = 0; n < n_out; n++)
438         {
439                 if (out_fdc(fdc, va_arg(ap, int)) < 0)
440                 {
441                         char msg[50];
442                         snprintf(msg, sizeof(msg),
443                                 "cmd %x failed at out byte %d of %d\n",
444                                 cmd, n + 1, n_out);
445                         return fdc_err(fdc, msg);
446                 }
447         }
448         n_in = va_arg(ap, int);
449         for (n = 0; n < n_in; n++)
450         {
451                 int *ptr = va_arg(ap, int *);
452                 if (fd_in(fdc, ptr) < 0)
453                 {
454                         char msg[50];
455                         snprintf(msg, sizeof(msg),
456                                 "cmd %02x failed at in byte %d of %d\n",
457                                 cmd, n + 1, n_in);
458                         return fdc_err(fdc, msg);
459                 }
460         }
461
462         return 0;
463 }
464
465 static int 
466 enable_fifo(fdc_p fdc)
467 {
468         int i, j;
469
470         if ((fdc->flags & FDC_HAS_FIFO) == 0) {
471                 
472                 /*
473                  * Cannot use fd_cmd the normal way here, since
474                  * this might be an invalid command. Thus we send the
475                  * first byte, and check for an early turn of data directon.
476                  */
477                 
478                 if (out_fdc(fdc, I8207X_CONFIG) < 0)
479                         return fdc_err(fdc, "Enable FIFO failed\n");
480                 
481                 /* If command is invalid, return */
482                 j = FDSTS_TIMEOUT;
483                 while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM))
484                        != NE7_RQM && j-- > 0) {
485                         if (i == (NE7_DIO | NE7_RQM)) {
486                                 fdc_reset(fdc);
487                                 return FD_FAILED;
488                         }
489                         DELAY(1);
490                 }
491                 if (j<0 || 
492                     fd_cmd(fdc, 3,
493                            0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
494                         fdc_reset(fdc);
495                         return fdc_err(fdc, "Enable FIFO failed\n");
496                 }
497                 fdc->flags |= FDC_HAS_FIFO;
498                 return 0;
499         }
500         if (fd_cmd(fdc, 4,
501                    I8207X_CONFIG, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0)
502                 return fdc_err(fdc, "Re-enable FIFO failed\n");
503         return 0;
504 }
505
506 static int
507 fd_sense_drive_status(fdc_p fdc, int *st3p)
508 {
509         int st3;
510
511         if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
512         {
513                 return fdc_err(fdc, "Sense Drive Status failed\n");
514         }
515         if (st3p)
516                 *st3p = st3;
517
518         return 0;
519 }
520
521 static int
522 fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
523 {
524         int cyl, st0, ret;
525
526         ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0);
527         if (ret) {
528                 (void)fdc_err(fdc,
529                               "sense intr err reading stat reg 0\n");
530                 return ret;
531         }
532
533         if (st0p)
534                 *st0p = st0;
535
536         if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) {
537                 /*
538                  * There doesn't seem to have been an interrupt.
539                  */
540                 return FD_NOT_VALID;
541         }
542
543         if (fd_in(fdc, &cyl) < 0) {
544                 return fdc_err(fdc, "can't get cyl num\n");
545         }
546
547         if (cylp)
548                 *cylp = cyl;
549
550         return 0;
551 }
552
553
554 static int
555 fd_read_status(fdc_p fdc)
556 {
557         int i, ret;
558
559         for (i = ret = 0; i < 7; i++) {
560                 /*
561                  * XXX types are poorly chosen.  Only bytes can be read
562                  * from the hardware, but fdc->status[] wants u_ints and
563                  * fd_in() gives ints.
564                  */
565                 int status;
566
567                 ret = fd_in(fdc, &status);
568                 fdc->status[i] = status;
569                 if (ret != 0)
570                         break;
571         }
572
573         if (ret == 0)
574                 fdc->flags |= FDC_STAT_VALID;
575         else
576                 fdc->flags &= ~FDC_STAT_VALID;
577
578         return ret;
579 }
580
581 #ifdef PC98
582 static int pc98_trans = 0; /* 0 : HD , 1 : DD , 2 : 1.44 */
583 static int pc98_trans_prev = -1;
584
585 static void set_density(fdc_p fdc)
586 {
587         /* always motor on */
588         bus_space_write_1(fdc->sc_fdsiot, fdc->sc_fdsioh, 0,
589                           (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
590         DELAY(100);
591         fdctl_wr(fdc, FDC_RST | FDC_DMAE);
592         /* in the case of note W, always inhibit 100ms timer */
593 }
594
595 static int pc98_fd_check_ready(fdu_t fdu)
596 {
597         fd_p fd = devclass_get_softc(fd_devclass, fdu);
598         struct fdc_data *fdc = fd->fdc;
599         int retry = 0, status;
600
601         while (retry++ < 30000) {
602                 set_motor(fdc, fd->fdsu, TURNON);
603                 out_fdc(fdc, NE7CMD_SENSED); /* Sense Drive Status */
604                 DELAY(100);
605                 out_fdc(fdc, fdu); /* Drive number */
606                 DELAY(100);
607                 if ((fd_in(fdc, &status) == 0) && (status & NE7_ST3_RD)) {
608                         fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
609                         DELAY(10);
610                         return 0;
611                 }
612         }
613         return -1;
614 }
615
616 static void pc98_fd_check_type(struct fd_data *fd)
617 {
618         struct fdc_data *fdc;
619
620         if (fd->type != FDT_NONE || fd->fdu < 0 || fd->fdu > 3)
621                 return;
622
623         fdc = fd->fdc;
624
625         /* Look up what the BIOS thinks we have. */
626         if (!((PC98_SYSTEM_PARAMETER(0x55c) >> fd->fdu) & 0x01)) {
627                 fd->type = FDT_NONE;
628                 return;
629         }
630         if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fd->fdu) & 0x01) {
631                 /* Check 3mode I/F */
632                 fd->pc98_trans = 0;
633                 bus_space_write_1(fdc->sc_fdemsiot, fdc->sc_fdemsioh, 0,
634                                   (fd->fdu << 5) | 0x10);
635                 if (!(bus_space_read_1(fdc->sc_fdemsiot, fdc->sc_fdemsioh, 0) &
636                     0x01)) {
637                         fd->type = FDT_144M;
638                         return;
639                 }
640                 device_printf(fd->dev,
641                               "Warning: can't control 3mode I/F, fallback to 2mode.\n");
642         }
643
644         fd->type = FDT_12M;
645 }
646 #endif /* PC98 */
647
648 void
649 fdc_release_resources(struct fdc_data *fdc)
650 {
651         device_t dev;
652
653         dev = fdc->fdc_dev;
654         if (fdc->fdc_intr) {
655                 bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr);
656                 fdc->fdc_intr = NULL;
657         }
658         if (fdc->res_irq != 0) {
659                 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
660                                         fdc->res_irq);
661                 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
662                                      fdc->res_irq);
663                 fdc->res_irq = NULL;
664         }
665 #ifndef PC98
666         if (fdc->res_ctl != 0) {
667                 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
668                                         fdc->res_ctl);
669                 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
670                                      fdc->res_ctl);
671                 fdc->res_ctl = NULL;
672         }
673 #endif
674 #ifdef PC98
675         if (fdc->res_fdsio != 0) {
676                 bus_deactivate_resource(dev, SYS_RES_IOPORT, 3,
677                                         fdc->res_fdsio);
678                 bus_release_resource(dev, SYS_RES_IOPORT, 3, fdc->res_fdsio);
679                 fdc->res_fdsio = NULL;
680         }
681         if (fdc->res_fdemsio != 0) {
682                 bus_deactivate_resource(dev, SYS_RES_IOPORT, 4,
683                                         fdc->res_fdemsio);
684                 bus_release_resource(dev, SYS_RES_IOPORT, 4, fdc->res_fdemsio);
685                 fdc->res_fdemsio = NULL;
686         }
687 #endif
688         if (fdc->res_ioport != 0) {
689                 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
690                                         fdc->res_ioport);
691                 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
692                                      fdc->res_ioport);
693                 fdc->res_ioport = NULL;
694         }
695         if (fdc->res_drq != 0) {
696                 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
697                                         fdc->res_drq);
698                 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
699                                      fdc->res_drq);
700                 fdc->res_drq = NULL;
701         }
702 }
703
704 /*
705  * Configuration/initialization stuff, per controller.
706  */
707
708 int
709 fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
710 {
711         struct fdc_ivars *ivars = device_get_ivars(child);
712
713         switch (which) {
714         case FDC_IVAR_FDUNIT:
715                 *result = ivars->fdunit;
716                 break;
717         case FDC_IVAR_FDTYPE:
718                 *result = ivars->fdtype;
719                 break;
720         default:
721                 return (ENOENT);
722         }
723         return (0);
724 }
725
726 int
727 fdc_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
728 {
729         struct fdc_ivars *ivars = device_get_ivars(child);
730
731         switch (which) {
732         case FDC_IVAR_FDUNIT:
733                 ivars->fdunit = value;
734                 break;
735         case FDC_IVAR_FDTYPE:
736                 ivars->fdtype = value;
737                 break;
738         default:
739                 return (ENOENT);
740         }
741         return (0);
742 }
743
744 int
745 fdc_initial_reset(struct fdc_data *fdc)
746 {
747 #ifdef PC98
748         /* see if it can handle a command */
749         if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240), 
750                    NE7_SPEC_2(2, 0), 0))
751                 return (ENXIO);
752 #else
753         /* First, reset the floppy controller. */
754         fdout_wr(fdc, 0);
755         DELAY(100);
756         fdout_wr(fdc, FDO_FRST);
757
758         /* Then, see if it can handle a command. */
759         if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 
760             NE7_SPEC_2(2, 0), 0))
761                 return (ENXIO);
762 #endif
763         return (0);
764 }
765
766 int
767 fdc_detach(device_t dev)
768 {
769         struct  fdc_data *fdc;
770         int     error;
771
772         fdc = device_get_softc(dev);
773
774         /* have our children detached first */
775         if ((error = bus_generic_detach(dev)))
776                 return (error);
777
778 #ifdef PC98
779         /* reset controller, turn motor off */
780         fdc_reset(fdc);
781 #else
782         /* reset controller, turn motor off */
783         fdout_wr(fdc, 0);
784 #endif
785
786         fdc_release_resources(fdc);
787         return (0);
788 }
789
790 /*
791  * Add a child device to the fdc controller.  It will then be probed etc.
792  */
793 device_t
794 fdc_add_child(device_t dev, const char *name, int unit)
795 {
796         struct fdc_ivars *ivar;
797         device_t child;
798
799         ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
800         if (ivar == NULL)
801                 return (NULL);
802         child = device_add_child(dev, name, unit);
803         if (child == NULL) {
804                 free(ivar, M_DEVBUF);
805                 return (NULL);
806         }
807         device_set_ivars(child, ivar);
808         ivar->fdunit = unit;
809         ivar->fdtype = FDT_NONE;
810         if (resource_disabled(name, unit))
811                 device_disable(child);
812         return (child);
813 }
814
815 int
816 fdc_attach(device_t dev)
817 {
818         struct  fdc_data *fdc;
819         int     error;
820
821         fdc = device_get_softc(dev);
822         fdc->fdc_dev = dev;
823         error = bus_setup_intr(dev, fdc->res_irq,
824                                INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
825                                &fdc->fdc_intr);
826         if (error) {
827                 device_printf(dev, "cannot setup interrupt\n");
828                 return error;
829         }
830         fdc->fdcu = device_get_unit(dev);
831         fdc->flags |= FDC_NEEDS_RESET;
832
833         fdc->state = DEVIDLE;
834
835 #ifdef PC98
836         /* reset controller, turn motor off, clear fdout mirror reg */
837         fdc_reset(fdc);
838 #else
839         /* reset controller, turn motor off, clear fdout mirror reg */
840         fdout_wr(fdc, fdc->fdout = 0);
841 #endif
842         bioq_init(&fdc->head);
843
844         return (0);
845 }
846
847 int
848 fdc_hints_probe(device_t dev)
849 {
850         const char *name, *dname;
851         int i, error, dunit;
852
853         /*
854          * Probe and attach any children.  We should probably detect
855          * devices from the BIOS unless overridden.
856          */
857         name = device_get_nameunit(dev);
858         i = 0;
859         while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) {
860                 resource_int_value(dname, dunit, "drive", &dunit);
861                 fdc_add_child(dev, dname, dunit);
862         }
863
864         if ((error = bus_generic_attach(dev)) != 0)
865                 return (error);
866         return (0);
867 }
868
869 int
870 fdc_print_child(device_t me, device_t child)
871 {
872         int retval = 0, flags;
873
874         retval += bus_print_child_header(me, child);
875         retval += printf(" on %s drive %d", device_get_nameunit(me),
876                fdc_get_fdunit(child));
877         if ((flags = device_get_flags(me)) != 0)
878                 retval += printf(" flags %#x", flags);
879         retval += printf("\n");
880         
881         return (retval);
882 }
883
884 /*
885  * Configuration/initialization, per drive.
886  */
887 static int
888 fd_probe(device_t dev)
889 {
890         int     i;
891 #ifndef PC98
892         u_int   st0, st3;
893 #endif
894         struct  fd_data *fd;
895         struct  fdc_data *fdc;
896         fdsu_t  fdsu;
897         int     flags, type;
898
899         fdsu = fdc_get_fdunit(dev);
900         fd = device_get_softc(dev);
901         fdc = device_get_softc(device_get_parent(dev));
902         flags = device_get_flags(dev);
903
904         fd->dev = dev;
905         fd->fdc = fdc;
906         fd->fdsu = fdsu;
907         fd->fdu = device_get_unit(dev);
908
909         /* Auto-probe if fdinfo is present, but always allow override. */
910         type = FD_DTYPE(flags);
911         if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) {
912                 fd->type = type;
913                 goto done;
914         } else {
915                 /* make sure fdautoselect() will be called */
916                 fd->flags = FD_UA;
917                 fd->type = type;
918         }
919
920 #ifdef PC98
921         pc98_fd_check_type(fd);
922 #else
923 /*
924  * XXX I think using __i386__ is wrong here since we actually want to probe
925  * for the machine type, not the CPU type (so non-PC arch's like the PC98 will
926  * fail the probe).
927  */
928 #ifdef __i386__
929         if (fd->type == FDT_NONE && (fd->fdu == 0 || fd->fdu == 1)) {
930                 /* Look up what the BIOS thinks we have. */
931                 if (fd->fdu == 0) {
932                         if ((fdc->flags & FDC_ISPCMCIA))
933                                 /*
934                                  * Somewhat special.  No need to force the
935                                  * user to set device flags, since the Y-E
936                                  * Data PCMCIA floppy is always a 1.44 MB
937                                  * device.
938                                  */
939                                 fd->type = FDT_144M;
940                         else
941                                 fd->type = (rtcin(RTC_FDISKETTE) & 0xf0) >> 4;
942                 } else {
943                         fd->type = rtcin(RTC_FDISKETTE) & 0x0f;
944                 }
945                 if (fd->type == FDT_288M_1)
946                         fd->type = FDT_288M;
947         }
948 #endif /* __i386__ */
949 #endif /* PC98 */
950
951         /* is there a unit? */
952         if (fd->type == FDT_NONE)
953                 return (ENXIO);
954
955 #ifndef PC98
956         /* select it */
957         set_motor(fdc, fdsu, TURNON);
958         fdc_reset(fdc);         /* XXX reset, then unreset, etc. */
959         DELAY(1000000); /* 1 sec */
960
961         if ((flags & FD_NO_PROBE) == 0) {
962                 /* If we're at track 0 first seek inwards. */
963                 if ((fd_sense_drive_status(fdc, &st3) == 0) &&
964                     (st3 & NE7_ST3_T0)) {
965                         /* Seek some steps... */
966                         if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
967                                 /* ...wait a moment... */
968                                 DELAY(300000);
969                                 /* make ctrlr happy: */
970                                 fd_sense_int(fdc, 0, 0);
971                         }
972                 }
973
974                 for (i = 0; i < 2; i++) {
975                         /*
976                          * we must recalibrate twice, just in case the
977                          * heads have been beyond cylinder 76, since
978                          * most FDCs still barf when attempting to
979                          * recalibrate more than 77 steps
980                          */
981                         /* go back to 0: */
982                         if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
983                                 /* a second being enough for full stroke seek*/
984                                 DELAY(i == 0 ? 1000000 : 300000);
985
986                                 /* anything responding? */
987                                 if (fd_sense_int(fdc, &st0, 0) == 0 &&
988                                     (st0 & NE7_ST0_EC) == 0)
989                                         break; /* already probed succesfully */
990                         }
991                 }
992         }
993
994         set_motor(fdc, fdsu, TURNOFF);
995
996         if ((flags & FD_NO_PROBE) == 0 &&
997             (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
998                 return (ENXIO);
999 #endif /* PC98 */
1000
1001 done:
1002 #ifndef PC98
1003         /* This doesn't work before the first reset. */
1004         if ((fdc->flags & FDC_HAS_FIFO) == 0 &&
1005             fdc->fdct == FDC_ENHANCED &&
1006             (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 &&
1007             enable_fifo(fdc) == 0) {
1008                 device_printf(device_get_parent(dev),
1009                     "FIFO enabled, %d bytes threshold\n", fifo_threshold);
1010         }
1011 #endif /* PC98 */
1012
1013 #ifdef PC98
1014         switch (fd->type) {
1015         case FDT_144M:
1016                 device_set_desc(dev, "1.44M FDD");
1017                 break;
1018         case FDT_12M:
1019                 device_set_desc(dev, "1M/640K FDD");
1020                 break;
1021         default:
1022                 return (ENXIO);
1023         }
1024 #else
1025         switch (fd->type) {
1026         case FDT_12M:
1027                 device_set_desc(dev, "1200-KB 5.25\" drive");
1028                 break;
1029         case FDT_144M:
1030                 device_set_desc(dev, "1440-KB 3.5\" drive");
1031                 break;
1032         case FDT_288M:
1033                 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
1034                 break;
1035         case FDT_360K:
1036                 device_set_desc(dev, "360-KB 5.25\" drive");
1037                 break;
1038         case FDT_720K:
1039                 device_set_desc(dev, "720-KB 3.5\" drive");
1040                 break;
1041         default:
1042                 return (ENXIO);
1043         }
1044 #endif
1045         fd->track = FD_NO_TRACK;
1046         fd->fdc = fdc;
1047         fd->fdsu = fdsu;
1048         fd->options = 0;
1049 #ifdef PC98
1050         fd->pc98_trans = 0;
1051 #endif
1052         callout_handle_init(&fd->toffhandle);
1053         callout_handle_init(&fd->tohandle);
1054
1055         /* initialize densities for subdevices */
1056 #ifdef PC98
1057         for (i = 0; i < NUMDENS; i++)
1058                 memcpy(fd->fts + i, fd_searchlist_144m + i,
1059                        sizeof(struct fd_type));
1060 #else
1061         for (i = 0; i < NUMDENS; i++)
1062                 memcpy(fd->fts + i, fd_native_types + fd->type,
1063                        sizeof(struct fd_type));
1064 #endif
1065         return (0);
1066 }
1067
1068 static int
1069 fd_attach(device_t dev)
1070 {
1071         struct  fd_data *fd;
1072
1073         fd = device_get_softc(dev);
1074         fd->masterdev = make_dev(&fd_cdevsw, fd->fdu,
1075                                  UID_ROOT, GID_OPERATOR, 0640, "fd%d", fd->fdu);
1076         fd->masterdev->si_drv1 = fd;
1077         fd->device_stats = devstat_new_entry(device_get_name(dev), 
1078                           device_get_unit(dev), 0, DEVSTAT_NO_ORDERED_TAGS,
1079                           DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER,
1080                           DEVSTAT_PRIORITY_FD);
1081         return (0);
1082 }
1083
1084 static int
1085 fd_detach(device_t dev)
1086 {
1087         struct  fd_data *fd;
1088
1089         fd = device_get_softc(dev);
1090         untimeout(fd_turnoff, fd, fd->toffhandle);
1091         devstat_remove_entry(fd->device_stats);
1092         destroy_dev(fd->masterdev);
1093
1094         return (0);
1095 }
1096
1097 static device_method_t fd_methods[] = {
1098         /* Device interface */
1099         DEVMETHOD(device_probe,         fd_probe),
1100         DEVMETHOD(device_attach,        fd_attach),
1101         DEVMETHOD(device_detach,        fd_detach),
1102         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
1103         DEVMETHOD(device_suspend,       bus_generic_suspend), /* XXX */
1104         DEVMETHOD(device_resume,        bus_generic_resume), /* XXX */
1105
1106         { 0, 0 }
1107 };
1108
1109 static driver_t fd_driver = {
1110         "fd",
1111         fd_methods,
1112         sizeof(struct fd_data)
1113 };
1114
1115 DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, 0, 0);
1116
1117 /*
1118  * More auxiliary functions.
1119  */
1120 /*
1121  * Motor control stuff.
1122  * Remember to not deselect the drive we're working on.
1123  */
1124 static void
1125 set_motor(struct fdc_data *fdc, int fdsu, int turnon)
1126 {
1127 #ifdef PC98
1128         bus_space_write_1(fdc->sc_fdsiot, fdc->sc_fdsioh, 0,
1129                           (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
1130         DELAY(10);
1131         fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
1132 #else
1133         int fdout;
1134
1135         fdout = fdc->fdout;
1136         if (turnon) {
1137                 fdout &= ~FDO_FDSEL;
1138                 fdout |= (FDO_MOEN0 << fdsu) | FDO_FDMAEN | FDO_FRST | fdsu;
1139         } else
1140                 fdout &= ~(FDO_MOEN0 << fdsu);
1141         fdc->fdout = fdout;
1142         fdout_wr(fdc, fdout);
1143         TRACE1("[0x%x->FDOUT]", fdout);
1144 #endif
1145 }
1146
1147 static void
1148 fd_turnoff(void *xfd)
1149 {
1150         int     s;
1151         fd_p fd = xfd;
1152
1153         TRACE1("[fd%d: turnoff]", fd->fdu);
1154
1155         s = splbio();
1156         /*
1157          * Don't turn off the motor yet if the drive is active.
1158          *
1159          * If we got here, this could only mean we missed an interrupt.
1160          * This can e. g. happen on the Y-E Date PCMCIA floppy controller
1161          * after a controller reset.  Just schedule a pseudo-interrupt
1162          * so the state machine gets re-entered.
1163          */
1164         if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) {
1165                 fdc_intr(fd->fdc);
1166                 splx(s);
1167                 return;
1168         }
1169
1170         fd->flags &= ~FD_MOTOR;
1171         set_motor(fd->fdc, fd->fdsu, TURNOFF);
1172         splx(s);
1173 }
1174
1175 static void
1176 fd_motor_on(void *xfd)
1177 {
1178         int     s;
1179         fd_p fd = xfd;
1180
1181         s = splbio();
1182         fd->flags &= ~FD_MOTOR_WAIT;
1183         if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT))
1184         {
1185                 fdc_intr(fd->fdc);
1186         }
1187         splx(s);
1188 }
1189
1190 static void
1191 fd_turnon(fd_p fd)
1192 {
1193         if(!(fd->flags & FD_MOTOR))
1194         {
1195                 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
1196                 set_motor(fd->fdc, fd->fdsu, TURNON);
1197                 timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */
1198         }
1199 }
1200
1201 static void
1202 fdc_reset(fdc_p fdc)
1203 {
1204         /* Try a reset, keep motor on */
1205 #ifdef PC98
1206         set_density(fdc);
1207         if (pc98_machine_type & M_EPSON_PC98)
1208                 fdctl_wr(fdc, FDC_RST | FDC_RDY | FDC_DD | FDC_MTON);
1209         else
1210                 fdctl_wr(fdc, FDC_RST | FDC_RDY | FDC_DMAE | FDC_MTON);
1211         DELAY(200);
1212         fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
1213         DELAY(10);
1214 #else
1215         fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
1216         TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
1217         DELAY(100);
1218         /* enable FDC, but defer interrupts a moment */
1219         fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
1220         TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN);
1221         DELAY(100);
1222         fdout_wr(fdc, fdc->fdout);
1223         TRACE1("[0x%x->FDOUT]", fdc->fdout);
1224 #endif
1225
1226         /* XXX after a reset, silently believe the FDC will accept commands */
1227 #ifdef PC98
1228         (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
1229                      NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
1230                      0);
1231 #else
1232         (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
1233                      NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
1234                      0);
1235 #endif
1236         if (fdc->flags & FDC_HAS_FIFO)
1237                 (void) enable_fifo(fdc);
1238 }
1239
1240 /*
1241  * FDC IO functions, take care of the main status register, timeout
1242  * in case the desired status bits are never set.
1243  *
1244  * These PIO loops initially start out with short delays between
1245  * each iteration in the expectation that the required condition
1246  * is usually met quickly, so it can be handled immediately.  After
1247  * about 1 ms, stepping is increased to achieve a better timing
1248  * accuracy in the calls to DELAY().
1249  */
1250 static int
1251 fd_in(struct fdc_data *fdc, int *ptr)
1252 {
1253         int i, j, step;
1254
1255         for (j = 0, step = 1;
1256             (i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM) &&
1257             j < FDSTS_TIMEOUT;
1258             j += step) {
1259                 if (i == NE7_RQM)
1260                         return (fdc_err(fdc, "ready for output in input\n"));
1261                 if (j == 1000)
1262                         step = 1000;
1263                 DELAY(step);
1264         }
1265         if (j >= FDSTS_TIMEOUT)
1266                 return (fdc_err(fdc, bootverbose? "input ready timeout\n": 0));
1267 #ifdef  FDC_DEBUG
1268         i = fddata_rd(fdc);
1269         TRACE1("[FDDATA->0x%x]", (unsigned char)i);
1270         *ptr = i;
1271         return (0);
1272 #else   /* !FDC_DEBUG */
1273         i = fddata_rd(fdc);
1274         if (ptr)
1275                 *ptr = i;
1276         return (0);
1277 #endif  /* FDC_DEBUG */
1278 }
1279
1280 static int
1281 out_fdc(struct fdc_data *fdc, int x)
1282 {
1283         int i, j, step;
1284
1285         for (j = 0, step = 1;
1286             (i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) != NE7_RQM &&
1287             j < FDSTS_TIMEOUT;
1288             j += step) {
1289                 if (i == (NE7_DIO|NE7_RQM))
1290                         return (fdc_err(fdc, "ready for input in output\n"));
1291                 if (j == 1000)
1292                         step = 1000;
1293                 DELAY(step);
1294         }
1295         if (j >= FDSTS_TIMEOUT)
1296                 return (fdc_err(fdc, bootverbose? "output ready timeout\n": 0));
1297
1298         /* Send the command and return */
1299         fddata_wr(fdc, x);
1300         TRACE1("[0x%x->FDDATA]", x);
1301         return (0);
1302 }
1303
1304 /*
1305  * Block device driver interface functions (interspersed with even more
1306  * auxiliary functions).
1307  */
1308 static int
1309 fdopen(struct cdev *dev, int flags, int mode, struct thread *td)
1310 {
1311         fd_p    fd;
1312         fdc_p   fdc;
1313 #ifdef PC98
1314         fdu_t   fdu;
1315 #endif
1316         int rv, unitattn, dflags;
1317
1318         fd = dev->si_drv1;
1319         if (fd == NULL)
1320                 return (ENXIO);
1321         fdc = fd->fdc;
1322         if ((fdc == NULL) || (fd->type == FDT_NONE))
1323                 return (ENXIO);
1324 #ifdef PC98
1325         fdu = fd->fdu;
1326 #endif
1327         dflags = device_get_flags(fd->dev);
1328         /*
1329          * This is a bit bogus.  It's still possible that e. g. a
1330          * descriptor gets inherited to a child, but then it's at
1331          * least for the same subdevice.  By checking FD_OPEN here, we
1332          * can ensure that a device isn't attempted to be opened with
1333          * different densities at the same time where the second open
1334          * could clobber the settings from the first one.
1335          */
1336         if (fd->flags & FD_OPEN)
1337                 return (EBUSY);
1338
1339 #ifdef PC98
1340         if (pc98_fd_check_ready(fdu) == -1)
1341                 return(EIO);
1342 #endif
1343
1344         if (flags & FNONBLOCK) {
1345                 /*
1346                  * Unfortunately, physio(9) discards its ioflag
1347                  * argument, thus preventing us from seeing the
1348                  * O_NONBLOCK bit.  So we need to keep track
1349                  * ourselves.
1350                  */
1351                 fd->flags |= FD_NONBLOCK;
1352                 fd->ft = 0;
1353         } else {
1354                 /*
1355                  * Figure out a unit attention condition.
1356                  *
1357                  * If UA has been forced, proceed.
1358                  *
1359                  * If the drive has no changeline support,
1360                  * or if the drive parameters have been lost
1361                  * due to previous non-blocking access,
1362                  * assume a forced UA condition.
1363                  *
1364                  * If motor is off, turn it on for a moment
1365                  * and select our drive, in order to read the
1366                  * UA hardware signal.
1367                  *
1368                  * If motor is on, and our drive is currently
1369                  * selected, just read the hardware bit.
1370                  *
1371                  * If motor is on, but active for another
1372                  * drive on that controller, we are lost.  We
1373                  * cannot risk to deselect the other drive, so
1374                  * we just assume a forced UA condition to be
1375                  * on the safe side.
1376                  */
1377                 unitattn = 0;
1378                 if ((dflags & FD_NO_CHLINE) != 0 ||
1379                     (fd->flags & FD_UA) != 0 ||
1380                     fd->ft == 0) {
1381                         unitattn = 1;
1382                         fd->flags &= ~FD_UA;
1383 #ifndef PC98
1384                 } else if (fdc->fdout & (FDO_MOEN0 | FDO_MOEN1 |
1385                                          FDO_MOEN2 | FDO_MOEN3)) {
1386                         if ((fdc->fdout & FDO_FDSEL) == fd->fdsu)
1387                                 unitattn = fdin_rd(fdc) & FDI_DCHG;
1388                         else
1389                                 unitattn = 1;
1390                 } else {
1391                         set_motor(fdc, fd->fdsu, TURNON);
1392                         unitattn = fdin_rd(fdc) & FDI_DCHG;
1393                         set_motor(fdc, fd->fdsu, TURNOFF);
1394 #endif /* PC98 */
1395                 }
1396                 if (unitattn && (rv = fdautoselect(dev)) != 0)
1397                         return (rv);
1398         }
1399         fd->flags |= FD_OPEN;
1400
1401         if ((fdc->flags & FDC_NODMA) == 0) {
1402                 if (fdc->dmacnt++ == 0) {
1403                         isa_dma_acquire(fdc->dmachan);
1404                         isa_dmainit(fdc->dmachan, MAX_SEC_SIZE);
1405                 }
1406         }
1407
1408         /*
1409          * Clearing the DMA overrun counter at open time is a bit messy.
1410          * Since we're only managing one counter per controller, opening
1411          * the second drive could mess it up.  Anyway, if the DMA overrun
1412          * condition is really persistent, it will eventually time out
1413          * still.  OTOH, clearing it here will ensure we'll at least start
1414          * trying again after a previous (maybe even long ago) failure.
1415          * Also, this is merely a stop-gap measure only that should not
1416          * happen during normal operation, so we can tolerate it to be a
1417          * bit sloppy about this.
1418          */
1419         fdc->dma_overruns = 0;
1420
1421         return 0;
1422 }
1423
1424 static int
1425 fdclose(struct cdev *dev, int flags, int mode, struct thread *td)
1426 {
1427         struct fd_data *fd;
1428         fdc_p   fdc;
1429
1430         fd = dev->si_drv1;
1431         fdc = fd->fdc;
1432         fd->flags &= ~(FD_OPEN | FD_NONBLOCK);
1433         fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR);
1434
1435         if ((fdc->flags & FDC_NODMA) == 0)
1436                 if (--fdc->dmacnt == 0)
1437                         isa_dma_release(fdc->dmachan);
1438
1439         return (0);
1440 }
1441
1442 static void
1443 fdstrategy(struct bio *bp)
1444 {
1445         long blknum, nblocks;
1446         int     s;
1447         fdu_t   fdu;
1448         fdc_p   fdc;
1449         fd_p    fd;
1450         size_t  fdblk;
1451
1452         fd = bp->bio_dev->si_drv1;
1453         fdu = fd->fdu;
1454         fdc = fd->fdc;
1455         bp->bio_resid = bp->bio_bcount;
1456         if (fd->type == FDT_NONE || fd->ft == 0) {
1457                 if (fd->type != FDT_NONE && (fd->flags & FD_NONBLOCK))
1458                         bp->bio_error = EAGAIN;
1459                 else
1460                         bp->bio_error = ENXIO;
1461                 bp->bio_flags |= BIO_ERROR;
1462                 goto bad;
1463         }
1464         fdblk = 128 << (fd->ft->secsize);
1465         if (bp->bio_cmd != FDBIO_FORMAT && bp->bio_cmd != FDBIO_RDSECTID) {
1466                 if (fd->flags & FD_NONBLOCK) {
1467                         bp->bio_error = EAGAIN;
1468                         bp->bio_flags |= BIO_ERROR;
1469                         goto bad;
1470                 }
1471                 if (bp->bio_offset < 0) {
1472                         printf(
1473                 "fd%d: fdstrat: bad request offset = %ju, bcount = %ld\n",
1474                                fdu, (intmax_t)bp->bio_offset, bp->bio_bcount);
1475                         bp->bio_error = EINVAL;
1476                         bp->bio_flags |= BIO_ERROR;
1477                         goto bad;
1478                 }
1479                 if ((bp->bio_bcount % fdblk) != 0) {
1480                         bp->bio_error = EINVAL;
1481                         bp->bio_flags |= BIO_ERROR;
1482                         goto bad;
1483                 }
1484         }
1485
1486         /*
1487          * Set up block calculations.
1488          */
1489 #ifndef PC98
1490         if (bp->bio_offset >= ((off_t)128 << fd->ft->secsize) * fd->ft->size) {
1491                 bp->bio_error = EINVAL;
1492                 bp->bio_flags |= BIO_ERROR;
1493                 goto bad;
1494         }
1495 #endif
1496         blknum = bp->bio_offset / fdblk;
1497         nblocks = fd->ft->size;
1498         if (blknum + bp->bio_bcount / fdblk > nblocks) {
1499                 if (blknum >= nblocks) {
1500                         if (bp->bio_cmd != BIO_READ) {
1501                                 bp->bio_error = ENOSPC;
1502                                 bp->bio_flags |= BIO_ERROR;
1503                         }
1504                         goto bad;       /* not always bad, but EOF */
1505                 }
1506                 bp->bio_bcount = (nblocks - blknum) * fdblk;
1507         }
1508         bp->bio_pblkno = blknum;
1509         s = splbio();
1510         bioq_disksort(&fdc->head, bp);
1511         untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
1512         devstat_start_transaction_bio(fd->device_stats, bp);
1513         device_busy(fd->dev);
1514         fdstart(fdc);
1515         splx(s);
1516         return;
1517
1518 bad:
1519         biodone(bp);
1520 }
1521
1522 /*
1523  * fdstart
1524  *
1525  * We have just queued something.  If the controller is not busy
1526  * then simulate the case where it has just finished a command
1527  * So that it (the interrupt routine) looks on the queue for more
1528  * work to do and picks up what we just added.
1529  *
1530  * If the controller is already busy, we need do nothing, as it
1531  * will pick up our work when the present work completes.
1532  */
1533 static void
1534 fdstart(struct fdc_data *fdc)
1535 {
1536         int s;
1537
1538         s = splbio();
1539         if(fdc->state == DEVIDLE)
1540         {
1541                 fdc_intr(fdc);
1542         }
1543         splx(s);
1544 }
1545
1546 static void
1547 fd_iotimeout(void *xfdc)
1548 {
1549         fdc_p fdc;
1550         int s;
1551
1552         fdc = xfdc;
1553         TRACE1("fd%d[fd_iotimeout()]", fdc->fdu);
1554
1555         /*
1556          * Due to IBM's brain-dead design, the FDC has a faked ready
1557          * signal, hardwired to ready == true. Thus, any command
1558          * issued if there's no diskette in the drive will _never_
1559          * complete, and must be aborted by resetting the FDC.
1560          * Many thanks, Big Blue!
1561          * The FDC must not be reset directly, since that would
1562          * interfere with the state machine.  Instead, pretend that
1563          * the command completed but was invalid.  The state machine
1564          * will reset the FDC and retry once.
1565          */
1566         s = splbio();
1567         fdc->status[0] = NE7_ST0_IC_IV;
1568         fdc->flags &= ~FDC_STAT_VALID;
1569         fdc->state = IOTIMEDOUT;
1570         fdc_intr(fdc);
1571         splx(s);
1572 }
1573
1574 /* Just ensure it has the right spl. */
1575 static void
1576 fd_pseudointr(void *xfdc)
1577 {
1578         int     s;
1579
1580         s = splbio();
1581         fdc_intr(xfdc);
1582         splx(s);
1583 }
1584
1585 /*
1586  * fdc_intr
1587  *
1588  * Keep calling the state machine until it returns a 0.
1589  * Always called at splbio.
1590  */
1591 static void
1592 fdc_intr(void *xfdc)
1593 {
1594         fdc_p fdc = xfdc;
1595         while(fdstate(fdc))
1596                 ;
1597 }
1598
1599 /*
1600  * Magic pseudo-DMA initialization for YE FDC. Sets count and
1601  * direction.
1602  */
1603 #define SET_BCDR(fdc,wr,cnt,port) \
1604         bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port,  \
1605             ((cnt)-1) & 0xff);                                           \
1606         bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port + 1, \
1607             ((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f)));
1608
1609 /*
1610  * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy.
1611  */
1612 static int
1613 fdcpio(fdc_p fdc, long flags, caddr_t addr, u_int count)
1614 {
1615         u_char *cptr = (u_char *)addr;
1616
1617         if (flags == BIO_READ) {
1618                 if (fdc->state != PIOREAD) {
1619                         fdc->state = PIOREAD;
1620                         return(0);
1621                 }
1622                 SET_BCDR(fdc, 0, count, 0);
1623                 bus_space_read_multi_1(fdc->portt, fdc->porth, fdc->port_off +
1624                     FDC_YE_DATAPORT, cptr, count);
1625         } else {
1626                 bus_space_write_multi_1(fdc->portt, fdc->porth, fdc->port_off +
1627                     FDC_YE_DATAPORT, cptr, count);
1628                 SET_BCDR(fdc, 0, count, 0);
1629         }
1630         return(1);
1631 }
1632
1633 /*
1634  * Try figuring out the density of the media present in our device.
1635  */
1636 static int
1637 fdautoselect(struct cdev *dev)
1638 {
1639         fd_p fd;
1640         struct fd_type *fdtp;
1641         struct fdc_readid id;
1642         int i, n, oopts, rv;
1643
1644         fd = dev->si_drv1;
1645
1646         switch (fd->type) {
1647         default:
1648                 return (ENXIO);
1649
1650 #ifndef PC98
1651         case FDT_360K:
1652         case FDT_720K:
1653                 /* no autoselection on those drives */
1654                 fd->ft = fd_native_types + fd->type;
1655                 return (0);
1656 #endif
1657
1658         case FDT_12M:
1659                 fdtp = fd_searchlist_12m;
1660                 n = sizeof fd_searchlist_12m / sizeof(struct fd_type);
1661                 break;
1662
1663         case FDT_144M:
1664                 fdtp = fd_searchlist_144m;
1665                 n = sizeof fd_searchlist_144m / sizeof(struct fd_type);
1666                 break;
1667
1668 #ifndef PC98
1669         case FDT_288M:
1670                 fdtp = fd_searchlist_288m;
1671                 n = sizeof fd_searchlist_288m / sizeof(struct fd_type);
1672                 break;
1673 #endif
1674         }
1675
1676         /*
1677          * Try reading sector ID fields, first at cylinder 0, head 0,
1678          * then at cylinder 2, head N.  We don't probe cylinder 1,
1679          * since for 5.25in DD media in a HD drive, there are no data
1680          * to read (2 step pulses per media cylinder required).  For
1681          * two-sided media, the second probe always goes to head 1, so
1682          * we can tell them apart from single-sided media.  As a
1683          * side-effect this means that single-sided media should be
1684          * mentioned in the search list after two-sided media of an
1685          * otherwise identical density.  Media with a different number
1686          * of sectors per track but otherwise identical parameters
1687          * cannot be distinguished at all.
1688          *
1689          * If we successfully read an ID field on both cylinders where
1690          * the recorded values match our expectation, we are done.
1691          * Otherwise, we try the next density entry from the table.
1692          *
1693          * Stepping to cylinder 2 has the side-effect of clearing the
1694          * unit attention bit.
1695          */
1696         oopts = fd->options;
1697         fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY;
1698         for (i = 0; i < n; i++, fdtp++) {
1699                 fd->ft = fdtp;
1700
1701                 id.cyl = id.head = 0;
1702                 rv = fdmisccmd(dev, FDBIO_RDSECTID, &id);
1703                 if (rv != 0)
1704                         continue;
1705                 if (id.cyl != 0 || id.head != 0 ||
1706                     id.secshift != fdtp->secsize)
1707                         continue;
1708                 id.cyl = 2;
1709                 id.head = fd->ft->heads - 1;
1710                 rv = fdmisccmd(dev, FDBIO_RDSECTID, &id);
1711                 if (id.cyl != 2 || id.head != fdtp->heads - 1 ||
1712                     id.secshift != fdtp->secsize)
1713                         continue;
1714                 if (rv == 0)
1715                         break;
1716         }
1717
1718         fd->options = oopts;
1719         if (i == n) {
1720                 if (bootverbose)
1721                         device_printf(fd->dev, "autoselection failed\n");
1722                 fd->ft = 0;
1723                 return (EIO);
1724         } else {
1725                 if (bootverbose)
1726                         device_printf(fd->dev, "autoselected %d KB medium\n",
1727 #ifdef PC98
1728                                       (128 << (fd->ft->secsize)) *
1729                                       fd->ft->size / 1024);
1730 #else
1731                                       fd->ft->size / 2);
1732 #endif
1733                 return (0);
1734         }
1735 }
1736
1737
1738 /*
1739  * The controller state machine.
1740  *
1741  * If it returns a non zero value, it should be called again immediately.
1742  */
1743 static int
1744 fdstate(fdc_p fdc)
1745 {
1746         struct fdc_readid *idp;
1747         int read, format, rdsectid, cylinder, head, i, sec = 0, sectrac;
1748         int st0, cyl, st3, idf, ne7cmd, mfm, steptrac;
1749         unsigned long blknum;
1750         fdu_t fdu = fdc->fdu;
1751         fd_p fd;
1752         register struct bio *bp;
1753         struct fd_formb *finfo = NULL;
1754         size_t fdblk;
1755
1756         bp = fdc->bp;
1757         if (bp == NULL) {
1758                 bp = bioq_takefirst(&fdc->head);
1759                 if (bp != NULL)
1760                         fdc->bp = bp;
1761         }
1762         if (bp == NULL) {
1763                 /*
1764                  * Nothing left for this controller to do,
1765                  * force into the IDLE state.
1766                  */
1767                 fdc->state = DEVIDLE;
1768                 if (fdc->fd) {
1769                         device_printf(fdc->fdc_dev,
1770                             "unexpected valid fd pointer\n");
1771                         fdc->fd = (fd_p) 0;
1772                         fdc->fdu = -1;
1773                 }
1774                 TRACE1("[fdc%d IDLE]", fdc->fdcu);
1775                 return (0);
1776         }
1777         fd = bp->bio_dev->si_drv1;
1778         fdu = fd->fdu;
1779         fdblk = 128 << fd->ft->secsize;
1780         if (fdc->fd && (fd != fdc->fd))
1781                 device_printf(fd->dev, "confused fd pointers\n");
1782         read = bp->bio_cmd == BIO_READ;
1783         mfm = (fd->ft->flags & FL_MFM)? NE7CMD_MFM: 0;
1784         steptrac = (fd->ft->flags & FL_2STEP)? 2: 1;
1785         if (read)
1786                 idf = ISADMA_READ;
1787         else
1788                 idf = ISADMA_WRITE;
1789         format = bp->bio_cmd == FDBIO_FORMAT;
1790         rdsectid = bp->bio_cmd == FDBIO_RDSECTID;
1791         if (format)
1792                 finfo = (struct fd_formb *)bp->bio_data;
1793         TRACE1("fd%d", fdu);
1794         TRACE1("[%s]", fdstates[fdc->state]);
1795         TRACE1("(0x%x)", fd->flags);
1796         untimeout(fd_turnoff, fd, fd->toffhandle);
1797         fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
1798         switch (fdc->state)
1799         {
1800         case DEVIDLE:
1801         case FINDWORK:  /* we have found new work */
1802                 fdc->retry = 0;
1803                 fd->skip = 0;
1804                 fdc->fd = fd;
1805                 fdc->fdu = fdu;
1806 #ifdef PC98
1807                 pc98_trans = fd->ft->trans;
1808                 if (pc98_trans_prev != pc98_trans) {
1809                         int i;
1810                         set_density(fdc);
1811                         for (i = 0; i < 10; i++) {
1812                                 outb(0x5f, 0);
1813                                 outb(0x5f, 0);
1814                         }
1815                         pc98_trans_prev = pc98_trans;
1816                 }
1817                 if (pc98_trans != fd->pc98_trans) {
1818                         if (fd->type == FDT_144M) {
1819                                 bus_space_write_1(fdc->sc_fdemsiot,
1820                                                   fdc->sc_fdemsioh,
1821                                                   0,
1822                                                   (fdu << 5) | 0x10 |
1823                                                   (pc98_trans >> 1));
1824                                 outb(0x5f, 0);
1825                                 outb(0x5f, 0);
1826                         }
1827                         fd->pc98_trans = pc98_trans;
1828                 }
1829 #else
1830                 fdc->fdctl_wr(fdc, fd->ft->trans);
1831 #endif
1832                 TRACE1("[0x%x->FDCTL]", fd->ft->trans);
1833                 /*
1834                  * If the next drive has a motor startup pending, then
1835                  * it will start up in its own good time.
1836                  */
1837                 if(fd->flags & FD_MOTOR_WAIT) {
1838                         fdc->state = MOTORWAIT;
1839                         return (0); /* will return later */
1840                 }
1841                 /*
1842                  * Maybe if it's not starting, it SHOULD be starting.
1843                  */
1844                 if (!(fd->flags & FD_MOTOR))
1845                 {
1846                         fdc->state = MOTORWAIT;
1847                         fd_turnon(fd);
1848                         return (0); /* will return later */
1849                 }
1850                 else    /* at least make sure we are selected */
1851                 {
1852                         set_motor(fdc, fd->fdsu, TURNON);
1853                 }
1854                 if (fdc->flags & FDC_NEEDS_RESET) {
1855                         fdc->state = RESETCTLR;
1856                         fdc->flags &= ~FDC_NEEDS_RESET;
1857                 } else
1858                         fdc->state = DOSEEK;
1859                 return (1);     /* will return immediately */
1860
1861         case DOSEEK:
1862                 blknum = bp->bio_pblkno + fd->skip / fdblk;
1863                 cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
1864                 if (cylinder == fd->track)
1865                 {
1866                         fdc->state = SEEKCOMPLETE;
1867                         return (1); /* will return immediately */
1868                 }
1869 #ifdef PC98
1870                 pc98_fd_check_ready(fdu);
1871 #endif
1872                 if (fd_cmd(fdc, 3, NE7CMD_SEEK,
1873                            fd->fdsu, cylinder * steptrac, 0))
1874                 {
1875                         /*
1876                          * Seek command not accepted, looks like
1877                          * the FDC went off to the Saints...
1878                          */
1879                         fdc->retry = 6; /* try a reset */
1880                         return(retrier(fdc));
1881                 }
1882                 fd->track = FD_NO_TRACK;
1883                 fdc->state = SEEKWAIT;
1884                 return(0);      /* will return later */
1885
1886         case SEEKWAIT:
1887                 /* allow heads to settle */
1888                 timeout(fd_pseudointr, fdc, hz / 16);
1889                 fdc->state = SEEKCOMPLETE;
1890                 return(0);      /* will return later */
1891
1892         case SEEKCOMPLETE : /* seek done, start DMA */
1893                 blknum = bp->bio_pblkno + fd->skip / fdblk;
1894                 cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
1895
1896                 /* Make sure seek really happened. */
1897                 if(fd->track == FD_NO_TRACK) {
1898                         int descyl = cylinder * steptrac;
1899                         do {
1900                                 /*
1901                                  * This might be a "ready changed" interrupt,
1902                                  * which cannot really happen since the
1903                                  * RDY pin is hardwired to + 5 volts.  This
1904                                  * generally indicates a "bouncing" intr
1905                                  * line, so do one of the following:
1906                                  *
1907                                  * When running on an enhanced FDC that is
1908                                  * known to not go stuck after responding
1909                                  * with INVALID, fetch all interrupt states
1910                                  * until seeing either an INVALID or a
1911                                  * real interrupt condition.
1912                                  *
1913                                  * When running on a dumb old NE765, give
1914                                  * up immediately.  The controller will
1915                                  * provide up to four dummy RC interrupt
1916                                  * conditions right after reset (for the
1917                                  * corresponding four drives), so this is
1918                                  * our only chance to get notice that it
1919                                  * was not the FDC that caused the interrupt.
1920                                  */
1921                                 if (fd_sense_int(fdc, &st0, &cyl)
1922                                     == FD_NOT_VALID)
1923                                         return (0); /* will return later */
1924                                 if(fdc->fdct == FDC_NE765
1925                                    && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
1926                                         return (0); /* hope for a real intr */
1927                         } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
1928
1929                         if (0 == descyl) {
1930                                 int failed = 0;
1931                                 /*
1932                                  * seek to cyl 0 requested; make sure we are
1933                                  * really there
1934                                  */
1935                                 if (fd_sense_drive_status(fdc, &st3))
1936                                         failed = 1;
1937                                 if ((st3 & NE7_ST3_T0) == 0) {
1938                                         printf(
1939                 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n",
1940                                                fdu, st3, NE7_ST3BITS);
1941                                         failed = 1;
1942                                 }
1943
1944                                 if (failed) {
1945                                         if(fdc->retry < 3)
1946                                                 fdc->retry = 3;
1947                                         return (retrier(fdc));
1948                                 }
1949                         }
1950
1951                         if (cyl != descyl) {
1952                                 printf(
1953                 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
1954                                        fdu, descyl, cyl, st0);
1955                                 if (fdc->retry < 3)
1956                                         fdc->retry = 3;
1957                                 return (retrier(fdc));
1958                         }
1959                 }
1960
1961                 fd->track = cylinder;
1962                 if (format)
1963                         fd->skip = (char *)&(finfo->fd_formb_cylno(0))
1964                             - (char *)finfo;
1965                 if (!rdsectid && !(fdc->flags & FDC_NODMA))
1966                         isa_dmastart(idf, bp->bio_data+fd->skip,
1967                                 format ? bp->bio_bcount : fdblk, fdc->dmachan);
1968                 blknum = bp->bio_pblkno + fd->skip / fdblk;
1969                 sectrac = fd->ft->sectrac;
1970                 sec = blknum %  (sectrac * fd->ft->heads);
1971                 head = sec / sectrac;
1972                 sec = sec % sectrac + 1;
1973                 if (head != 0 && fd->ft->offset_side2 != 0)
1974                         sec += fd->ft->offset_side2;
1975                 fd->hddrv = ((head&1)<<2)+fdu;
1976
1977                 if(format || !(read || rdsectid))
1978                 {
1979                         /* make sure the drive is writable */
1980                         if(fd_sense_drive_status(fdc, &st3) != 0)
1981                         {
1982                                 /* stuck controller? */
1983                                 if (!(fdc->flags & FDC_NODMA))
1984                                         isa_dmadone(idf,
1985                                                     bp->bio_data + fd->skip,
1986                                                     format ? bp->bio_bcount : fdblk,
1987                                                     fdc->dmachan);
1988                                 fdc->retry = 6; /* reset the beast */
1989                                 return (retrier(fdc));
1990                         }
1991                         if(st3 & NE7_ST3_WP)
1992                         {
1993                                 /*
1994                                  * XXX YES! this is ugly.
1995                                  * in order to force the current operation
1996                                  * to fail, we will have to fake an FDC
1997                                  * error - all error handling is done
1998                                  * by the retrier()
1999                                  */
2000                                 fdc->status[0] = NE7_ST0_IC_AT;
2001                                 fdc->status[1] = NE7_ST1_NW;
2002                                 fdc->status[2] = 0;
2003                                 fdc->status[3] = fd->track;
2004                                 fdc->status[4] = head;
2005                                 fdc->status[5] = sec;
2006                                 fdc->retry = 8; /* break out immediately */
2007                                 fdc->state = IOTIMEDOUT; /* not really... */
2008                                 return (1); /* will return immediately */
2009                         }
2010                 }
2011
2012                 if (format) {
2013                         ne7cmd = NE7CMD_FORMAT | mfm;
2014                         if (fdc->flags & FDC_NODMA) {
2015                                 /*
2016                                  * This seems to be necessary for
2017                                  * whatever obscure reason; if we omit
2018                                  * it, we end up filling the sector ID
2019                                  * fields of the newly formatted track
2020                                  * entirely with garbage, causing
2021                                  * `wrong cylinder' errors all over
2022                                  * the place when trying to read them
2023                                  * back.
2024                                  *
2025                                  * Umpf.
2026                                  */
2027                                 SET_BCDR(fdc, 1, bp->bio_bcount, 0);
2028
2029                                 (void)fdcpio(fdc,bp->bio_cmd,
2030                                         bp->bio_data+fd->skip,
2031                                         bp->bio_bcount);
2032
2033                         }
2034                         /* formatting */
2035                         if(fd_cmd(fdc, 6,  ne7cmd, head << 2 | fdu,
2036                                   finfo->fd_formb_secshift,
2037                                   finfo->fd_formb_nsecs,
2038                                   finfo->fd_formb_gaplen,
2039                                   finfo->fd_formb_fillbyte, 0)) {
2040                                 /* controller fell over */
2041                                 if (!(fdc->flags & FDC_NODMA))
2042                                         isa_dmadone(idf,
2043                                                     bp->bio_data + fd->skip,
2044                                                     format ? bp->bio_bcount : fdblk,
2045                                                     fdc->dmachan);
2046                                 fdc->retry = 6;
2047                                 return (retrier(fdc));
2048                         }
2049                 } else if (rdsectid) {
2050                         ne7cmd = NE7CMD_READID | mfm;
2051                         if (fd_cmd(fdc, 2, ne7cmd, head << 2 | fdu, 0)) {
2052                                 /* controller jamming */
2053                                 fdc->retry = 6;
2054                                 return (retrier(fdc));
2055                         }
2056                 } else {
2057                         /* read or write operation */
2058                         ne7cmd = (read ? NE7CMD_READ | NE7CMD_SK : NE7CMD_WRITE) | mfm;
2059                         if (fdc->flags & FDC_NODMA) {
2060                                 /*
2061                                  * This seems to be necessary even when
2062                                  * reading data.
2063                                  */
2064                                 SET_BCDR(fdc, 1, fdblk, 0);
2065
2066                                 /*
2067                                  * Perform the write pseudo-DMA before
2068                                  * the WRITE command is sent.
2069                                  */
2070                                 if (!read)
2071                                         (void)fdcpio(fdc,bp->bio_cmd,
2072                                             bp->bio_data+fd->skip,
2073                                             fdblk);
2074                         }
2075                         if (fd_cmd(fdc, 9,
2076                                    ne7cmd,
2077                                    head << 2 | fdu,  /* head & unit */
2078                                    fd->track,        /* track */
2079                                    head,
2080                                    sec,              /* sector + 1 */
2081                                    fd->ft->secsize,  /* sector size */
2082                                    sectrac,          /* sectors/track */
2083                                    fd->ft->gap,      /* gap size */
2084                                    fd->ft->datalen,  /* data length */
2085                                    0)) {
2086                                 /* the beast is sleeping again */
2087                                 if (!(fdc->flags & FDC_NODMA))
2088                                         isa_dmadone(idf,
2089                                                     bp->bio_data + fd->skip,
2090                                                     format ? bp->bio_bcount : fdblk,
2091                                                     fdc->dmachan);
2092                                 fdc->retry = 6;
2093                                 return (retrier(fdc));
2094                         }
2095                 }
2096                 if (!rdsectid && (fdc->flags & FDC_NODMA))
2097                         /*
2098                          * If this is a read, then simply await interrupt
2099                          * before performing PIO.
2100                          */
2101                         if (read && !fdcpio(fdc,bp->bio_cmd,
2102                             bp->bio_data+fd->skip,fdblk)) {
2103                                 fd->tohandle = timeout(fd_iotimeout, fdc, hz);
2104                                 return(0);      /* will return later */
2105                         }
2106
2107                 /*
2108                  * Write (or format) operation will fall through and
2109                  * await completion interrupt.
2110                  */
2111                 fdc->state = IOCOMPLETE;
2112                 fd->tohandle = timeout(fd_iotimeout, fdc, hz);
2113                 return (0);     /* will return later */
2114
2115         case PIOREAD:
2116                 /* 
2117                  * Actually perform the PIO read.  The IOCOMPLETE case
2118                  * removes the timeout for us.
2119                  */
2120                 (void)fdcpio(fdc,bp->bio_cmd,bp->bio_data+fd->skip,fdblk);
2121                 fdc->state = IOCOMPLETE;
2122                 /* FALLTHROUGH */
2123         case IOCOMPLETE: /* IO done, post-analyze */
2124                 untimeout(fd_iotimeout, fdc, fd->tohandle);
2125
2126                 if (fd_read_status(fdc)) {
2127                         if (!rdsectid && !(fdc->flags & FDC_NODMA))
2128                                 isa_dmadone(idf, bp->bio_data + fd->skip,
2129                                             format ? bp->bio_bcount : fdblk,
2130                                             fdc->dmachan);
2131                         if (fdc->retry < 6)
2132                                 fdc->retry = 6; /* force a reset */
2133                         return (retrier(fdc));
2134                 }
2135
2136                 fdc->state = IOTIMEDOUT;
2137
2138                 /* FALLTHROUGH */
2139         case IOTIMEDOUT:
2140                 if (!rdsectid && !(fdc->flags & FDC_NODMA))
2141                         isa_dmadone(idf, bp->bio_data + fd->skip,
2142                                 format ? bp->bio_bcount : fdblk, fdc->dmachan);
2143                 if (fdc->status[0] & NE7_ST0_IC) {
2144                         if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
2145                             && fdc->status[1] & NE7_ST1_OR) {
2146                                 /*
2147                                  * DMA overrun. Someone hogged the bus and
2148                                  * didn't release it in time for the next
2149                                  * FDC transfer.
2150                                  *
2151                                  * We normally restart this without bumping
2152                                  * the retry counter.  However, in case
2153                                  * something is seriously messed up (like
2154                                  * broken hardware), we rather limit the
2155                                  * number of retries so the IO operation
2156                                  * doesn't block indefinately.
2157                                  */
2158                                 if (fdc->dma_overruns++ < FDC_DMAOV_MAX) {
2159                                         fdc->state = SEEKCOMPLETE;
2160                                         return (1);/* will return immediately */
2161                                 } /* else fall through */
2162                         }
2163                         if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV
2164                                 && fdc->retry < 6)
2165                                 fdc->retry = 6; /* force a reset */
2166                         else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
2167                                 && fdc->status[2] & NE7_ST2_WC
2168                                 && fdc->retry < 3)
2169                                 fdc->retry = 3; /* force recalibrate */
2170                         return (retrier(fdc));
2171                 }
2172                 /* All OK */
2173                 if (rdsectid) {
2174                         /* copy out ID field contents */
2175                         idp = (struct fdc_readid *)bp->bio_data;
2176                         idp->cyl = fdc->status[3];
2177                         idp->head = fdc->status[4];
2178                         idp->sec = fdc->status[5];
2179                         idp->secshift = fdc->status[6];
2180                 }
2181                 /* Operation successful, retry DMA overruns again next time. */
2182                 fdc->dma_overruns = 0;
2183                 fd->skip += fdblk;
2184                 if (!rdsectid && !format && fd->skip < bp->bio_bcount) {
2185                         /* set up next transfer */
2186                         fdc->state = DOSEEK;
2187                 } else {
2188                         /* ALL DONE */
2189                         fd->skip = 0;
2190                         bp->bio_resid = 0;
2191                         fdc->bp = NULL;
2192                         device_unbusy(fd->dev);
2193                         biofinish(bp, fd->device_stats, 0);
2194                         fdc->fd = (fd_p) 0;
2195                         fdc->fdu = -1;
2196                         fdc->state = FINDWORK;
2197                 }
2198                 return (1);     /* will return immediately */
2199
2200         case RESETCTLR:
2201                 fdc_reset(fdc);
2202                 fdc->retry++;
2203                 fdc->state = RESETCOMPLETE;
2204                 return (0);     /* will return later */
2205
2206         case RESETCOMPLETE:
2207                 /*
2208                  * Discard all the results from the reset so that they
2209                  * can't cause an unexpected interrupt later.
2210                  */
2211                 for (i = 0; i < 4; i++)
2212                         (void)fd_sense_int(fdc, &st0, &cyl);
2213                 fdc->state = STARTRECAL;
2214                 /* FALLTHROUGH */
2215         case STARTRECAL:
2216 #ifdef PC98
2217                 pc98_fd_check_ready(fdu);
2218 #endif
2219                 if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) {
2220                         /* arrgl */
2221                         fdc->retry = 6;
2222                         return (retrier(fdc));
2223                 }
2224                 fdc->state = RECALWAIT;
2225                 return (0);     /* will return later */
2226
2227         case RECALWAIT:
2228                 /* allow heads to settle */
2229                 timeout(fd_pseudointr, fdc, hz / 8);
2230                 fdc->state = RECALCOMPLETE;
2231                 return (0);     /* will return later */
2232
2233         case RECALCOMPLETE:
2234                 do {
2235                         /*
2236                          * See SEEKCOMPLETE for a comment on this:
2237                          */
2238                         if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
2239                                 return (0); /* will return later */
2240                         if(fdc->fdct == FDC_NE765
2241                            && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
2242                                 return (0); /* hope for a real intr */
2243                 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
2244                 if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
2245                 {
2246                         if(fdc->retry > 3)
2247                                 /*
2248                                  * A recalibrate from beyond cylinder 77
2249                                  * will "fail" due to the FDC limitations;
2250                                  * since people used to complain much about
2251                                  * the failure message, try not logging
2252                                  * this one if it seems to be the first
2253                                  * time in a line.
2254                                  */
2255                                 printf("fd%d: recal failed ST0 %b cyl %d\n",
2256                                        fdu, st0, NE7_ST0BITS, cyl);
2257                         if(fdc->retry < 3) fdc->retry = 3;
2258                         return (retrier(fdc));
2259                 }
2260                 fd->track = 0;
2261                 /* Seek (probably) necessary */
2262                 fdc->state = DOSEEK;
2263                 return (1);     /* will return immediately */
2264
2265         case MOTORWAIT:
2266                 if(fd->flags & FD_MOTOR_WAIT)
2267                 {
2268                         return (0); /* time's not up yet */
2269                 }
2270                 if (fdc->flags & FDC_NEEDS_RESET) {
2271                         fdc->state = RESETCTLR;
2272                         fdc->flags &= ~FDC_NEEDS_RESET;
2273                 } else
2274                         fdc->state = DOSEEK;
2275                 return (1);     /* will return immediately */
2276
2277         default:
2278                 device_printf(fdc->fdc_dev, "unexpected FD int->");
2279                 if (fd_read_status(fdc) == 0)
2280                         printf("FDC status :%x %x %x %x %x %x %x   ",
2281                                fdc->status[0],
2282                                fdc->status[1],
2283                                fdc->status[2],
2284                                fdc->status[3],
2285                                fdc->status[4],
2286                                fdc->status[5],
2287                                fdc->status[6] );
2288                 else
2289                         printf("No status available   ");
2290                 if (fd_sense_int(fdc, &st0, &cyl) != 0)
2291                 {
2292                         printf("[controller is dead now]\n");
2293                         return (0); /* will return later */
2294                 }
2295                 printf("ST0 = %x, PCN = %x\n", st0, cyl);
2296                 return (0);     /* will return later */
2297         }
2298         /* noone should ever get here */
2299 }
2300
2301 static int
2302 retrier(struct fdc_data *fdc)
2303 {
2304         struct bio *bp;
2305         struct fd_data *fd;
2306         int fdu;
2307
2308         bp = fdc->bp;
2309
2310         /* XXX shouldn't this be cached somewhere?  */
2311         fd = bp->bio_dev->si_drv1;
2312         fdu = fd->fdu;
2313         if (fd->options & FDOPT_NORETRY)
2314                 goto fail;
2315
2316         switch (fdc->retry) {
2317         case 0: case 1: case 2:
2318                 fdc->state = SEEKCOMPLETE;
2319                 break;
2320         case 3: case 4: case 5:
2321                 fdc->state = STARTRECAL;
2322                 break;
2323         case 6:
2324                 fdc->state = RESETCTLR;
2325                 break;
2326         case 7:
2327                 break;
2328         default:
2329         fail:
2330                 if ((fd->options & FDOPT_NOERRLOG) == 0) {
2331                         disk_err(bp, "hard error",
2332                             fdc->fd->skip / DEV_BSIZE, 0);
2333                         if (fdc->flags & FDC_STAT_VALID) {
2334                                 printf(
2335                                 " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n",
2336                                        fdc->status[0], NE7_ST0BITS,
2337                                        fdc->status[1], NE7_ST1BITS,
2338                                        fdc->status[2], NE7_ST2BITS,
2339                                        fdc->status[3], fdc->status[4],
2340                                        fdc->status[5]);
2341                         }
2342                         else
2343                                 printf(" (No status)\n");
2344                 }
2345                 if ((fd->options & FDOPT_NOERROR) == 0) {
2346                         bp->bio_flags |= BIO_ERROR;
2347                         bp->bio_error = EIO;
2348                         bp->bio_resid = bp->bio_bcount - fdc->fd->skip;
2349                 } else
2350                         bp->bio_resid = 0;
2351                 fdc->bp = NULL;
2352                 fdc->fd->skip = 0;
2353                 device_unbusy(fd->dev);
2354                 biofinish(bp, fdc->fd->device_stats, 0);
2355                 fdc->state = FINDWORK;
2356                 fdc->flags |= FDC_NEEDS_RESET;
2357                 fdc->fd = (fd_p) 0;
2358                 fdc->fdu = -1;
2359                 return (1);
2360         }
2361         fdc->retry++;
2362         return (1);
2363 }
2364
2365 static void
2366 fdbiodone(struct bio *bp)
2367 {
2368         wakeup(bp);
2369 }
2370
2371 static int
2372 fdmisccmd(struct cdev *dev, u_int cmd, void *data)
2373 {
2374         fdu_t fdu;
2375         fd_p fd;
2376         struct bio *bp;
2377         struct fd_formb *finfo;
2378         struct fdc_readid *idfield;
2379         size_t fdblk;
2380         int error;
2381
2382         fd = dev->si_drv1;
2383         fdu = fd->fdu;
2384         fdblk = 128 << fd->ft->secsize;
2385         finfo = (struct fd_formb *)data;
2386         idfield = (struct fdc_readid *)data;
2387
2388         bp = malloc(sizeof(struct bio), M_TEMP, M_WAITOK | M_ZERO);
2389
2390         /*
2391          * Set up a bio request for fdstrategy().  bio_offset is faked
2392          * so that fdstrategy() will seek to the the requested
2393          * cylinder, and use the desired head.
2394          */
2395         bp->bio_cmd = cmd;
2396         if (cmd == FDBIO_FORMAT) {
2397                 bp->bio_offset =
2398                     (finfo->cyl * (fd->ft->sectrac * fd->ft->heads) +
2399                      finfo->head * fd->ft->sectrac) * fdblk;
2400                 bp->bio_bcount = sizeof(struct fd_idfield_data) *
2401                     finfo->fd_formb_nsecs;
2402         } else if (cmd == FDBIO_RDSECTID) {
2403                 bp->bio_offset =
2404                     (idfield->cyl * (fd->ft->sectrac * fd->ft->heads) +
2405                      idfield->head * fd->ft->sectrac) * fdblk;
2406                 bp->bio_bcount = sizeof(struct fdc_readid);
2407         } else
2408                 panic("wrong cmd in fdmisccmd()");
2409         bp->bio_data = data;
2410         bp->bio_dev = dev;
2411         bp->bio_done = fdbiodone;
2412         bp->bio_flags = 0;
2413
2414         /* Now run the command. */
2415         fdstrategy(bp);
2416         error = biowait(bp, "fdcmd");
2417
2418         free(bp, M_TEMP);
2419         return (error);
2420 }
2421
2422 static int
2423 fdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
2424 {
2425         fdu_t fdu;
2426         fd_p fd;
2427         struct fdc_status *fsp;
2428         struct fdc_readid *rid;
2429         int error;
2430
2431         fd = dev->si_drv1;
2432         fdu = fd->fdu;
2433
2434 #ifdef PC98
2435         pc98_fd_check_ready(fdu);
2436 #endif  
2437
2438         /*
2439          * First, handle everything that could be done with
2440          * FD_NONBLOCK still being set.
2441          */
2442         switch (cmd) {
2443
2444         case DIOCGMEDIASIZE:
2445                 if (fd->ft == 0)
2446                         return ((fd->flags & FD_NONBLOCK) ? EAGAIN : ENXIO);
2447                 *(off_t *)addr = (128 << (fd->ft->secsize)) * fd->ft->size;
2448                 return (0);
2449
2450         case DIOCGSECTORSIZE:
2451                 if (fd->ft == 0)
2452                         return ((fd->flags & FD_NONBLOCK) ? EAGAIN : ENXIO);
2453                 *(u_int *)addr = 128 << (fd->ft->secsize);
2454                 return (0);
2455
2456         case FIONBIO:
2457                 if (*(int *)addr != 0)
2458                         fd->flags |= FD_NONBLOCK;
2459                 else {
2460                         if (fd->ft == 0) {
2461                                 /*
2462                                  * No drive type has been selected yet,
2463                                  * cannot turn FNONBLOCK off.
2464                                  */
2465                                 return (EINVAL);
2466                         }
2467                         fd->flags &= ~FD_NONBLOCK;
2468                 }
2469                 return (0);
2470
2471         case FIOASYNC:
2472                 /* keep the generic fcntl() code happy */
2473                 return (0);
2474
2475         case FD_GTYPE:                  /* get drive type */
2476                 if (fd->ft == 0)
2477                         /* no type known yet, return the native type */
2478                         *(struct fd_type *)addr = fd_native_types[fd->type];
2479                 else
2480                         *(struct fd_type *)addr = *fd->ft;
2481                 return (0);
2482
2483         case FD_STYPE:                  /* set drive type */
2484                 /*
2485                  * Allow setting drive type temporarily iff
2486                  * currently unset.  Used for fdformat so any
2487                  * user can set it, and then start formatting.
2488                  */
2489                 if (fd->ft)
2490                         return (EINVAL); /* already set */
2491                 fd->fts[0] = *(struct fd_type *)addr;
2492                 fd->ft = &fd->fts[0];
2493                 fd->flags |= FD_UA;
2494                 return (0);
2495
2496         case FD_GOPTS:                  /* get drive options */
2497                 *(int *)addr = fd->options + FDOPT_AUTOSEL;
2498                 return (0);
2499
2500         case FD_SOPTS:                  /* set drive options */
2501                 fd->options = *(int *)addr & ~FDOPT_AUTOSEL;
2502                 return (0);
2503
2504 #ifdef FDC_DEBUG
2505         case FD_DEBUG:
2506                 if ((fd_debug != 0) != (*(int *)addr != 0)) {
2507                         fd_debug = (*(int *)addr != 0);
2508                         printf("fd%d: debugging turned %s\n",
2509                             fd->fdu, fd_debug ? "on" : "off");
2510                 }
2511                 return (0);
2512 #endif
2513
2514         case FD_CLRERR:
2515                 if (suser(td) != 0)
2516                         return (EPERM);
2517                 fd->fdc->fdc_errs = 0;
2518                 return (0);
2519
2520         case FD_GSTAT:
2521                 fsp = (struct fdc_status *)addr;
2522                 if ((fd->fdc->flags & FDC_STAT_VALID) == 0)
2523                         return (EINVAL);
2524                 memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int));
2525                 return (0);
2526
2527         case FD_GDTYPE:
2528                 *(enum fd_drivetype *)addr = fd->type;
2529                 return (0);
2530         }
2531
2532         /*
2533          * Now handle everything else.  Make sure we have a valid
2534          * drive type.
2535          */
2536         if (fd->flags & FD_NONBLOCK)
2537                 return (EAGAIN);
2538         if (fd->ft == 0)
2539                 return (ENXIO);
2540         error = 0;
2541
2542         switch (cmd) {
2543
2544         case FD_FORM:
2545                 if ((flag & FWRITE) == 0)
2546                         return (EBADF); /* must be opened for writing */
2547                 if (((struct fd_formb *)addr)->format_version !=
2548                     FD_FORMAT_VERSION)
2549                         return (EINVAL); /* wrong version of formatting prog */
2550                 error = fdmisccmd(dev, FDBIO_FORMAT, addr);
2551                 break;
2552
2553         case FD_GTYPE:                  /* get drive type */
2554                 *(struct fd_type *)addr = *fd->ft;
2555                 break;
2556
2557         case FD_STYPE:                  /* set drive type */
2558                 /* this is considered harmful; only allow for superuser */
2559                 if (suser(td) != 0)
2560                         return (EPERM);
2561                 *fd->ft = *(struct fd_type *)addr;
2562                 break;
2563
2564         case FD_GOPTS:                  /* get drive options */
2565                 *(int *)addr = fd->options;
2566                 break;
2567
2568         case FD_SOPTS:                  /* set drive options */
2569                 fd->options = *(int *)addr;
2570                 break;
2571
2572 #ifdef FDC_DEBUG
2573         case FD_DEBUG:
2574                 if ((fd_debug != 0) != (*(int *)addr != 0)) {
2575                         fd_debug = (*(int *)addr != 0);
2576                         printf("fd%d: debugging turned %s\n",
2577                             fd->fdu, fd_debug ? "on" : "off");
2578                 }
2579                 break;
2580 #endif
2581
2582         case FD_CLRERR:
2583                 if (suser(td) != 0)
2584                         return (EPERM);
2585                 fd->fdc->fdc_errs = 0;
2586                 break;
2587
2588         case FD_GSTAT:
2589                 fsp = (struct fdc_status *)addr;
2590                 if ((fd->fdc->flags & FDC_STAT_VALID) == 0)
2591                         return (EINVAL);
2592                 memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int));
2593                 break;
2594
2595         case FD_READID:
2596                 rid = (struct fdc_readid *)addr;
2597                 if (rid->cyl > MAX_CYLINDER || rid->head > MAX_HEAD)
2598                         return (EINVAL);
2599                 error = fdmisccmd(dev, FDBIO_RDSECTID, addr);
2600                 break;
2601
2602         default:
2603                 error = ENOTTY;
2604                 break;
2605         }
2606         return (error);
2607 }