Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / dev / disk / fd / 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.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: src/sys/isa/fd.c,v 1.176.2.8 2002/05/15 21:56:14 joerg Exp $
54  *
55  */
56
57 #include "opt_fdc.h"
58 #include "card.h"
59
60 #include <sys/param.h>
61 #include <sys/systm.h>
62 #include <sys/kernel.h>
63 #include <sys/buf.h>
64 #include <sys/bus.h>
65 #include <sys/conf.h>
66 #include <sys/disklabel.h>
67 #include <sys/devicestat.h>
68 #include <sys/fcntl.h>
69 #include <sys/malloc.h>
70 #include <sys/module.h>
71 #include <sys/proc.h>
72 #include <sys/syslog.h>
73
74 #include <sys/bus.h>
75 #include <machine/bus.h>
76 #include <sys/rman.h>
77
78 #include <machine/clock.h>
79 #include <machine/ioctl_fd.h>
80 #include <machine/resource.h>
81 #include <machine/stdarg.h>
82
83 #include <isa/isavar.h>
84 #include <isa/isareg.h>
85 #include <isa/fdreg.h>
86 #include <isa/fdc.h>
87 #include <isa/rtc.h>
88
89 /* misuse a flag to identify format operation */
90 #define B_FORMAT B_XXX
91
92 /* configuration flags */
93 #define FDC_PRETEND_D0  (1 << 0)        /* pretend drive 0 to be there */
94 #define FDC_NO_FIFO     (1 << 2)        /* do not enable FIFO  */
95
96 /* internally used only, not really from CMOS: */
97 #define RTCFDT_144M_PRETENDED   0x1000
98
99 /* error returns for fd_cmd() */
100 #define FD_FAILED -1
101 #define FD_NOT_VALID -2
102 #define FDC_ERRMAX      100     /* do not log more */
103 /*
104  * Stop retrying after this many DMA overruns.  Since each retry takes
105  * one revolution, with 300 rpm., 25 retries take approximately 10
106  * seconds which the read attempt will block in case the DMA overrun
107  * is persistent.
108  */
109 #define FDC_DMAOV_MAX   25
110
111 /*
112  * Timeout value for the PIO loops to wait until the FDC main status
113  * register matches our expectations (request for master, direction
114  * bit).  This is supposed to be a number of microseconds, although
115  * timing might actually not be very accurate.
116  *
117  * Timeouts of 100 msec are believed to be required for some broken
118  * (old) hardware.
119  */
120 #define FDSTS_TIMEOUT   100000
121
122 #define NUMTYPES 17
123 #define NUMDENS  (NUMTYPES - 7)
124
125 /* These defines (-1) must match index for fd_types */
126 #define F_TAPE_TYPE     0x020   /* bit for fd_types to indicate tape */
127 #define NO_TYPE         0       /* must match NO_TYPE in ft.c */
128 #define FD_1720         1
129 #define FD_1480         2
130 #define FD_1440         3
131 #define FD_1200         4
132 #define FD_820          5
133 #define FD_800          6
134 #define FD_720          7
135 #define FD_360          8
136 #define FD_640          9
137 #define FD_1232         10
138
139 #define FD_1480in5_25   11
140 #define FD_1440in5_25   12
141 #define FD_820in5_25    13
142 #define FD_800in5_25    14
143 #define FD_720in5_25    15
144 #define FD_360in5_25    16
145 #define FD_640in5_25    17
146
147
148 static struct fd_type fd_types[NUMTYPES] =
149 {
150 { 21,2,0xFF,0x04,82,3444,1,FDC_500KBPS,2,0x0C,2 }, /* 1.72M in HD 3.5in */
151 { 18,2,0xFF,0x1B,82,2952,1,FDC_500KBPS,2,0x6C,1 }, /* 1.48M in HD 3.5in */
152 { 18,2,0xFF,0x1B,80,2880,1,FDC_500KBPS,2,0x6C,1 }, /* 1.44M in HD 3.5in */
153 { 15,2,0xFF,0x1B,80,2400,1,FDC_500KBPS,2,0x54,1 }, /*  1.2M in HD 5.25/3.5 */
154 { 10,2,0xFF,0x10,82,1640,1,FDC_250KBPS,2,0x2E,1 }, /*  820K in HD 3.5in */
155 { 10,2,0xFF,0x10,80,1600,1,FDC_250KBPS,2,0x2E,1 }, /*  800K in HD 3.5in */
156 {  9,2,0xFF,0x20,80,1440,1,FDC_250KBPS,2,0x50,1 }, /*  720K in HD 3.5in */
157 {  9,2,0xFF,0x2A,40, 720,1,FDC_250KBPS,2,0x50,1 }, /*  360K in DD 5.25in */
158 {  8,2,0xFF,0x2A,80,1280,1,FDC_250KBPS,2,0x50,1 }, /*  640K in DD 5.25in */
159 {  8,3,0xFF,0x35,77,1232,1,FDC_500KBPS,2,0x74,1 }, /* 1.23M in HD 5.25in */
160
161 { 18,2,0xFF,0x02,82,2952,1,FDC_500KBPS,2,0x02,2 }, /* 1.48M in HD 5.25in */
162 { 18,2,0xFF,0x02,80,2880,1,FDC_500KBPS,2,0x02,2 }, /* 1.44M in HD 5.25in */
163 { 10,2,0xFF,0x10,82,1640,1,FDC_300KBPS,2,0x2E,1 }, /*  820K in HD 5.25in */
164 { 10,2,0xFF,0x10,80,1600,1,FDC_300KBPS,2,0x2E,1 }, /*  800K in HD 5.25in */
165 {  9,2,0xFF,0x20,80,1440,1,FDC_300KBPS,2,0x50,1 }, /*  720K in HD 5.25in */
166 {  9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /*  360K in HD 5.25in */
167 {  8,2,0xFF,0x2A,80,1280,1,FDC_300KBPS,2,0x50,1 }, /*  640K in HD 5.25in */
168 };
169
170 #define DRVS_PER_CTLR 2         /* 2 floppies */
171
172 /***********************************************************************\
173 * Per controller structure.                                             *
174 \***********************************************************************/
175 static devclass_t fdc_devclass;
176
177 /***********************************************************************\
178 * Per drive structure.                                                  *
179 * N per controller  (DRVS_PER_CTLR)                                     *
180 \***********************************************************************/
181 struct fd_data {
182         struct  fdc_data *fdc;  /* pointer to controller structure */
183         int     fdsu;           /* this units number on this controller */
184         int     type;           /* Drive type (FD_1440...) */
185         struct  fd_type *ft;    /* pointer to the type descriptor */
186         int     flags;
187 #define FD_OPEN         0x01    /* it's open            */
188 #define FD_ACTIVE       0x02    /* it's active          */
189 #define FD_MOTOR        0x04    /* motor should be on   */
190 #define FD_MOTOR_WAIT   0x08    /* motor coming up      */
191         int     skip;
192         int     hddrv;
193 #define FD_NO_TRACK -2
194         int     track;          /* where we think the head is */
195         int     options;        /* user configurable options, see ioctl_fd.h */
196         struct  callout_handle toffhandle;
197         struct  callout_handle tohandle;
198         struct  devstat device_stats;
199         device_t dev;
200         fdu_t   fdu;
201 };
202
203 struct fdc_ivars {
204         int     fdunit;
205 };
206 static devclass_t fd_devclass;
207
208 /***********************************************************************\
209 * Throughout this file the following conventions will be used:          *
210 * fd is a pointer to the fd_data struct for the drive in question       *
211 * fdc is a pointer to the fdc_data struct for the controller            *
212 * fdu is the floppy drive unit number                                   *
213 * fdcu is the floppy controller unit number                             *
214 * fdsu is the floppy drive unit number on that controller. (sub-unit)   *
215 \***********************************************************************/
216
217 /* internal functions */
218 static  void fdc_intr(void *);
219 static void set_motor(struct fdc_data *, int, int);
220 #  define TURNON 1
221 #  define TURNOFF 0
222 static timeout_t fd_turnoff;
223 static timeout_t fd_motor_on;
224 static void fd_turnon(struct fd_data *);
225 static void fdc_reset(fdc_p);
226 static int fd_in(struct fdc_data *, int *);
227 static int out_fdc(struct fdc_data *, int);
228 static void fdstart(struct fdc_data *);
229 static timeout_t fd_iotimeout;
230 static timeout_t fd_pseudointr;
231 static int fdstate(struct fdc_data *);
232 static int retrier(struct fdc_data *);
233 static int fdformat(dev_t, struct fd_formb *, struct proc *);
234
235 static int enable_fifo(fdc_p fdc);
236
237 static int fifo_threshold = 8;  /* XXX: should be accessible via sysctl */
238
239
240 #define DEVIDLE         0
241 #define FINDWORK        1
242 #define DOSEEK          2
243 #define SEEKCOMPLETE    3
244 #define IOCOMPLETE      4
245 #define RECALCOMPLETE   5
246 #define STARTRECAL      6
247 #define RESETCTLR       7
248 #define SEEKWAIT        8
249 #define RECALWAIT       9
250 #define MOTORWAIT       10
251 #define IOTIMEDOUT      11
252 #define RESETCOMPLETE   12
253 #define PIOREAD         13
254
255 #ifdef  FDC_DEBUG
256 static char const * const fdstates[] =
257 {
258 "DEVIDLE",
259 "FINDWORK",
260 "DOSEEK",
261 "SEEKCOMPLETE",
262 "IOCOMPLETE",
263 "RECALCOMPLETE",
264 "STARTRECAL",
265 "RESETCTLR",
266 "SEEKWAIT",
267 "RECALWAIT",
268 "MOTORWAIT",
269 "IOTIMEDOUT",
270 "RESETCOMPLETE",
271 "PIOREAD",
272 };
273
274 /* CAUTION: fd_debug causes huge amounts of logging output */
275 static int volatile fd_debug = 0;
276 #define TRACE0(arg) if(fd_debug) printf(arg)
277 #define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2)
278 #else /* FDC_DEBUG */
279 #define TRACE0(arg)
280 #define TRACE1(arg1, arg2)
281 #endif /* FDC_DEBUG */
282
283 static void
284 fdout_wr(fdc_p fdc, u_int8_t v)
285 {
286         bus_space_write_1(fdc->portt, fdc->porth, FDOUT+fdc->port_off, v);
287 }
288
289 static u_int8_t
290 fdsts_rd(fdc_p fdc)
291 {
292         return bus_space_read_1(fdc->portt, fdc->porth, FDSTS+fdc->port_off);
293 }
294
295 static void
296 fddata_wr(fdc_p fdc, u_int8_t v)
297 {
298         bus_space_write_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off, v);
299 }
300
301 static u_int8_t
302 fddata_rd(fdc_p fdc)
303 {
304         return bus_space_read_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off);
305 }
306
307 static void
308 fdctl_wr_isa(fdc_p fdc, u_int8_t v)
309 {
310         bus_space_write_1(fdc->ctlt, fdc->ctlh, 0, v);
311 }
312
313 #if NCARD > 0
314 static void
315 fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v)
316 {
317         bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v);
318 }
319 #endif
320
321 #if 0
322
323 static u_int8_t
324 fdin_rd(fdc_p fdc)
325 {
326         return bus_space_read_1(fdc->portt, fdc->porth, FDIN);
327 }
328
329 #endif
330
331 static  d_open_t        Fdopen; /* NOTE, not fdopen */
332 static  d_close_t       fdclose;
333 static  d_ioctl_t       fdioctl;
334 static  d_strategy_t    fdstrategy;
335
336 #define CDEV_MAJOR 9
337 #define BDEV_MAJOR 2
338
339 static struct cdevsw fd_cdevsw = {
340         /* open */      Fdopen,
341         /* close */     fdclose,
342         /* read */      physread,
343         /* write */     physwrite,
344         /* ioctl */     fdioctl,
345         /* poll */      nopoll,
346         /* mmap */      nommap,
347         /* strategy */  fdstrategy,
348         /* name */      "fd",
349         /* maj */       CDEV_MAJOR,
350         /* dump */      nodump,
351         /* psize */     nopsize,
352         /* flags */     D_DISK,
353         /* bmaj */      BDEV_MAJOR
354 };
355
356 static int
357 fdc_err(struct fdc_data *fdc, const char *s)
358 {
359         fdc->fdc_errs++;
360         if (s) {
361                 if (fdc->fdc_errs < FDC_ERRMAX)
362                         device_printf(fdc->fdc_dev, "%s", s);
363                 else if (fdc->fdc_errs == FDC_ERRMAX)
364                         device_printf(fdc->fdc_dev, "too many errors, not "
365                                                     "logging any more\n");
366         }
367
368         return FD_FAILED;
369 }
370
371 /*
372  * fd_cmd: Send a command to the chip.  Takes a varargs with this structure:
373  * Unit number,
374  * # of output bytes, output bytes as ints ...,
375  * # of input bytes, input bytes as ints ...
376  */
377 static int
378 fd_cmd(struct fdc_data *fdc, int n_out, ...)
379 {
380         u_char cmd;
381         int n_in;
382         int n;
383         va_list ap;
384
385         va_start(ap, n_out);
386         cmd = (u_char)(va_arg(ap, int));
387         va_end(ap);
388         va_start(ap, n_out);
389         for (n = 0; n < n_out; n++)
390         {
391                 if (out_fdc(fdc, va_arg(ap, int)) < 0)
392                 {
393                         char msg[50];
394                         snprintf(msg, sizeof(msg),
395                                 "cmd %x failed at out byte %d of %d\n",
396                                 cmd, n + 1, n_out);
397                         return fdc_err(fdc, msg);
398                 }
399         }
400         n_in = va_arg(ap, int);
401         for (n = 0; n < n_in; n++)
402         {
403                 int *ptr = va_arg(ap, int *);
404                 if (fd_in(fdc, ptr) < 0)
405                 {
406                         char msg[50];
407                         snprintf(msg, sizeof(msg),
408                                 "cmd %02x failed at in byte %d of %d\n",
409                                 cmd, n + 1, n_in);
410                         return fdc_err(fdc, msg);
411                 }
412         }
413
414         return 0;
415 }
416
417 static int 
418 enable_fifo(fdc_p fdc)
419 {
420         int i, j;
421
422         if ((fdc->flags & FDC_HAS_FIFO) == 0) {
423                 
424                 /*
425                  * XXX: 
426                  * Cannot use fd_cmd the normal way here, since
427                  * this might be an invalid command. Thus we send the
428                  * first byte, and check for an early turn of data directon.
429                  */
430                 
431                 if (out_fdc(fdc, I8207X_CONFIGURE) < 0)
432                         return fdc_err(fdc, "Enable FIFO failed\n");
433                 
434                 /* If command is invalid, return */
435                 j = FDSTS_TIMEOUT;
436                 while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM))
437                        != NE7_RQM && j-- > 0) {
438                         if (i == (NE7_DIO | NE7_RQM)) {
439                                 fdc_reset(fdc);
440                                 return FD_FAILED;
441                         }
442                         DELAY(1);
443                 }
444                 if (j<0 || 
445                     fd_cmd(fdc, 3,
446                            0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
447                         fdc_reset(fdc);
448                         return fdc_err(fdc, "Enable FIFO failed\n");
449                 }
450                 fdc->flags |= FDC_HAS_FIFO;
451                 return 0;
452         }
453         if (fd_cmd(fdc, 4,
454                    I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0)
455                 return fdc_err(fdc, "Re-enable FIFO failed\n");
456         return 0;
457 }
458
459 static int
460 fd_sense_drive_status(fdc_p fdc, int *st3p)
461 {
462         int st3;
463
464         if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
465         {
466                 return fdc_err(fdc, "Sense Drive Status failed\n");
467         }
468         if (st3p)
469                 *st3p = st3;
470
471         return 0;
472 }
473
474 static int
475 fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
476 {
477         int cyl, st0, ret;
478
479         ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0);
480         if (ret) {
481                 (void)fdc_err(fdc,
482                               "sense intr err reading stat reg 0\n");
483                 return ret;
484         }
485
486         if (st0p)
487                 *st0p = st0;
488
489         if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) {
490                 /*
491                  * There doesn't seem to have been an interrupt.
492                  */
493                 return FD_NOT_VALID;
494         }
495
496         if (fd_in(fdc, &cyl) < 0) {
497                 return fdc_err(fdc, "can't get cyl num\n");
498         }
499
500         if (cylp)
501                 *cylp = cyl;
502
503         return 0;
504 }
505
506
507 static int
508 fd_read_status(fdc_p fdc, int fdsu)
509 {
510         int i, ret;
511
512         for (i = 0; i < 7; i++) {
513                 /*
514                  * XXX types are poorly chosen.  Only bytes can by read
515                  * from the hardware, but fdc->status[] wants u_ints and
516                  * fd_in() gives ints.
517                  */
518                 int status;
519
520                 ret = fd_in(fdc, &status);
521                 fdc->status[i] = status;
522                 if (ret != 0)
523                         break;
524         }
525
526         if (ret == 0)
527                 fdc->flags |= FDC_STAT_VALID;
528         else
529                 fdc->flags &= ~FDC_STAT_VALID;
530
531         return ret;
532 }
533
534 /****************************************************************************/
535 /*                      autoconfiguration stuff                             */
536 /****************************************************************************/
537
538 static int
539 fdc_alloc_resources(struct fdc_data *fdc)
540 {
541         device_t dev;
542         int ispnp, ispcmcia;
543
544         dev = fdc->fdc_dev;
545         ispnp = (fdc->flags & FDC_ISPNP) != 0;
546         ispcmcia = (fdc->flags & FDC_ISPCMCIA) != 0;
547         fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0;
548         fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0;
549
550         /*
551          * On standard ISA, we don't just use an 8 port range
552          * (e.g. 0x3f0-0x3f7) since that covers an IDE control
553          * register at 0x3f6.
554          *
555          * Isn't PC hardware wonderful.
556          *
557          * The Y-E Data PCMCIA FDC doesn't have this problem, it
558          * uses the register with offset 6 for pseudo-DMA, and the
559          * one with offset 7 as control register.
560          */
561         fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
562                                              &fdc->rid_ioport, 0ul, ~0ul, 
563                                              ispcmcia ? 8 : (ispnp ? 1 : 6),
564                                              RF_ACTIVE);
565         if (fdc->res_ioport == 0) {
566                 device_printf(dev, "cannot reserve I/O port range\n");
567                 return ENXIO;
568         }
569         fdc->portt = rman_get_bustag(fdc->res_ioport);
570         fdc->porth = rman_get_bushandle(fdc->res_ioport);
571
572         if (!ispcmcia) {
573                 /*
574                  * Some BIOSen report the device at 0x3f2-0x3f5,0x3f7
575                  * and some at 0x3f0-0x3f5,0x3f7. We detect the former
576                  * by checking the size and adjust the port address
577                  * accordingly.
578                  */
579                 if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 4)
580                         fdc->port_off = -2;
581
582                 /*
583                  * Register the control port range as rid 1 if it
584                  * isn't there already. Most PnP BIOSen will have
585                  * already done this but non-PnP configurations don't.
586                  *
587                  * And some (!!) report 0x3f2-0x3f5 and completely
588                  * leave out the control register!  It seems that some
589                  * non-antique controller chips have a different
590                  * method of programming the transfer speed which
591                  * doesn't require the control register, but it's
592                  * mighty bogus as the chip still responds to the
593                  * address for the control register.
594                  */
595                 if (bus_get_resource_count(dev, SYS_RES_IOPORT, 1) == 0) {
596                         u_long ctlstart;
597
598                         /* Find the control port, usually 0x3f7 */
599                         ctlstart = rman_get_start(fdc->res_ioport) +
600                                 fdc->port_off + 7;
601
602                         bus_set_resource(dev, SYS_RES_IOPORT, 1, ctlstart, 1);
603                 }
604
605                 /*
606                  * Now (finally!) allocate the control port.
607                  */
608                 fdc->rid_ctl = 1;
609                 fdc->res_ctl = bus_alloc_resource(dev, SYS_RES_IOPORT,
610                                                   &fdc->rid_ctl,
611                                                   0ul, ~0ul, 1, RF_ACTIVE);
612                 if (fdc->res_ctl == 0) {
613                         device_printf(dev,
614                                       "cannot reserve control I/O port range\n");
615                         return ENXIO;
616                 }
617                 fdc->ctlt = rman_get_bustag(fdc->res_ctl);
618                 fdc->ctlh = rman_get_bushandle(fdc->res_ctl);
619         }
620
621         fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ,
622                                           &fdc->rid_irq, 0ul, ~0ul, 1, 
623                                           RF_ACTIVE);
624         if (fdc->res_irq == 0) {
625                 device_printf(dev, "cannot reserve interrupt line\n");
626                 return ENXIO;
627         }
628
629         if ((fdc->flags & FDC_NODMA) == 0) {
630                 fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ,
631                                                   &fdc->rid_drq, 0ul, ~0ul, 1, 
632                                                   RF_ACTIVE);
633                 if (fdc->res_drq == 0) {
634                         device_printf(dev, "cannot reserve DMA request line\n");
635                         return ENXIO;
636                 }
637                 fdc->dmachan = fdc->res_drq->r_start;
638         }
639
640         return 0;
641 }
642
643 static void
644 fdc_release_resources(struct fdc_data *fdc)
645 {
646         device_t dev;
647
648         dev = fdc->fdc_dev;
649         if (fdc->res_irq != 0) {
650                 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
651                                         fdc->res_irq);
652                 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
653                                      fdc->res_irq);
654         }
655         if (fdc->res_ctl != 0) {
656                 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
657                                         fdc->res_ctl);
658                 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
659                                      fdc->res_ctl);
660         }
661         if (fdc->res_ioport != 0) {
662                 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
663                                         fdc->res_ioport);
664                 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
665                                      fdc->res_ioport);
666         }
667         if (fdc->res_drq != 0) {
668                 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
669                                         fdc->res_drq);
670                 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
671                                      fdc->res_drq);
672         }
673 }
674
675 /****************************************************************************/
676 /*                      autoconfiguration stuff                             */
677 /****************************************************************************/
678
679 static struct isa_pnp_id fdc_ids[] = {
680         {0x0007d041, "PC standard floppy disk controller"}, /* PNP0700 */
681         {0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */
682         {0}
683 };
684
685 static int
686 fdc_read_ivar(device_t dev, device_t child, int which, u_long *result)
687 {
688         struct fdc_ivars *ivars = device_get_ivars(child);
689
690         switch (which) {
691         case FDC_IVAR_FDUNIT:
692                 *result = ivars->fdunit;
693                 break;
694         default:
695                 return ENOENT;
696         }
697         return 0;
698 }
699
700 /*
701  * fdc controller section.
702  */
703 static int
704 fdc_probe(device_t dev)
705 {
706         int     error, ic_type;
707         struct  fdc_data *fdc;
708
709         fdc = device_get_softc(dev);
710         bzero(fdc, sizeof *fdc);
711         fdc->fdc_dev = dev;
712         fdc->fdctl_wr = fdctl_wr_isa;
713
714         /* Check pnp ids */
715         error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids);
716         if (error == ENXIO)
717                 return ENXIO;
718         if (error == 0)
719                 fdc->flags |= FDC_ISPNP;
720
721         /* Attempt to allocate our resources for the duration of the probe */
722         error = fdc_alloc_resources(fdc);
723         if (error)
724                 goto out;
725
726         /* First - lets reset the floppy controller */
727         fdout_wr(fdc, 0);
728         DELAY(100);
729         fdout_wr(fdc, FDO_FRST);
730
731         /* see if it can handle a command */
732         if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 
733                    NE7_SPEC_2(2, 0), 0)) {
734                 error = ENXIO;
735                 goto out;
736         }
737
738         if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) {
739                 ic_type = (u_char)ic_type;
740                 switch (ic_type) {
741                 case 0x80:
742                         device_set_desc(dev, "NEC 765 or clone");
743                         fdc->fdct = FDC_NE765;
744                         break;
745                 case 0x81:
746                         device_set_desc(dev, "Intel 82077 or clone");
747                         fdc->fdct = FDC_I82077;
748                         break;
749                 case 0x90:
750                         device_set_desc(dev, "NEC 72065B or clone");
751                         fdc->fdct = FDC_NE72065;
752                         break;
753                 default:
754                         device_set_desc(dev, "generic floppy controller");
755                         fdc->fdct = FDC_UNKNOWN;
756                         break;
757                 }
758         }
759
760 out:
761         fdc_release_resources(fdc);
762         return (error);
763 }
764
765 #if NCARD > 0
766
767 static int
768 fdc_pccard_probe(device_t dev)
769 {
770         int     error;
771         struct  fdc_data *fdc;
772
773         fdc = device_get_softc(dev);
774         bzero(fdc, sizeof *fdc);
775         fdc->fdc_dev = dev;
776         fdc->fdctl_wr = fdctl_wr_pcmcia;
777
778         fdc->flags |= FDC_ISPCMCIA | FDC_NODMA;
779
780         /* Attempt to allocate our resources for the duration of the probe */
781         error = fdc_alloc_resources(fdc);
782         if (error)
783                 goto out;
784
785         /* First - lets reset the floppy controller */
786         fdout_wr(fdc, 0);
787         DELAY(100);
788         fdout_wr(fdc, FDO_FRST);
789
790         /* see if it can handle a command */
791         if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 
792                    NE7_SPEC_2(2, 0), 0)) {
793                 error = ENXIO;
794                 goto out;
795         }
796
797         device_set_desc(dev, "Y-E Data PCMCIA floppy");
798         fdc->fdct = FDC_NE765;
799
800 out:
801         fdc_release_resources(fdc);
802         return (error);
803 }
804
805 static int
806 fdc_pccard_detach(device_t dev)
807 {
808         struct  fdc_data *fdc;
809         int     error;
810
811         fdc = device_get_softc(dev);
812
813         /* have our children detached first */
814         if ((error = bus_generic_detach(dev)))
815                 return (error);
816
817         if ((fdc->flags & FDC_ATTACHED) == 0) {
818                 device_printf(dev, "already unloaded\n");
819                 return (0);
820         }
821         fdc->flags &= ~FDC_ATTACHED;
822
823         BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
824                           fdc->fdc_intr);
825         fdc_release_resources(fdc);
826         device_printf(dev, "unload\n");
827         return (0);
828 }
829
830 #endif /* NCARD > 0 */
831
832 /*
833  * Add a child device to the fdc controller.  It will then be probed etc.
834  */
835 static void
836 fdc_add_child(device_t dev, const char *name, int unit)
837 {
838         int     disabled;
839         struct fdc_ivars *ivar;
840         device_t child;
841
842         ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT);
843         if (ivar == NULL)
844                 return;
845         bzero(ivar, sizeof *ivar);
846         if (resource_int_value(name, unit, "drive", &ivar->fdunit) != 0)
847                 ivar->fdunit = 0;
848         child = device_add_child(dev, name, unit);
849         if (child == NULL)
850                 return;
851         device_set_ivars(child, ivar);
852         if (resource_int_value(name, unit, "disabled", &disabled) == 0
853             && disabled != 0)
854                 device_disable(child);
855 }
856
857 static int
858 fdc_attach(device_t dev)
859 {
860         struct  fdc_data *fdc;
861         int     i, error;
862
863         fdc = device_get_softc(dev);
864         error = fdc_alloc_resources(fdc);
865         if (error) {
866                 device_printf(dev, "cannot re-aquire resources\n");
867                 return error;
868         }
869         error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
870                                INTR_TYPE_BIO, fdc_intr, fdc, &fdc->fdc_intr);
871         if (error) {
872                 device_printf(dev, "cannot setup interrupt\n");
873                 return error;
874         }
875         fdc->fdcu = device_get_unit(dev);
876         fdc->flags |= FDC_ATTACHED;
877
878         if ((fdc->flags & FDC_NODMA) == 0) {
879                 /* Acquire the DMA channel forever, The driver will do the rest */
880                                 /* XXX should integrate with rman */
881                 isa_dma_acquire(fdc->dmachan);
882                 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
883         }
884         fdc->state = DEVIDLE;
885
886         /* reset controller, turn motor off, clear fdout mirror reg */
887         fdout_wr(fdc, ((fdc->fdout = 0)));
888         bufq_init(&fdc->head);
889
890         /*
891          * Probe and attach any children.  We should probably detect
892          * devices from the BIOS unless overridden.
893          */
894         for (i = resource_query_string(-1, "at", device_get_nameunit(dev));
895              i != -1;
896              i = resource_query_string(i, "at", device_get_nameunit(dev)))
897                 fdc_add_child(dev, resource_query_name(i),
898                                resource_query_unit(i));
899
900         return (bus_generic_attach(dev));
901 }
902
903 static int
904 fdc_print_child(device_t me, device_t child)
905 {
906         int retval = 0;
907
908         retval += bus_print_child_header(me, child);
909         retval += printf(" on %s drive %d\n", device_get_nameunit(me),
910                fdc_get_fdunit(child));
911         
912         return (retval);
913 }
914
915 static device_method_t fdc_methods[] = {
916         /* Device interface */
917         DEVMETHOD(device_probe,         fdc_probe),
918         DEVMETHOD(device_attach,        fdc_attach),
919         DEVMETHOD(device_detach,        bus_generic_detach),
920         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
921         DEVMETHOD(device_suspend,       bus_generic_suspend),
922         DEVMETHOD(device_resume,        bus_generic_resume),
923
924         /* Bus interface */
925         DEVMETHOD(bus_print_child,      fdc_print_child),
926         DEVMETHOD(bus_read_ivar,        fdc_read_ivar),
927         /* Our children never use any other bus interface methods. */
928
929         { 0, 0 }
930 };
931
932 static driver_t fdc_driver = {
933         "fdc",
934         fdc_methods,
935         sizeof(struct fdc_data)
936 };
937
938 DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0);
939
940 #if NCARD > 0
941
942 static device_method_t fdc_pccard_methods[] = {
943         /* Device interface */
944         DEVMETHOD(device_probe,         fdc_pccard_probe),
945         DEVMETHOD(device_attach,        fdc_attach),
946         DEVMETHOD(device_detach,        fdc_pccard_detach),
947         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
948         DEVMETHOD(device_suspend,       bus_generic_suspend),
949         DEVMETHOD(device_resume,        bus_generic_resume),
950
951         /* Bus interface */
952         DEVMETHOD(bus_print_child,      fdc_print_child),
953         DEVMETHOD(bus_read_ivar,        fdc_read_ivar),
954         /* Our children never use any other bus interface methods. */
955
956         { 0, 0 }
957 };
958
959 static driver_t fdc_pccard_driver = {
960         "fdc",
961         fdc_pccard_methods,
962         sizeof(struct fdc_data)
963 };
964
965 DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0);
966
967 #endif /* NCARD > 0 */
968
969 /******************************************************************/
970 /*
971  * devices attached to the controller section.  
972  */
973 static int
974 fd_probe(device_t dev)
975 {
976         int     i;
977         u_int   fdt, st0, st3;
978         struct  fd_data *fd;
979         struct  fdc_data *fdc;
980         fdsu_t  fdsu;
981         static int fd_fifo = 0;
982
983         fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */
984         fd = device_get_softc(dev);
985         fdc = device_get_softc(device_get_parent(dev));
986
987         bzero(fd, sizeof *fd);
988         fd->dev = dev;
989         fd->fdc = fdc;
990         fd->fdsu = fdsu;
991         fd->fdu = device_get_unit(dev);
992
993 #ifdef __i386__
994         /* look up what bios thinks we have */
995         switch (fd->fdu) {
996         case 0:
997                 if ((fdc->flags & FDC_ISPCMCIA))
998                         fdt = RTCFDT_144M;
999                 else if (device_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0)
1000                         fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED;
1001                 else
1002                         fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
1003                 break;
1004         case 1:
1005                 fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
1006                 break;
1007         default:
1008                 fdt = RTCFDT_NONE;
1009                 break;
1010         }
1011 #else
1012         fdt = RTCFDT_144M;      /* XXX probably */
1013 #endif
1014
1015         /* is there a unit? */
1016         if (fdt == RTCFDT_NONE)
1017                 return (ENXIO);
1018
1019         /* select it */
1020         set_motor(fdc, fdsu, TURNON);
1021         DELAY(1000000); /* 1 sec */
1022
1023         /* XXX This doesn't work before the first set_motor() */
1024         if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN
1025             && (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0
1026             && enable_fifo(fdc) == 0) {
1027                 device_printf(device_get_parent(dev),
1028                     "FIFO enabled, %d bytes threshold\n", fifo_threshold);
1029         }
1030         fd_fifo = 1;
1031
1032         if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0)
1033             && (st3 & NE7_ST3_T0)) {
1034                 /* if at track 0, first seek inwards */
1035                 /* seek some steps: */
1036                 fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0);
1037                 DELAY(300000); /* ...wait a moment... */
1038                 fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
1039         }
1040
1041         /* If we're at track 0 first seek inwards. */
1042         if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) {
1043                 /* Seek some steps... */
1044                 if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
1045                         /* ...wait a moment... */
1046                         DELAY(300000);
1047                         /* make ctrlr happy: */
1048                         fd_sense_int(fdc, 0, 0);
1049                 }
1050         }
1051
1052         for (i = 0; i < 2; i++) {
1053                 /*
1054                  * we must recalibrate twice, just in case the
1055                  * heads have been beyond cylinder 76, since most
1056                  * FDCs still barf when attempting to recalibrate
1057                  * more than 77 steps
1058                  */
1059                 /* go back to 0: */
1060                 if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
1061                         /* a second being enough for full stroke seek*/
1062                         DELAY(i == 0 ? 1000000 : 300000);
1063
1064                         /* anything responding? */
1065                         if (fd_sense_int(fdc, &st0, 0) == 0 &&
1066                             (st0 & NE7_ST0_EC) == 0)
1067                                 break; /* already probed succesfully */
1068                 }
1069         }
1070
1071         set_motor(fdc, fdsu, TURNOFF);
1072
1073         if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
1074                 return (ENXIO);
1075
1076         fd->track = FD_NO_TRACK;
1077         fd->fdc = fdc;
1078         fd->fdsu = fdsu;
1079         fd->options = 0;
1080         callout_handle_init(&fd->toffhandle);
1081         callout_handle_init(&fd->tohandle);
1082
1083         switch (fdt) {
1084         case RTCFDT_12M:
1085                 device_set_desc(dev, "1200-KB 5.25\" drive");
1086                 fd->type = FD_1200;
1087                 break;
1088         case RTCFDT_144M | RTCFDT_144M_PRETENDED:
1089                 device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive");
1090                 fdt = RTCFDT_144M;
1091                 fd->type = FD_1440;
1092         case RTCFDT_144M:
1093                 device_set_desc(dev, "1440-KB 3.5\" drive");
1094                 fd->type = FD_1440;
1095                 break;
1096         case RTCFDT_288M:
1097         case RTCFDT_288M_1:
1098                 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
1099                 fd->type = FD_1440;
1100                 break;
1101         case RTCFDT_360K:
1102                 device_set_desc(dev, "360-KB 5.25\" drive");
1103                 fd->type = FD_360;
1104                 break;
1105         case RTCFDT_720K:
1106                 printf("720-KB 3.5\" drive");
1107                 fd->type = FD_720;
1108                 break;
1109         default:
1110                 return (ENXIO);
1111         }
1112         return (0);
1113 }
1114
1115 static int
1116 fd_attach(device_t dev)
1117 {
1118         struct  fd_data *fd;
1119 #if 0
1120         int     i;
1121         int     mynor;
1122         int     typemynor;
1123         int     typesize;
1124 #endif
1125         static int cdevsw_add_done = 0;
1126
1127         fd = device_get_softc(dev);
1128
1129         if (!cdevsw_add_done) {
1130                 cdevsw_add(&fd_cdevsw); /* XXX */
1131                 cdevsw_add_done++;
1132         }
1133         make_dev(&fd_cdevsw, (fd->fdu << 6),
1134                 UID_ROOT, GID_OPERATOR, 0640, "rfd%d", fd->fdu);
1135
1136 #if 0
1137         /* Other make_dev() go here. */
1138 #endif
1139
1140         /*
1141          * Export the drive to the devstat interface.
1142          */
1143         devstat_add_entry(&fd->device_stats, device_get_name(dev), 
1144                           device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS,
1145                           DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER,
1146                           DEVSTAT_PRIORITY_FD);
1147         return (0);
1148 }
1149
1150 static int
1151 fd_detach(device_t dev)
1152 {
1153         struct  fd_data *fd;
1154
1155         fd = device_get_softc(dev);
1156         untimeout(fd_turnoff, fd, fd->toffhandle);
1157
1158         return (0);
1159 }
1160
1161 static device_method_t fd_methods[] = {
1162         /* Device interface */
1163         DEVMETHOD(device_probe,         fd_probe),
1164         DEVMETHOD(device_attach,        fd_attach),
1165         DEVMETHOD(device_detach,        fd_detach),
1166         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
1167         DEVMETHOD(device_suspend,       bus_generic_suspend), /* XXX */
1168         DEVMETHOD(device_resume,        bus_generic_resume), /* XXX */
1169
1170         { 0, 0 }
1171 };
1172
1173 static driver_t fd_driver = {
1174         "fd",
1175         fd_methods,
1176         sizeof(struct fd_data)
1177 };
1178
1179 DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, 0, 0);
1180
1181 /****************************************************************************/
1182 /*                            motor control stuff                           */
1183 /*              remember to not deselect the drive we're working on         */
1184 /****************************************************************************/
1185 static void
1186 set_motor(struct fdc_data *fdc, int fdsu, int turnon)
1187 {
1188         int fdout = fdc->fdout;
1189         int needspecify = 0;
1190
1191         if(turnon) {
1192                 fdout &= ~FDO_FDSEL;
1193                 fdout |= (FDO_MOEN0 << fdsu) + fdsu;
1194         } else
1195                 fdout &= ~(FDO_MOEN0 << fdsu);
1196
1197         if(!turnon
1198            && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0)
1199                 /* gonna turn off the last drive, put FDC to bed */
1200                 fdout &= ~ (FDO_FRST|FDO_FDMAEN);
1201         else {
1202                 /* make sure controller is selected and specified */
1203                 if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0)
1204                         needspecify = 1;
1205                 fdout |= (FDO_FRST|FDO_FDMAEN);
1206         }
1207
1208         fdout_wr(fdc, fdout);
1209         fdc->fdout = fdout;
1210         TRACE1("[0x%x->FDOUT]", fdout);
1211
1212         if (needspecify) {
1213                 /*
1214                  * XXX
1215                  * special case: since we have just woken up the FDC
1216                  * from its sleep, we silently assume the command will
1217                  * be accepted, and do not test for a timeout
1218                  */
1219                 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
1220                              NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
1221                              0);
1222                 if (fdc->flags & FDC_HAS_FIFO)
1223                         (void) enable_fifo(fdc);
1224         }
1225 }
1226
1227 static void
1228 fd_turnoff(void *xfd)
1229 {
1230         int     s;
1231         fd_p fd = xfd;
1232
1233         TRACE1("[fd%d: turnoff]", fd->fdu);
1234
1235         s = splbio();
1236         /*
1237          * Don't turn off the motor yet if the drive is active.
1238          *
1239          * If we got here, this could only mean we missed an interrupt.
1240          * This can e. g. happen on the Y-E Date PCMCIA floppy controller
1241          * after a controller reset.  Just schedule a pseudo-interrupt
1242          * so the state machine gets re-entered.
1243          */
1244         if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) {
1245                 fdc_intr(fd->fdc);
1246                 splx(s);
1247                 return;
1248         }
1249
1250         fd->flags &= ~FD_MOTOR;
1251         set_motor(fd->fdc, fd->fdsu, TURNOFF);
1252         splx(s);
1253 }
1254
1255 static void
1256 fd_motor_on(void *xfd)
1257 {
1258         int     s;
1259         fd_p fd = xfd;
1260
1261         s = splbio();
1262         fd->flags &= ~FD_MOTOR_WAIT;
1263         if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT))
1264         {
1265                 fdc_intr(fd->fdc);
1266         }
1267         splx(s);
1268 }
1269
1270 static void
1271 fd_turnon(fd_p fd)
1272 {
1273         if(!(fd->flags & FD_MOTOR))
1274         {
1275                 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
1276                 set_motor(fd->fdc, fd->fdsu, TURNON);
1277                 timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */
1278         }
1279 }
1280
1281 static void
1282 fdc_reset(fdc_p fdc)
1283 {
1284         /* Try a reset, keep motor on */
1285         fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
1286         TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
1287         DELAY(100);
1288         /* enable FDC, but defer interrupts a moment */
1289         fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
1290         TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN);
1291         DELAY(100);
1292         fdout_wr(fdc, fdc->fdout);
1293         TRACE1("[0x%x->FDOUT]", fdc->fdout);
1294
1295         /* XXX after a reset, silently believe the FDC will accept commands */
1296         (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
1297                      NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
1298                      0);
1299         if (fdc->flags & FDC_HAS_FIFO)
1300                 (void) enable_fifo(fdc);
1301 }
1302
1303 /****************************************************************************/
1304 /*                             fdc in/out                                   */
1305 /****************************************************************************/
1306 /*
1307  * FDC IO functions, take care of the main status register, timeout
1308  * in case the desired status bits are never set.
1309  *
1310  * These PIO loops initially start out with short delays between
1311  * each iteration in the expectation that the required condition
1312  * is usually met quickly, so it can be handled immediately.  After
1313  * about 1 ms, stepping is increased to achieve a better timing
1314  * accuracy in the calls to DELAY().
1315  */
1316 static int
1317 fd_in(struct fdc_data *fdc, int *ptr)
1318 {
1319         int i, j, step;
1320
1321         for (j = 0, step = 1;
1322             (i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM) &&
1323             j < FDSTS_TIMEOUT;
1324             j += step) {
1325                 if (i == NE7_RQM)
1326                         return (fdc_err(fdc, "ready for output in input\n"));
1327                 if (j == 1000)
1328                         step = 1000;
1329                 DELAY(step);
1330         }
1331         if (j >= FDSTS_TIMEOUT)
1332                 return (fdc_err(fdc, bootverbose? "input ready timeout\n": 0));
1333 #ifdef  FDC_DEBUG
1334         i = fddata_rd(fdc);
1335         TRACE1("[FDDATA->0x%x]", (unsigned char)i);
1336         *ptr = i;
1337         return (0);
1338 #else   /* !FDC_DEBUG */
1339         i = fddata_rd(fdc);
1340         if (ptr)
1341                 *ptr = i;
1342         return (0);
1343 #endif  /* FDC_DEBUG */
1344 }
1345
1346 static int
1347 out_fdc(struct fdc_data *fdc, int x)
1348 {
1349         int i, j, step;
1350
1351         for (j = 0, step = 1;
1352             (i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) != NE7_RQM &&
1353             j < FDSTS_TIMEOUT;
1354             j += step) {
1355                 if (i == (NE7_DIO|NE7_RQM))
1356                         return (fdc_err(fdc, "ready for input in output\n"));
1357                 if (j == 1000)
1358                         step = 1000;
1359                 DELAY(step);
1360         }
1361         if (j >= FDSTS_TIMEOUT)
1362                 return (fdc_err(fdc, bootverbose? "output ready timeout\n": 0));
1363
1364         /* Send the command and return */
1365         fddata_wr(fdc, x);
1366         TRACE1("[0x%x->FDDATA]", x);
1367         return (0);
1368 }
1369
1370 /****************************************************************************/
1371 /*                           fdopen/fdclose                                 */
1372 /****************************************************************************/
1373 int
1374 Fdopen(dev_t dev, int flags, int mode, struct proc *p)
1375 {
1376         fdu_t fdu = FDUNIT(minor(dev));
1377         int type = FDTYPE(minor(dev));
1378         fd_p    fd;
1379         fdc_p   fdc;
1380
1381         /* check bounds */
1382         if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0)
1383                 return (ENXIO);
1384         fdc = fd->fdc;
1385         if ((fdc == NULL) || (fd->type == NO_TYPE))
1386                 return (ENXIO);
1387         if (type > NUMDENS)
1388                 return (ENXIO);
1389         if (type == 0)
1390                 type = fd->type;
1391         else {
1392                 /*
1393                  * For each type of basic drive, make sure we are trying
1394                  * to open a type it can do,
1395                  */
1396                 if (type != fd->type) {
1397                         switch (fd->type) {
1398                         case FD_360:
1399                                 return (ENXIO);
1400                         case FD_720:
1401                                 if (   type != FD_820
1402                                     && type != FD_800
1403                                     && type != FD_640
1404                                    )
1405                                         return (ENXIO);
1406                                 break;
1407                         case FD_1200:
1408                                 switch (type) {
1409                                 case FD_1480:
1410                                         type = FD_1480in5_25;
1411                                         break;
1412                                 case FD_1440:
1413                                         type = FD_1440in5_25;
1414                                         break;
1415                                 case FD_1232:
1416                                         break;
1417                                 case FD_820:
1418                                         type = FD_820in5_25;
1419                                         break;
1420                                 case FD_800:
1421                                         type = FD_800in5_25;
1422                                         break;
1423                                 case FD_720:
1424                                         type = FD_720in5_25;
1425                                         break;
1426                                 case FD_640:
1427                                         type = FD_640in5_25;
1428                                         break;
1429                                 case FD_360:
1430                                         type = FD_360in5_25;
1431                                         break;
1432                                 default:
1433                                         return(ENXIO);
1434                                 }
1435                                 break;
1436                         case FD_1440:
1437                                 if (   type != FD_1720
1438                                     && type != FD_1480
1439                                     && type != FD_1200
1440                                     && type != FD_820
1441                                     && type != FD_800
1442                                     && type != FD_720
1443                                     && type != FD_640
1444                                     )
1445                                         return(ENXIO);
1446                                 break;
1447                         }
1448                 }
1449         }
1450         fd->ft = fd_types + type - 1;
1451         fd->flags |= FD_OPEN;
1452         /*
1453          * Clearing the DMA overrun counter at open time is a bit messy.
1454          * Since we're only managing one counter per controller, opening
1455          * the second drive could mess it up.  Anyway, if the DMA overrun
1456          * condition is really persistent, it will eventually time out
1457          * still.  OTOH, clearing it here will ensure we'll at least start
1458          * trying again after a previous (maybe even long ago) failure.
1459          * Also, this is merely a stop-gap measure only that should not
1460          * happen during normal operation, so we can tolerate it to be a
1461          * bit sloppy about this.
1462          */
1463         fdc->dma_overruns = 0;
1464
1465         return 0;
1466 }
1467
1468 int
1469 fdclose(dev_t dev, int flags, int mode, struct proc *p)
1470 {
1471         fdu_t fdu = FDUNIT(minor(dev));
1472         struct fd_data *fd;
1473
1474         fd = devclass_get_softc(fd_devclass, fdu);
1475         fd->flags &= ~FD_OPEN;
1476         fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG);
1477
1478         return (0);
1479 }
1480
1481 /****************************************************************************/
1482 /*                               fdstrategy                                 */
1483 /****************************************************************************/
1484 void
1485 fdstrategy(struct buf *bp)
1486 {
1487         unsigned nblocks, blknum, cando;
1488         int     s;
1489         fdu_t   fdu;
1490         fdc_p   fdc;
1491         fd_p    fd;
1492         size_t  fdblk;
1493
1494         fdu = FDUNIT(minor(bp->b_dev));
1495         fd = devclass_get_softc(fd_devclass, fdu);
1496         if (fd == 0)
1497                 panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)",
1498                       (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev));
1499         fdc = fd->fdc;
1500         if (fd->type == NO_TYPE) {
1501                 bp->b_error = ENXIO;
1502                 bp->b_flags |= B_ERROR;
1503                 goto bad;
1504         };
1505
1506         fdblk = 128 << (fd->ft->secsize);
1507         if (!(bp->b_flags & B_FORMAT)) {
1508                 if (bp->b_blkno < 0) {
1509                         printf(
1510                 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n",
1511                                fdu, (u_long)bp->b_blkno, bp->b_bcount);
1512                         bp->b_error = EINVAL;
1513                         bp->b_flags |= B_ERROR;
1514                         goto bad;
1515                 }
1516                 if ((bp->b_bcount % fdblk) != 0) {
1517                         bp->b_error = EINVAL;
1518                         bp->b_flags |= B_ERROR;
1519                         goto bad;
1520                 }
1521         }
1522
1523         /*
1524          * Set up block calculations.
1525          */
1526         if (bp->b_blkno > 20000000) {
1527                 /*
1528                  * Reject unreasonably high block number, prevent the
1529                  * multiplication below from overflowing.
1530                  */
1531                 bp->b_error = EINVAL;
1532                 bp->b_flags |= B_ERROR;
1533                 goto bad;
1534         }
1535         blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk;
1536         nblocks = fd->ft->size;
1537         bp->b_resid = 0;
1538         if (blknum + (bp->b_bcount / fdblk) > nblocks) {
1539                 if (blknum <= nblocks) {
1540                         cando = (nblocks - blknum) * fdblk;
1541                         bp->b_resid = bp->b_bcount - cando;
1542                         if (cando == 0)
1543                                 goto bad;       /* not actually bad but EOF */
1544                 } else {
1545                         bp->b_error = EINVAL;
1546                         bp->b_flags |= B_ERROR;
1547                         goto bad;
1548                 }
1549         }
1550         bp->b_pblkno = bp->b_blkno;
1551         s = splbio();
1552         bufqdisksort(&fdc->head, bp);
1553         untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
1554
1555         /* Tell devstat we are starting on the transaction */
1556         devstat_start_transaction(&fd->device_stats);
1557         device_busy(fd->dev);
1558
1559         fdstart(fdc);
1560         splx(s);
1561         return;
1562
1563 bad:
1564         biodone(bp);
1565 }
1566
1567 /***************************************************************\
1568 *                               fdstart                         *
1569 * We have just queued something.. if the controller is not busy *
1570 * then simulate the case where it has just finished a command   *
1571 * So that it (the interrupt routine) looks on the queue for more*
1572 * work to do and picks up what we just added.                   *
1573 * If the controller is already busy, we need do nothing, as it  *
1574 * will pick up our work when the present work completes         *
1575 \***************************************************************/
1576 static void
1577 fdstart(struct fdc_data *fdc)
1578 {
1579         int s;
1580
1581         s = splbio();
1582         if(fdc->state == DEVIDLE)
1583         {
1584                 fdc_intr(fdc);
1585         }
1586         splx(s);
1587 }
1588
1589 static void
1590 fd_iotimeout(void *xfdc)
1591 {
1592         fdc_p fdc;
1593         int s;
1594
1595         fdc = xfdc;
1596         TRACE1("fd%d[fd_iotimeout()]", fdc->fdu);
1597
1598         /*
1599          * Due to IBM's brain-dead design, the FDC has a faked ready
1600          * signal, hardwired to ready == true. Thus, any command
1601          * issued if there's no diskette in the drive will _never_
1602          * complete, and must be aborted by resetting the FDC.
1603          * Many thanks, Big Blue!
1604          * The FDC must not be reset directly, since that would
1605          * interfere with the state machine.  Instead, pretend that
1606          * the command completed but was invalid.  The state machine
1607          * will reset the FDC and retry once.
1608          */
1609         s = splbio();
1610         fdc->status[0] = NE7_ST0_IC_IV;
1611         fdc->flags &= ~FDC_STAT_VALID;
1612         fdc->state = IOTIMEDOUT;
1613         fdc_intr(fdc);
1614         splx(s);
1615 }
1616
1617 /* just ensure it has the right spl */
1618 static void
1619 fd_pseudointr(void *xfdc)
1620 {
1621         int     s;
1622
1623         s = splbio();
1624         fdc_intr(xfdc);
1625         splx(s);
1626 }
1627
1628 /***********************************************************************\
1629 *                                 fdintr                                *
1630 * keep calling the state machine until it returns a 0                   *
1631 * ALWAYS called at SPLBIO                                               *
1632 \***********************************************************************/
1633 static void
1634 fdc_intr(void *xfdc)
1635 {
1636         fdc_p fdc = xfdc;
1637         while(fdstate(fdc))
1638                 ;
1639 }
1640
1641 /*
1642  * magic pseudo-DMA initialization for YE FDC. Sets count and
1643  * direction
1644  */
1645 #define SET_BCDR(fdc,wr,cnt,port) \
1646         bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port,  \
1647             ((cnt)-1) & 0xff);                                           \
1648         bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port + 1, \
1649             ((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f)));
1650
1651 /*
1652  * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy
1653  */
1654 static int fdcpio(fdc_p fdc, long flags, caddr_t addr, u_int count)
1655 {
1656         u_char *cptr = (u_char *)addr;
1657
1658         if (flags & B_READ) {
1659                 if (fdc->state != PIOREAD) {
1660                         fdc->state = PIOREAD;
1661                         return(0);
1662                 };
1663                 SET_BCDR(fdc, 0, count, 0);
1664                 bus_space_read_multi_1(fdc->portt, fdc->porth, fdc->port_off +
1665                     FDC_YE_DATAPORT, cptr, count);
1666         } else {
1667                 bus_space_write_multi_1(fdc->portt, fdc->porth, fdc->port_off +
1668                     FDC_YE_DATAPORT, cptr, count);
1669                 SET_BCDR(fdc, 0, count, 0);
1670         };
1671         return(1);
1672 }
1673
1674 /***********************************************************************\
1675 * The controller state machine.                                         *
1676 * if it returns a non zero value, it should be called again immediatly  *
1677 \***********************************************************************/
1678 static int
1679 fdstate(fdc_p fdc)
1680 {
1681         int read, format, head, i, sec = 0, sectrac, st0, cyl, st3;
1682         unsigned blknum = 0, b_cylinder = 0;
1683         fdu_t fdu = fdc->fdu;
1684         fd_p fd;
1685         register struct buf *bp;
1686         struct fd_formb *finfo = NULL;
1687         size_t fdblk;
1688
1689         bp = fdc->bp;
1690         if (bp == NULL) {
1691                 bp = bufq_first(&fdc->head);
1692                 if (bp != NULL) {
1693                         bufq_remove(&fdc->head, bp);
1694                         fdc->bp = bp;
1695                 }
1696         }
1697         if (bp == NULL) {
1698                 /***********************************************\
1699                 * nothing left for this controller to do        *
1700                 * Force into the IDLE state,                    *
1701                 \***********************************************/
1702                 fdc->state = DEVIDLE;
1703                 if (fdc->fd) {
1704                         device_printf(fdc->fdc_dev,
1705                             "unexpected valid fd pointer\n");
1706                         fdc->fd = (fd_p) 0;
1707                         fdc->fdu = -1;
1708                 }
1709                 TRACE1("[fdc%d IDLE]", fdc->fdcu);
1710                 return (0);
1711         }
1712         fdu = FDUNIT(minor(bp->b_dev));
1713         fd = devclass_get_softc(fd_devclass, fdu);
1714         fdblk = 128 << fd->ft->secsize;
1715         if (fdc->fd && (fd != fdc->fd))
1716                 device_printf(fd->dev, "confused fd pointers\n");
1717         read = bp->b_flags & B_READ;
1718         format = bp->b_flags & B_FORMAT;
1719         if (format) {
1720                 finfo = (struct fd_formb *)bp->b_data;
1721                 fd->skip = (char *)&(finfo->fd_formb_cylno(0))
1722                         - (char *)finfo;
1723         }
1724         if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) {
1725                 blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk +
1726                         fd->skip/fdblk;
1727                 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
1728         }
1729         TRACE1("fd%d", fdu);
1730         TRACE1("[%s]", fdstates[fdc->state]);
1731         TRACE1("(0x%x)", fd->flags);
1732         untimeout(fd_turnoff, fd, fd->toffhandle);
1733         fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
1734         switch (fdc->state)
1735         {
1736         case DEVIDLE:
1737         case FINDWORK:  /* we have found new work */
1738                 fdc->retry = 0;
1739                 fd->skip = 0;
1740                 fdc->fd = fd;
1741                 fdc->fdu = fdu;
1742                 fdc->fdctl_wr(fdc, fd->ft->trans);
1743                 TRACE1("[0x%x->FDCTL]", fd->ft->trans);
1744                 /*******************************************************\
1745                 * If the next drive has a motor startup pending, then   *
1746                 * it will start up in its own good time         *
1747                 \*******************************************************/
1748                 if(fd->flags & FD_MOTOR_WAIT) {
1749                         fdc->state = MOTORWAIT;
1750                         return (0); /* come back later */
1751                 }
1752                 /*******************************************************\
1753                 * Maybe if it's not starting, it SHOULD be starting     *
1754                 \*******************************************************/
1755                 if (!(fd->flags & FD_MOTOR))
1756                 {
1757                         fdc->state = MOTORWAIT;
1758                         fd_turnon(fd);
1759                         return (0);
1760                 }
1761                 else    /* at least make sure we are selected */
1762                 {
1763                         set_motor(fdc, fd->fdsu, TURNON);
1764                 }
1765                 if (fdc->flags & FDC_NEEDS_RESET) {
1766                         fdc->state = RESETCTLR;
1767                         fdc->flags &= ~FDC_NEEDS_RESET;
1768                 } else
1769                         fdc->state = DOSEEK;
1770                 break;
1771         case DOSEEK:
1772                 if (b_cylinder == (unsigned)fd->track)
1773                 {
1774                         fdc->state = SEEKCOMPLETE;
1775                         break;
1776                 }
1777                 if (fd_cmd(fdc, 3, NE7CMD_SEEK,
1778                            fd->fdsu, b_cylinder * fd->ft->steptrac,
1779                            0))
1780                 {
1781                         /*
1782                          * seek command not accepted, looks like
1783                          * the FDC went off to the Saints...
1784                          */
1785                         fdc->retry = 6; /* try a reset */
1786                         return(retrier(fdc));
1787                 }
1788                 fd->track = FD_NO_TRACK;
1789                 fdc->state = SEEKWAIT;
1790                 return(0);      /* will return later */
1791         case SEEKWAIT:
1792                 /* allow heads to settle */
1793                 timeout(fd_pseudointr, fdc, hz / 16);
1794                 fdc->state = SEEKCOMPLETE;
1795                 return(0);      /* will return later */
1796         case SEEKCOMPLETE : /* SEEK DONE, START DMA */
1797                 /* Make sure seek really happened*/
1798                 if(fd->track == FD_NO_TRACK) {
1799                         int descyl = b_cylinder * fd->ft->steptrac;
1800                         do {
1801                                 /*
1802                                  * This might be a "ready changed" interrupt,
1803                                  * which cannot really happen since the
1804                                  * RDY pin is hardwired to + 5 volts.  This
1805                                  * generally indicates a "bouncing" intr
1806                                  * line, so do one of the following:
1807                                  *
1808                                  * When running on an enhanced FDC that is
1809                                  * known to not go stuck after responding
1810                                  * with INVALID, fetch all interrupt states
1811                                  * until seeing either an INVALID or a
1812                                  * real interrupt condition.
1813                                  *
1814                                  * When running on a dumb old NE765, give
1815                                  * up immediately.  The controller will
1816                                  * provide up to four dummy RC interrupt
1817                                  * conditions right after reset (for the
1818                                  * corresponding four drives), so this is
1819                                  * our only chance to get notice that it
1820                                  * was not the FDC that caused the interrupt.
1821                                  */
1822                                 if (fd_sense_int(fdc, &st0, &cyl)
1823                                     == FD_NOT_VALID)
1824                                         return 0;
1825                                 if(fdc->fdct == FDC_NE765
1826                                    && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
1827                                         return 0; /* hope for a real intr */
1828                         } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
1829
1830                         if (0 == descyl) {
1831                                 int failed = 0;
1832                                 /*
1833                                  * seek to cyl 0 requested; make sure we are
1834                                  * really there
1835                                  */
1836                                 if (fd_sense_drive_status(fdc, &st3))
1837                                         failed = 1;
1838                                 if ((st3 & NE7_ST3_T0) == 0) {
1839                                         printf(
1840                 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n",
1841                                                fdu, st3, NE7_ST3BITS);
1842                                         failed = 1;
1843                                 }
1844
1845                                 if (failed) {
1846                                         if(fdc->retry < 3)
1847                                                 fdc->retry = 3;
1848                                         return (retrier(fdc));
1849                                 }
1850                         }
1851
1852                         if (cyl != descyl) {
1853                                 printf(
1854                 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
1855                                        fdu, descyl, cyl, st0);
1856                                 if (fdc->retry < 3)
1857                                         fdc->retry = 3;
1858                                 return (retrier(fdc));
1859                         }
1860                 }
1861
1862                 fd->track = b_cylinder;
1863                 if (!(fdc->flags & FDC_NODMA))
1864                         isa_dmastart(bp->b_flags, bp->b_data+fd->skip,
1865                                 format ? bp->b_bcount : fdblk, fdc->dmachan);
1866                 sectrac = fd->ft->sectrac;
1867                 sec = blknum %  (sectrac * fd->ft->heads);
1868                 head = sec / sectrac;
1869                 sec = sec % sectrac + 1;
1870                 fd->hddrv = ((head&1)<<2)+fdu;
1871
1872                 if(format || !read)
1873                 {
1874                         /* make sure the drive is writable */
1875                         if(fd_sense_drive_status(fdc, &st3) != 0)
1876                         {
1877                                 /* stuck controller? */
1878                                 if (!(fdc->flags & FDC_NODMA))
1879                                         isa_dmadone(bp->b_flags,
1880                                                     bp->b_data + fd->skip,
1881                                                     format ? bp->b_bcount : fdblk,
1882                                                     fdc->dmachan);
1883                                 fdc->retry = 6; /* reset the beast */
1884                                 return (retrier(fdc));
1885                         }
1886                         if(st3 & NE7_ST3_WP)
1887                         {
1888                                 /*
1889                                  * XXX YES! this is ugly.
1890                                  * in order to force the current operation
1891                                  * to fail, we will have to fake an FDC
1892                                  * error - all error handling is done
1893                                  * by the retrier()
1894                                  */
1895                                 fdc->status[0] = NE7_ST0_IC_AT;
1896                                 fdc->status[1] = NE7_ST1_NW;
1897                                 fdc->status[2] = 0;
1898                                 fdc->status[3] = fd->track;
1899                                 fdc->status[4] = head;
1900                                 fdc->status[5] = sec;
1901                                 fdc->retry = 8; /* break out immediately */
1902                                 fdc->state = IOTIMEDOUT; /* not really... */
1903                                 return (1);
1904                         }
1905                 }
1906
1907                 if (format) {
1908                         if (fdc->flags & FDC_NODMA) {
1909                                 /*
1910                                  * This seems to be necessary for
1911                                  * whatever obscure reason; if we omit
1912                                  * it, we end up filling the sector ID
1913                                  * fields of the newly formatted track
1914                                  * entirely with garbage, causing
1915                                  * `wrong cylinder' errors all over
1916                                  * the place when trying to read them
1917                                  * back.
1918                                  *
1919                                  * Umpf.
1920                                  */
1921                                 SET_BCDR(fdc, 1, bp->b_bcount, 0);
1922
1923                                 (void)fdcpio(fdc,bp->b_flags,
1924                                         bp->b_data+fd->skip,
1925                                         bp->b_bcount);
1926
1927                         }
1928                         /* formatting */
1929                         if(fd_cmd(fdc, 6,  NE7CMD_FORMAT, head << 2 | fdu,
1930                                   finfo->fd_formb_secshift,
1931                                   finfo->fd_formb_nsecs,
1932                                   finfo->fd_formb_gaplen,
1933                                   finfo->fd_formb_fillbyte, 0)) {
1934                                 /* controller fell over */
1935                                 if (!(fdc->flags & FDC_NODMA))
1936                                         isa_dmadone(bp->b_flags,
1937                                                     bp->b_data + fd->skip,
1938                                                     format ? bp->b_bcount : fdblk,
1939                                                     fdc->dmachan);
1940                                 fdc->retry = 6;
1941                                 return (retrier(fdc));
1942                         }
1943                 } else {
1944                         if (fdc->flags & FDC_NODMA) {
1945                                 /*
1946                                  * this seems to be necessary even when
1947                                  * reading data
1948                                  */
1949                                 SET_BCDR(fdc, 1, fdblk, 0);
1950
1951                                 /*
1952                                  * perform the write pseudo-DMA before
1953                                  * the WRITE command is sent
1954                                  */
1955                                 if (!read)
1956                                         (void)fdcpio(fdc,bp->b_flags,
1957                                             bp->b_data+fd->skip,
1958                                             fdblk);
1959                         }
1960                         if (fd_cmd(fdc, 9,
1961                                    (read ? NE7CMD_READ : NE7CMD_WRITE),
1962                                    head << 2 | fdu,  /* head & unit */
1963                                    fd->track,        /* track */
1964                                    head,
1965                                    sec,              /* sector + 1 */
1966                                    fd->ft->secsize,  /* sector size */
1967                                    sectrac,          /* sectors/track */
1968                                    fd->ft->gap,      /* gap size */
1969                                    fd->ft->datalen,  /* data length */
1970                                    0)) {
1971                                 /* the beast is sleeping again */
1972                                 if (!(fdc->flags & FDC_NODMA))
1973                                         isa_dmadone(bp->b_flags,
1974                                                     bp->b_data + fd->skip,
1975                                                     format ? bp->b_bcount : fdblk,
1976                                                     fdc->dmachan);
1977                                 fdc->retry = 6;
1978                                 return (retrier(fdc));
1979                         }
1980                 }
1981                 if (fdc->flags & FDC_NODMA)
1982                         /*
1983                          * if this is a read, then simply await interrupt
1984                          * before performing PIO
1985                          */
1986                         if (read && !fdcpio(fdc,bp->b_flags,
1987                             bp->b_data+fd->skip,fdblk)) {
1988                                 fd->tohandle = timeout(fd_iotimeout, fdc, hz);
1989                                 return(0);      /* will return later */
1990                         };
1991
1992                 /*
1993                  * write (or format) operation will fall through and
1994                  * await completion interrupt
1995                  */
1996                 fdc->state = IOCOMPLETE;
1997                 fd->tohandle = timeout(fd_iotimeout, fdc, hz);
1998                 return (0);     /* will return later */
1999         case PIOREAD:
2000                 /* 
2001                  * actually perform the PIO read.  The IOCOMPLETE case
2002                  * removes the timeout for us.  
2003                  */
2004                 (void)fdcpio(fdc,bp->b_flags,bp->b_data+fd->skip,fdblk);
2005                 fdc->state = IOCOMPLETE;
2006                 /* FALLTHROUGH */
2007         case IOCOMPLETE: /* IO DONE, post-analyze */
2008                 untimeout(fd_iotimeout, fdc, fd->tohandle);
2009
2010                 if (fd_read_status(fdc, fd->fdsu)) {
2011                         if (!(fdc->flags & FDC_NODMA))
2012                                 isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
2013                                             format ? bp->b_bcount : fdblk,
2014                                             fdc->dmachan);
2015                         if (fdc->retry < 6)
2016                                 fdc->retry = 6; /* force a reset */
2017                         return (retrier(fdc));
2018                 }
2019
2020                 fdc->state = IOTIMEDOUT;
2021
2022                 /* FALLTHROUGH */
2023
2024         case IOTIMEDOUT:
2025                 if (!(fdc->flags & FDC_NODMA))
2026                         isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
2027                                 format ? bp->b_bcount : fdblk, fdc->dmachan);
2028                 if (fdc->status[0] & NE7_ST0_IC) {
2029                         if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
2030                             && fdc->status[1] & NE7_ST1_OR) {
2031                                 /*
2032                                  * DMA overrun. Someone hogged the bus and
2033                                  * didn't release it in time for the next
2034                                  * FDC transfer.
2035                                  *
2036                                  * We normally restart this without bumping
2037                                  * the retry counter.  However, in case
2038                                  * something is seriously messed up (like
2039                                  * broken hardware), we rather limit the
2040                                  * number of retries so the IO operation
2041                                  * doesn't block indefinately.
2042                                  */
2043                                 if (fdc->dma_overruns++ < FDC_DMAOV_MAX) {
2044                                         fdc->state = SEEKCOMPLETE;
2045                                         return (1);
2046                                 } /* else fall through */
2047                         }
2048                         if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV
2049                                 && fdc->retry < 6)
2050                                 fdc->retry = 6; /* force a reset */
2051                         else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
2052                                 && fdc->status[2] & NE7_ST2_WC
2053                                 && fdc->retry < 3)
2054                                 fdc->retry = 3; /* force recalibrate */
2055                         return (retrier(fdc));
2056                 }
2057                 /* All OK */
2058                 /* Operation successful, retry DMA overruns again next time. */
2059                 fdc->dma_overruns = 0;
2060                 fd->skip += fdblk;
2061                 if (!format && fd->skip < bp->b_bcount - bp->b_resid) {
2062                         /* set up next transfer */
2063                         fdc->state = DOSEEK;
2064                 } else {
2065                         /* ALL DONE */
2066                         fd->skip = 0;
2067                         fdc->bp = NULL;
2068                         device_unbusy(fd->dev);
2069                         devstat_end_transaction_buf(&fd->device_stats, bp);
2070                         biodone(bp);
2071                         fdc->fd = (fd_p) 0;
2072                         fdc->fdu = -1;
2073                         fdc->state = FINDWORK;
2074                 }
2075                 return (1);
2076         case RESETCTLR:
2077                 fdc_reset(fdc);
2078                 fdc->retry++;
2079                 fdc->state = RESETCOMPLETE;
2080                 return (0);
2081         case RESETCOMPLETE:
2082                 /*
2083                  * Discard all the results from the reset so that they
2084                  * can't cause an unexpected interrupt later.
2085                  */
2086                 for (i = 0; i < 4; i++)
2087                         (void)fd_sense_int(fdc, &st0, &cyl);
2088                 fdc->state = STARTRECAL;
2089                 /* Fall through. */
2090         case STARTRECAL:
2091                 if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) {
2092                         /* arrgl */
2093                         fdc->retry = 6;
2094                         return (retrier(fdc));
2095                 }
2096                 fdc->state = RECALWAIT;
2097                 return (0);     /* will return later */
2098         case RECALWAIT:
2099                 /* allow heads to settle */
2100                 timeout(fd_pseudointr, fdc, hz / 8);
2101                 fdc->state = RECALCOMPLETE;
2102                 return (0);     /* will return later */
2103         case RECALCOMPLETE:
2104                 do {
2105                         /*
2106                          * See SEEKCOMPLETE for a comment on this:
2107                          */
2108                         if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
2109                                 return 0;
2110                         if(fdc->fdct == FDC_NE765
2111                            && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
2112                                 return 0; /* hope for a real intr */
2113                 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
2114                 if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
2115                 {
2116                         if(fdc->retry > 3)
2117                                 /*
2118                                  * a recalibrate from beyond cylinder 77
2119                                  * will "fail" due to the FDC limitations;
2120                                  * since people used to complain much about
2121                                  * the failure message, try not logging
2122                                  * this one if it seems to be the first
2123                                  * time in a line
2124                                  */
2125                                 printf("fd%d: recal failed ST0 %b cyl %d\n",
2126                                        fdu, st0, NE7_ST0BITS, cyl);
2127                         if(fdc->retry < 3) fdc->retry = 3;
2128                         return (retrier(fdc));
2129                 }
2130                 fd->track = 0;
2131                 /* Seek (probably) necessary */
2132                 fdc->state = DOSEEK;
2133                 return (1);     /* will return immediatly */
2134         case MOTORWAIT:
2135                 if(fd->flags & FD_MOTOR_WAIT)
2136                 {
2137                         return (0); /* time's not up yet */
2138                 }
2139                 if (fdc->flags & FDC_NEEDS_RESET) {
2140                         fdc->state = RESETCTLR;
2141                         fdc->flags &= ~FDC_NEEDS_RESET;
2142                 } else {
2143                         /*
2144                          * If all motors were off, then the controller was
2145                          * reset, so it has lost track of the current
2146                          * cylinder.  Recalibrate to handle this case.
2147                          * But first, discard the results of the reset.
2148                          */
2149                         fdc->state = RESETCOMPLETE;
2150                 }
2151                 return (1);     /* will return immediatly */
2152         default:
2153                 device_printf(fdc->fdc_dev, "unexpected FD int->");
2154                 if (fd_read_status(fdc, fd->fdsu) == 0)
2155                         printf("FDC status :%x %x %x %x %x %x %x   ",
2156                                fdc->status[0],
2157                                fdc->status[1],
2158                                fdc->status[2],
2159                                fdc->status[3],
2160                                fdc->status[4],
2161                                fdc->status[5],
2162                                fdc->status[6] );
2163                 else
2164                         printf("No status available   ");
2165                 if (fd_sense_int(fdc, &st0, &cyl) != 0)
2166                 {
2167                         printf("[controller is dead now]\n");
2168                         return (0);
2169                 }
2170                 printf("ST0 = %x, PCN = %x\n", st0, cyl);
2171                 return (0);
2172         }
2173         /*XXX confusing: some branches return immediately, others end up here*/
2174         return (1); /* Come back immediatly to new state */
2175 }
2176
2177 static int
2178 retrier(struct fdc_data *fdc)
2179 {
2180         register struct buf *bp;
2181         struct fd_data *fd;
2182         int fdu;
2183
2184         bp = fdc->bp;
2185
2186         /* XXX shouldn't this be cached somewhere?  */
2187         fdu = FDUNIT(minor(bp->b_dev));
2188         fd = devclass_get_softc(fd_devclass, fdu);
2189         if (fd->options & FDOPT_NORETRY)
2190                 goto fail;
2191
2192         switch (fdc->retry) {
2193         case 0: case 1: case 2:
2194                 fdc->state = SEEKCOMPLETE;
2195                 break;
2196         case 3: case 4: case 5:
2197                 fdc->state = STARTRECAL;
2198                 break;
2199         case 6:
2200                 fdc->state = RESETCTLR;
2201                 break;
2202         case 7:
2203                 break;
2204         default:
2205         fail:
2206                 {
2207                         int printerror = (fd->options & FDOPT_NOERRLOG) == 0;
2208                         dev_t sav_b_dev = bp->b_dev;
2209
2210                         /* Trick diskerr */
2211                         bp->b_dev = makedev(major(bp->b_dev),
2212                                     (FDUNIT(minor(bp->b_dev))<<3)|RAW_PART);
2213                         if (printerror)
2214                                 diskerr(bp, "hard error", LOG_PRINTF,
2215                                         fdc->fd->skip / DEV_BSIZE,
2216                                         (struct disklabel *)NULL);
2217                         bp->b_dev = sav_b_dev;
2218                         if (printerror) {
2219                                 if (fdc->flags & FDC_STAT_VALID)
2220                                         printf(
2221                         " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n",
2222                                                fdc->status[0], NE7_ST0BITS,
2223                                                fdc->status[1], NE7_ST1BITS,
2224                                                fdc->status[2], NE7_ST2BITS,
2225                                                fdc->status[3], fdc->status[4],
2226                                                fdc->status[5]);
2227                                 else
2228                                         printf(" (No status)\n");
2229                         }
2230                 }
2231                 bp->b_flags |= B_ERROR;
2232                 bp->b_error = EIO;
2233                 bp->b_resid += bp->b_bcount - fdc->fd->skip;
2234                 fdc->bp = NULL;
2235                 fdc->fd->skip = 0;
2236                 device_unbusy(fd->dev);
2237                 devstat_end_transaction_buf(&fdc->fd->device_stats, bp);
2238                 biodone(bp);
2239                 fdc->state = FINDWORK;
2240                 fdc->flags |= FDC_NEEDS_RESET;
2241                 fdc->fd = (fd_p) 0;
2242                 fdc->fdu = -1;
2243                 return (1);
2244         }
2245         fdc->retry++;
2246         return (1);
2247 }
2248
2249 static int
2250 fdformat(dev, finfo, p)
2251         dev_t dev;
2252         struct fd_formb *finfo;
2253         struct proc *p;
2254 {
2255         fdu_t   fdu;
2256         fd_p    fd;
2257
2258         struct buf *bp;
2259         int rv = 0, s;
2260         size_t fdblk;
2261
2262         fdu     = FDUNIT(minor(dev));
2263         fd      = devclass_get_softc(fd_devclass, fdu);
2264         fdblk = 128 << fd->ft->secsize;
2265
2266         /* set up a buffer header for fdstrategy() */
2267         bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT);
2268         if(bp == 0)
2269                 return ENOBUFS;
2270         /*
2271          * keep the process from being swapped
2272          */
2273         PHOLD(p);
2274         bzero((void *)bp, sizeof(struct buf));
2275         BUF_LOCKINIT(bp);
2276         BUF_LOCK(bp, LK_EXCLUSIVE);
2277         bp->b_flags = B_PHYS | B_FORMAT;
2278
2279         /*
2280          * calculate a fake blkno, so fdstrategy() would initiate a
2281          * seek to the requested cylinder
2282          */
2283         bp->b_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads)
2284                 + finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE;
2285
2286         bp->b_bcount = sizeof(struct fd_idfield_data) * finfo->fd_formb_nsecs;
2287         bp->b_data = (caddr_t)finfo;
2288
2289         /* now do the format */
2290         bp->b_dev = dev;
2291         BUF_STRATEGY(bp, 0);
2292
2293         /* ...and wait for it to complete */
2294         s = splbio();
2295         while(!(bp->b_flags & B_DONE)) {
2296                 rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz);
2297                 if (rv == EWOULDBLOCK)
2298                         break;
2299         }
2300         splx(s);
2301
2302         if (rv == EWOULDBLOCK) {
2303                 /* timed out */
2304                 rv = EIO;
2305                 device_unbusy(fd->dev);
2306                 biodone(bp);
2307         }
2308         if (bp->b_flags & B_ERROR)
2309                 rv = bp->b_error;
2310         /*
2311          * allow the process to be swapped
2312          */
2313         PRELE(p);
2314         BUF_UNLOCK(bp);
2315         BUF_LOCKFREE(bp);
2316         free(bp, M_TEMP);
2317         return rv;
2318 }
2319
2320 /*
2321  * TODO: don't allocate buffer on stack.
2322  */
2323
2324 static int
2325 fdioctl(dev, cmd, addr, flag, p)
2326         dev_t dev;
2327         u_long cmd;
2328         caddr_t addr;
2329         int flag;
2330         struct proc *p;
2331 {
2332         fdu_t   fdu = FDUNIT(minor(dev));
2333         fd_p    fd = devclass_get_softc(fd_devclass, fdu);
2334         size_t fdblk;
2335
2336         struct fd_type *fdt;
2337         struct disklabel *dl;
2338         struct fdc_status *fsp;
2339         char buffer[DEV_BSIZE];
2340         int error = 0;
2341
2342         fdblk = 128 << fd->ft->secsize;
2343
2344         switch (cmd) {
2345         case DIOCGDINFO:
2346                 bzero(buffer, sizeof (buffer));
2347                 dl = (struct disklabel *)buffer;
2348                 dl->d_secsize = fdblk;
2349                 fdt = fd->ft;
2350                 dl->d_secpercyl = fdt->size / fdt->tracks;
2351                 dl->d_type = DTYPE_FLOPPY;
2352
2353                 if (readdisklabel(dev, dl)
2354                     == NULL)
2355                         error = 0;
2356                 else
2357                         error = EINVAL;
2358
2359                 *(struct disklabel *)addr = *dl;
2360                 break;
2361
2362         case DIOCSDINFO:
2363                 if ((flag & FWRITE) == 0)
2364                         error = EBADF;
2365                 break;
2366
2367         case DIOCWLABEL:
2368                 if ((flag & FWRITE) == 0)
2369                         error = EBADF;
2370                 break;
2371
2372         case DIOCWDINFO:
2373                 if ((flag & FWRITE) == 0) {
2374                         error = EBADF;
2375                         break;
2376                 }
2377
2378                 dl = (struct disklabel *)addr;
2379
2380                 if ((error = setdisklabel((struct disklabel *)buffer, dl,
2381                                           (u_long)0)) != 0)
2382                         break;
2383
2384                 error = writedisklabel(dev, (struct disklabel *)buffer);
2385                 break;
2386         case FD_FORM:
2387                 if ((flag & FWRITE) == 0)
2388                         error = EBADF;  /* must be opened for writing */
2389                 else if (((struct fd_formb *)addr)->format_version !=
2390                         FD_FORMAT_VERSION)
2391                         error = EINVAL; /* wrong version of formatting prog */
2392                 else
2393                         error = fdformat(dev, (struct fd_formb *)addr, p);
2394                 break;
2395
2396         case FD_GTYPE:                  /* get drive type */
2397                 *(struct fd_type *)addr = *fd->ft;
2398                 break;
2399
2400         case FD_STYPE:                  /* set drive type */
2401                 /* this is considered harmful; only allow for superuser */
2402                 if (suser(p) != 0)
2403                         return EPERM;
2404                 *fd->ft = *(struct fd_type *)addr;
2405                 break;
2406
2407         case FD_GOPTS:                  /* get drive options */
2408                 *(int *)addr = fd->options;
2409                 break;
2410
2411         case FD_SOPTS:                  /* set drive options */
2412                 fd->options = *(int *)addr;
2413                 break;
2414
2415         case FD_GSTAT:
2416                 fsp = (struct fdc_status *)addr;
2417                 if ((fd->fdc->flags & FDC_STAT_VALID) == 0)
2418                         return EINVAL;
2419                 memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int));
2420                 break;
2421
2422         default:
2423                 error = ENOTTY;
2424                 break;
2425         }
2426         return (error);
2427 }
2428
2429 /*
2430  * Hello emacs, these are the
2431  * Local Variables:
2432  *  c-indent-level:               8
2433  *  c-continued-statement-offset: 8
2434  *  c-continued-brace-offset:     0
2435  *  c-brace-offset:              -8
2436  *  c-brace-imaginary-offset:     0
2437  *  c-argdecl-indent:             8
2438  *  c-label-offset:              -8
2439  *  c++-hanging-braces:           1
2440  *  c++-access-specifier-offset: -8
2441  *  c++-empty-arglist-indent:     8
2442  *  c++-friend-offset:            0
2443  * End:
2444  */