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