The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/isa/fd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 10d2cd1b45271bf6b79db65191d32aac


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.