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

Cache object: 8d5a91c661157909eedbfaba5cd0e034


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