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