fdc.c revision 77788
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 * 33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43 * SUCH DAMAGE. 44 * 45 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 46 * $FreeBSD: head/sys/dev/fdc/fdc.c 77788 2001-06-05 21:01:46Z joerg $ 47 * 48 */ 49 50#include "opt_fdc.h" 51#include "card.h" 52 53#include <sys/param.h> 54#include <sys/systm.h> 55#include <sys/bio.h> 56#include <sys/bus.h> 57#include <sys/conf.h> 58#include <sys/devicestat.h> 59#include <sys/disklabel.h> 60#include <sys/fcntl.h> 61#include <sys/kernel.h> 62#include <sys/lock.h> 63#include <sys/malloc.h> 64#include <sys/module.h> 65#include <sys/mutex.h> 66#include <sys/proc.h> 67#include <sys/syslog.h> 68 69#include <sys/bus.h> 70#include <machine/bus.h> 71#include <sys/rman.h> 72 73#include <machine/clock.h> 74#include <machine/ioctl_fd.h> 75#include <machine/resource.h> 76#include <machine/stdarg.h> 77 78#include <isa/isavar.h> 79#include <isa/isareg.h> 80#include <isa/fdreg.h> 81#include <isa/fdc.h> 82#include <isa/rtc.h> 83 84/* misuse a flag to identify format operation */ 85 86/* configuration flags */ 87#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 88#define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */ 89 90/* internally used only, not really from CMOS: */ 91#define RTCFDT_144M_PRETENDED 0x1000 92 93/* error returns for fd_cmd() */ 94#define FD_FAILED -1 95#define FD_NOT_VALID -2 96#define FDC_ERRMAX 100 /* do not log more */ 97 98#define NUMTYPES 17 99#define NUMDENS (NUMTYPES - 7) 100 101/* These defines (-1) must match index for fd_types */ 102#define F_TAPE_TYPE 0x020 /* bit for fd_types to indicate tape */ 103#define NO_TYPE 0 /* must match NO_TYPE in ft.c */ 104#define FD_1720 1 105#define FD_1480 2 106#define FD_1440 3 107#define FD_1200 4 108#define FD_820 5 109#define FD_800 6 110#define FD_720 7 111#define FD_360 8 112#define FD_640 9 113#define FD_1232 10 114 115#define FD_1480in5_25 11 116#define FD_1440in5_25 12 117#define FD_820in5_25 13 118#define FD_800in5_25 14 119#define FD_720in5_25 15 120#define FD_360in5_25 16 121#define FD_640in5_25 17 122 123 124static struct fd_type fd_types[NUMTYPES] = 125{ 126{ 21,2,0xFF,0x04,82,3444,1,FDC_500KBPS,2,0x0C,2 }, /* 1.72M in HD 3.5in */ 127{ 18,2,0xFF,0x1B,82,2952,1,FDC_500KBPS,2,0x6C,1 }, /* 1.48M in HD 3.5in */ 128{ 18,2,0xFF,0x1B,80,2880,1,FDC_500KBPS,2,0x6C,1 }, /* 1.44M in HD 3.5in */ 129{ 15,2,0xFF,0x1B,80,2400,1,FDC_500KBPS,2,0x54,1 }, /* 1.2M in HD 5.25/3.5 */ 130{ 10,2,0xFF,0x10,82,1640,1,FDC_250KBPS,2,0x2E,1 }, /* 820K in HD 3.5in */ 131{ 10,2,0xFF,0x10,80,1600,1,FDC_250KBPS,2,0x2E,1 }, /* 800K in HD 3.5in */ 132{ 9,2,0xFF,0x20,80,1440,1,FDC_250KBPS,2,0x50,1 }, /* 720K in HD 3.5in */ 133{ 9,2,0xFF,0x2A,40, 720,1,FDC_250KBPS,2,0x50,1 }, /* 360K in DD 5.25in */ 134{ 8,2,0xFF,0x2A,80,1280,1,FDC_250KBPS,2,0x50,1 }, /* 640K in DD 5.25in */ 135{ 8,3,0xFF,0x35,77,1232,1,FDC_500KBPS,2,0x74,1 }, /* 1.23M in HD 5.25in */ 136 137{ 18,2,0xFF,0x02,82,2952,1,FDC_500KBPS,2,0x02,2 }, /* 1.48M in HD 5.25in */ 138{ 18,2,0xFF,0x02,80,2880,1,FDC_500KBPS,2,0x02,2 }, /* 1.44M in HD 5.25in */ 139{ 10,2,0xFF,0x10,82,1640,1,FDC_300KBPS,2,0x2E,1 }, /* 820K in HD 5.25in */ 140{ 10,2,0xFF,0x10,80,1600,1,FDC_300KBPS,2,0x2E,1 }, /* 800K in HD 5.25in */ 141{ 9,2,0xFF,0x20,80,1440,1,FDC_300KBPS,2,0x50,1 }, /* 720K in HD 5.25in */ 142{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */ 143{ 8,2,0xFF,0x2A,80,1280,1,FDC_300KBPS,2,0x50,1 }, /* 640K in HD 5.25in */ 144}; 145 146#define DRVS_PER_CTLR 2 /* 2 floppies */ 147 148/***********************************************************************\ 149* Per controller structure. * 150\***********************************************************************/ 151static devclass_t fdc_devclass; 152 153/***********************************************************************\ 154* Per drive structure. * 155* N per controller (DRVS_PER_CTLR) * 156\***********************************************************************/ 157struct fd_data { 158 struct fdc_data *fdc; /* pointer to controller structure */ 159 int fdsu; /* this units number on this controller */ 160 int type; /* Drive type (FD_1440...) */ 161 struct fd_type *ft; /* pointer to the type descriptor */ 162 int flags; 163#define FD_OPEN 0x01 /* it's open */ 164#define FD_ACTIVE 0x02 /* it's active */ 165#define FD_MOTOR 0x04 /* motor should be on */ 166#define FD_MOTOR_WAIT 0x08 /* motor coming up */ 167 int skip; 168 int hddrv; 169#define FD_NO_TRACK -2 170 int track; /* where we think the head is */ 171 int options; /* user configurable options, see ioctl_fd.h */ 172 struct callout_handle toffhandle; 173 struct callout_handle tohandle; 174 struct devstat device_stats; 175 device_t dev; 176 fdu_t fdu; 177}; 178 179struct fdc_ivars { 180 int fdunit; 181}; 182static devclass_t fd_devclass; 183 184/***********************************************************************\ 185* Throughout this file the following conventions will be used: * 186* fd is a pointer to the fd_data struct for the drive in question * 187* fdc is a pointer to the fdc_data struct for the controller * 188* fdu is the floppy drive unit number * 189* fdcu is the floppy controller unit number * 190* fdsu is the floppy drive unit number on that controller. (sub-unit) * 191\***********************************************************************/ 192 193/* needed for ft driver, thus exported */ 194int in_fdc(struct fdc_data *); 195int out_fdc(struct fdc_data *, int); 196 197/* internal functions */ 198static void fdc_intr(void *); 199static void set_motor(struct fdc_data *, int, int); 200# define TURNON 1 201# define TURNOFF 0 202static timeout_t fd_turnoff; 203static timeout_t fd_motor_on; 204static void fd_turnon(struct fd_data *); 205static void fdc_reset(fdc_p); 206static int fd_in(struct fdc_data *, int *); 207static void fdstart(struct fdc_data *); 208static timeout_t fd_iotimeout; 209static timeout_t fd_pseudointr; 210static int fdstate(struct fdc_data *); 211static int retrier(struct fdc_data *); 212static int fdformat(dev_t, struct fd_formb *, struct proc *); 213 214static int enable_fifo(fdc_p fdc); 215 216static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 217 218#ifdef FDC_DEBUG 219static char const * const fdstates[] = 220{ 221"DEVIDLE", 222"FINDWORK", 223"DOSEEK", 224"SEEKCOMPLETE", 225"IOCOMPLETE", 226"RECALCOMPLETE", 227"STARTRECAL", 228"RESETCTLR", 229"SEEKWAIT", 230"RECALWAIT", 231"MOTORWAIT", 232"IOTIMEDOUT", 233"RESETCOMPLETE", 234"PIOREAD", 235}; 236 237/* CAUTION: fd_debug causes huge amounts of logging output */ 238static int volatile fd_debug = 0; 239#define TRACE0(arg) if(fd_debug) printf(arg) 240#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2) 241#else /* FDC_DEBUG */ 242#define TRACE0(arg) 243#define TRACE1(arg1, arg2) 244#endif /* FDC_DEBUG */ 245 246static void 247fdout_wr(fdc_p fdc, u_int8_t v) 248{ 249 bus_space_write_1(fdc->portt, fdc->porth, FDOUT+fdc->port_off, v); 250} 251 252static u_int8_t 253fdsts_rd(fdc_p fdc) 254{ 255 return bus_space_read_1(fdc->portt, fdc->porth, FDSTS+fdc->port_off); 256} 257 258static void 259fddata_wr(fdc_p fdc, u_int8_t v) 260{ 261 bus_space_write_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off, v); 262} 263 264static u_int8_t 265fddata_rd(fdc_p fdc) 266{ 267 return bus_space_read_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off); 268} 269 270static void 271fdctl_wr_isa(fdc_p fdc, u_int8_t v) 272{ 273 bus_space_write_1(fdc->ctlt, fdc->ctlh, 0, v); 274} 275 276#if NCARD > 0 277static void 278fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v) 279{ 280 bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v); 281} 282#endif 283 284#if 0 285 286static u_int8_t 287fdin_rd(fdc_p fdc) 288{ 289 return bus_space_read_1(fdc->portt, fdc->porth, FDIN); 290} 291 292#endif 293 294static d_open_t Fdopen; /* NOTE, not fdopen */ 295static d_close_t fdclose; 296static d_ioctl_t fdioctl; 297static d_strategy_t fdstrategy; 298 299#define CDEV_MAJOR 9 300 301static struct cdevsw fd_cdevsw = { 302 /* open */ Fdopen, 303 /* close */ fdclose, 304 /* read */ physread, 305 /* write */ physwrite, 306 /* ioctl */ fdioctl, 307 /* poll */ nopoll, 308 /* mmap */ nommap, 309 /* strategy */ fdstrategy, 310 /* name */ "fd", 311 /* maj */ CDEV_MAJOR, 312 /* dump */ nodump, 313 /* psize */ nopsize, 314 /* flags */ D_DISK, 315}; 316 317static int 318fdc_err(struct fdc_data *fdc, const char *s) 319{ 320 fdc->fdc_errs++; 321 if (s) { 322 if (fdc->fdc_errs < FDC_ERRMAX) 323 device_printf(fdc->fdc_dev, "%s", s); 324 else if (fdc->fdc_errs == FDC_ERRMAX) 325 device_printf(fdc->fdc_dev, "too many errors, not " 326 "logging any more\n"); 327 } 328 329 return FD_FAILED; 330} 331 332/* 333 * fd_cmd: Send a command to the chip. Takes a varargs with this structure: 334 * Unit number, 335 * # of output bytes, output bytes as ints ..., 336 * # of input bytes, input bytes as ints ... 337 */ 338static int 339fd_cmd(struct fdc_data *fdc, int n_out, ...) 340{ 341 u_char cmd; 342 int n_in; 343 int n; 344 va_list ap; 345 346 va_start(ap, n_out); 347 cmd = (u_char)(va_arg(ap, int)); 348 va_end(ap); 349 va_start(ap, n_out); 350 for (n = 0; n < n_out; n++) 351 { 352 if (out_fdc(fdc, va_arg(ap, int)) < 0) 353 { 354 char msg[50]; 355 snprintf(msg, sizeof(msg), 356 "cmd %x failed at out byte %d of %d\n", 357 cmd, n + 1, n_out); 358 return fdc_err(fdc, msg); 359 } 360 } 361 n_in = va_arg(ap, int); 362 for (n = 0; n < n_in; n++) 363 { 364 int *ptr = va_arg(ap, int *); 365 if (fd_in(fdc, ptr) < 0) 366 { 367 char msg[50]; 368 snprintf(msg, sizeof(msg), 369 "cmd %02x failed at in byte %d of %d\n", 370 cmd, n + 1, n_in); 371 return fdc_err(fdc, msg); 372 } 373 } 374 375 return 0; 376} 377 378static int 379enable_fifo(fdc_p fdc) 380{ 381 int i, j; 382 383 if ((fdc->flags & FDC_HAS_FIFO) == 0) { 384 385 /* 386 * XXX: 387 * Cannot use fd_cmd the normal way here, since 388 * this might be an invalid command. Thus we send the 389 * first byte, and check for an early turn of data directon. 390 */ 391 392 if (out_fdc(fdc, I8207X_CONFIGURE) < 0) 393 return fdc_err(fdc, "Enable FIFO failed\n"); 394 395 /* If command is invalid, return */ 396 j = 100000; 397 while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM)) 398 != NE7_RQM && j-- > 0) 399 if (i == (NE7_DIO | NE7_RQM)) { 400 fdc_reset(fdc); 401 return FD_FAILED; 402 } 403 if (j<0 || 404 fd_cmd(fdc, 3, 405 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 406 fdc_reset(fdc); 407 return fdc_err(fdc, "Enable FIFO failed\n"); 408 } 409 fdc->flags |= FDC_HAS_FIFO; 410 return 0; 411 } 412 if (fd_cmd(fdc, 4, 413 I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) 414 return fdc_err(fdc, "Re-enable FIFO failed\n"); 415 return 0; 416} 417 418static int 419fd_sense_drive_status(fdc_p fdc, int *st3p) 420{ 421 int st3; 422 423 if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) 424 { 425 return fdc_err(fdc, "Sense Drive Status failed\n"); 426 } 427 if (st3p) 428 *st3p = st3; 429 430 return 0; 431} 432 433static int 434fd_sense_int(fdc_p fdc, int *st0p, int *cylp) 435{ 436 int cyl, st0, ret; 437 438 ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0); 439 if (ret) { 440 (void)fdc_err(fdc, 441 "sense intr err reading stat reg 0\n"); 442 return ret; 443 } 444 445 if (st0p) 446 *st0p = st0; 447 448 if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) { 449 /* 450 * There doesn't seem to have been an interrupt. 451 */ 452 return FD_NOT_VALID; 453 } 454 455 if (fd_in(fdc, &cyl) < 0) { 456 return fdc_err(fdc, "can't get cyl num\n"); 457 } 458 459 if (cylp) 460 *cylp = cyl; 461 462 return 0; 463} 464 465 466static int 467fd_read_status(fdc_p fdc, int fdsu) 468{ 469 int i, ret; 470 471 for (i = 0; i < 7; i++) { 472 /* 473 * XXX types are poorly chosen. Only bytes can by read 474 * from the hardware, but fdc->status[] wants u_ints and 475 * fd_in() gives ints. 476 */ 477 int status; 478 479 ret = fd_in(fdc, &status); 480 fdc->status[i] = status; 481 if (ret != 0) 482 break; 483 } 484 485 if (ret == 0) 486 fdc->flags |= FDC_STAT_VALID; 487 else 488 fdc->flags &= ~FDC_STAT_VALID; 489 490 return ret; 491} 492 493/****************************************************************************/ 494/* autoconfiguration stuff */ 495/****************************************************************************/ 496 497static int 498fdc_alloc_resources(struct fdc_data *fdc) 499{ 500 device_t dev; 501 int ispnp, ispcmcia; 502 503 dev = fdc->fdc_dev; 504 ispnp = (fdc->flags & FDC_ISPNP) != 0; 505 ispcmcia = (fdc->flags & FDC_ISPCMCIA) != 0; 506 fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0; 507 fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0; 508 509 /* 510 * On standard ISA, we don't just use an 8 port range 511 * (e.g. 0x3f0-0x3f7) since that covers an IDE control 512 * register at 0x3f6. 513 * 514 * Isn't PC hardware wonderful. 515 * 516 * The Y-E Data PCMCIA FDC doesn't have this problem, it 517 * uses the register with offset 6 for pseudo-DMA, and the 518 * one with offset 7 as control register. 519 */ 520 fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, 521 &fdc->rid_ioport, 0ul, ~0ul, 522 ispcmcia ? 8 : (ispnp ? 1 : 6), 523 RF_ACTIVE); 524 if (fdc->res_ioport == 0) { 525 device_printf(dev, "cannot reserve I/O port range\n"); 526 return ENXIO; 527 } 528 fdc->portt = rman_get_bustag(fdc->res_ioport); 529 fdc->porth = rman_get_bushandle(fdc->res_ioport); 530 531 if (!ispcmcia) { 532 /* 533 * Some BIOSen report the device at 0x3f2-0x3f5,0x3f7 534 * and some at 0x3f0-0x3f5,0x3f7. We detect the former 535 * by checking the size and adjust the port address 536 * accordingly. 537 */ 538 if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 4) 539 fdc->port_off = -2; 540 541 /* 542 * Register the control port range as rid 1 if it 543 * isn't there already. Most PnP BIOSen will have 544 * already done this but non-PnP configurations don't. 545 * 546 * And some (!!) report 0x3f2-0x3f5 and completely 547 * leave out the control register! It seems that some 548 * non-antique controller chips have a different 549 * method of programming the transfer speed which 550 * doesn't require the control register, but it's 551 * mighty bogus as the chip still responds to the 552 * address for the control register. 553 */ 554 if (bus_get_resource_count(dev, SYS_RES_IOPORT, 1) == 0) { 555 u_long ctlstart; 556 557 /* Find the control port, usually 0x3f7 */ 558 ctlstart = rman_get_start(fdc->res_ioport) + 559 fdc->port_off + 7; 560 561 bus_set_resource(dev, SYS_RES_IOPORT, 1, ctlstart, 1); 562 } 563 564 /* 565 * Now (finally!) allocate the control port. 566 */ 567 fdc->rid_ctl = 1; 568 fdc->res_ctl = bus_alloc_resource(dev, SYS_RES_IOPORT, 569 &fdc->rid_ctl, 570 0ul, ~0ul, 1, RF_ACTIVE); 571 if (fdc->res_ctl == 0) { 572 device_printf(dev, 573 "cannot reserve control I/O port range\n"); 574 return ENXIO; 575 } 576 fdc->ctlt = rman_get_bustag(fdc->res_ctl); 577 fdc->ctlh = rman_get_bushandle(fdc->res_ctl); 578 } 579 580 fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, 581 &fdc->rid_irq, 0ul, ~0ul, 1, 582 RF_ACTIVE); 583 if (fdc->res_irq == 0) { 584 device_printf(dev, "cannot reserve interrupt line\n"); 585 return ENXIO; 586 } 587 588 if ((fdc->flags & FDC_NODMA) == 0) { 589 fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, 590 &fdc->rid_drq, 0ul, ~0ul, 1, 591 RF_ACTIVE); 592 if (fdc->res_drq == 0) { 593 device_printf(dev, "cannot reserve DMA request line\n"); 594 return ENXIO; 595 } 596 fdc->dmachan = fdc->res_drq->r_start; 597 } 598 599 return 0; 600} 601 602static void 603fdc_release_resources(struct fdc_data *fdc) 604{ 605 device_t dev; 606 607 dev = fdc->fdc_dev; 608 if (fdc->res_irq != 0) { 609 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 610 fdc->res_irq); 611 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 612 fdc->res_irq); 613 } 614 if (fdc->res_ctl != 0) { 615 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl, 616 fdc->res_ctl); 617 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl, 618 fdc->res_ctl); 619 } 620 if (fdc->res_ioport != 0) { 621 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 622 fdc->res_ioport); 623 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 624 fdc->res_ioport); 625 } 626 if (fdc->res_drq != 0) { 627 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 628 fdc->res_drq); 629 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 630 fdc->res_drq); 631 } 632} 633 634/****************************************************************************/ 635/* autoconfiguration stuff */ 636/****************************************************************************/ 637 638static struct isa_pnp_id fdc_ids[] = { 639 {0x0007d041, "PC standard floppy disk controller"}, /* PNP0700 */ 640 {0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */ 641 {0} 642}; 643 644static int 645fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 646{ 647 struct fdc_ivars *ivars = device_get_ivars(child); 648 649 switch (which) { 650 case FDC_IVAR_FDUNIT: 651 *result = ivars->fdunit; 652 break; 653 default: 654 return ENOENT; 655 } 656 return 0; 657} 658 659/* 660 * fdc controller section. 661 */ 662static int 663fdc_probe(device_t dev) 664{ 665 int error, ic_type; 666 struct fdc_data *fdc; 667 668 fdc = device_get_softc(dev); 669 bzero(fdc, sizeof *fdc); 670 fdc->fdc_dev = dev; 671 fdc->fdctl_wr = fdctl_wr_isa; 672 673 /* Check pnp ids */ 674 error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids); 675 if (error == ENXIO) 676 return ENXIO; 677 if (error == 0) 678 fdc->flags |= FDC_ISPNP; 679 680 /* Attempt to allocate our resources for the duration of the probe */ 681 error = fdc_alloc_resources(fdc); 682 if (error) 683 goto out; 684 685 /* First - lets reset the floppy controller */ 686 fdout_wr(fdc, 0); 687 DELAY(100); 688 fdout_wr(fdc, FDO_FRST); 689 690 /* see if it can handle a command */ 691 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 692 NE7_SPEC_2(2, 0), 0)) { 693 error = ENXIO; 694 goto out; 695 } 696 697 if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) { 698 ic_type = (u_char)ic_type; 699 switch (ic_type) { 700 case 0x80: 701 device_set_desc(dev, "NEC 765 or clone"); 702 fdc->fdct = FDC_NE765; 703 break; 704 case 0x81: 705 device_set_desc(dev, "Intel 82077 or clone"); 706 fdc->fdct = FDC_I82077; 707 break; 708 case 0x90: 709 device_set_desc(dev, "NEC 72065B or clone"); 710 fdc->fdct = FDC_NE72065; 711 break; 712 default: 713 device_set_desc(dev, "generic floppy controller"); 714 fdc->fdct = FDC_UNKNOWN; 715 break; 716 } 717 } 718 719out: 720 fdc_release_resources(fdc); 721 return (error); 722} 723 724#if NCARD > 0 725 726static int 727fdc_pccard_probe(device_t dev) 728{ 729 int error; 730 struct fdc_data *fdc; 731 732 fdc = device_get_softc(dev); 733 bzero(fdc, sizeof *fdc); 734 fdc->fdc_dev = dev; 735 fdc->fdctl_wr = fdctl_wr_pcmcia; 736 737 fdc->flags |= FDC_ISPCMCIA | FDC_NODMA; 738 739 /* Attempt to allocate our resources for the duration of the probe */ 740 error = fdc_alloc_resources(fdc); 741 if (error) 742 goto out; 743 744 /* First - lets reset the floppy controller */ 745 fdout_wr(fdc, 0); 746 DELAY(100); 747 fdout_wr(fdc, FDO_FRST); 748 749 /* see if it can handle a command */ 750 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 751 NE7_SPEC_2(2, 0), 0)) { 752 error = ENXIO; 753 goto out; 754 } 755 756 device_set_desc(dev, "Y-E Data PCMCIA floppy"); 757 fdc->fdct = FDC_NE765; 758 759out: 760 fdc_release_resources(fdc); 761 return (error); 762} 763 764static int 765fdc_pccard_detach(device_t dev) 766{ 767 struct fdc_data *fdc; 768 int error; 769 770 fdc = device_get_softc(dev); 771 772 /* have our children detached first */ 773 if ((error = bus_generic_detach(dev))) 774 return (error); 775 776 if ((fdc->flags & FDC_ATTACHED) == 0) { 777 device_printf(dev, "already unloaded\n"); 778 return (0); 779 } 780 fdc->flags &= ~FDC_ATTACHED; 781 782 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 783 fdc->fdc_intr); 784 fdc_release_resources(fdc); 785 device_printf(dev, "unload\n"); 786 return (0); 787} 788 789#endif /* NCARD > 0 */ 790 791/* 792 * Add a child device to the fdc controller. It will then be probed etc. 793 */ 794static void 795fdc_add_child(device_t dev, const char *name, int unit) 796{ 797 int disabled; 798 struct fdc_ivars *ivar; 799 device_t child; 800 801 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO); 802 if (ivar == NULL) 803 return; 804 if (resource_int_value(name, unit, "drive", &ivar->fdunit) != 0) 805 ivar->fdunit = 0; 806 child = device_add_child(dev, name, unit); 807 if (child == NULL) 808 return; 809 device_set_ivars(child, ivar); 810 if (resource_int_value(name, unit, "disabled", &disabled) == 0 811 && disabled != 0) 812 device_disable(child); 813} 814 815static int 816fdc_attach(device_t dev) 817{ 818 struct fdc_data *fdc; 819 int i, error; 820 const char *name; 821 822 fdc = device_get_softc(dev); 823 error = fdc_alloc_resources(fdc); 824 if (error) { 825 device_printf(dev, "cannot re-aquire resources\n"); 826 return error; 827 } 828 error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq, 829 INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc, 830 &fdc->fdc_intr); 831 if (error) { 832 device_printf(dev, "cannot setup interrupt\n"); 833 return error; 834 } 835 fdc->fdcu = device_get_unit(dev); 836 fdc->flags |= FDC_ATTACHED; 837 838 if ((fdc->flags & FDC_NODMA) == 0) { 839 /* Acquire the DMA channel forever, The driver will do the rest */ 840 /* XXX should integrate with rman */ 841 isa_dma_acquire(fdc->dmachan); 842 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); 843 } 844 fdc->state = DEVIDLE; 845 846 /* reset controller, turn motor off, clear fdout mirror reg */ 847 fdout_wr(fdc, ((fdc->fdout = 0))); 848 bioq_init(&fdc->head); 849 850 /* 851 * Probe and attach any children. We should probably detect 852 * devices from the BIOS unless overridden. 853 */ 854 name = device_get_nameunit(dev); 855 i = -1; 856 while ((i = resource_query_string(i, "at", name)) != -1) 857 fdc_add_child(dev, resource_query_name(i), 858 resource_query_unit(i)); 859 860 return (bus_generic_attach(dev)); 861} 862 863static int 864fdc_print_child(device_t me, device_t child) 865{ 866 int retval = 0; 867 868 retval += bus_print_child_header(me, child); 869 retval += printf(" on %s drive %d\n", device_get_nameunit(me), 870 fdc_get_fdunit(child)); 871 872 return (retval); 873} 874 875static device_method_t fdc_methods[] = { 876 /* Device interface */ 877 DEVMETHOD(device_probe, fdc_probe), 878 DEVMETHOD(device_attach, fdc_attach), 879 DEVMETHOD(device_detach, bus_generic_detach), 880 DEVMETHOD(device_shutdown, bus_generic_shutdown), 881 DEVMETHOD(device_suspend, bus_generic_suspend), 882 DEVMETHOD(device_resume, bus_generic_resume), 883 884 /* Bus interface */ 885 DEVMETHOD(bus_print_child, fdc_print_child), 886 DEVMETHOD(bus_read_ivar, fdc_read_ivar), 887 /* Our children never use any other bus interface methods. */ 888 889 { 0, 0 } 890}; 891 892static driver_t fdc_driver = { 893 "fdc", 894 fdc_methods, 895 sizeof(struct fdc_data) 896}; 897 898DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0); 899 900#if NCARD > 0 901 902static device_method_t fdc_pccard_methods[] = { 903 /* Device interface */ 904 DEVMETHOD(device_probe, fdc_pccard_probe), 905 DEVMETHOD(device_attach, fdc_attach), 906 DEVMETHOD(device_detach, fdc_pccard_detach), 907 DEVMETHOD(device_shutdown, bus_generic_shutdown), 908 DEVMETHOD(device_suspend, bus_generic_suspend), 909 DEVMETHOD(device_resume, bus_generic_resume), 910 911 /* Bus interface */ 912 DEVMETHOD(bus_print_child, fdc_print_child), 913 DEVMETHOD(bus_read_ivar, fdc_read_ivar), 914 /* Our children never use any other bus interface methods. */ 915 916 { 0, 0 } 917}; 918 919static driver_t fdc_pccard_driver = { 920 "fdc", 921 fdc_pccard_methods, 922 sizeof(struct fdc_data) 923}; 924 925DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0); 926 927#endif /* NCARD > 0 */ 928 929static void fd_clone __P((void *arg, char *name, int namelen, dev_t *dev)); 930 931static struct { 932 char *match; 933 int minor; 934 int link; 935} fd_suffix[] = { 936 { "a", 0, 1 }, 937 { "b", 0, 1 }, 938 { "c", 0, 1 }, 939 { "d", 0, 1 }, 940 { "e", 0, 1 }, 941 { "f", 0, 1 }, 942 { "g", 0, 1 }, 943 { "h", 0, 1 }, 944 { ".1720", 1, 0 }, 945 { ".1480", 2, 0 }, 946 { ".1440", 3, 0 }, 947 { ".1200", 4, 0 }, 948 { ".820", 5, 0 }, 949 { ".800", 6, 0 }, 950 { ".720", 7, 0 }, 951 { ".360", 8, 0 }, 952 { ".640", 9, 0 }, 953 { ".1232", 10, 0 }, 954 { 0, 0 } 955}; 956static void 957fd_clone(arg, name, namelen, dev) 958 void *arg; 959 char *name; 960 int namelen; 961 dev_t *dev; 962{ 963 int u, d, i; 964 char *n; 965 dev_t pdev; 966 967 if (*dev != NODEV) 968 return; 969 if (dev_stdclone(name, &n, "fd", &u) != 2) 970 return; 971 for (i = 0; ; i++) { 972 if (fd_suffix[i].match == NULL) 973 return; 974 if (strcmp(n, fd_suffix[i].match)) 975 continue; 976 d = fd_suffix[i].minor; 977 break; 978 } 979 if (fd_suffix[i].link == 0) { 980 *dev = make_dev(&fd_cdevsw, (u << 6) + d, 981 UID_ROOT, GID_OPERATOR, 0640, name); 982 } else { 983 pdev = makedev(fd_cdevsw.d_maj, (u << 6) + d); 984 *dev = make_dev_alias(pdev, name); 985 } 986} 987 988/******************************************************************/ 989/* 990 * devices attached to the controller section. 991 */ 992static int 993fd_probe(device_t dev) 994{ 995 int i; 996 u_int fdt, st0, st3; 997 struct fd_data *fd; 998 struct fdc_data *fdc; 999 fdsu_t fdsu; 1000 static int fd_fifo = 0; 1001 1002 fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */ 1003 fd = device_get_softc(dev); 1004 fdc = device_get_softc(device_get_parent(dev)); 1005 1006 bzero(fd, sizeof *fd); 1007 fd->dev = dev; 1008 fd->fdc = fdc; 1009 fd->fdsu = fdsu; 1010 fd->fdu = device_get_unit(dev); 1011 1012#ifdef __i386__ 1013 /* look up what bios thinks we have */ 1014 switch (fd->fdu) { 1015 case 0: 1016 if ((fdc->flags & FDC_ISPCMCIA)) 1017 fdt = RTCFDT_144M; 1018 else if (device_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0) 1019 fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; 1020 else 1021 fdt = (rtcin(RTC_FDISKETTE) & 0xf0); 1022 break; 1023 case 1: 1024 fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); 1025 break; 1026 default: 1027 fdt = RTCFDT_NONE; 1028 break; 1029 } 1030#else 1031 fdt = RTCFDT_144M; /* XXX probably */ 1032#endif 1033 1034 /* is there a unit? */ 1035 if (fdt == RTCFDT_NONE) 1036 return (ENXIO); 1037 1038 /* select it */ 1039 set_motor(fdc, fdsu, TURNON); 1040 DELAY(1000000); /* 1 sec */ 1041 1042 /* XXX This doesn't work before the first set_motor() */ 1043 if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 1044 && (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 1045 && enable_fifo(fdc) == 0) { 1046 device_printf(device_get_parent(dev), 1047 "FIFO enabled, %d bytes threshold\n", fifo_threshold); 1048 } 1049 fd_fifo = 1; 1050 1051 if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) 1052 && (st3 & NE7_ST3_T0)) { 1053 /* if at track 0, first seek inwards */ 1054 /* seek some steps: */ 1055 fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0); 1056 DELAY(300000); /* ...wait a moment... */ 1057 fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 1058 } 1059 1060 /* If we're at track 0 first seek inwards. */ 1061 if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { 1062 /* Seek some steps... */ 1063 if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 1064 /* ...wait a moment... */ 1065 DELAY(300000); 1066 /* make ctrlr happy: */ 1067 fd_sense_int(fdc, 0, 0); 1068 } 1069 } 1070 1071 for (i = 0; i < 2; i++) { 1072 /* 1073 * we must recalibrate twice, just in case the 1074 * heads have been beyond cylinder 76, since most 1075 * FDCs still barf when attempting to recalibrate 1076 * more than 77 steps 1077 */ 1078 /* go back to 0: */ 1079 if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 1080 /* a second being enough for full stroke seek*/ 1081 DELAY(i == 0 ? 1000000 : 300000); 1082 1083 /* anything responding? */ 1084 if (fd_sense_int(fdc, &st0, 0) == 0 && 1085 (st0 & NE7_ST0_EC) == 0) 1086 break; /* already probed succesfully */ 1087 } 1088 } 1089 1090 set_motor(fdc, fdsu, TURNOFF); 1091 1092 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 1093 return (ENXIO); 1094 1095 fd->track = FD_NO_TRACK; 1096 fd->fdc = fdc; 1097 fd->fdsu = fdsu; 1098 fd->options = 0; 1099 callout_handle_init(&fd->toffhandle); 1100 callout_handle_init(&fd->tohandle); 1101 1102 switch (fdt) { 1103 case RTCFDT_12M: 1104 device_set_desc(dev, "1200-KB 5.25\" drive"); 1105 fd->type = FD_1200; 1106 break; 1107 case RTCFDT_144M | RTCFDT_144M_PRETENDED: 1108 device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive"); 1109 fdt = RTCFDT_144M; 1110 fd->type = FD_1440; 1111 case RTCFDT_144M: 1112 device_set_desc(dev, "1440-KB 3.5\" drive"); 1113 fd->type = FD_1440; 1114 break; 1115 case RTCFDT_288M: 1116 case RTCFDT_288M_1: 1117 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)"); 1118 fd->type = FD_1440; 1119 break; 1120 case RTCFDT_360K: 1121 device_set_desc(dev, "360-KB 5.25\" drive"); 1122 fd->type = FD_360; 1123 break; 1124 case RTCFDT_720K: 1125 printf("720-KB 3.5\" drive"); 1126 fd->type = FD_720; 1127 break; 1128 default: 1129 return (ENXIO); 1130 } 1131 return (0); 1132} 1133 1134static int 1135fd_attach(device_t dev) 1136{ 1137 struct fd_data *fd; 1138 static int cdevsw_add_done = 0; 1139 1140 fd = device_get_softc(dev); 1141 1142 if (!cdevsw_add_done) { 1143 cdevsw_add(&fd_cdevsw); /* XXX */ 1144 cdevsw_add_done++; 1145 } 1146 EVENTHANDLER_REGISTER(dev_clone, fd_clone, 0, 1000); 1147 make_dev(&fd_cdevsw, (fd->fdu << 6), 1148 UID_ROOT, GID_OPERATOR, 0640, "fd%d", fd->fdu); 1149 1150 /* 1151 * Export the drive to the devstat interface. 1152 */ 1153 devstat_add_entry(&fd->device_stats, device_get_name(dev), 1154 device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS, 1155 DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, 1156 DEVSTAT_PRIORITY_FD); 1157 return (0); 1158} 1159 1160static int 1161fd_detach(device_t dev) 1162{ 1163 struct fd_data *fd; 1164 1165 fd = device_get_softc(dev); 1166 untimeout(fd_turnoff, fd, fd->toffhandle); 1167 1168 return (0); 1169} 1170 1171static device_method_t fd_methods[] = { 1172 /* Device interface */ 1173 DEVMETHOD(device_probe, fd_probe), 1174 DEVMETHOD(device_attach, fd_attach), 1175 DEVMETHOD(device_detach, fd_detach), 1176 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1177 DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */ 1178 DEVMETHOD(device_resume, bus_generic_resume), /* XXX */ 1179 1180 { 0, 0 } 1181}; 1182 1183static driver_t fd_driver = { 1184 "fd", 1185 fd_methods, 1186 sizeof(struct fd_data) 1187}; 1188 1189DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, 0, 0); 1190 1191/****************************************************************************/ 1192/* motor control stuff */ 1193/* remember to not deselect the drive we're working on */ 1194/****************************************************************************/ 1195static void 1196set_motor(struct fdc_data *fdc, int fdsu, int turnon) 1197{ 1198 int fdout = fdc->fdout; 1199 int needspecify = 0; 1200 1201 if(turnon) { 1202 fdout &= ~FDO_FDSEL; 1203 fdout |= (FDO_MOEN0 << fdsu) + fdsu; 1204 } else 1205 fdout &= ~(FDO_MOEN0 << fdsu); 1206 1207 if(!turnon 1208 && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0) 1209 /* gonna turn off the last drive, put FDC to bed */ 1210 fdout &= ~ (FDO_FRST|FDO_FDMAEN); 1211 else { 1212 /* make sure controller is selected and specified */ 1213 if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0) 1214 needspecify = 1; 1215 fdout |= (FDO_FRST|FDO_FDMAEN); 1216 } 1217 1218 fdout_wr(fdc, fdout); 1219 fdc->fdout = fdout; 1220 TRACE1("[0x%x->FDOUT]", fdout); 1221 1222 if (needspecify) { 1223 /* 1224 * XXX 1225 * special case: since we have just woken up the FDC 1226 * from its sleep, we silently assume the command will 1227 * be accepted, and do not test for a timeout 1228 */ 1229 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, 1230 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1231 0); 1232 if (fdc->flags & FDC_HAS_FIFO) 1233 (void) enable_fifo(fdc); 1234 } 1235} 1236 1237static void 1238fd_turnoff(void *xfd) 1239{ 1240 int s; 1241 fd_p fd = xfd; 1242 1243 TRACE1("[fd%d: turnoff]", fd->fdu); 1244 1245 s = splbio(); 1246 /* 1247 * Don't turn off the motor yet if the drive is active. 1248 * 1249 * If we got here, this could only mean we missed an interrupt. 1250 * This can e. g. happen on the Y-E Date PCMCIA floppy controller 1251 * after a controller reset. Just schedule a pseudo-interrupt 1252 * so the state machine gets re-entered. 1253 */ 1254 if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) { 1255 fdc_intr(fd->fdc); 1256 splx(s); 1257 return; 1258 } 1259 1260 fd->flags &= ~FD_MOTOR; 1261 set_motor(fd->fdc, fd->fdsu, TURNOFF); 1262 splx(s); 1263} 1264 1265static void 1266fd_motor_on(void *xfd) 1267{ 1268 int s; 1269 fd_p fd = xfd; 1270 1271 s = splbio(); 1272 fd->flags &= ~FD_MOTOR_WAIT; 1273 if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) 1274 { 1275 fdc_intr(fd->fdc); 1276 } 1277 splx(s); 1278} 1279 1280static void 1281fd_turnon(fd_p fd) 1282{ 1283 if(!(fd->flags & FD_MOTOR)) 1284 { 1285 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); 1286 set_motor(fd->fdc, fd->fdsu, TURNON); 1287 timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */ 1288 } 1289} 1290 1291static void 1292fdc_reset(fdc_p fdc) 1293{ 1294 /* Try a reset, keep motor on */ 1295 fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1296 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1297 DELAY(100); 1298 /* enable FDC, but defer interrupts a moment */ 1299 fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN); 1300 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN); 1301 DELAY(100); 1302 fdout_wr(fdc, fdc->fdout); 1303 TRACE1("[0x%x->FDOUT]", fdc->fdout); 1304 1305 /* XXX after a reset, silently believe the FDC will accept commands */ 1306 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, 1307 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1308 0); 1309 if (fdc->flags & FDC_HAS_FIFO) 1310 (void) enable_fifo(fdc); 1311} 1312 1313/****************************************************************************/ 1314/* fdc in/out */ 1315/****************************************************************************/ 1316int 1317in_fdc(struct fdc_data *fdc) 1318{ 1319 int i, j = 100000; 1320 while ((i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) 1321 != (NE7_DIO|NE7_RQM) && j-- > 0) 1322 if (i == NE7_RQM) 1323 return fdc_err(fdc, "ready for output in input\n"); 1324 if (j <= 0) 1325 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); 1326#ifdef FDC_DEBUG 1327 i = fddata_rd(fdc); 1328 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1329 return(i); 1330#else /* !FDC_DEBUG */ 1331 return fddata_rd(fdc); 1332#endif /* FDC_DEBUG */ 1333} 1334 1335/* 1336 * fd_in: Like in_fdc, but allows you to see if it worked. 1337 */ 1338static int 1339fd_in(struct fdc_data *fdc, int *ptr) 1340{ 1341 int i, j = 100000; 1342 while ((i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) 1343 != (NE7_DIO|NE7_RQM) && j-- > 0) 1344 if (i == NE7_RQM) 1345 return fdc_err(fdc, "ready for output in input\n"); 1346 if (j <= 0) 1347 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); 1348#ifdef FDC_DEBUG 1349 i = fddata_rd(fdc); 1350 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1351 *ptr = i; 1352 return 0; 1353#else /* !FDC_DEBUG */ 1354 i = fddata_rd(fdc); 1355 if (ptr) 1356 *ptr = i; 1357 return 0; 1358#endif /* FDC_DEBUG */ 1359} 1360 1361int 1362out_fdc(struct fdc_data *fdc, int x) 1363{ 1364 int i; 1365 1366 /* Check that the direction bit is set */ 1367 i = 100000; 1368 while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0); 1369 if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); 1370 1371 /* Check that the floppy controller is ready for a command */ 1372 i = 100000; 1373 while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0); 1374 if (i <= 0) 1375 return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); 1376 1377 /* Send the command and return */ 1378 fddata_wr(fdc, x); 1379 TRACE1("[0x%x->FDDATA]", x); 1380 return (0); 1381} 1382 1383/****************************************************************************/ 1384/* fdopen/fdclose */ 1385/****************************************************************************/ 1386int 1387Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1388{ 1389 fdu_t fdu = FDUNIT(minor(dev)); 1390 int type = FDTYPE(minor(dev)); 1391 fd_p fd; 1392 fdc_p fdc; 1393 1394 /* check bounds */ 1395 if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0) 1396 return (ENXIO); 1397 fdc = fd->fdc; 1398 if ((fdc == NULL) || (fd->type == NO_TYPE)) 1399 return (ENXIO); 1400 if (type > NUMDENS) 1401 return (ENXIO); 1402 if (type == 0) 1403 type = fd->type; 1404 else { 1405 /* 1406 * For each type of basic drive, make sure we are trying 1407 * to open a type it can do, 1408 */ 1409 if (type != fd->type) { 1410 switch (fd->type) { 1411 case FD_360: 1412 return (ENXIO); 1413 case FD_720: 1414 if ( type != FD_820 1415 && type != FD_800 1416 && type != FD_640 1417 ) 1418 return (ENXIO); 1419 break; 1420 case FD_1200: 1421 switch (type) { 1422 case FD_1480: 1423 type = FD_1480in5_25; 1424 break; 1425 case FD_1440: 1426 type = FD_1440in5_25; 1427 break; 1428 case FD_1232: 1429 break; 1430 case FD_820: 1431 type = FD_820in5_25; 1432 break; 1433 case FD_800: 1434 type = FD_800in5_25; 1435 break; 1436 case FD_720: 1437 type = FD_720in5_25; 1438 break; 1439 case FD_640: 1440 type = FD_640in5_25; 1441 break; 1442 case FD_360: 1443 type = FD_360in5_25; 1444 break; 1445 default: 1446 return(ENXIO); 1447 } 1448 break; 1449 case FD_1440: 1450 if ( type != FD_1720 1451 && type != FD_1480 1452 && type != FD_1200 1453 && type != FD_820 1454 && type != FD_800 1455 && type != FD_720 1456 && type != FD_640 1457 ) 1458 return(ENXIO); 1459 break; 1460 } 1461 } 1462 } 1463 fd->ft = fd_types + type - 1; 1464 fd->flags |= FD_OPEN; 1465 1466 return 0; 1467} 1468 1469int 1470fdclose(dev_t dev, int flags, int mode, struct proc *p) 1471{ 1472 fdu_t fdu = FDUNIT(minor(dev)); 1473 struct fd_data *fd; 1474 1475 fd = devclass_get_softc(fd_devclass, fdu); 1476 fd->flags &= ~FD_OPEN; 1477 fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR); 1478 1479 return (0); 1480} 1481 1482/****************************************************************************/ 1483/* fdstrategy */ 1484/****************************************************************************/ 1485void 1486fdstrategy(struct bio *bp) 1487{ 1488 unsigned nblocks, blknum, cando; 1489 int s; 1490 fdu_t fdu; 1491 fdc_p fdc; 1492 fd_p fd; 1493 size_t fdblk; 1494 1495 fdu = FDUNIT(minor(bp->bio_dev)); 1496 fd = devclass_get_softc(fd_devclass, fdu); 1497 if (fd == 0) 1498 panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)", 1499 (u_long)major(bp->bio_dev), (u_long)minor(bp->bio_dev)); 1500 fdc = fd->fdc; 1501 if (fd->type == NO_TYPE) { 1502 bp->bio_error = ENXIO; 1503 bp->bio_flags |= BIO_ERROR; 1504 goto bad; 1505 }; 1506 1507 fdblk = 128 << (fd->ft->secsize); 1508 if (!(bp->bio_cmd & BIO_FORMAT)) { 1509 if (bp->bio_blkno < 0) { 1510 printf( 1511 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", 1512 fdu, (u_long)bp->bio_blkno, bp->bio_bcount); 1513 bp->bio_error = EINVAL; 1514 bp->bio_flags |= BIO_ERROR; 1515 goto bad; 1516 } 1517 if ((bp->bio_bcount % fdblk) != 0) { 1518 bp->bio_error = EINVAL; 1519 bp->bio_flags |= BIO_ERROR; 1520 goto bad; 1521 } 1522 } 1523 1524 /* 1525 * Set up block calculations. 1526 */ 1527 if (bp->bio_blkno > 20000000) { 1528 /* 1529 * Reject unreasonably high block number, prevent the 1530 * multiplication below from overflowing. 1531 */ 1532 bp->bio_error = EINVAL; 1533 bp->bio_flags |= BIO_ERROR; 1534 goto bad; 1535 } 1536 blknum = (unsigned) bp->bio_blkno * DEV_BSIZE/fdblk; 1537 nblocks = fd->ft->size; 1538 bp->bio_resid = 0; 1539 if (blknum + (bp->bio_bcount / fdblk) > nblocks) { 1540 if (blknum <= nblocks) { 1541 cando = (nblocks - blknum) * fdblk; 1542 bp->bio_resid = bp->bio_bcount - cando; 1543 if (cando == 0) 1544 goto bad; /* not actually bad but EOF */ 1545 } else { 1546 bp->bio_error = EINVAL; 1547 bp->bio_flags |= BIO_ERROR; 1548 goto bad; 1549 } 1550 } 1551 bp->bio_pblkno = bp->bio_blkno; 1552 s = splbio(); 1553 bioqdisksort(&fdc->head, bp); 1554 untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */ 1555 1556 /* Tell devstat we are starting on the transaction */ 1557 devstat_start_transaction(&fd->device_stats); 1558 device_busy(fd->dev); 1559 1560 fdstart(fdc); 1561 splx(s); 1562 return; 1563 1564bad: 1565 biodone(bp); 1566} 1567 1568/***************************************************************\ 1569* fdstart * 1570* We have just queued something.. if the controller is not busy * 1571* then simulate the case where it has just finished a command * 1572* So that it (the interrupt routine) looks on the queue for more* 1573* work to do and picks up what we just added. * 1574* If the controller is already busy, we need do nothing, as it * 1575* will pick up our work when the present work completes * 1576\***************************************************************/ 1577static void 1578fdstart(struct fdc_data *fdc) 1579{ 1580 int s; 1581 1582 s = splbio(); 1583 if(fdc->state == DEVIDLE) 1584 { 1585 fdc_intr(fdc); 1586 } 1587 splx(s); 1588} 1589 1590static void 1591fd_iotimeout(void *xfdc) 1592{ 1593 fdc_p fdc; 1594 int s; 1595 1596 fdc = xfdc; 1597 TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); 1598 1599 /* 1600 * Due to IBM's brain-dead design, the FDC has a faked ready 1601 * signal, hardwired to ready == true. Thus, any command 1602 * issued if there's no diskette in the drive will _never_ 1603 * complete, and must be aborted by resetting the FDC. 1604 * Many thanks, Big Blue! 1605 * The FDC must not be reset directly, since that would 1606 * interfere with the state machine. Instead, pretend that 1607 * the command completed but was invalid. The state machine 1608 * will reset the FDC and retry once. 1609 */ 1610 s = splbio(); 1611 fdc->status[0] = NE7_ST0_IC_IV; 1612 fdc->flags &= ~FDC_STAT_VALID; 1613 fdc->state = IOTIMEDOUT; 1614 fdc_intr(fdc); 1615 splx(s); 1616} 1617 1618/* just ensure it has the right spl */ 1619static void 1620fd_pseudointr(void *xfdc) 1621{ 1622 int s; 1623 1624 s = splbio(); 1625 fdc_intr(xfdc); 1626 splx(s); 1627} 1628 1629/***********************************************************************\ 1630* fdintr * 1631* keep calling the state machine until it returns a 0 * 1632* ALWAYS called at SPLBIO * 1633\***********************************************************************/ 1634static void 1635fdc_intr(void *xfdc) 1636{ 1637 fdc_p fdc = xfdc; 1638 while(fdstate(fdc)) 1639 ; 1640} 1641 1642/* 1643 * magic pseudo-DMA initialization for YE FDC. Sets count and 1644 * direction 1645 */ 1646#define SET_BCDR(fdc,wr,cnt,port) \ 1647 bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port, \ 1648 ((cnt)-1) & 0xff); \ 1649 bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port + 1, \ 1650 ((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f))); 1651 1652/* 1653 * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy 1654 */ 1655static int fdcpio(fdc_p fdc, long flags, caddr_t addr, u_int count) 1656{ 1657 u_char *cptr = (u_char *)addr; 1658 1659 if (flags == BIO_READ) { 1660 if (fdc->state != PIOREAD) { 1661 fdc->state = PIOREAD; 1662 return(0); 1663 }; 1664 SET_BCDR(fdc, 0, count, 0); 1665 bus_space_read_multi_1(fdc->portt, fdc->porth, fdc->port_off + 1666 FDC_YE_DATAPORT, cptr, count); 1667 } else { 1668 bus_space_write_multi_1(fdc->portt, fdc->porth, fdc->port_off + 1669 FDC_YE_DATAPORT, cptr, count); 1670 SET_BCDR(fdc, 0, count, 0); 1671 }; 1672 return(1); 1673} 1674 1675/***********************************************************************\ 1676* The controller state machine. * 1677* if it returns a non zero value, it should be called again immediatly * 1678\***********************************************************************/ 1679static int 1680fdstate(fdc_p fdc) 1681{ 1682 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3, idf; 1683 unsigned blknum = 0, b_cylinder = 0; 1684 fdu_t fdu = fdc->fdu; 1685 fd_p fd; 1686 register struct bio *bp; 1687 struct fd_formb *finfo = NULL; 1688 size_t fdblk; 1689 1690 bp = fdc->bp; 1691 if (bp == NULL) { 1692 bp = bioq_first(&fdc->head); 1693 if (bp != NULL) { 1694 bioq_remove(&fdc->head, bp); 1695 fdc->bp = bp; 1696 } 1697 } 1698 if (bp == NULL) { 1699 /***********************************************\ 1700 * nothing left for this controller to do * 1701 * Force into the IDLE state, * 1702 \***********************************************/ 1703 fdc->state = DEVIDLE; 1704 if (fdc->fd) { 1705 device_printf(fdc->fdc_dev, 1706 "unexpected valid fd pointer\n"); 1707 fdc->fd = (fd_p) 0; 1708 fdc->fdu = -1; 1709 } 1710 TRACE1("[fdc%d IDLE]", fdc->fdcu); 1711 return (0); 1712 } 1713 fdu = FDUNIT(minor(bp->bio_dev)); 1714 fd = devclass_get_softc(fd_devclass, fdu); 1715 fdblk = 128 << fd->ft->secsize; 1716 if (fdc->fd && (fd != fdc->fd)) 1717 device_printf(fd->dev, "confused fd pointers\n"); 1718 read = bp->bio_cmd == BIO_READ; 1719 if (read) 1720 idf = ISADMA_READ; 1721 else 1722 idf = ISADMA_WRITE; 1723 format = bp->bio_cmd & BIO_FORMAT; 1724 if (format) { 1725 finfo = (struct fd_formb *)bp->bio_data; 1726 fd->skip = (char *)&(finfo->fd_formb_cylno(0)) 1727 - (char *)finfo; 1728 } 1729 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { 1730 blknum = (unsigned) bp->bio_pblkno * DEV_BSIZE/fdblk + 1731 fd->skip/fdblk; 1732 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1733 } 1734 TRACE1("fd%d", fdu); 1735 TRACE1("[%s]", fdstates[fdc->state]); 1736 TRACE1("(0x%x)", fd->flags); 1737 untimeout(fd_turnoff, fd, fd->toffhandle); 1738 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); 1739 switch (fdc->state) 1740 { 1741 case DEVIDLE: 1742 case FINDWORK: /* we have found new work */ 1743 fdc->retry = 0; 1744 fd->skip = 0; 1745 fdc->fd = fd; 1746 fdc->fdu = fdu; 1747 fdc->fdctl_wr(fdc, fd->ft->trans); 1748 TRACE1("[0x%x->FDCTL]", fd->ft->trans); 1749 /*******************************************************\ 1750 * If the next drive has a motor startup pending, then * 1751 * it will start up in its own good time * 1752 \*******************************************************/ 1753 if(fd->flags & FD_MOTOR_WAIT) { 1754 fdc->state = MOTORWAIT; 1755 return (0); /* come back later */ 1756 } 1757 /*******************************************************\ 1758 * Maybe if it's not starting, it SHOULD be starting * 1759 \*******************************************************/ 1760 if (!(fd->flags & FD_MOTOR)) 1761 { 1762 fdc->state = MOTORWAIT; 1763 fd_turnon(fd); 1764 return (0); 1765 } 1766 else /* at least make sure we are selected */ 1767 { 1768 set_motor(fdc, fd->fdsu, TURNON); 1769 } 1770 if (fdc->flags & FDC_NEEDS_RESET) { 1771 fdc->state = RESETCTLR; 1772 fdc->flags &= ~FDC_NEEDS_RESET; 1773 } else 1774 fdc->state = DOSEEK; 1775 break; 1776 case DOSEEK: 1777 if (b_cylinder == (unsigned)fd->track) 1778 { 1779 fdc->state = SEEKCOMPLETE; 1780 break; 1781 } 1782 if (fd_cmd(fdc, 3, NE7CMD_SEEK, 1783 fd->fdsu, b_cylinder * fd->ft->steptrac, 1784 0)) 1785 { 1786 /* 1787 * seek command not accepted, looks like 1788 * the FDC went off to the Saints... 1789 */ 1790 fdc->retry = 6; /* try a reset */ 1791 return(retrier(fdc)); 1792 } 1793 fd->track = FD_NO_TRACK; 1794 fdc->state = SEEKWAIT; 1795 return(0); /* will return later */ 1796 case SEEKWAIT: 1797 /* allow heads to settle */ 1798 timeout(fd_pseudointr, fdc, hz / 16); 1799 fdc->state = SEEKCOMPLETE; 1800 return(0); /* will return later */ 1801 case SEEKCOMPLETE : /* SEEK DONE, START DMA */ 1802 /* Make sure seek really happened*/ 1803 if(fd->track == FD_NO_TRACK) { 1804 int descyl = b_cylinder * fd->ft->steptrac; 1805 do { 1806 /* 1807 * This might be a "ready changed" interrupt, 1808 * which cannot really happen since the 1809 * RDY pin is hardwired to + 5 volts. This 1810 * generally indicates a "bouncing" intr 1811 * line, so do one of the following: 1812 * 1813 * When running on an enhanced FDC that is 1814 * known to not go stuck after responding 1815 * with INVALID, fetch all interrupt states 1816 * until seeing either an INVALID or a 1817 * real interrupt condition. 1818 * 1819 * When running on a dumb old NE765, give 1820 * up immediately. The controller will 1821 * provide up to four dummy RC interrupt 1822 * conditions right after reset (for the 1823 * corresponding four drives), so this is 1824 * our only chance to get notice that it 1825 * was not the FDC that caused the interrupt. 1826 */ 1827 if (fd_sense_int(fdc, &st0, &cyl) 1828 == FD_NOT_VALID) 1829 return 0; 1830 if(fdc->fdct == FDC_NE765 1831 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 1832 return 0; /* hope for a real intr */ 1833 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 1834 1835 if (0 == descyl) { 1836 int failed = 0; 1837 /* 1838 * seek to cyl 0 requested; make sure we are 1839 * really there 1840 */ 1841 if (fd_sense_drive_status(fdc, &st3)) 1842 failed = 1; 1843 if ((st3 & NE7_ST3_T0) == 0) { 1844 printf( 1845 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n", 1846 fdu, st3, NE7_ST3BITS); 1847 failed = 1; 1848 } 1849 1850 if (failed) { 1851 if(fdc->retry < 3) 1852 fdc->retry = 3; 1853 return (retrier(fdc)); 1854 } 1855 } 1856 1857 if (cyl != descyl) { 1858 printf( 1859 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", 1860 fdu, descyl, cyl, st0); 1861 if (fdc->retry < 3) 1862 fdc->retry = 3; 1863 return (retrier(fdc)); 1864 } 1865 } 1866 1867 fd->track = b_cylinder; 1868 if (!(fdc->flags & FDC_NODMA)) 1869 isa_dmastart(idf, bp->bio_data+fd->skip, 1870 format ? bp->bio_bcount : fdblk, fdc->dmachan); 1871 sectrac = fd->ft->sectrac; 1872 sec = blknum % (sectrac * fd->ft->heads); 1873 head = sec / sectrac; 1874 sec = sec % sectrac + 1; 1875 fd->hddrv = ((head&1)<<2)+fdu; 1876 1877 if(format || !read) 1878 { 1879 /* make sure the drive is writable */ 1880 if(fd_sense_drive_status(fdc, &st3) != 0) 1881 { 1882 /* stuck controller? */ 1883 if (!(fdc->flags & FDC_NODMA)) 1884 isa_dmadone(idf, 1885 bp->bio_data + fd->skip, 1886 format ? bp->bio_bcount : fdblk, 1887 fdc->dmachan); 1888 fdc->retry = 6; /* reset the beast */ 1889 return (retrier(fdc)); 1890 } 1891 if(st3 & NE7_ST3_WP) 1892 { 1893 /* 1894 * XXX YES! this is ugly. 1895 * in order to force the current operation 1896 * to fail, we will have to fake an FDC 1897 * error - all error handling is done 1898 * by the retrier() 1899 */ 1900 fdc->status[0] = NE7_ST0_IC_AT; 1901 fdc->status[1] = NE7_ST1_NW; 1902 fdc->status[2] = 0; 1903 fdc->status[3] = fd->track; 1904 fdc->status[4] = head; 1905 fdc->status[5] = sec; 1906 fdc->retry = 8; /* break out immediately */ 1907 fdc->state = IOTIMEDOUT; /* not really... */ 1908 return (1); 1909 } 1910 } 1911 1912 if (format) { 1913 if (fdc->flags & FDC_NODMA) { 1914 /* 1915 * This seems to be necessary for 1916 * whatever obscure reason; if we omit 1917 * it, we end up filling the sector ID 1918 * fields of the newly formatted track 1919 * entirely with garbage, causing 1920 * `wrong cylinder' errors all over 1921 * the place when trying to read them 1922 * back. 1923 * 1924 * Umpf. 1925 */ 1926 SET_BCDR(fdc, 1, bp->bio_bcount, 0); 1927 1928 (void)fdcpio(fdc,bp->bio_cmd, 1929 bp->bio_data+fd->skip, 1930 bp->bio_bcount); 1931 1932 } 1933 /* formatting */ 1934 if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu, 1935 finfo->fd_formb_secshift, 1936 finfo->fd_formb_nsecs, 1937 finfo->fd_formb_gaplen, 1938 finfo->fd_formb_fillbyte, 0)) { 1939 /* controller fell over */ 1940 if (!(fdc->flags & FDC_NODMA)) 1941 isa_dmadone(idf, 1942 bp->bio_data + fd->skip, 1943 format ? bp->bio_bcount : fdblk, 1944 fdc->dmachan); 1945 fdc->retry = 6; 1946 return (retrier(fdc)); 1947 } 1948 } else { 1949 if (fdc->flags & FDC_NODMA) { 1950 /* 1951 * this seems to be necessary even when 1952 * reading data 1953 */ 1954 SET_BCDR(fdc, 1, fdblk, 0); 1955 1956 /* 1957 * perform the write pseudo-DMA before 1958 * the WRITE command is sent 1959 */ 1960 if (!read) 1961 (void)fdcpio(fdc,bp->bio_cmd, 1962 bp->bio_data+fd->skip, 1963 fdblk); 1964 } 1965 if (fd_cmd(fdc, 9, 1966 (read ? NE7CMD_READ : NE7CMD_WRITE), 1967 head << 2 | fdu, /* head & unit */ 1968 fd->track, /* track */ 1969 head, 1970 sec, /* sector + 1 */ 1971 fd->ft->secsize, /* sector size */ 1972 sectrac, /* sectors/track */ 1973 fd->ft->gap, /* gap size */ 1974 fd->ft->datalen, /* data length */ 1975 0)) { 1976 /* the beast is sleeping again */ 1977 if (!(fdc->flags & FDC_NODMA)) 1978 isa_dmadone(idf, 1979 bp->bio_data + fd->skip, 1980 format ? bp->bio_bcount : fdblk, 1981 fdc->dmachan); 1982 fdc->retry = 6; 1983 return (retrier(fdc)); 1984 } 1985 } 1986 if (fdc->flags & FDC_NODMA) 1987 /* 1988 * if this is a read, then simply await interrupt 1989 * before performing PIO 1990 */ 1991 if (read && !fdcpio(fdc,bp->bio_cmd, 1992 bp->bio_data+fd->skip,fdblk)) { 1993 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 1994 return(0); /* will return later */ 1995 }; 1996 1997 /* 1998 * write (or format) operation will fall through and 1999 * await completion interrupt 2000 */ 2001 fdc->state = IOCOMPLETE; 2002 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 2003 return (0); /* will return later */ 2004 case PIOREAD: 2005 /* 2006 * actually perform the PIO read. The IOCOMPLETE case 2007 * removes the timeout for us. 2008 */ 2009 (void)fdcpio(fdc,bp->bio_cmd,bp->bio_data+fd->skip,fdblk); 2010 fdc->state = IOCOMPLETE; 2011 /* FALLTHROUGH */ 2012 case IOCOMPLETE: /* IO DONE, post-analyze */ 2013 untimeout(fd_iotimeout, fdc, fd->tohandle); 2014 2015 if (fd_read_status(fdc, fd->fdsu)) { 2016 if (!(fdc->flags & FDC_NODMA)) 2017 isa_dmadone(idf, bp->bio_data + fd->skip, 2018 format ? bp->bio_bcount : fdblk, 2019 fdc->dmachan); 2020 if (fdc->retry < 6) 2021 fdc->retry = 6; /* force a reset */ 2022 return (retrier(fdc)); 2023 } 2024 2025 fdc->state = IOTIMEDOUT; 2026 2027 /* FALLTHROUGH */ 2028 2029 case IOTIMEDOUT: 2030 if (!(fdc->flags & FDC_NODMA)) 2031 isa_dmadone(idf, bp->bio_data + fd->skip, 2032 format ? bp->bio_bcount : fdblk, fdc->dmachan); 2033 if (fdc->status[0] & NE7_ST0_IC) { 2034 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 2035 && fdc->status[1] & NE7_ST1_OR) { 2036 /* 2037 * DMA overrun. Someone hogged the bus 2038 * and didn't release it in time for the 2039 * next FDC transfer. 2040 * Just restart it, don't increment retry 2041 * count. (vak) 2042 */ 2043 fdc->state = SEEKCOMPLETE; 2044 return (1); 2045 } 2046 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 2047 && fdc->retry < 6) 2048 fdc->retry = 6; /* force a reset */ 2049 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 2050 && fdc->status[2] & NE7_ST2_WC 2051 && fdc->retry < 3) 2052 fdc->retry = 3; /* force recalibrate */ 2053 return (retrier(fdc)); 2054 } 2055 /* All OK */ 2056 fd->skip += fdblk; 2057 if (!format && fd->skip < bp->bio_bcount - bp->bio_resid) { 2058 /* set up next transfer */ 2059 fdc->state = DOSEEK; 2060 } else { 2061 /* ALL DONE */ 2062 fd->skip = 0; 2063 fdc->bp = NULL; 2064 device_unbusy(fd->dev); 2065 biofinish(bp, &fd->device_stats, 0); 2066 fdc->fd = (fd_p) 0; 2067 fdc->fdu = -1; 2068 fdc->state = FINDWORK; 2069 } 2070 return (1); 2071 case RESETCTLR: 2072 fdc_reset(fdc); 2073 fdc->retry++; 2074 fdc->state = RESETCOMPLETE; 2075 return (0); 2076 case RESETCOMPLETE: 2077 /* 2078 * Discard all the results from the reset so that they 2079 * can't cause an unexpected interrupt later. 2080 */ 2081 for (i = 0; i < 4; i++) 2082 (void)fd_sense_int(fdc, &st0, &cyl); 2083 fdc->state = STARTRECAL; 2084 /* Fall through. */ 2085 case STARTRECAL: 2086 if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) { 2087 /* arrgl */ 2088 fdc->retry = 6; 2089 return (retrier(fdc)); 2090 } 2091 fdc->state = RECALWAIT; 2092 return (0); /* will return later */ 2093 case RECALWAIT: 2094 /* allow heads to settle */ 2095 timeout(fd_pseudointr, fdc, hz / 8); 2096 fdc->state = RECALCOMPLETE; 2097 return (0); /* will return later */ 2098 case RECALCOMPLETE: 2099 do { 2100 /* 2101 * See SEEKCOMPLETE for a comment on this: 2102 */ 2103 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 2104 return 0; 2105 if(fdc->fdct == FDC_NE765 2106 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 2107 return 0; /* hope for a real intr */ 2108 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 2109 if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0) 2110 { 2111 if(fdc->retry > 3) 2112 /* 2113 * a recalibrate from beyond cylinder 77 2114 * will "fail" due to the FDC limitations; 2115 * since people used to complain much about 2116 * the failure message, try not logging 2117 * this one if it seems to be the first 2118 * time in a line 2119 */ 2120 printf("fd%d: recal failed ST0 %b cyl %d\n", 2121 fdu, st0, NE7_ST0BITS, cyl); 2122 if(fdc->retry < 3) fdc->retry = 3; 2123 return (retrier(fdc)); 2124 } 2125 fd->track = 0; 2126 /* Seek (probably) necessary */ 2127 fdc->state = DOSEEK; 2128 return (1); /* will return immediatly */ 2129 case MOTORWAIT: 2130 if(fd->flags & FD_MOTOR_WAIT) 2131 { 2132 return (0); /* time's not up yet */ 2133 } 2134 if (fdc->flags & FDC_NEEDS_RESET) { 2135 fdc->state = RESETCTLR; 2136 fdc->flags &= ~FDC_NEEDS_RESET; 2137 } else { 2138 /* 2139 * If all motors were off, then the controller was 2140 * reset, so it has lost track of the current 2141 * cylinder. Recalibrate to handle this case. 2142 * But first, discard the results of the reset. 2143 */ 2144 fdc->state = RESETCOMPLETE; 2145 } 2146 return (1); /* will return immediatly */ 2147 default: 2148 device_printf(fdc->fdc_dev, "unexpected FD int->"); 2149 if (fd_read_status(fdc, fd->fdsu) == 0) 2150 printf("FDC status :%x %x %x %x %x %x %x ", 2151 fdc->status[0], 2152 fdc->status[1], 2153 fdc->status[2], 2154 fdc->status[3], 2155 fdc->status[4], 2156 fdc->status[5], 2157 fdc->status[6] ); 2158 else 2159 printf("No status available "); 2160 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2161 { 2162 printf("[controller is dead now]\n"); 2163 return (0); 2164 } 2165 printf("ST0 = %x, PCN = %x\n", st0, cyl); 2166 return (0); 2167 } 2168 /*XXX confusing: some branches return immediately, others end up here*/ 2169 return (1); /* Come back immediatly to new state */ 2170} 2171 2172static int 2173retrier(struct fdc_data *fdc) 2174{ 2175 struct bio *bp; 2176 struct fd_data *fd; 2177 int fdu; 2178 2179 bp = fdc->bp; 2180 2181 /* XXX shouldn't this be cached somewhere? */ 2182 fdu = FDUNIT(minor(bp->bio_dev)); 2183 fd = devclass_get_softc(fd_devclass, fdu); 2184 if (fd->options & FDOPT_NORETRY) 2185 goto fail; 2186 2187 switch (fdc->retry) { 2188 case 0: case 1: case 2: 2189 fdc->state = SEEKCOMPLETE; 2190 break; 2191 case 3: case 4: case 5: 2192 fdc->state = STARTRECAL; 2193 break; 2194 case 6: 2195 fdc->state = RESETCTLR; 2196 break; 2197 case 7: 2198 break; 2199 default: 2200 fail: 2201 { 2202 int printerror = (fd->options & FDOPT_NOERRLOG) == 0; 2203 2204 if (printerror) 2205 diskerr(bp, "hard error", fdc->fd->skip / DEV_BSIZE, 2206 (struct disklabel *)NULL); 2207 if (printerror) { 2208 if (fdc->flags & FDC_STAT_VALID) 2209 { 2210 printf( 2211 " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n", 2212 fdc->status[0], NE7_ST0BITS, 2213 fdc->status[1], NE7_ST1BITS, 2214 fdc->status[2], NE7_ST2BITS, 2215 fdc->status[3], fdc->status[4], 2216 fdc->status[5]); 2217 } 2218 else 2219 printf(" (No status)\n"); 2220 } 2221 } 2222 if ((fd->options & FDOPT_NOERROR) == 0) { 2223 bp->bio_flags |= BIO_ERROR; 2224 bp->bio_error = EIO; 2225 bp->bio_resid += bp->bio_bcount - fdc->fd->skip; 2226 } 2227 fdc->bp = NULL; 2228 fdc->fd->skip = 0; 2229 device_unbusy(fd->dev); 2230 biofinish(bp, &fdc->fd->device_stats, 0); 2231 fdc->state = FINDWORK; 2232 fdc->flags |= FDC_NEEDS_RESET; 2233 fdc->fd = (fd_p) 0; 2234 fdc->fdu = -1; 2235 return (1); 2236 } 2237 fdc->retry++; 2238 return (1); 2239} 2240 2241static void 2242fdbiodone(struct bio *bp) 2243{ 2244 wakeup(bp); 2245} 2246 2247static int 2248fdformat(dev, finfo, p) 2249 dev_t dev; 2250 struct fd_formb *finfo; 2251 struct proc *p; 2252{ 2253 fdu_t fdu; 2254 fd_p fd; 2255 2256 struct bio *bp; 2257 int rv = 0, s; 2258 size_t fdblk; 2259 2260 fdu = FDUNIT(minor(dev)); 2261 fd = devclass_get_softc(fd_devclass, fdu); 2262 fdblk = 128 << fd->ft->secsize; 2263 2264 /* set up a buffer header for fdstrategy() */ 2265 bp = (struct bio *)malloc(sizeof(struct bio), M_TEMP, M_NOWAIT); 2266 if(bp == 0) 2267 return ENOMEM; 2268 /* 2269 * keep the process from being swapped 2270 */ 2271 PHOLD(p); 2272 bzero((void *)bp, sizeof(*bp)); 2273 bp->bio_cmd = BIO_FORMAT; 2274 2275 /* 2276 * calculate a fake blkno, so fdstrategy() would initiate a 2277 * seek to the requested cylinder 2278 */ 2279 bp->bio_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads) 2280 + finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE; 2281 2282 bp->bio_bcount = sizeof(struct fd_idfield_data) * finfo->fd_formb_nsecs; 2283 bp->bio_data = (caddr_t)finfo; 2284 2285 /* now do the format */ 2286 bp->bio_dev = dev; 2287 bp->bio_done = fdbiodone; 2288 fdstrategy(bp); 2289 2290 /* ...and wait for it to complete */ 2291 s = splbio(); 2292 while(!(bp->bio_flags & BIO_DONE)) { 2293 rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz); 2294 if (rv == EWOULDBLOCK) 2295 break; 2296 } 2297 splx(s); 2298 2299 if (rv == EWOULDBLOCK) { 2300 /* timed out */ 2301 rv = EIO; 2302 device_unbusy(fd->dev); 2303 } 2304 if (bp->bio_flags & BIO_ERROR) 2305 rv = bp->bio_error; 2306 /* 2307 * allow the process to be swapped 2308 */ 2309 PRELE(p); 2310 free(bp, M_TEMP); 2311 return rv; 2312} 2313 2314/* 2315 * TODO: don't allocate buffer on stack. 2316 */ 2317 2318static int 2319fdioctl(dev, cmd, addr, flag, p) 2320 dev_t dev; 2321 u_long cmd; 2322 caddr_t addr; 2323 int flag; 2324 struct proc *p; 2325{ 2326 fdu_t fdu = FDUNIT(minor(dev)); 2327 fd_p fd = devclass_get_softc(fd_devclass, fdu); 2328 size_t fdblk; 2329 2330 struct fd_type *fdt; 2331 struct disklabel *dl; 2332 struct fdc_status *fsp; 2333 char buffer[DEV_BSIZE]; 2334 int error = 0; 2335 2336 fdblk = 128 << fd->ft->secsize; 2337 2338 switch (cmd) { 2339 case DIOCGDINFO: 2340 bzero(buffer, sizeof (buffer)); 2341 dl = (struct disklabel *)buffer; 2342 dl->d_secsize = fdblk; 2343 fdt = fd->ft; 2344 dl->d_secpercyl = fdt->size / fdt->tracks; 2345 dl->d_type = DTYPE_FLOPPY; 2346 2347 if (readdisklabel(dkmodpart(dev, RAW_PART), dl) 2348 == NULL) 2349 error = 0; 2350 else 2351 error = EINVAL; 2352 2353 *(struct disklabel *)addr = *dl; 2354 break; 2355 2356 case DIOCSDINFO: 2357 if ((flag & FWRITE) == 0) 2358 error = EBADF; 2359 break; 2360 2361 case DIOCWLABEL: 2362 if ((flag & FWRITE) == 0) 2363 error = EBADF; 2364 break; 2365 2366 case DIOCWDINFO: 2367 if ((flag & FWRITE) == 0) { 2368 error = EBADF; 2369 break; 2370 } 2371 2372 dl = (struct disklabel *)addr; 2373 2374 if ((error = setdisklabel((struct disklabel *)buffer, dl, 2375 (u_long)0)) != 0) 2376 break; 2377 2378 error = writedisklabel(dev, (struct disklabel *)buffer); 2379 break; 2380 case FD_FORM: 2381 if ((flag & FWRITE) == 0) 2382 error = EBADF; /* must be opened for writing */ 2383 else if (((struct fd_formb *)addr)->format_version != 2384 FD_FORMAT_VERSION) 2385 error = EINVAL; /* wrong version of formatting prog */ 2386 else 2387 error = fdformat(dev, (struct fd_formb *)addr, p); 2388 break; 2389 2390 case FD_GTYPE: /* get drive type */ 2391 *(struct fd_type *)addr = *fd->ft; 2392 break; 2393 2394 case FD_STYPE: /* set drive type */ 2395 /* this is considered harmful; only allow for superuser */ 2396 if (suser(p) != 0) 2397 return EPERM; 2398 *fd->ft = *(struct fd_type *)addr; 2399 break; 2400 2401 case FD_GOPTS: /* get drive options */ 2402 *(int *)addr = fd->options; 2403 break; 2404 2405 case FD_SOPTS: /* set drive options */ 2406 fd->options = *(int *)addr; 2407 break; 2408 2409 case FD_CLRERR: 2410 if (suser(p) != 0) 2411 return EPERM; 2412 fd->fdc->fdc_errs = 0; 2413 break; 2414 2415 case FD_GSTAT: 2416 fsp = (struct fdc_status *)addr; 2417 if ((fd->fdc->flags & FDC_STAT_VALID) == 0) 2418 return EINVAL; 2419 memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int)); 2420 break; 2421 2422 default: 2423 error = ENOTTY; 2424 break; 2425 } 2426 return (error); 2427} 2428 2429/* 2430 * Hello emacs, these are the 2431 * Local Variables: 2432 * c-indent-level: 8 2433 * c-continued-statement-offset: 8 2434 * c-continued-brace-offset: 0 2435 * c-brace-offset: -8 2436 * c-brace-imaginary-offset: 0 2437 * c-argdecl-indent: 8 2438 * c-label-offset: -8 2439 * c++-hanging-braces: 1 2440 * c++-access-specifier-offset: -8 2441 * c++-empty-arglist-indent: 8 2442 * c++-friend-offset: 0 2443 * End: 2444 */ 2445