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/dev/fdc/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) 2004 Poul-Henning Kamp
    3  * Copyright (c) 1990 The Regents of the University of California.
    4  * All rights reserved.
    5  *
    6  * This code is derived from software contributed to Berkeley by
    7  * Don Ahn.
    8  *
    9  * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)
   10  * aided by the Linux floppy driver modifications from David Bateman
   11  * (dbateman@eng.uts.edu.au).
   12  *
   13  * Copyright (c) 1993, 1994 by
   14  *  jc@irbs.UUCP (John Capo)
   15  *  vak@zebub.msk.su (Serge Vakulenko)
   16  *  ache@astral.msk.su (Andrew A. Chernov)
   17  *
   18  * Copyright (c) 1993, 1994, 1995 by
   19  *  joerg_wunsch@uriah.sax.de (Joerg Wunsch)
   20  *  dufault@hda.com (Peter Dufault)
   21  *
   22  * Copyright (c) 2001 Joerg Wunsch,
   23  *  joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch)
   24  *
   25  * Redistribution and use in source and binary forms, with or without
   26  * modification, are permitted provided that the following conditions
   27  * are met:
   28  * 1. Redistributions of source code must retain the above copyright
   29  *    notice, this list of conditions and the following disclaimer.
   30  * 2. Redistributions in binary form must reproduce the above copyright
   31  *    notice, this list of conditions and the following disclaimer in the
   32  *    documentation and/or other materials provided with the distribution.
   33  * 4. Neither the name of the University nor the names of its contributors
   34  *    may be used to endorse or promote products derived from this software
   35  *    without specific prior written permission.
   36  *
   37  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   38  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   40  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   41  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   42  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   43  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   45  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   46  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   47  * SUCH DAMAGE.
   48  *
   49  *      from:   @(#)fd.c        7.4 (Berkeley) 5/25/91
   50  *
   51  */
   52 
   53 #include <sys/cdefs.h>
   54 __FBSDID("$FreeBSD$");
   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/kthread.h>
   68 #include <sys/lock.h>
   69 #include <sys/malloc.h>
   70 #include <sys/module.h>
   71 #include <sys/mutex.h>
   72 #include <sys/priv.h>
   73 #include <sys/proc.h>
   74 #include <sys/rman.h>
   75 #include <sys/sysctl.h>
   76 #include <sys/systm.h>
   77 
   78 #include <geom/geom.h>
   79 
   80 #include <machine/bus.h>
   81 #include <machine/clock.h>
   82 #include <machine/stdarg.h>
   83 
   84 #include <isa/isavar.h>
   85 #ifdef PC98
   86 #include <pc98/pc98/pc98_machdep.h>
   87 #else
   88 #include <isa/isareg.h>
   89 #include <isa/rtc.h>
   90 #endif
   91 #include <dev/fdc/fdcvar.h>
   92 
   93 #include <dev/ic/nec765.h>
   94 
   95 /*
   96  * Runtime configuration hints/flags
   97  */
   98 
   99 /* configuration flags for fd */
  100 #define FD_TYPEMASK     0x0f    /* drive type, matches enum
  101                                  * fd_drivetype; on i386 machines, if
  102                                  * given as 0, use RTC type for fd0
  103                                  * and fd1 */
  104 #define FD_NO_CHLINE    0x10    /* drive does not support changeline
  105                                  * aka. unit attention */
  106 #define FD_NO_PROBE     0x20    /* don't probe drive (seek test), just
  107                                  * assume it is there */
  108 
  109 /*
  110  * Things that could conceiveably considered parameters or tweakables
  111  */
  112 
  113 /*
  114  * Maximal number of bytes in a cylinder.
  115  * This is used for ISADMA bouncebuffer allocation and sets the max
  116  * xfersize we support.
  117  *
  118  * 2.88M format has 2 x 36 x 512, allow for hacked up density.
  119  */
  120 #define MAX_BYTES_PER_CYL       (2 * 40 * 512)
  121 
  122 /*
  123  * Timeout value for the PIO loops to wait until the FDC main status
  124  * register matches our expectations (request for master, direction
  125  * bit).  This is supposed to be a number of microseconds, although
  126  * timing might actually not be very accurate.
  127  *
  128  * Timeouts of 100 msec are believed to be required for some broken
  129  * (old) hardware.
  130  */
  131 #define FDSTS_TIMEOUT   100000
  132 
  133 /*
  134  * After this many errors, stop whining.  Close will reset this count.
  135  */
  136 #define FDC_ERRMAX      100
  137 
  138 /*
  139  * AutoDensity search lists for each drive type.
  140  */
  141 
  142 static struct fd_type fd_searchlist_360k[] = {
  143 #ifndef PC98
  144         { FDF_5_360 },
  145 #endif
  146         { 0 }
  147 };
  148 
  149 static struct fd_type fd_searchlist_12m[] = {
  150 #ifdef PC98
  151         { FDF_5_1200 | FL_AUTO },
  152         { FDF_5_720 | FL_AUTO },
  153         { FDF_5_360 | FL_AUTO },
  154         { FDF_5_640 | FL_AUTO },
  155         { FDF_5_1230 | FL_AUTO },
  156 #else
  157         { FDF_5_1200 | FL_AUTO },
  158         { FDF_5_400 | FL_AUTO },
  159         { FDF_5_360 | FL_2STEP | FL_AUTO},
  160 #endif
  161         { 0 }
  162 };
  163 
  164 static struct fd_type fd_searchlist_720k[] = {
  165 #ifndef PC98
  166         { FDF_3_720 },
  167 #endif
  168         { 0 }
  169 };
  170 
  171 static struct fd_type fd_searchlist_144m[] = {
  172 #ifdef PC98
  173         { FDF_3_1440 | FL_AUTO},
  174         { FDF_3_1200 | FL_AUTO},
  175         { FDF_3_720 | FL_AUTO},
  176         { FDF_3_360 | FL_AUTO},
  177         { FDF_3_640 | FL_AUTO},
  178         { FDF_3_1230 | FL_AUTO},
  179 #else
  180         { FDF_3_1440 | FL_AUTO},
  181         { FDF_3_720 | FL_AUTO},
  182 #endif
  183         { 0 }
  184 };
  185 
  186 static struct fd_type fd_searchlist_288m[] = {
  187 #ifndef PC98
  188         { FDF_3_1440 | FL_AUTO },
  189 #if 0
  190         { FDF_3_2880 | FL_AUTO }, /* XXX: probably doesn't work */
  191 #endif
  192         { FDF_3_720 | FL_AUTO},
  193 #endif
  194         { 0 }
  195 };
  196 
  197 /*
  198  * Order must match enum fd_drivetype in <sys/fdcio.h>.
  199  */
  200 static struct fd_type *fd_native_types[] = {
  201         NULL,                           /* FDT_NONE */
  202         fd_searchlist_360k,             /* FDT_360K */
  203         fd_searchlist_12m,              /* FDT_12M */
  204         fd_searchlist_720k,             /* FDT_720K */
  205         fd_searchlist_144m,             /* FDT_144M */
  206         fd_searchlist_288m,             /* FDT_288M_1 (mapped to FDT_288M) */
  207         fd_searchlist_288m,             /* FDT_288M */
  208 };
  209 
  210 /*
  211  * Internals start here
  212  */
  213 
  214 #ifdef PC98
  215 /* registers */
  216 #define FDSTS   0       /* NEC 765 Main Status Register (R) */
  217 #define FDDATA  1       /* NEC 765 Data Register (R/W) */
  218 #define FDCTL   2       /* FD Control Register */
  219 #define FDC_RST         0x80    /*  FDC RESET */
  220 #define FDC_RDY         0x40    /*  force READY */
  221 #define FDC_DD          0x20    /*  FDD Mode Exchange 0:1M 1:640K */
  222 #define FDC_DMAE        0x10    /*  enable floppy DMA */
  223 #define FDC_MTON        0x08    /*  MOTOR ON (when EMTON=1)*/
  224 #define FDC_TMSK        0x04    /*  TIMER MASK */
  225 #define FDC_TTRG        0x01    /*  TIMER TRIGER */
  226 
  227 #define FDP     3
  228 #define FDP_EMTON       0x04    /*  enable MTON */
  229 #define FDP_FDDEXC      0x02    /*  FDD Mode Exchange 1:1M 0:640K */
  230 #define FDP_PORTEXC     0x01    /*  PORT Exchane 1:1M 0:640K */
  231 
  232 #define FDEM    4
  233 #else
  234 /* registers */
  235 #define FDOUT   2       /* Digital Output Register (W) */
  236 #define FDO_FDSEL       0x03    /*  floppy device select */
  237 #define FDO_FRST        0x04    /*  floppy controller reset */
  238 #define FDO_FDMAEN      0x08    /*  enable floppy DMA and Interrupt */
  239 #define FDO_MOEN0       0x10    /*  motor enable drive 0 */
  240 #define FDO_MOEN1       0x20    /*  motor enable drive 1 */
  241 #define FDO_MOEN2       0x40    /*  motor enable drive 2 */
  242 #define FDO_MOEN3       0x80    /*  motor enable drive 3 */
  243 
  244 #define FDSTS   4       /* NEC 765 Main Status Register (R) */
  245 #define FDDSR   4       /* Data Rate Select Register (W) */
  246 #define FDDATA  5       /* NEC 765 Data Register (R/W) */
  247 #define FDCTL   7       /* Control Register (W) */
  248 #endif /* PC98 */
  249 
  250 /*
  251  * The YE-DATA PC Card floppies use PIO to read in the data rather
  252  * than DMA due to the wild variability of DMA for the PC Card
  253  * devices.  DMA was deleted from the PC Card specification in version
  254  * 7.2 of the standard, but that post-dates the YE-DATA devices by many
  255  * years.
  256  *
  257  * In addition, if we cannot setup the DMA resources for the ISA
  258  * attachment, we'll use this same offset for data transfer.  However,
  259  * that almost certainly won't work.
  260  *
  261  * For this mode, offset 0 and 1 must be used to setup the transfer
  262  * for this floppy.  This is OK for PC Card YE Data devices, but for
  263  * ISA this is likely wrong.  These registers are only available on
  264  * those systems that map them to the floppy drive.  Newer systems do
  265  * not do this, and we should likely prohibit access to them (or
  266  * disallow NODMA to be set).
  267  */
  268 #define FDBCDR          0       /* And 1 */
  269 #define FD_YE_DATAPORT  6       /* Drive Data port */
  270 
  271 #ifndef PC98
  272 #define FDI_DCHG        0x80    /* diskette has been changed */
  273                                 /* requires drive and motor being selected */
  274                                 /* is cleared by any step pulse to drive */
  275 #endif
  276 
  277 /*
  278  * We have three private BIO commands.
  279  */
  280 #define BIO_PROBE       BIO_CMD0
  281 #define BIO_RDID        BIO_CMD1
  282 #define BIO_FMT         BIO_CMD2
  283 
  284 /*
  285  * Per drive structure (softc).
  286  */
  287 struct fd_data {
  288         u_char  *fd_ioptr;      /* IO pointer */
  289         u_int   fd_iosize;      /* Size of IO chunks */
  290         u_int   fd_iocount;     /* Outstanding requests */
  291         struct  fdc_data *fdc;  /* pointer to controller structure */
  292         int     fdsu;           /* this units number on this controller */
  293         enum    fd_drivetype type; /* drive type */
  294         struct  fd_type *ft;    /* pointer to current type descriptor */
  295         struct  fd_type fts;    /* type descriptors */
  296         int     sectorsize;
  297         int     flags;
  298 #define FD_WP           (1<<0)  /* Write protected      */
  299 #define FD_MOTOR        (1<<1)  /* motor should be on   */
  300 #define FD_MOTORWAIT    (1<<2)  /* motor should be on   */
  301 #define FD_EMPTY        (1<<3)  /* no media             */
  302 #define FD_NEWDISK      (1<<4)  /* media changed        */
  303 #define FD_ISADMA       (1<<5)  /* isa dma started      */
  304         int     track;          /* where we think the head is */
  305 #define FD_NO_TRACK      -2
  306         int     options;        /* FDOPT_* */
  307         struct  callout toffhandle;
  308         struct g_geom *fd_geom;
  309         struct g_provider *fd_provider;
  310         device_t dev;
  311         struct bio_queue_head fd_bq;
  312 #ifdef PC98
  313         int     pc98_trans;
  314 #endif
  315 };
  316 
  317 #define FD_NOT_VALID -2
  318 
  319 static driver_intr_t fdc_intr;
  320 static driver_filter_t fdc_intr_fast;
  321 static void fdc_reset(struct fdc_data *);
  322 static int fd_probe_disk(struct fd_data *, int *);
  323 
  324 static SYSCTL_NODE(_debug, OID_AUTO, fdc, CTLFLAG_RW, 0, "fdc driver");
  325 
  326 static int fifo_threshold = 8;
  327 SYSCTL_INT(_debug_fdc, OID_AUTO, fifo, CTLFLAG_RW, &fifo_threshold, 0,
  328         "FIFO threshold setting");
  329 
  330 static int debugflags = 0;
  331 SYSCTL_INT(_debug_fdc, OID_AUTO, debugflags, CTLFLAG_RW, &debugflags, 0,
  332         "Debug flags");
  333 
  334 static int retries = 10;
  335 SYSCTL_INT(_debug_fdc, OID_AUTO, retries, CTLFLAG_RW, &retries, 0,
  336         "Number of retries to attempt");
  337 
  338 #ifdef PC98
  339 static int spec1 = NE7_SPEC_1(4, 240);
  340 #else
  341 static int spec1 = NE7_SPEC_1(6, 240);
  342 #endif
  343 SYSCTL_INT(_debug_fdc, OID_AUTO, spec1, CTLFLAG_RW, &spec1, 0,
  344         "Specification byte one (step-rate + head unload)");
  345 
  346 #ifdef PC98
  347 static int spec2 = NE7_SPEC_2(2, 0);
  348 #else
  349 static int spec2 = NE7_SPEC_2(16, 0);
  350 #endif
  351 SYSCTL_INT(_debug_fdc, OID_AUTO, spec2, CTLFLAG_RW, &spec2, 0,
  352         "Specification byte two (head load time + no-dma)");
  353 
  354 static int settle;
  355 SYSCTL_INT(_debug_fdc, OID_AUTO, settle, CTLFLAG_RW, &settle, 0,
  356         "Head settling time in sec/hz");
  357 
  358 static void
  359 fdprinttype(struct fd_type *ft)
  360 {
  361 
  362         printf("(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,0x%x)",
  363             ft->sectrac, ft->secsize, ft->datalen, ft->gap, ft->tracks,
  364             ft->size, ft->trans, ft->heads, ft->f_gap, ft->f_inter,
  365             ft->offset_side2, ft->flags);
  366 }
  367 
  368 static void
  369 fdsettype(struct fd_data *fd, struct fd_type *ft)
  370 {
  371         fd->ft = ft;
  372         ft->size = ft->sectrac * ft->heads * ft->tracks;
  373         fd->sectorsize = 128 << fd->ft->secsize;
  374 }
  375 
  376 /*
  377  * Bus space handling (access to low-level IO).
  378  */
  379 static inline void
  380 fdregwr(struct fdc_data *fdc, int reg, uint8_t v)
  381 {
  382 
  383         bus_space_write_1(fdc->iot, fdc->ioh[reg], fdc->ioff[reg], v);
  384 }
  385 
  386 static inline uint8_t
  387 fdregrd(struct fdc_data *fdc, int reg)
  388 {
  389 
  390         return bus_space_read_1(fdc->iot, fdc->ioh[reg], fdc->ioff[reg]);
  391 }
  392 
  393 static void
  394 fdctl_wr(struct fdc_data *fdc, u_int8_t v)
  395 {
  396 
  397         fdregwr(fdc, FDCTL, v);
  398 }
  399 
  400 #ifndef PC98
  401 static void
  402 fdout_wr(struct fdc_data *fdc, u_int8_t v)
  403 {
  404 
  405         fdregwr(fdc, FDOUT, v);
  406 }
  407 #endif
  408 
  409 static u_int8_t
  410 fdsts_rd(struct fdc_data *fdc)
  411 {
  412 
  413         return fdregrd(fdc, FDSTS);
  414 }
  415 
  416 #ifndef PC98
  417 static void
  418 fddsr_wr(struct fdc_data *fdc, u_int8_t v)
  419 {
  420 
  421         fdregwr(fdc, FDDSR, v);
  422 }
  423 #endif
  424 
  425 static void
  426 fddata_wr(struct fdc_data *fdc, u_int8_t v)
  427 {
  428 
  429         fdregwr(fdc, FDDATA, v);
  430 }
  431 
  432 static u_int8_t
  433 fddata_rd(struct fdc_data *fdc)
  434 {
  435 
  436         return fdregrd(fdc, FDDATA);
  437 }
  438 
  439 #ifndef PC98
  440 static u_int8_t
  441 fdin_rd(struct fdc_data *fdc)
  442 {
  443 
  444         return fdregrd(fdc, FDCTL);
  445 }
  446 #endif
  447 
  448 /*
  449  * Magic pseudo-DMA initialization for YE FDC. Sets count and
  450  * direction.
  451  */
  452 static void
  453 fdbcdr_wr(struct fdc_data *fdc, int iswrite, uint16_t count)
  454 {
  455         fdregwr(fdc, FDBCDR, (count - 1) & 0xff);
  456         fdregwr(fdc, FDBCDR + 1,
  457             (iswrite ? 0x80 : 0) | (((count - 1) >> 8) & 0x7f));
  458 }
  459 
  460 static int
  461 fdc_err(struct fdc_data *fdc, const char *s)
  462 {
  463         fdc->fdc_errs++;
  464         if (s) {
  465                 if (fdc->fdc_errs < FDC_ERRMAX)
  466                         device_printf(fdc->fdc_dev, "%s", s);
  467                 else if (fdc->fdc_errs == FDC_ERRMAX)
  468                         device_printf(fdc->fdc_dev, "too many errors, not "
  469                                                     "logging any more\n");
  470         }
  471 
  472         return (1);
  473 }
  474 
  475 /*
  476  * FDC IO functions, take care of the main status register, timeout
  477  * in case the desired status bits are never set.
  478  *
  479  * These PIO loops initially start out with short delays between
  480  * each iteration in the expectation that the required condition
  481  * is usually met quickly, so it can be handled immediately.
  482  */
  483 static int
  484 fdc_in(struct fdc_data *fdc, int *ptr)
  485 {
  486         int i, j, step;
  487 
  488         step = 1;
  489         for (j = 0; j < FDSTS_TIMEOUT; j += step) {
  490                 i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM);
  491                 if (i == (NE7_DIO|NE7_RQM)) {
  492                         i = fddata_rd(fdc);
  493                         if (ptr)
  494                                 *ptr = i;
  495                         return (0);
  496                 }
  497                 if (i == NE7_RQM)
  498                         return (fdc_err(fdc, "ready for output in input\n"));
  499                 step += step;
  500                 DELAY(step);
  501         }
  502         return (fdc_err(fdc, bootverbose? "input ready timeout\n": 0));
  503 }
  504 
  505 static int
  506 fdc_out(struct fdc_data *fdc, int x)
  507 {
  508         int i, j, step;
  509 
  510         step = 1;
  511         for (j = 0; j < FDSTS_TIMEOUT; j += step) {
  512                 i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM);
  513                 if (i == NE7_RQM) {
  514                         fddata_wr(fdc, x);
  515                         return (0);
  516                 }
  517                 if (i == (NE7_DIO|NE7_RQM))
  518                         return (fdc_err(fdc, "ready for input in output\n"));
  519                 step += step;
  520                 DELAY(step);
  521         }
  522         return (fdc_err(fdc, bootverbose? "output ready timeout\n": 0));
  523 }
  524 
  525 /*
  526  * fdc_cmd: Send a command to the chip.
  527  * Takes a varargs with this structure:
  528  *      # of output bytes
  529  *      output bytes as int [...]
  530  *      # of input bytes
  531  *      input bytes as int* [...]
  532  */
  533 static int
  534 fdc_cmd(struct fdc_data *fdc, int n_out, ...)
  535 {
  536         u_char cmd = 0;
  537         int n_in;
  538         int n, i;
  539         va_list ap;
  540 
  541         va_start(ap, n_out);
  542         for (n = 0; n < n_out; n++) {
  543                 i = va_arg(ap, int);
  544                 if (n == 0)
  545                         cmd = i;
  546                 if (fdc_out(fdc, i) < 0) {
  547                         char msg[50];
  548                         snprintf(msg, sizeof(msg),
  549                                 "cmd %x failed at out byte %d of %d\n",
  550                                 cmd, n + 1, n_out);
  551                         fdc->flags |= FDC_NEEDS_RESET;
  552                         va_end(ap);
  553                         return fdc_err(fdc, msg);
  554                 }
  555         }
  556         n_in = va_arg(ap, int);
  557         for (n = 0; n < n_in; n++) {
  558                 int *ptr = va_arg(ap, int *);
  559                 if (fdc_in(fdc, ptr) < 0) {
  560                         char msg[50];
  561                         snprintf(msg, sizeof(msg),
  562                                 "cmd %02x failed at in byte %d of %d\n",
  563                                 cmd, n + 1, n_in);
  564                         fdc->flags |= FDC_NEEDS_RESET;
  565                         va_end(ap);
  566                         return fdc_err(fdc, msg);
  567                 }
  568         }
  569         va_end(ap);
  570         return (0);
  571 }
  572 
  573 #ifdef PC98
  574 static void     fd_motor(struct fd_data *fd, int turnon);
  575 
  576 static int pc98_trans = 0; /* 0 : HD , 1 : DD , 2 : 1.44 */
  577 static int pc98_trans_prev = -1;
  578 
  579 static void
  580 set_density(struct fdc_data *fdc)
  581 {
  582         /* always motor on */
  583         fdregwr(fdc, FDP, (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
  584         DELAY(100);
  585         fdctl_wr(fdc, FDC_RST | FDC_DMAE);
  586         /* in the case of note W, always inhibit 100ms timer */
  587 }
  588 
  589 static int
  590 pc98_fd_check_ready(struct fd_data *fd)
  591 {
  592         struct fdc_data *fdc = fd->fdc;
  593         int retry = 0, status;
  594         int fdu = device_get_unit(fd->dev);
  595 
  596         while (retry++ < 30000) {
  597                 fd_motor(fd, 1);
  598                 fdc_out(fdc, NE7CMD_SENSED); /* Sense Drive Status */
  599                 DELAY(100);
  600                 fdc_out(fdc, fdu); /* Drive number */
  601                 DELAY(100);
  602                 if ((fdc_in(fdc, &status) == 0) && (status & NE7_ST3_RD)) {
  603                         fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
  604                         DELAY(10);
  605                         return (0);
  606                 }
  607         }
  608         return (-1);
  609 }
  610 
  611 static void
  612 pc98_fd_check_type(struct fd_data *fd, int unit)
  613 {
  614         struct fdc_data *fdc;
  615 
  616         if (fd->type != FDT_NONE || unit < 0 || unit > 3)
  617                 return;
  618 
  619         fdc = fd->fdc;
  620 
  621         /* Look up what the BIOS thinks we have. */
  622         if (!((PC98_SYSTEM_PARAMETER(0x55c) >> unit) & 0x01)) {
  623                 fd->type = FDT_NONE;
  624                 return;
  625         }
  626         if ((PC98_SYSTEM_PARAMETER(0x5ae) >> unit) & 0x01) {
  627                 /* Check 3mode I/F */
  628                 fd->pc98_trans = 0;
  629                 fdregwr(fdc, FDEM, (unit << 5) | 0x10);
  630                 if (!(fdregrd(fdc, FDEM) & 0x01)) {
  631                         fd->type = FDT_144M;
  632                         return;
  633                 }
  634                 device_printf(fd->dev,
  635                     "Warning: can't control 3mode I/F, fallback to 2mode.\n");
  636         }
  637 
  638         fd->type = FDT_12M;
  639 }
  640 #endif /* PC98 */
  641 
  642 static void
  643 fdc_reset(struct fdc_data *fdc)
  644 {
  645         int i, r[10];
  646 
  647 #ifdef PC98
  648         set_density(fdc);
  649         if (pc98_machine_type & M_EPSON_PC98)
  650                 fdctl_wr(fdc, FDC_RST | FDC_RDY | FDC_DD | FDC_MTON);
  651         else
  652                 fdctl_wr(fdc, FDC_RST | FDC_RDY | FDC_DMAE | FDC_MTON);
  653         DELAY(200);
  654         fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
  655         DELAY(10);
  656 #else
  657         if (fdc->fdct == FDC_ENHANCED) {
  658                 /* Try a software reset, default precomp, and 500 kb/s */
  659                 fddsr_wr(fdc, I8207X_DSR_SR);
  660         } else {
  661                 /* Try a hardware reset, keep motor on */
  662                 fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
  663                 DELAY(100);
  664                 /* enable FDC, but defer interrupts a moment */
  665                 fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
  666         }
  667         DELAY(100);
  668         fdout_wr(fdc, fdc->fdout);
  669 #endif
  670 
  671         /* XXX after a reset, silently believe the FDC will accept commands */
  672         if (fdc_cmd(fdc, 3, NE7CMD_SPECIFY, spec1, spec2, 0))
  673                 device_printf(fdc->fdc_dev, " SPECIFY failed in reset\n");
  674 
  675         if (fdc->fdct == FDC_ENHANCED) {
  676                 if (fdc_cmd(fdc, 4,
  677                     I8207X_CONFIG,
  678                     0,
  679                     /* 0x40 | */                /* Enable Implied Seek -
  680                                                  * breaks 2step! */
  681                     0x10 |                      /* Polling disabled */
  682                     (fifo_threshold - 1),       /* Fifo threshold */
  683                     0x00,                       /* Precomp track */
  684                     0))
  685                         device_printf(fdc->fdc_dev,
  686                             " CONFIGURE failed in reset\n");
  687                 if (debugflags & 1) {
  688                         if (fdc_cmd(fdc, 1,
  689                             I8207X_DUMPREG,
  690                             10, &r[0], &r[1], &r[2], &r[3], &r[4],
  691                             &r[5], &r[6], &r[7], &r[8], &r[9]))
  692                                 device_printf(fdc->fdc_dev,
  693                                     " DUMPREG failed in reset\n");
  694                         for (i = 0; i < 10; i++)
  695                                 printf(" %02x", r[i]);
  696                         printf("\n");
  697                 }
  698         }
  699 }
  700 
  701 static int
  702 fdc_sense_drive(struct fdc_data *fdc, int *st3p)
  703 {
  704         int st3;
  705 
  706         if (fdc_cmd(fdc, 2, NE7CMD_SENSED, fdc->fd->fdsu, 1, &st3))
  707                 return (fdc_err(fdc, "Sense Drive Status failed\n"));
  708         if (st3p)
  709                 *st3p = st3;
  710         return (0);
  711 }
  712 
  713 static int
  714 fdc_sense_int(struct fdc_data *fdc, int *st0p, int *cylp)
  715 {
  716         int cyl, st0, ret;
  717 
  718         ret = fdc_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0);
  719         if (ret) {
  720                 (void)fdc_err(fdc, "sense intr err reading stat reg 0\n");
  721                 return (ret);
  722         }
  723 
  724         if (st0p)
  725                 *st0p = st0;
  726 
  727         if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) {
  728                 /*
  729                  * There doesn't seem to have been an interrupt.
  730                  */
  731                 return (FD_NOT_VALID);
  732         }
  733 
  734         if (fdc_in(fdc, &cyl) < 0)
  735                 return fdc_err(fdc, "can't get cyl num\n");
  736 
  737         if (cylp)
  738                 *cylp = cyl;
  739 
  740         return (0);
  741 }
  742 
  743 static int
  744 fdc_read_status(struct fdc_data *fdc)
  745 {
  746         int i, ret, status;
  747 
  748         for (i = ret = 0; i < 7; i++) {
  749                 ret = fdc_in(fdc, &status);
  750                 fdc->status[i] = status;
  751                 if (ret != 0)
  752                         break;
  753         }
  754 
  755         if (ret == 0)
  756                 fdc->flags |= FDC_STAT_VALID;
  757         else
  758                 fdc->flags &= ~FDC_STAT_VALID;
  759 
  760         return ret;
  761 }
  762 
  763 #ifndef PC98
  764 /*
  765  * Select this drive
  766  */
  767 static void
  768 fd_select(struct fd_data *fd)
  769 {
  770         struct fdc_data *fdc;
  771 
  772         /* XXX: lock controller */
  773         fdc = fd->fdc;
  774         fdc->fdout &= ~FDO_FDSEL;
  775         fdc->fdout |= FDO_FDMAEN | FDO_FRST | fd->fdsu;
  776         fdout_wr(fdc, fdc->fdout);
  777 }
  778 
  779 static void
  780 fd_turnon(void *arg)
  781 {
  782         struct fd_data *fd;
  783         struct bio *bp;
  784         int once;
  785 
  786         fd = arg;
  787         mtx_assert(&fd->fdc->fdc_mtx, MA_OWNED);
  788         fd->flags &= ~FD_MOTORWAIT;
  789         fd->flags |= FD_MOTOR;
  790         once = 0;
  791         for (;;) {
  792                 bp = bioq_takefirst(&fd->fd_bq);
  793                 if (bp == NULL)
  794                         break;
  795                 bioq_disksort(&fd->fdc->head, bp);
  796                 once = 1;
  797         }
  798         if (once)
  799                 wakeup(&fd->fdc->head);
  800 }
  801 #endif
  802 
  803 static void
  804 fd_motor(struct fd_data *fd, int turnon)
  805 {
  806         struct fdc_data *fdc;
  807 
  808         fdc = fd->fdc;
  809 /*
  810         mtx_assert(&fdc->fdc_mtx, MA_OWNED);
  811 */
  812 #ifdef PC98
  813         fdregwr(fdc, FDP, (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
  814         DELAY(10);
  815         fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
  816 #else
  817         if (turnon) {
  818                 fd->flags |= FD_MOTORWAIT;
  819                 fdc->fdout |= (FDO_MOEN0 << fd->fdsu);
  820                 callout_reset(&fd->toffhandle, hz, fd_turnon, fd);
  821         } else {
  822                 callout_stop(&fd->toffhandle);
  823                 fd->flags &= ~(FD_MOTOR|FD_MOTORWAIT);
  824                 fdc->fdout &= ~(FDO_MOEN0 << fd->fdsu);
  825         }
  826         fdout_wr(fdc, fdc->fdout);
  827 #endif
  828 }
  829 
  830 static void
  831 fd_turnoff(void *xfd)
  832 {
  833         struct fd_data *fd = xfd;
  834 
  835         mtx_assert(&fd->fdc->fdc_mtx, MA_OWNED);
  836         fd_motor(fd, 0);
  837 }
  838 
  839 /*
  840  * fdc_intr - wake up the worker thread.
  841  */
  842 
  843 static void
  844 fdc_intr(void *arg)
  845 {
  846 
  847         wakeup(arg);
  848 }
  849 
  850 static int
  851 fdc_intr_fast(void *arg)
  852 {
  853 
  854         wakeup(arg);
  855         return(FILTER_HANDLED);
  856 }
  857 
  858 /*
  859  * fdc_pio(): perform programmed IO read/write for YE PCMCIA floppy.
  860  */
  861 static void
  862 fdc_pio(struct fdc_data *fdc)
  863 {
  864         u_char *cptr;
  865         struct bio *bp;
  866         u_int count;
  867 
  868         bp = fdc->bp;
  869         cptr = fdc->fd->fd_ioptr;
  870         count = fdc->fd->fd_iosize;
  871 
  872         if (bp->bio_cmd == BIO_READ) {
  873                 fdbcdr_wr(fdc, 0, count);
  874                 bus_space_read_multi_1(fdc->iot, fdc->ioh[FD_YE_DATAPORT],
  875                     fdc->ioff[FD_YE_DATAPORT], cptr, count);
  876         } else {
  877                 bus_space_write_multi_1(fdc->iot, fdc->ioh[FD_YE_DATAPORT],
  878                     fdc->ioff[FD_YE_DATAPORT], cptr, count);
  879                 fdbcdr_wr(fdc, 0, count);       /* needed? */
  880         }
  881 }
  882 
  883 static int
  884 fdc_biodone(struct fdc_data *fdc, int error)
  885 {
  886         struct fd_data *fd;
  887         struct bio *bp;
  888 
  889         fd = fdc->fd;
  890         bp = fdc->bp;
  891 
  892         mtx_lock(&fdc->fdc_mtx);
  893         if (--fd->fd_iocount == 0)
  894                 callout_reset(&fd->toffhandle, 4 * hz, fd_turnoff, fd);
  895         fdc->bp = NULL;
  896         fdc->fd = NULL;
  897         mtx_unlock(&fdc->fdc_mtx);
  898         if (bp->bio_to != NULL) {
  899                 if ((debugflags & 2) && fd->fdc->retry > 0)
  900                         printf("retries: %d\n", fd->fdc->retry);
  901                 g_io_deliver(bp, error);
  902                 return (0);
  903         }
  904         bp->bio_error = error;
  905         bp->bio_flags |= BIO_DONE;
  906         wakeup(bp);
  907         return (0);
  908 }
  909 
  910 static int retry_line;
  911 
  912 static int
  913 fdc_worker(struct fdc_data *fdc)
  914 {
  915         struct fd_data *fd;
  916         struct bio *bp;
  917         int i, nsect;
  918         int st0, st3, cyl, mfm, steptrac, cylinder, descyl, sec;
  919         int head;
  920         int override_error;
  921         static int need_recal;
  922         struct fdc_readid *idp;
  923         struct fd_formb *finfo;
  924 
  925         override_error = 0;
  926 
  927         /* Have we exhausted our retries ? */
  928         bp = fdc->bp;
  929         fd = fdc->fd;
  930         if (bp != NULL &&
  931                 (fdc->retry >= retries || (fd->options & FDOPT_NORETRY))) {
  932                 if ((debugflags & 4))
  933                         printf("Too many retries (EIO)\n");
  934                 if (fdc->flags & FDC_NEEDS_RESET) {
  935                         mtx_lock(&fdc->fdc_mtx);
  936                         fd->flags |= FD_EMPTY;
  937                         mtx_unlock(&fdc->fdc_mtx);
  938                 }
  939                 return (fdc_biodone(fdc, EIO));
  940         }
  941 
  942         /* Disable ISADMA if we bailed while it was active */
  943         if (fd != NULL && (fd->flags & FD_ISADMA)) {
  944                 isa_dmadone(
  945                     bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE,
  946                     fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
  947                 mtx_lock(&fdc->fdc_mtx);
  948                 fd->flags &= ~FD_ISADMA;
  949                 mtx_unlock(&fdc->fdc_mtx);
  950         }
  951 
  952         /* Unwedge the controller ? */
  953         if (fdc->flags & FDC_NEEDS_RESET) {
  954                 fdc->flags &= ~FDC_NEEDS_RESET;
  955                 fdc_reset(fdc);
  956                 if (cold)
  957                         DELAY(1000000);
  958                 else
  959                         tsleep(fdc, PRIBIO, "fdcrst", hz);
  960                 /* Discard results */
  961                 for (i = 0; i < 4; i++)
  962                         fdc_sense_int(fdc, &st0, &cyl);
  963                 /* All drives must recal */
  964                 need_recal = 0xf;
  965         }
  966 
  967         /* Pick up a request, if need be wait for it */
  968         if (fdc->bp == NULL) {
  969                 mtx_lock(&fdc->fdc_mtx);
  970                 do {
  971                         fdc->bp = bioq_takefirst(&fdc->head);
  972                         if (fdc->bp == NULL)
  973                                 msleep(&fdc->head, &fdc->fdc_mtx,
  974                                     PRIBIO, "-", 0);
  975                 } while (fdc->bp == NULL &&
  976                     (fdc->flags & FDC_KTHREAD_EXIT) == 0);
  977                 mtx_unlock(&fdc->fdc_mtx);
  978 
  979                 if (fdc->bp == NULL)
  980                         /*
  981                          * Nothing to do, worker thread has been
  982                          * requested to stop.
  983                          */
  984                         return (0);
  985 
  986                 bp = fdc->bp;
  987                 fd = fdc->fd = bp->bio_driver1;
  988                 fdc->retry = 0;
  989                 fd->fd_ioptr = bp->bio_data;
  990                 if (bp->bio_cmd == BIO_FMT) {
  991                         i = offsetof(struct fd_formb, fd_formb_cylno(0));
  992                         fd->fd_ioptr += i;
  993                         fd->fd_iosize = bp->bio_length - i;
  994                 }
  995         }
  996 
  997         /* Select drive, setup params */
  998 #ifdef PC98
  999         pc98_trans = fd->ft->trans;
 1000         if (pc98_trans_prev != pc98_trans) {
 1001                 int i;
 1002 
 1003                 set_density(fdc);
 1004                 for (i = 0; i < 10; i++) {
 1005                         outb(0x5f, 0);
 1006                         outb(0x5f, 0);
 1007                 }
 1008                 pc98_trans_prev = pc98_trans;
 1009         }
 1010         if (pc98_trans != fd->pc98_trans) {
 1011                 if (fd->type == FDT_144M) {
 1012                         fdregwr(fdc, FDEM,
 1013                             (device_get_unit(fd->dev) << 5) | 0x10 |
 1014                             (pc98_trans >> 1));
 1015                         outb(0x5f, 0);
 1016                         outb(0x5f, 0);
 1017                 }
 1018                 fd->pc98_trans = pc98_trans;
 1019         }
 1020 #else
 1021         fd_select(fd);
 1022         if (fdc->fdct == FDC_ENHANCED)
 1023                 fddsr_wr(fdc, fd->ft->trans);
 1024         else
 1025                 fdctl_wr(fdc, fd->ft->trans);
 1026 #endif
 1027 
 1028         if (bp->bio_cmd == BIO_PROBE) {
 1029                 if ((!(device_get_flags(fd->dev) & FD_NO_CHLINE) &&
 1030 #ifndef PC98
 1031                     !(fdin_rd(fdc) & FDI_DCHG) &&
 1032 #endif
 1033                     !(fd->flags & FD_EMPTY)) ||
 1034                     fd_probe_disk(fd, &need_recal) == 0)
 1035                         return (fdc_biodone(fdc, 0));
 1036                 return (1);
 1037         }
 1038 
 1039         /*
 1040          * If we are dead just flush the requests
 1041          */
 1042         if (fd->flags & FD_EMPTY)
 1043                 return (fdc_biodone(fdc, ENXIO));
 1044 
 1045 #ifndef PC98
 1046         /* Check if we lost our media */
 1047         if (fdin_rd(fdc) & FDI_DCHG) {
 1048                 if (debugflags & 0x40)
 1049                         printf("Lost disk\n");
 1050                 mtx_lock(&fdc->fdc_mtx);
 1051                 fd->flags |= FD_EMPTY;
 1052                 fd->flags |= FD_NEWDISK;
 1053                 mtx_unlock(&fdc->fdc_mtx);
 1054                 g_topology_lock();
 1055                 g_orphan_provider(fd->fd_provider, ENXIO);
 1056                 fd->fd_provider->flags |= G_PF_WITHER;
 1057                 fd->fd_provider =
 1058                     g_new_providerf(fd->fd_geom, "%s", fd->fd_geom->name);
 1059                 g_error_provider(fd->fd_provider, 0);
 1060                 g_topology_unlock();
 1061                 return (fdc_biodone(fdc, ENXIO));
 1062         }
 1063 #endif
 1064 
 1065         /* Check if the floppy is write-protected */
 1066         if (bp->bio_cmd == BIO_FMT || bp->bio_cmd == BIO_WRITE) {
 1067                 retry_line = __LINE__;
 1068                 if(fdc_sense_drive(fdc, &st3) != 0)
 1069                         return (1);
 1070                 if(st3 & NE7_ST3_WP)
 1071                         return (fdc_biodone(fdc, EROFS));
 1072         }
 1073 
 1074         mfm = (fd->ft->flags & FL_MFM)? NE7CMD_MFM: 0;
 1075         steptrac = (fd->ft->flags & FL_2STEP)? 2: 1;
 1076         i = fd->ft->sectrac * fd->ft->heads;
 1077         cylinder = bp->bio_pblkno / i;
 1078         descyl = cylinder * steptrac;
 1079         sec = bp->bio_pblkno % i;
 1080         nsect = i - sec;
 1081         head = sec / fd->ft->sectrac;
 1082         sec = sec % fd->ft->sectrac + 1;
 1083 
 1084         /* If everything is going swimmingly, use multisector xfer */
 1085         if (fdc->retry == 0 &&
 1086             (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE)) {
 1087                 fd->fd_iosize = imin(nsect * fd->sectorsize, bp->bio_resid);
 1088                 nsect = fd->fd_iosize / fd->sectorsize;
 1089         } else if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
 1090                 fd->fd_iosize = fd->sectorsize;
 1091                 nsect = 1;
 1092         }
 1093 
 1094         /* Do RECAL if we need to or are going to track zero anyway */
 1095         if ((need_recal & (1 << fd->fdsu)) ||
 1096             (cylinder == 0 && fd->track != 0) ||
 1097             fdc->retry > 2) {
 1098 #ifdef PC98
 1099                 pc98_fd_check_ready(fd);
 1100 #endif
 1101                 retry_line = __LINE__;
 1102                 if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fd->fdsu, 0))
 1103                         return (1);
 1104                 tsleep(fdc, PRIBIO, "fdrecal", hz);
 1105                 retry_line = __LINE__;
 1106                 if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
 1107                         return (1); /* XXX */
 1108                 retry_line = __LINE__;
 1109                 if ((st0 & 0xc0) || cyl != 0)
 1110                         return (1);
 1111                 need_recal &= ~(1 << fd->fdsu);
 1112                 fd->track = 0;
 1113                 /* let the heads settle */
 1114                 if (settle)
 1115                         tsleep(fdc->fd, PRIBIO, "fdhdstl", settle);
 1116         }
 1117 
 1118         /*
 1119          * SEEK to where we want to be
 1120          */
 1121         if (cylinder != fd->track) {
 1122 #ifdef PC98
 1123                 pc98_fd_check_ready(fd);
 1124 #endif          
 1125                 retry_line = __LINE__;
 1126                 if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, descyl, 0))
 1127                         return (1);
 1128                 tsleep(fdc, PRIBIO, "fdseek", hz);
 1129                 retry_line = __LINE__;
 1130                 if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
 1131                         return (1); /* XXX */
 1132                 retry_line = __LINE__;
 1133                 if ((st0 & 0xc0) || cyl != descyl) {
 1134                         need_recal |= (1 << fd->fdsu);
 1135                         return (1);
 1136                 }
 1137                 /* let the heads settle */
 1138                 if (settle)
 1139                         tsleep(fdc->fd, PRIBIO, "fdhdstl", settle);
 1140         }
 1141         fd->track = cylinder;
 1142 
 1143         if (debugflags & 8)
 1144                 printf("op %x bn %ju siz %u ptr %p retry %d\n",
 1145                     bp->bio_cmd, bp->bio_pblkno, fd->fd_iosize,
 1146                     fd->fd_ioptr, fdc->retry);
 1147 
 1148         /* Setup ISADMA if we need it and have it */
 1149         if ((bp->bio_cmd == BIO_READ ||
 1150                 bp->bio_cmd == BIO_WRITE ||
 1151                 bp->bio_cmd == BIO_FMT)
 1152              && !(fdc->flags & FDC_NODMA)) {
 1153                 isa_dmastart(
 1154                     bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE,
 1155                     fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
 1156                 mtx_lock(&fdc->fdc_mtx);
 1157                 fd->flags |= FD_ISADMA;
 1158                 mtx_unlock(&fdc->fdc_mtx);
 1159         }
 1160 
 1161         /* Do PIO if we have to */
 1162         if (fdc->flags & FDC_NODMA) {
 1163                 if (bp->bio_cmd == BIO_READ ||
 1164                     bp->bio_cmd == BIO_WRITE ||
 1165                     bp->bio_cmd == BIO_FMT)
 1166                         fdbcdr_wr(fdc, 1, fd->fd_iosize);
 1167                 if (bp->bio_cmd == BIO_WRITE ||
 1168                     bp->bio_cmd == BIO_FMT)
 1169                         fdc_pio(fdc);
 1170         }
 1171 
 1172         switch(bp->bio_cmd) {
 1173         case BIO_FMT:
 1174                 /* formatting */
 1175                 finfo = (struct fd_formb *)bp->bio_data;
 1176                 retry_line = __LINE__;
 1177                 if (fdc_cmd(fdc, 6,
 1178                     NE7CMD_FORMAT | mfm,
 1179                     head << 2 | fd->fdsu,
 1180                     finfo->fd_formb_secshift,
 1181                     finfo->fd_formb_nsecs,
 1182                     finfo->fd_formb_gaplen,
 1183                     finfo->fd_formb_fillbyte, 0))
 1184                         return (1);
 1185                 break;
 1186         case BIO_RDID:
 1187                 retry_line = __LINE__;
 1188                 if (fdc_cmd(fdc, 2,
 1189                     NE7CMD_READID | mfm,
 1190                     head << 2 | fd->fdsu, 0))
 1191                         return (1);
 1192                 break;
 1193         case BIO_READ:
 1194                 retry_line = __LINE__;
 1195                 if (fdc_cmd(fdc, 9,
 1196                     NE7CMD_READ | NE7CMD_SK | mfm | NE7CMD_MT,
 1197                     head << 2 | fd->fdsu,       /* head & unit */
 1198                     fd->track,                  /* track */
 1199                     head,                       /* head */
 1200                     sec,                        /* sector + 1 */
 1201                     fd->ft->secsize,            /* sector size */
 1202                     fd->ft->sectrac,            /* sectors/track */
 1203                     fd->ft->gap,                /* gap size */
 1204                     fd->ft->datalen,            /* data length */
 1205                     0))
 1206                         return (1);
 1207                 break;
 1208         case BIO_WRITE:
 1209                 retry_line = __LINE__;
 1210                 if (fdc_cmd(fdc, 9,
 1211                     NE7CMD_WRITE | mfm | NE7CMD_MT,
 1212                     head << 2 | fd->fdsu,       /* head & unit */
 1213                     fd->track,                  /* track */
 1214                     head,                       /* head */
 1215                     sec,                        /* sector + 1 */
 1216                     fd->ft->secsize,            /* sector size */
 1217                     fd->ft->sectrac,            /* sectors/track */
 1218                     fd->ft->gap,                /* gap size */
 1219                     fd->ft->datalen,            /* data length */
 1220                     0))
 1221                         return (1);
 1222                 break;
 1223         default:
 1224                 KASSERT(0 == 1, ("Wrong bio_cmd %x\n", bp->bio_cmd));
 1225         }
 1226 
 1227         /* Wait for interrupt */
 1228         i = tsleep(fdc, PRIBIO, "fddata", hz);
 1229 
 1230         /* PIO if the read looks good */
 1231         if (i == 0 && (fdc->flags & FDC_NODMA) && (bp->bio_cmd == BIO_READ))
 1232                 fdc_pio(fdc);
 1233 
 1234         /* Finish DMA */
 1235         if (fd->flags & FD_ISADMA) {
 1236                 isa_dmadone(
 1237                     bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE,
 1238                     fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
 1239                 mtx_lock(&fdc->fdc_mtx);
 1240                 fd->flags &= ~FD_ISADMA;
 1241                 mtx_unlock(&fdc->fdc_mtx);
 1242         }
 1243 
 1244         if (i != 0) {
 1245                 /*
 1246                  * Timeout.
 1247                  *
 1248                  * Due to IBM's brain-dead design, the FDC has a faked ready
 1249                  * signal, hardwired to ready == true. Thus, any command
 1250                  * issued if there's no diskette in the drive will _never_
 1251                  * complete, and must be aborted by resetting the FDC.
 1252                  * Many thanks, Big Blue!
 1253                  */
 1254                 retry_line = __LINE__;
 1255                 fdc->flags |= FDC_NEEDS_RESET;
 1256                 return (1);
 1257         }
 1258 
 1259         retry_line = __LINE__;
 1260         if (fdc_read_status(fdc))
 1261                 return (1);
 1262 
 1263         if (debugflags & 0x10)
 1264                 printf("  -> %x %x %x %x\n",
 1265                     fdc->status[0], fdc->status[1],
 1266                     fdc->status[2], fdc->status[3]);
 1267 
 1268         st0 = fdc->status[0] & NE7_ST0_IC;
 1269         if (st0 != 0) {
 1270                 retry_line = __LINE__;
 1271                 if (st0 == NE7_ST0_IC_AT && fdc->status[1] & NE7_ST1_OR) {
 1272                         /*
 1273                          * DMA overrun. Someone hogged the bus and
 1274                          * didn't release it in time for the next
 1275                          * FDC transfer.
 1276                          */
 1277                         return (1);
 1278                 }
 1279                 retry_line = __LINE__;
 1280                 if(st0 == NE7_ST0_IC_IV) {
 1281                         fdc->flags |= FDC_NEEDS_RESET;
 1282                         return (1);
 1283                 }
 1284                 retry_line = __LINE__;
 1285                 if(st0 == NE7_ST0_IC_AT && fdc->status[2] & NE7_ST2_WC) {
 1286                         need_recal |= (1 << fd->fdsu);
 1287                         return (1);
 1288                 }
 1289                 if (debugflags & 0x20) {
 1290                         printf("status %02x %02x %02x %02x %02x %02x\n",
 1291                             fdc->status[0], fdc->status[1], fdc->status[2],
 1292                             fdc->status[3], fdc->status[4], fdc->status[5]);
 1293                 }
 1294                 retry_line = __LINE__;
 1295                 if (fd->options & FDOPT_NOERROR)
 1296                         override_error = 1;
 1297                 else
 1298                         return (1);
 1299         }
 1300         /* All OK */
 1301         switch(bp->bio_cmd) {
 1302         case BIO_RDID:
 1303                 /* copy out ID field contents */
 1304                 idp = (struct fdc_readid *)bp->bio_data;
 1305                 idp->cyl = fdc->status[3];
 1306                 idp->head = fdc->status[4];
 1307                 idp->sec = fdc->status[5];
 1308                 idp->secshift = fdc->status[6];
 1309                 if (debugflags & 0x40)
 1310                         printf("c %d h %d s %d z %d\n",
 1311                             idp->cyl, idp->head, idp->sec, idp->secshift);
 1312                 break;
 1313         case BIO_READ:
 1314         case BIO_WRITE:
 1315                 bp->bio_pblkno += nsect;
 1316                 bp->bio_resid -= fd->fd_iosize;
 1317                 bp->bio_completed += fd->fd_iosize;
 1318                 fd->fd_ioptr += fd->fd_iosize;
 1319                 if (override_error) {
 1320                         if ((debugflags & 4))
 1321                                 printf("FDOPT_NOERROR: returning bad data\n");
 1322                 } else {
 1323                         /* Since we managed to get something done,
 1324                          * reset the retry */
 1325                         fdc->retry = 0;
 1326                         if (bp->bio_resid > 0)
 1327                                 return (0);
 1328                 }
 1329                 break;
 1330         case BIO_FMT:
 1331                 break;
 1332         }
 1333         return (fdc_biodone(fdc, 0));
 1334 }
 1335 
 1336 static void
 1337 fdc_thread(void *arg)
 1338 {
 1339         struct fdc_data *fdc;
 1340 
 1341         fdc = arg;
 1342         int i;
 1343 
 1344         mtx_lock(&fdc->fdc_mtx);
 1345         fdc->flags |= FDC_KTHREAD_ALIVE;
 1346         while ((fdc->flags & FDC_KTHREAD_EXIT) == 0) {
 1347                 mtx_unlock(&fdc->fdc_mtx);
 1348                 i = fdc_worker(fdc);
 1349                 if (i && debugflags & 0x20) {
 1350                         if (fdc->bp != NULL) {
 1351                                 g_print_bio(fdc->bp);
 1352                                 printf("\n");
 1353                         }
 1354                         printf("Retry line %d\n", retry_line);
 1355                 }
 1356                 fdc->retry += i;
 1357                 mtx_lock(&fdc->fdc_mtx);
 1358         }
 1359         fdc->flags &= ~(FDC_KTHREAD_EXIT | FDC_KTHREAD_ALIVE);
 1360         mtx_unlock(&fdc->fdc_mtx);
 1361 
 1362         kproc_exit(0);
 1363 }
 1364 
 1365 /*
 1366  * Enqueue a request.
 1367  */
 1368 static void
 1369 fd_enqueue(struct fd_data *fd, struct bio *bp)
 1370 {
 1371         struct fdc_data *fdc;
 1372         int call;
 1373 
 1374         call = 0;
 1375         fdc = fd->fdc;
 1376         mtx_lock(&fdc->fdc_mtx);
 1377         /* If we go from idle, cancel motor turnoff */
 1378         if (fd->fd_iocount++ == 0)
 1379                 callout_stop(&fd->toffhandle);
 1380         if (fd->flags & FD_MOTOR) {
 1381                 /* The motor is on, send it directly to the controller */
 1382                 bioq_disksort(&fdc->head, bp);
 1383                 wakeup(&fdc->head);
 1384         } else {
 1385                 /* Queue it on the drive until the motor has started */
 1386                 bioq_insert_tail(&fd->fd_bq, bp);
 1387                 if (!(fd->flags & FD_MOTORWAIT))
 1388                         fd_motor(fd, 1);
 1389         }
 1390         mtx_unlock(&fdc->fdc_mtx);
 1391 }
 1392 
 1393 /*
 1394  * Try to find out if we have a disk in the drive.
 1395  */
 1396 static int
 1397 fd_probe_disk(struct fd_data *fd, int *recal)
 1398 {
 1399         struct fdc_data *fdc;
 1400         int st0, st3, cyl;
 1401         int oopts, ret;
 1402 
 1403         fdc = fd->fdc;
 1404         oopts = fd->options;
 1405         fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY;
 1406         ret = 1;
 1407 
 1408         /*
 1409          * First recal, then seek to cyl#1, this clears the old condition on
 1410          * the disk change line so we can examine it for current status.
 1411          */
 1412         if (debugflags & 0x40)
 1413                 printf("New disk in probe\n");
 1414         mtx_lock(&fdc->fdc_mtx);
 1415         fd->flags |= FD_NEWDISK;
 1416         mtx_unlock(&fdc->fdc_mtx);
 1417         if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fd->fdsu, 0))
 1418                 goto done;
 1419         tsleep(fdc, PRIBIO, "fdrecal", hz);
 1420         if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
 1421                 goto done;      /* XXX */
 1422         if ((st0 & 0xc0) || cyl != 0)
 1423                 goto done;
 1424 
 1425         /* Seek to track 1 */
 1426         if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, 1, 0))
 1427                 goto done;
 1428         tsleep(fdc, PRIBIO, "fdseek", hz);
 1429         if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
 1430                 goto done;      /* XXX */
 1431         *recal |= (1 << fd->fdsu);
 1432 #ifndef PC98
 1433         if (fdin_rd(fdc) & FDI_DCHG) {
 1434                 if (debugflags & 0x40)
 1435                         printf("Empty in probe\n");
 1436                 mtx_lock(&fdc->fdc_mtx);
 1437                 fd->flags |= FD_EMPTY;
 1438                 mtx_unlock(&fdc->fdc_mtx);
 1439         } else {
 1440 #else
 1441         {
 1442 #endif
 1443                 if (fdc_sense_drive(fdc, &st3) != 0)
 1444                         goto done;
 1445                 if (debugflags & 0x40)
 1446                         printf("Got disk in probe\n");
 1447                 mtx_lock(&fdc->fdc_mtx);
 1448                 fd->flags &= ~FD_EMPTY;
 1449                 if (st3 & NE7_ST3_WP)
 1450                         fd->flags |= FD_WP;
 1451                 else
 1452                         fd->flags &= ~FD_WP;
 1453                 mtx_unlock(&fdc->fdc_mtx);
 1454         }
 1455         ret = 0;
 1456 
 1457 done:
 1458         fd->options = oopts;
 1459         return (ret);
 1460 }
 1461 
 1462 static int
 1463 fdmisccmd(struct fd_data *fd, u_int cmd, void *data)
 1464 {
 1465         struct bio *bp;
 1466         struct fd_formb *finfo;
 1467         struct fdc_readid *idfield;
 1468         int error;
 1469 
 1470         bp = malloc(sizeof(struct bio), M_TEMP, M_WAITOK | M_ZERO);
 1471 
 1472         /*
 1473          * Set up a bio request for fdstrategy().  bio_offset is faked
 1474          * so that fdstrategy() will seek to the requested
 1475          * cylinder, and use the desired head.
 1476          */
 1477         bp->bio_cmd = cmd;
 1478         if (cmd == BIO_FMT) {
 1479                 finfo = (struct fd_formb *)data;
 1480                 bp->bio_pblkno =
 1481                     (finfo->cyl * fd->ft->heads + finfo->head) *
 1482                     fd->ft->sectrac;
 1483                 bp->bio_length = sizeof *finfo;
 1484         } else if (cmd == BIO_RDID) {
 1485                 idfield = (struct fdc_readid *)data;
 1486                 bp->bio_pblkno =
 1487                     (idfield->cyl * fd->ft->heads + idfield->head) *
 1488                     fd->ft->sectrac;
 1489                 bp->bio_length = sizeof(struct fdc_readid);
 1490         } else if (cmd == BIO_PROBE) {
 1491                 /* nothing */
 1492         } else
 1493                 panic("wrong cmd in fdmisccmd()");
 1494         bp->bio_offset = bp->bio_pblkno * fd->sectorsize;
 1495         bp->bio_data = data;
 1496         bp->bio_driver1 = fd;
 1497         bp->bio_flags = 0;
 1498 
 1499         fd_enqueue(fd, bp);
 1500 
 1501         do {
 1502                 tsleep(bp, PRIBIO, "fdwait", hz);
 1503         } while (!(bp->bio_flags & BIO_DONE));
 1504         error = bp->bio_error;
 1505 
 1506         free(bp, M_TEMP);
 1507         return (error);
 1508 }
 1509 
 1510 /*
 1511  * Try figuring out the density of the media present in our device.
 1512  */
 1513 static int
 1514 fdautoselect(struct fd_data *fd)
 1515 {
 1516         struct fd_type *fdtp;
 1517         struct fdc_readid id;
 1518         int oopts, rv;
 1519 
 1520         if (!(fd->ft->flags & FL_AUTO))
 1521                 return (0);
 1522 
 1523         fdtp = fd_native_types[fd->type];
 1524         fdsettype(fd, fdtp);
 1525         if (!(fd->ft->flags & FL_AUTO))
 1526                 return (0);
 1527 
 1528         /*
 1529          * Try reading sector ID fields, first at cylinder 0, head 0,
 1530          * then at cylinder 2, head N.  We don't probe cylinder 1,
 1531          * since for 5.25in DD media in a HD drive, there are no data
 1532          * to read (2 step pulses per media cylinder required).  For
 1533          * two-sided media, the second probe always goes to head 1, so
 1534          * we can tell them apart from single-sided media.  As a
 1535          * side-effect this means that single-sided media should be
 1536          * mentioned in the search list after two-sided media of an
 1537          * otherwise identical density.  Media with a different number
 1538          * of sectors per track but otherwise identical parameters
 1539          * cannot be distinguished at all.
 1540          *
 1541          * If we successfully read an ID field on both cylinders where
 1542          * the recorded values match our expectation, we are done.
 1543          * Otherwise, we try the next density entry from the table.
 1544          *
 1545          * Stepping to cylinder 2 has the side-effect of clearing the
 1546          * unit attention bit.
 1547          */
 1548         oopts = fd->options;
 1549         fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY;
 1550         for (; fdtp->heads; fdtp++) {
 1551                 fdsettype(fd, fdtp);
 1552 
 1553                 id.cyl = id.head = 0;
 1554                 rv = fdmisccmd(fd, BIO_RDID, &id);
 1555                 if (rv != 0)
 1556                         continue;
 1557                 if (id.cyl != 0 || id.head != 0 || id.secshift != fdtp->secsize)
 1558                         continue;
 1559                 id.cyl = 2;
 1560                 id.head = fd->ft->heads - 1;
 1561                 rv = fdmisccmd(fd, BIO_RDID, &id);
 1562                 if (id.cyl != 2 || id.head != fdtp->heads - 1 ||
 1563                     id.secshift != fdtp->secsize)
 1564                         continue;
 1565                 if (rv == 0)
 1566                         break;
 1567         }
 1568 
 1569         fd->options = oopts;
 1570         if (fdtp->heads == 0) {
 1571                 if (debugflags & 0x40)
 1572                         device_printf(fd->dev, "autoselection failed\n");
 1573                 fdsettype(fd, fd_native_types[fd->type]);
 1574                 return (-1);
 1575         } else {
 1576                 if (debugflags & 0x40) {
 1577                         device_printf(fd->dev,
 1578                             "autoselected %d KB medium\n",
 1579 #ifdef PC98
 1580                             (128 << (fd->ft->secsize)) * fd->ft->size / 1024);
 1581 #else
 1582                             fd->ft->size / 2);
 1583 #endif
 1584                         fdprinttype(fd->ft);
 1585                 }
 1586                 return (0);
 1587         }
 1588 }
 1589 
 1590 /*
 1591  * GEOM class implementation
 1592  */
 1593 
 1594 static g_access_t       fd_access;
 1595 static g_start_t        fd_start;
 1596 static g_ioctl_t        fd_ioctl;
 1597 
 1598 struct g_class g_fd_class = {
 1599         .name =         "FD",
 1600         .version =      G_VERSION,
 1601         .start =        fd_start,
 1602         .access =       fd_access,
 1603         .ioctl =        fd_ioctl,
 1604 };
 1605 
 1606 static int
 1607 fd_access(struct g_provider *pp, int r, int w, int e)
 1608 {
 1609         struct fd_data *fd;
 1610         struct fdc_data *fdc;
 1611         int ar, aw, ae;
 1612         int busy;
 1613 
 1614         fd = pp->geom->softc;
 1615         fdc = fd->fdc;
 1616 
 1617         /*
 1618          * If our provider is withering, we can only get negative requests
 1619          * and we don't want to even see them
 1620          */
 1621         if (pp->flags & G_PF_WITHER)
 1622                 return (0);
 1623 
 1624         ar = r + pp->acr;
 1625         aw = w + pp->acw;
 1626         ae = e + pp->ace;
 1627 
 1628         if (ar == 0 && aw == 0 && ae == 0) {
 1629                 fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR);
 1630                 device_unbusy(fd->dev);
 1631                 return (0);
 1632         }
 1633 
 1634         busy = 0;
 1635         if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) {
 1636 #ifdef PC98
 1637                 if (pc98_fd_check_ready(fd) == -1)
 1638                         return (ENXIO);
 1639 #endif
 1640                 if (fdmisccmd(fd, BIO_PROBE, NULL))
 1641                         return (ENXIO);
 1642                 if (fd->flags & FD_EMPTY)
 1643                         return (ENXIO);
 1644                 if (fd->flags & FD_NEWDISK) {
 1645                         if (fdautoselect(fd) != 0 &&
 1646                             (device_get_flags(fd->dev) & FD_NO_CHLINE)) {
 1647                                 mtx_lock(&fdc->fdc_mtx);
 1648                                 fd->flags |= FD_EMPTY;
 1649                                 mtx_unlock(&fdc->fdc_mtx);
 1650                                 return (ENXIO);
 1651                         }
 1652                         mtx_lock(&fdc->fdc_mtx);
 1653                         fd->flags &= ~FD_NEWDISK;
 1654                         mtx_unlock(&fdc->fdc_mtx);
 1655                 }
 1656                 device_busy(fd->dev);
 1657                 busy = 1;
 1658         }
 1659 
 1660         if (w > 0 && (fd->flags & FD_WP)) {
 1661                 if (busy)
 1662                         device_unbusy(fd->dev);
 1663                 return (EROFS);
 1664         }
 1665 
 1666         pp->sectorsize = fd->sectorsize;
 1667         pp->stripesize = fd->ft->heads * fd->ft->sectrac * fd->sectorsize;
 1668         pp->mediasize = pp->stripesize * fd->ft->tracks;
 1669         return (0);
 1670 }
 1671 
 1672 static void
 1673 fd_start(struct bio *bp)
 1674 {
 1675         struct fdc_data *       fdc;
 1676         struct fd_data *        fd;
 1677 
 1678         fd = bp->bio_to->geom->softc;
 1679         fdc = fd->fdc;
 1680         bp->bio_driver1 = fd;
 1681         if (bp->bio_cmd == BIO_GETATTR) {
 1682                 if (g_handleattr_int(bp, "GEOM::fwsectors", fd->ft->sectrac))
 1683                         return;
 1684                 if (g_handleattr_int(bp, "GEOM::fwheads", fd->ft->heads))
 1685                         return;
 1686                 g_io_deliver(bp, ENOIOCTL);
 1687                 return;
 1688         }
 1689         if (!(bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE)) {
 1690                 g_io_deliver(bp, EOPNOTSUPP);
 1691                 return;
 1692         }
 1693         bp->bio_pblkno = bp->bio_offset / fd->sectorsize;
 1694         bp->bio_resid = bp->bio_length;
 1695         fd_enqueue(fd, bp);
 1696         return;
 1697 }
 1698 
 1699 static int
 1700 fd_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td)
 1701 {
 1702         struct fd_data *fd;
 1703         struct fdc_status *fsp;
 1704         struct fdc_readid *rid;
 1705         int error;
 1706 
 1707         fd = pp->geom->softc;
 1708 
 1709 #ifdef PC98
 1710         pc98_fd_check_ready(fd);
 1711 #endif  
 1712 
 1713         switch (cmd) {
 1714         case FD_GTYPE:                  /* get drive type */
 1715                 *(struct fd_type *)data = *fd->ft;
 1716                 return (0);
 1717 
 1718         case FD_STYPE:                  /* set drive type */
 1719                 /*
 1720                  * Allow setting drive type temporarily iff
 1721                  * currently unset.  Used for fdformat so any
 1722                  * user can set it, and then start formatting.
 1723                  */
 1724                 fd->fts = *(struct fd_type *)data;
 1725                 if (fd->fts.sectrac) {
 1726                         /* XXX: check for rubbish */
 1727                         fdsettype(fd, &fd->fts);
 1728                 } else {
 1729                         fdsettype(fd, fd_native_types[fd->type]);
 1730                 }
 1731                 if (debugflags & 0x40)
 1732                         fdprinttype(fd->ft);
 1733                 return (0);
 1734 
 1735         case FD_GOPTS:                  /* get drive options */
 1736                 *(int *)data = fd->options;
 1737                 return (0);
 1738 
 1739         case FD_SOPTS:                  /* set drive options */
 1740                 fd->options = *(int *)data;
 1741                 return (0);
 1742 
 1743         case FD_CLRERR:
 1744                 error = priv_check(td, PRIV_DRIVER);
 1745                 if (error)
 1746                         return (error);
 1747                 fd->fdc->fdc_errs = 0;
 1748                 return (0);
 1749 
 1750         case FD_GSTAT:
 1751                 fsp = (struct fdc_status *)data;
 1752                 if ((fd->fdc->flags & FDC_STAT_VALID) == 0)
 1753                         return (EINVAL);
 1754                 memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int));
 1755                 return (0);
 1756 
 1757         case FD_GDTYPE:
 1758                 *(enum fd_drivetype *)data = fd->type;
 1759                 return (0);
 1760 
 1761         case FD_FORM:
 1762                 if (!(fflag & FWRITE))
 1763                         return (EPERM);
 1764                 if (((struct fd_formb *)data)->format_version !=
 1765                     FD_FORMAT_VERSION)
 1766                         return (EINVAL); /* wrong version of formatting prog */
 1767                 error = fdmisccmd(fd, BIO_FMT, data);
 1768                 mtx_lock(&fd->fdc->fdc_mtx);
 1769                 fd->flags |= FD_NEWDISK;
 1770                 mtx_unlock(&fd->fdc->fdc_mtx);
 1771                 break;
 1772 
 1773         case FD_READID:
 1774                 rid = (struct fdc_readid *)data;
 1775                 if (rid->cyl > 85 || rid->head > 1)
 1776                         return (EINVAL);
 1777                 error = fdmisccmd(fd, BIO_RDID, data);
 1778                 break;
 1779 
 1780         case FIONBIO:
 1781         case FIOASYNC:
 1782                 /* For backwards compat with old fd*(8) tools */
 1783                 error = 0;
 1784                 break;
 1785 
 1786         default:
 1787                 if (debugflags & 0x80)
 1788                         printf("Unknown ioctl %lx\n", cmd);
 1789                 error = ENOIOCTL;
 1790                 break;
 1791         }
 1792         return (error);
 1793 };
 1794 
 1795 
 1796 
 1797 /*
 1798  * Configuration/initialization stuff, per controller.
 1799  */
 1800 
 1801 devclass_t fdc_devclass;
 1802 static devclass_t fd_devclass;
 1803 
 1804 struct fdc_ivars {
 1805         int     fdunit;
 1806         int     fdtype;
 1807 };
 1808 
 1809 void
 1810 fdc_release_resources(struct fdc_data *fdc)
 1811 {
 1812         device_t dev;
 1813         struct resource *last;
 1814         int i;
 1815 
 1816         dev = fdc->fdc_dev;
 1817         if (fdc->fdc_intr)
 1818                 bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr);
 1819         fdc->fdc_intr = NULL;
 1820         if (fdc->res_irq != NULL)
 1821                 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
 1822                     fdc->res_irq);
 1823         fdc->res_irq = NULL;
 1824         last = NULL;
 1825         for (i = 0; i < FDC_MAXREG; i++) {
 1826                 if (fdc->resio[i] != NULL && fdc->resio[i] != last) {
 1827                         bus_release_resource(dev, SYS_RES_IOPORT,
 1828                             fdc->ridio[i], fdc->resio[i]);
 1829                         last = fdc->resio[i];
 1830                         fdc->resio[i] = NULL;
 1831                 }
 1832         }
 1833         if (fdc->res_drq != NULL)
 1834                 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
 1835                     fdc->res_drq);
 1836         fdc->res_drq = NULL;
 1837 }
 1838 
 1839 int
 1840 fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
 1841 {
 1842         struct fdc_ivars *ivars = device_get_ivars(child);
 1843 
 1844         switch (which) {
 1845         case FDC_IVAR_FDUNIT:
 1846                 *result = ivars->fdunit;
 1847                 break;
 1848         case FDC_IVAR_FDTYPE:
 1849                 *result = ivars->fdtype;
 1850                 break;
 1851         default:
 1852                 return (ENOENT);
 1853         }
 1854         return (0);
 1855 }
 1856 
 1857 int
 1858 fdc_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
 1859 {
 1860         struct fdc_ivars *ivars = device_get_ivars(child);
 1861 
 1862         switch (which) {
 1863         case FDC_IVAR_FDUNIT:
 1864                 ivars->fdunit = value;
 1865                 break;
 1866         case FDC_IVAR_FDTYPE:
 1867                 ivars->fdtype = value;
 1868                 break;
 1869         default:
 1870                 return (ENOENT);
 1871         }
 1872         return (0);
 1873 }
 1874 
 1875 int
 1876 fdc_initial_reset(device_t dev, struct fdc_data *fdc)
 1877 {
 1878         int ic_type, part_id;
 1879 
 1880 #ifdef PC98
 1881         /* See if it can handle a command. */
 1882         if (fdc_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240),
 1883             NE7_SPEC_2(2, 0), 0))
 1884                 return (ENXIO);
 1885 #else
 1886         /*
 1887          * A status value of 0xff is very unlikely, but not theoretically
 1888          * impossible, but it is far more likely to indicate an empty bus.
 1889          */
 1890         if (fdsts_rd(fdc) == 0xff)
 1891                 return (ENXIO);
 1892 
 1893         /*
 1894          * Assert a reset to the floppy controller and check that the status
 1895          * register goes to zero.
 1896          */
 1897         fdout_wr(fdc, 0);
 1898         fdout_wr(fdc, 0);
 1899         if (fdsts_rd(fdc) != 0)
 1900                 return (ENXIO);
 1901 
 1902         /*
 1903          * Clear the reset and see it come ready.
 1904          */
 1905         fdout_wr(fdc, FDO_FRST);
 1906         DELAY(100);
 1907         if (fdsts_rd(fdc) != 0x80)
 1908                 return (ENXIO);
 1909 
 1910         /* Then, see if it can handle a command. */
 1911         if (fdc_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(6, 240),
 1912             NE7_SPEC_2(31, 0), 0))
 1913                 return (ENXIO);
 1914 #endif
 1915 
 1916         /*
 1917          * Try to identify the chip.
 1918          *
 1919          * The i8272 datasheet documents that unknown commands
 1920          * will return ST0 as 0x80.  The i8272 is supposedly identical
 1921          * to the NEC765.
 1922          * The i82077SL datasheet says 0x90 for the VERSION command,
 1923          * and several "superio" chips emulate this.
 1924          */
 1925         if (fdc_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type))
 1926                 return (ENXIO);
 1927         if (fdc_cmd(fdc, 1, 0x18, 1, &part_id))
 1928                 return (ENXIO);
 1929         if (bootverbose)
 1930                 device_printf(dev,
 1931                     "ic_type %02x part_id %02x\n", ic_type, part_id);
 1932         switch (ic_type & 0xff) {
 1933         case 0x80:
 1934                 device_set_desc(dev, "NEC 765 or clone");
 1935                 fdc->fdct = FDC_NE765;
 1936                 break;
 1937         case 0x81:
 1938         case 0x90:
 1939                 device_set_desc(dev,
 1940                     "Enhanced floppy controller");
 1941                 fdc->fdct = FDC_ENHANCED;
 1942                 break;
 1943         default:
 1944                 device_set_desc(dev, "Generic floppy controller");
 1945                 fdc->fdct = FDC_UNKNOWN;
 1946                 break;
 1947         }
 1948         return (0);
 1949 }
 1950 
 1951 int
 1952 fdc_detach(device_t dev)
 1953 {
 1954         struct  fdc_data *fdc;
 1955         int     error;
 1956 
 1957         fdc = device_get_softc(dev);
 1958 
 1959         /* have our children detached first */
 1960         if ((error = bus_generic_detach(dev)))
 1961                 return (error);
 1962 
 1963         if (fdc->fdc_intr)
 1964                 bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr);
 1965         fdc->fdc_intr = NULL;
 1966 
 1967         /* kill worker thread */
 1968         mtx_lock(&fdc->fdc_mtx);
 1969         fdc->flags |= FDC_KTHREAD_EXIT;
 1970         wakeup(&fdc->head);
 1971         while ((fdc->flags & FDC_KTHREAD_ALIVE) != 0)
 1972                 msleep(fdc->fdc_thread, &fdc->fdc_mtx, PRIBIO, "fdcdet", 0);
 1973         mtx_unlock(&fdc->fdc_mtx);
 1974 
 1975         /* reset controller, turn motor off */
 1976 #ifdef PC98
 1977         fdc_reset(fdc);
 1978 #else
 1979         fdout_wr(fdc, 0);
 1980 #endif
 1981 
 1982         if (!(fdc->flags & FDC_NODMA))
 1983                 isa_dma_release(fdc->dmachan);
 1984         fdc_release_resources(fdc);
 1985         mtx_destroy(&fdc->fdc_mtx);
 1986         return (0);
 1987 }
 1988 
 1989 /*
 1990  * Add a child device to the fdc controller.  It will then be probed etc.
 1991  */
 1992 device_t
 1993 fdc_add_child(device_t dev, const char *name, int unit)
 1994 {
 1995         struct fdc_ivars *ivar;
 1996         device_t child;
 1997 
 1998         ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
 1999         if (ivar == NULL)
 2000                 return (NULL);
 2001         child = device_add_child(dev, name, unit);
 2002         if (child == NULL) {
 2003                 free(ivar, M_DEVBUF);
 2004                 return (NULL);
 2005         }
 2006         device_set_ivars(child, ivar);
 2007         ivar->fdunit = unit;
 2008         ivar->fdtype = FDT_NONE;
 2009         if (resource_disabled(name, unit))
 2010                 device_disable(child);
 2011         return (child);
 2012 }
 2013 
 2014 int
 2015 fdc_attach(device_t dev)
 2016 {
 2017         struct  fdc_data *fdc;
 2018         int     error;
 2019 
 2020         fdc = device_get_softc(dev);
 2021         fdc->fdc_dev = dev;
 2022         error = fdc_initial_reset(dev, fdc);
 2023         if (error) {
 2024                 device_printf(dev, "does not respond\n");
 2025                 return (error);
 2026         }
 2027         error = bus_setup_intr(dev, fdc->res_irq,
 2028             INTR_TYPE_BIO | INTR_ENTROPY | 
 2029             ((fdc->flags & FDC_NOFAST) ? INTR_MPSAFE : 0),                     
 2030             ((fdc->flags & FDC_NOFAST) ? NULL : fdc_intr_fast),             
 2031             ((fdc->flags & FDC_NOFAST) ? fdc_intr : NULL), 
 2032                                fdc, &fdc->fdc_intr);
 2033         if (error) {
 2034                 device_printf(dev, "cannot setup interrupt\n");
 2035                 return (error);
 2036         }
 2037         if (!(fdc->flags & FDC_NODMA)) {
 2038                 error = isa_dma_acquire(fdc->dmachan);
 2039                 if (!error) {
 2040                         error = isa_dma_init(fdc->dmachan,
 2041                             MAX_BYTES_PER_CYL, M_WAITOK);
 2042                         if (error)
 2043                                 isa_dma_release(fdc->dmachan);
 2044                 }
 2045                 if (error)
 2046                         return (error);
 2047         }
 2048         fdc->fdcu = device_get_unit(dev);
 2049         fdc->flags |= FDC_NEEDS_RESET;
 2050 
 2051         mtx_init(&fdc->fdc_mtx, "fdc lock", NULL, MTX_DEF);
 2052 
 2053         /* reset controller, turn motor off, clear fdout mirror reg */
 2054 #ifdef PC98
 2055         fdc_reset(fdc);
 2056 #else
 2057         fdout_wr(fdc, fdc->fdout = 0);
 2058 #endif
 2059         bioq_init(&fdc->head);
 2060 
 2061         settle = hz / 8;
 2062 
 2063         return (0);
 2064 }
 2065 
 2066 void
 2067 fdc_start_worker(device_t dev)
 2068 {
 2069         struct  fdc_data *fdc;
 2070 
 2071         fdc = device_get_softc(dev);
 2072         kproc_create(fdc_thread, fdc, &fdc->fdc_thread, 0, 0,
 2073             "fdc%d", device_get_unit(dev));
 2074 }
 2075 
 2076 int
 2077 fdc_hints_probe(device_t dev)
 2078 {
 2079         const char *name, *dname;
 2080         int i, error, dunit;
 2081 
 2082         /*
 2083          * Probe and attach any children.  We should probably detect
 2084          * devices from the BIOS unless overridden.
 2085          */
 2086         name = device_get_nameunit(dev);
 2087         i = 0;
 2088         while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) {
 2089                 resource_int_value(dname, dunit, "drive", &dunit);
 2090                 fdc_add_child(dev, dname, dunit);
 2091         }
 2092 
 2093         if ((error = bus_generic_attach(dev)) != 0)
 2094                 return (error);
 2095         return (0);
 2096 }
 2097 
 2098 int
 2099 fdc_print_child(device_t me, device_t child)
 2100 {
 2101         int retval = 0, flags;
 2102 
 2103         retval += bus_print_child_header(me, child);
 2104         retval += printf(" on %s drive %d", device_get_nameunit(me),
 2105                fdc_get_fdunit(child));
 2106         if ((flags = device_get_flags(me)) != 0)
 2107                 retval += printf(" flags %#x", flags);
 2108         retval += printf("\n");
 2109 
 2110         return (retval);
 2111 }
 2112 
 2113 /*
 2114  * Configuration/initialization, per drive.
 2115  */
 2116 static int
 2117 fd_probe(device_t dev)
 2118 {
 2119         int     unit;
 2120 #ifndef PC98
 2121         int     i;
 2122         u_int   st0, st3;
 2123 #endif
 2124         struct  fd_data *fd;
 2125         struct  fdc_data *fdc;
 2126         int     fdsu;
 2127         int     flags, type;
 2128 
 2129         fdsu = fdc_get_fdunit(dev);
 2130         fd = device_get_softc(dev);
 2131         fdc = device_get_softc(device_get_parent(dev));
 2132         flags = device_get_flags(dev);
 2133 
 2134         fd->dev = dev;
 2135         fd->fdc = fdc;
 2136         fd->fdsu = fdsu;
 2137         unit = device_get_unit(dev);
 2138 
 2139         /* Auto-probe if fdinfo is present, but always allow override. */
 2140         type = flags & FD_TYPEMASK;
 2141         if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) {
 2142                 fd->type = type;
 2143                 goto done;
 2144         } else {
 2145                 /* make sure fdautoselect() will be called */
 2146                 fd->flags = FD_EMPTY;
 2147                 fd->type = type;
 2148         }
 2149 
 2150 #ifdef PC98
 2151         pc98_fd_check_type(fd, unit);
 2152 #elif defined(__i386__) || defined(__amd64__)
 2153         if (fd->type == FDT_NONE && (unit == 0 || unit == 1)) {
 2154                 /* Look up what the BIOS thinks we have. */
 2155                 if (unit == 0)
 2156                         fd->type = (rtcin(RTC_FDISKETTE) & 0xf0) >> 4;
 2157                 else
 2158                         fd->type = rtcin(RTC_FDISKETTE) & 0x0f;
 2159                 if (fd->type == FDT_288M_1)
 2160                         fd->type = FDT_288M;
 2161         }
 2162 #endif /* __i386__ || __amd64__ */
 2163         /* is there a unit? */
 2164         if (fd->type == FDT_NONE)
 2165                 return (ENXIO);
 2166 
 2167 #ifndef PC98
 2168         mtx_lock(&fdc->fdc_mtx);
 2169 
 2170         /* select it */
 2171         fd_select(fd);
 2172         fd_motor(fd, 1);
 2173         fdc->fd = fd;
 2174         fdc_reset(fdc);         /* XXX reset, then unreset, etc. */
 2175         DELAY(1000000); /* 1 sec */
 2176 
 2177         if ((flags & FD_NO_PROBE) == 0) {
 2178                 /* If we're at track 0 first seek inwards. */
 2179                 if ((fdc_sense_drive(fdc, &st3) == 0) &&
 2180                     (st3 & NE7_ST3_T0)) {
 2181                         /* Seek some steps... */
 2182                         if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
 2183                                 /* ...wait a moment... */
 2184                                 DELAY(300000);
 2185                                 /* make ctrlr happy: */
 2186                                 fdc_sense_int(fdc, NULL, NULL);
 2187                         }
 2188                 }
 2189 
 2190                 for (i = 0; i < 2; i++) {
 2191                         /*
 2192                          * we must recalibrate twice, just in case the
 2193                          * heads have been beyond cylinder 76, since
 2194                          * most FDCs still barf when attempting to
 2195                          * recalibrate more than 77 steps
 2196                          */
 2197                         /* go back to 0: */
 2198                         if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
 2199                                 /* a second being enough for full stroke seek*/
 2200                                 DELAY(i == 0 ? 1000000 : 300000);
 2201 
 2202                                 /* anything responding? */
 2203                                 if (fdc_sense_int(fdc, &st0, NULL) == 0 &&
 2204                                     (st0 & NE7_ST0_EC) == 0)
 2205                                         break; /* already probed successfully */
 2206                         }
 2207                 }
 2208         }
 2209 
 2210         fd_motor(fd, 0);
 2211         fdc->fd = NULL;
 2212         mtx_unlock(&fdc->fdc_mtx);
 2213 
 2214         if ((flags & FD_NO_PROBE) == 0 &&
 2215             (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
 2216                 return (ENXIO);
 2217 #endif /* PC98 */
 2218 
 2219 done:
 2220 
 2221         switch (fd->type) {
 2222 #ifdef PC98
 2223         case FDT_144M:
 2224                 device_set_desc(dev, "1.44M FDD");
 2225                 break;
 2226         case FDT_12M:
 2227                 device_set_desc(dev, "1M/640K FDD");
 2228                 break;
 2229 #else
 2230         case FDT_12M:
 2231                 device_set_desc(dev, "1200-KB 5.25\" drive");
 2232                 break;
 2233         case FDT_144M:
 2234                 device_set_desc(dev, "1440-KB 3.5\" drive");
 2235                 break;
 2236         case FDT_288M:
 2237                 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
 2238                 break;
 2239         case FDT_360K:
 2240                 device_set_desc(dev, "360-KB 5.25\" drive");
 2241                 break;
 2242         case FDT_720K:
 2243                 device_set_desc(dev, "720-KB 3.5\" drive");
 2244                 break;
 2245 #endif
 2246         default:
 2247                 return (ENXIO);
 2248         }
 2249         fd->track = FD_NO_TRACK;
 2250         fd->fdc = fdc;
 2251         fd->fdsu = fdsu;
 2252         fd->options = 0;
 2253 #ifdef PC98
 2254         fd->pc98_trans = 0;
 2255 #endif
 2256         callout_init_mtx(&fd->toffhandle, &fd->fdc->fdc_mtx, 0);
 2257 
 2258         /* initialize densities for subdevices */
 2259         fdsettype(fd, fd_native_types[fd->type]);
 2260         return (0);
 2261 }
 2262 
 2263 /*
 2264  * We have to do this in a geom event because GEOM is not running
 2265  * when fd_attach() is.
 2266  * XXX: move fd_attach after geom like ata/scsi disks
 2267  */
 2268 static void
 2269 fd_attach2(void *arg, int flag)
 2270 {
 2271         struct  fd_data *fd;
 2272 
 2273         fd = arg;
 2274 
 2275         fd->fd_geom = g_new_geomf(&g_fd_class,
 2276             "fd%d", device_get_unit(fd->dev));
 2277         fd->fd_provider = g_new_providerf(fd->fd_geom, "%s", fd->fd_geom->name);
 2278         fd->fd_geom->softc = fd;
 2279         g_error_provider(fd->fd_provider, 0);
 2280 }
 2281 
 2282 static int
 2283 fd_attach(device_t dev)
 2284 {
 2285         struct  fd_data *fd;
 2286 
 2287         fd = device_get_softc(dev);
 2288         g_post_event(fd_attach2, fd, M_WAITOK, NULL);
 2289         fd->flags |= FD_EMPTY;
 2290         bioq_init(&fd->fd_bq);
 2291 
 2292         return (0);
 2293 }
 2294 
 2295 static void
 2296 fd_detach_geom(void *arg, int flag)
 2297 {
 2298         struct  fd_data *fd = arg;
 2299 
 2300         g_topology_assert();
 2301         g_wither_geom(fd->fd_geom, ENXIO);
 2302 }
 2303 
 2304 static int
 2305 fd_detach(device_t dev)
 2306 {
 2307         struct  fd_data *fd;
 2308 
 2309         fd = device_get_softc(dev);
 2310         g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL);
 2311         while (device_get_state(dev) == DS_BUSY)
 2312                 tsleep(fd, PZERO, "fdd", hz/10);
 2313         callout_drain(&fd->toffhandle);
 2314 
 2315         return (0);
 2316 }
 2317 
 2318 static device_method_t fd_methods[] = {
 2319         /* Device interface */
 2320         DEVMETHOD(device_probe,         fd_probe),
 2321         DEVMETHOD(device_attach,        fd_attach),
 2322         DEVMETHOD(device_detach,        fd_detach),
 2323         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
 2324         DEVMETHOD(device_suspend,       bus_generic_suspend), /* XXX */
 2325         DEVMETHOD(device_resume,        bus_generic_resume), /* XXX */
 2326         { 0, 0 }
 2327 };
 2328 
 2329 static driver_t fd_driver = {
 2330         "fd",
 2331         fd_methods,
 2332         sizeof(struct fd_data)
 2333 };
 2334 
 2335 static int
 2336 fdc_modevent(module_t mod, int type, void *data)
 2337 {
 2338 
 2339         return (g_modevent(NULL, type, &g_fd_class));
 2340 }
 2341 
 2342 DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, fdc_modevent, 0);

Cache object: 8a6093c6220f8ba734a0f5e5c82ecdec


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