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

Cache object: cf37fbdb13f82cc1eadee5dd58fd4354


[ 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.