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/pc98/cbus/fdc.c

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

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

Cache object: 98bcd42546106056f20d5cce0d25f15b


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