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