51 * 52 */ 53 54#include "fd.h" 55#include "opt_devfs.h" 56#include "opt_fdc.h" 57 58#if NFDC > 0 59 60#include <sys/param.h> 61#include <sys/systm.h> 62#include <sys/kernel.h> 63#include <sys/buf.h> 64#include <sys/bus.h> 65#include <sys/conf.h> 66#include <sys/disklabel.h> 67#include <sys/devicestat.h> 68#include <sys/fcntl.h> 69#include <sys/malloc.h> 70#include <sys/module.h> 71#include <sys/proc.h> 72#include <sys/syslog.h> 73 74#include <sys/bus.h> 75#include <machine/bus.h> 76#include <sys/rman.h> 77 78#include <machine/clock.h> 79#include <machine/ioctl_fd.h> 80#include <machine/resource.h> 81#include <machine/stdarg.h> 82 83#ifdef DEVFS 84#include <sys/devfsext.h> 85#endif /* DEVFS */ 86 87#include <isa/isavar.h> 88#include <i386/isa/isa.h> 89#include <i386/isa/isa_dma.h> 90#include <i386/isa/fdreg.h> 91#include <i386/isa/fdc.h> 92#include <i386/isa/rtc.h> 93 94#ifdef FDC_YE 95#undef FDC_YE 96#warning "fix FDC_YE! - newbus casualty" 97#endif 98 99/* misuse a flag to identify format operation */ 100#define B_FORMAT B_XXX 101 102/* configuration flags */ 103#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 104#ifdef FDC_YE 105#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's 106 a PCMCIA device */ 107#endif 108 109/* internally used only, not really from CMOS: */ 110#define RTCFDT_144M_PRETENDED 0x1000 111 112/* 113 * this biotab field doubles as a field for the physical unit number 114 * on the controller 115 */ 116#define id_physid id_scsiid 117 118/* error returns for fd_cmd() */ 119#define FD_FAILED -1 120#define FD_NOT_VALID -2 121#define FDC_ERRMAX 100 /* do not log more */ 122 123#define NUMTYPES 14 124#define NUMDENS (NUMTYPES - 6) 125 126/* These defines (-1) must match index for fd_types */ 127#define F_TAPE_TYPE 0x020 /* bit for fd_types to indicate tape */ 128#define NO_TYPE 0 /* must match NO_TYPE in ft.c */ 129#define FD_1720 1 130#define FD_1480 2 131#define FD_1440 3 132#define FD_1200 4 133#define FD_820 5 134#define FD_800 6 135#define FD_720 7 136#define FD_360 8 137 138#define FD_1480in5_25 9 139#define FD_1440in5_25 10 140#define FD_820in5_25 11 141#define FD_800in5_25 12 142#define FD_720in5_25 13 143#define FD_360in5_25 14 144 145 146static struct fd_type fd_types[NUMTYPES] = 147{ 148{ 21,2,0xFF,0x04,82,3444,1,FDC_500KBPS,2,0x0C,2 }, /* 1.72M in HD 3.5in */ 149{ 18,2,0xFF,0x1B,82,2952,1,FDC_500KBPS,2,0x6C,1 }, /* 1.48M in HD 3.5in */ 150{ 18,2,0xFF,0x1B,80,2880,1,FDC_500KBPS,2,0x6C,1 }, /* 1.44M in HD 3.5in */ 151{ 15,2,0xFF,0x1B,80,2400,1,FDC_500KBPS,2,0x54,1 }, /* 1.2M in HD 5.25/3.5 */ 152{ 10,2,0xFF,0x10,82,1640,1,FDC_250KBPS,2,0x2E,1 }, /* 820K in HD 3.5in */ 153{ 10,2,0xFF,0x10,80,1600,1,FDC_250KBPS,2,0x2E,1 }, /* 800K in HD 3.5in */ 154{ 9,2,0xFF,0x20,80,1440,1,FDC_250KBPS,2,0x50,1 }, /* 720K in HD 3.5in */ 155{ 9,2,0xFF,0x2A,40, 720,1,FDC_250KBPS,2,0x50,1 }, /* 360K in DD 5.25in */ 156 157{ 18,2,0xFF,0x02,82,2952,1,FDC_500KBPS,2,0x02,2 }, /* 1.48M in HD 5.25in */ 158{ 18,2,0xFF,0x02,80,2880,1,FDC_500KBPS,2,0x02,2 }, /* 1.44M in HD 5.25in */ 159{ 10,2,0xFF,0x10,82,1640,1,FDC_300KBPS,2,0x2E,1 }, /* 820K in HD 5.25in */ 160{ 10,2,0xFF,0x10,80,1600,1,FDC_300KBPS,2,0x2E,1 }, /* 800K in HD 5.25in */ 161{ 9,2,0xFF,0x20,80,1440,1,FDC_300KBPS,2,0x50,1 }, /* 720K in HD 5.25in */ 162{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */ 163}; 164 165#define DRVS_PER_CTLR 2 /* 2 floppies */ 166 167/***********************************************************************\ 168* Per controller structure. * 169\***********************************************************************/ 170static devclass_t fdc_devclass; 171 172/***********************************************************************\ 173* Per drive structure. * 174* N per controller (DRVS_PER_CTLR) * 175\***********************************************************************/ 176struct fd_data { 177 struct fdc_data *fdc; /* pointer to controller structure */ 178 int fdsu; /* this units number on this controller */ 179 int type; /* Drive type (FD_1440...) */ 180 struct fd_type *ft; /* pointer to the type descriptor */ 181 int flags; 182#define FD_OPEN 0x01 /* it's open */ 183#define FD_ACTIVE 0x02 /* it's active */ 184#define FD_MOTOR 0x04 /* motor should be on */ 185#define FD_MOTOR_WAIT 0x08 /* motor coming up */ 186 int skip; 187 int hddrv; 188#define FD_NO_TRACK -2 189 int track; /* where we think the head is */ 190 int options; /* user configurable options, see ioctl_fd.h */ 191 struct callout_handle toffhandle; 192 struct callout_handle tohandle; 193 struct devstat device_stats; 194#ifdef DEVFS 195 void *bdevs[1 + NUMDENS + MAXPARTITIONS]; 196 void *cdevs[1 + NUMDENS + MAXPARTITIONS]; 197#endif 198 device_t dev; 199 fdu_t fdu; 200}; 201static devclass_t fd_devclass; 202 203/***********************************************************************\ 204* Throughout this file the following conventions will be used: * 205* fd is a pointer to the fd_data struct for the drive in question * 206* fdc is a pointer to the fdc_data struct for the controller * 207* fdu is the floppy drive unit number * 208* fdcu is the floppy controller unit number * 209* fdsu is the floppy drive unit number on that controller. (sub-unit) * 210\***********************************************************************/ 211 212#ifdef FDC_YE 213#include "card.h" 214static int yeattach(struct isa_device *); 215#endif 216 217/* needed for ft driver, thus exported */ 218int in_fdc(struct fdc_data *); 219int out_fdc(struct fdc_data *, int); 220 221/* internal functions */ 222static void fdc_add_device(device_t, const char *, int); 223static void fdc_intr(void *); 224static void set_motor(struct fdc_data *, int, int); 225# define TURNON 1 226# define TURNOFF 0 227static timeout_t fd_turnoff; 228static timeout_t fd_motor_on; 229static void fd_turnon(struct fd_data *); 230static void fdc_reset(fdc_p); 231static int fd_in(struct fdc_data *, int *); 232static void fdstart(struct fdc_data *); 233static timeout_t fd_iotimeout; 234static timeout_t fd_pseudointr; 235static int fdstate(struct fdc_data *); 236static int retrier(struct fdc_data *); 237static int fdformat(dev_t, struct fd_formb *, struct proc *); 238 239static int enable_fifo(fdc_p fdc); 240 241static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 242 243 244#define DEVIDLE 0 245#define FINDWORK 1 246#define DOSEEK 2 247#define SEEKCOMPLETE 3 248#define IOCOMPLETE 4 249#define RECALCOMPLETE 5 250#define STARTRECAL 6 251#define RESETCTLR 7 252#define SEEKWAIT 8 253#define RECALWAIT 9 254#define MOTORWAIT 10 255#define IOTIMEDOUT 11 256#define RESETCOMPLETE 12 257#ifdef FDC_YE 258#define PIOREAD 13 259#endif 260 261#ifdef FDC_DEBUG 262static char const * const fdstates[] = 263{ 264"DEVIDLE", 265"FINDWORK", 266"DOSEEK", 267"SEEKCOMPLETE", 268"IOCOMPLETE", 269"RECALCOMPLETE", 270"STARTRECAL", 271"RESETCTLR", 272"SEEKWAIT", 273"RECALWAIT", 274"MOTORWAIT", 275"IOTIMEDOUT", 276"RESETCOMPLETE", 277#ifdef FDC_YE 278"PIOREAD", 279#endif 280}; 281 282/* CAUTION: fd_debug causes huge amounts of logging output */ 283static int volatile fd_debug = 0; 284#define TRACE0(arg) if(fd_debug) printf(arg) 285#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2) 286#else /* FDC_DEBUG */ 287#define TRACE0(arg) 288#define TRACE1(arg1, arg2) 289#endif /* FDC_DEBUG */ 290 291#ifdef FDC_YE 292#if NCARD > 0 293#include <sys/select.h> 294#include <sys/module.h> 295#include <pccard/cardinfo.h> 296#include <pccard/driver.h> 297#include <pccard/slot.h> 298 299/* 300 * PC-Card (PCMCIA) specific code. 301 */ 302static int yeinit(struct pccard_devinfo *); /* init device */ 303static void yeunload(struct pccard_devinfo *); /* Disable driver */ 304static int yeintr(struct pccard_devinfo *); /* Interrupt handler */ 305 306PCCARD_MODULE(fdc, yeinit, yeunload, yeintr, 0, bio_imask); 307 308/* 309 * this is the secret PIO data port (offset from base) 310 */ 311#define FDC_YE_DATAPORT 6 312 313/* 314 * Initialize the device - called from Slot manager. 315 */ 316static int yeinit(struct pccard_devinfo *devi) 317{ 318 fdc_p fdc = &fdc_data[devi->isahd.id_unit]; 319 320 /* validate unit number. */ 321 if (devi->isahd.id_unit >= NFDC) 322 return(ENODEV); 323 fdc->baseport = devi->isahd.id_iobase; 324 /* 325 * reset controller 326 */ 327 outb(fdc->baseport+FDOUT, 0); 328 DELAY(100); 329 outb(fdc->baseport+FDOUT, FDO_FRST); 330 331 /* 332 * wire into system 333 */ 334 if (yeattach(&devi->isahd) == 0) 335 return(ENXIO); 336 337 return(0); 338} 339 340/* 341 * yeunload - unload the driver and clear the table. 342 * XXX TODO: 343 * This is usually called when the card is ejected, but 344 * can be caused by a modunload of a controller driver. 345 * The idea is to reset the driver's view of the device 346 * and ensure that any driver entry points such as 347 * read and write do not hang. 348 */ 349static void yeunload(struct pccard_devinfo *devi) 350{ 351 if (fd_data[devi->isahd.id_unit].type == NO_TYPE) 352 return; 353 354 /* 355 * this prevents Fdopen() and fdstrategy() from attempting 356 * to access unloaded controller 357 */ 358 fd_data[devi->isahd.id_unit].type = NO_TYPE; 359 360 printf("fdc%d: unload\n", devi->isahd.id_unit); 361} 362 363/* 364 * yeintr - Shared interrupt called from 365 * front end of PC-Card handler. 366 */ 367static int yeintr(struct pccard_devinfo *devi) 368{ 369 fdintr((fdcu_t)devi->isahd.id_unit); 370 return(1); 371} 372#endif /* NCARD > 0 */ 373#endif /* FDC_YE */ 374 375static d_open_t Fdopen; /* NOTE, not fdopen */ 376static d_read_t fdread; 377static d_write_t fdwrite; 378static d_close_t fdclose; 379static d_ioctl_t fdioctl; 380static d_strategy_t fdstrategy; 381 382static struct cdevsw fd_cdevsw = { 383 Fdopen, fdclose, fdread, fdwrite, 384 fdioctl, nostop, nullreset, nodevtotty, 385 seltrue, nommap, fdstrategy, "fd", 386 NULL, -1, nodump, nopsize, 387 D_DISK, 0, -1 388}; 389#define CDEV_MAJOR 9 390#define BDEV_MAJOR 2 391 392static int 393fdc_err(struct fdc_data *fdc, const char *s) 394{ 395 fdc->fdc_errs++; 396 if (s) { 397 if (fdc->fdc_errs < FDC_ERRMAX) { 398 device_print_prettyname(fdc->fdc_dev); 399 printf("%s", s); 400 } else if (fdc->fdc_errs == FDC_ERRMAX) { 401 device_print_prettyname(fdc->fdc_dev); 402 printf("too many errors, not logging any more\n"); 403 } 404 } 405 406 return FD_FAILED; 407} 408 409/* 410 * fd_cmd: Send a command to the chip. Takes a varargs with this structure: 411 * Unit number, 412 * # of output bytes, output bytes as ints ..., 413 * # of input bytes, input bytes as ints ... 414 */ 415static int 416fd_cmd(struct fdc_data *fdc, int n_out, ...) 417{ 418 u_char cmd; 419 int n_in; 420 int n; 421 va_list ap; 422 423 va_start(ap, n_out); 424 cmd = (u_char)(va_arg(ap, int)); 425 va_end(ap); 426 va_start(ap, n_out); 427 for (n = 0; n < n_out; n++) 428 { 429 if (out_fdc(fdc, va_arg(ap, int)) < 0) 430 { 431 char msg[50]; 432 snprintf(msg, sizeof(msg), 433 "cmd %x failed at out byte %d of %d\n", 434 cmd, n + 1, n_out); 435 return fdc_err(fdc, msg); 436 } 437 } 438 n_in = va_arg(ap, int); 439 for (n = 0; n < n_in; n++) 440 { 441 int *ptr = va_arg(ap, int *); 442 if (fd_in(fdc, ptr) < 0) 443 { 444 char msg[50]; 445 snprintf(msg, sizeof(msg), 446 "cmd %02x failed at in byte %d of %d\n", 447 cmd, n + 1, n_in); 448 return fdc_err(fdc, msg); 449 } 450 } 451 452 return 0; 453} 454 455static int 456enable_fifo(fdc_p fdc) 457{ 458 int i, j; 459 460 if ((fdc->flags & FDC_HAS_FIFO) == 0) { 461 462 /* 463 * XXX: 464 * Cannot use fd_cmd the normal way here, since 465 * this might be an invalid command. Thus we send the 466 * first byte, and check for an early turn of data directon. 467 */ 468 469 if (out_fdc(fdc, I8207X_CONFIGURE) < 0) 470 return fdc_err(fdc, "Enable FIFO failed\n"); 471 472 /* If command is invalid, return */ 473 j = 100000; 474 while ((i = inb(fdc->baseport + FDSTS) & (NE7_DIO | NE7_RQM)) 475 != NE7_RQM && j-- > 0) 476 if (i == (NE7_DIO | NE7_RQM)) { 477 fdc_reset(fdc); 478 return FD_FAILED; 479 } 480 if (j<0 || 481 fd_cmd(fdc, 3, 482 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 483 fdc_reset(fdc); 484 return fdc_err(fdc, "Enable FIFO failed\n"); 485 } 486 fdc->flags |= FDC_HAS_FIFO; 487 return 0; 488 } 489 if (fd_cmd(fdc, 4, 490 I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) 491 return fdc_err(fdc, "Re-enable FIFO failed\n"); 492 return 0; 493} 494 495static int 496fd_sense_drive_status(fdc_p fdc, int *st3p) 497{ 498 int st3; 499 500 if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) 501 { 502 return fdc_err(fdc, "Sense Drive Status failed\n"); 503 } 504 if (st3p) 505 *st3p = st3; 506 507 return 0; 508} 509 510static int 511fd_sense_int(fdc_p fdc, int *st0p, int *cylp) 512{ 513 int cyl, st0, ret; 514 515 ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0); 516 if (ret) { 517 (void)fdc_err(fdc, 518 "sense intr err reading stat reg 0\n"); 519 return ret; 520 } 521 522 if (st0p) 523 *st0p = st0; 524 525 if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) { 526 /* 527 * There doesn't seem to have been an interrupt. 528 */ 529 return FD_NOT_VALID; 530 } 531 532 if (fd_in(fdc, &cyl) < 0) { 533 return fdc_err(fdc, "can't get cyl num\n"); 534 } 535 536 if (cylp) 537 *cylp = cyl; 538 539 return 0; 540} 541 542 543static int 544fd_read_status(fdc_p fdc, int fdsu) 545{ 546 int i, ret; 547 548 for (i = 0; i < 7; i++) { 549 /* 550 * XXX types are poorly chosen. Only bytes can by read 551 * from the hardware, but fdc->status[] wants u_ints and 552 * fd_in() gives ints. 553 */ 554 int status; 555 556 ret = fd_in(fdc, &status); 557 fdc->status[i] = status; 558 if (ret != 0) 559 break; 560 } 561 562 if (ret == 0) 563 fdc->flags |= FDC_STAT_VALID; 564 else 565 fdc->flags &= ~FDC_STAT_VALID; 566 567 return ret; 568} 569 570/****************************************************************************/ 571/* autoconfiguration stuff */ 572/****************************************************************************/ 573 574static int 575fdc_probe(device_t dev) 576{ 577 int error, i, ic_type; 578 struct fdc_data *fdc; 579 char myname[8]; /* better be long enough */ 580 581 fdc = device_get_softc(dev); 582 bzero(fdc, sizeof *fdc); 583 fdc->fdc_dev = dev; 584 fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0; 585 fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0; 586 587 fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, 588 &fdc->rid_ioport, 0ul, ~0ul, 589 IO_FDCSIZE, RF_ACTIVE); 590 if (fdc->res_ioport == 0) { 591 device_print_prettyname(dev); 592 printf("cannot reserve I/O port range\n"); 593 error = ENXIO; 594 goto out; 595 } 596 fdc->baseport = fdc->res_ioport->r_start; 597 598 fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, 599 &fdc->rid_irq, 0ul, ~0ul, 1, 600 RF_ACTIVE); 601 if (fdc->res_irq == 0) { 602 device_print_prettyname(dev); 603 printf("cannot reserve interrupt line\n"); 604 error = ENXIO; 605 goto out; 606 } 607 fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, 608 &fdc->rid_drq, 0ul, ~0ul, 1, 609 RF_ACTIVE); 610 if (fdc->res_drq == 0) { 611 device_print_prettyname(dev); 612 printf("cannot reserve DMA request line\n"); 613 error = ENXIO; 614 goto out; 615 } 616 fdc->dmachan = fdc->res_drq->r_start; 617 error = BUS_SETUP_INTR(device_get_parent(dev), dev, 618 fdc->res_irq, fdc_intr, fdc, &fdc->fdc_intr); 619 620 /* First - lets reset the floppy controller */ 621 outb(fdc->baseport + FDOUT, 0); 622 DELAY(100); 623 outb(fdc->baseport + FDOUT, FDO_FRST); 624 625 /* see if it can handle a command */ 626 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 627 NE7_SPEC_2(2, 0), 0)) { 628 error = ENXIO; 629 goto out; 630 } 631 632 if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) { 633 ic_type = (u_char)ic_type; 634 switch (ic_type) { 635 case 0x80: 636 device_set_desc(dev, "NEC 765 or clone"); 637 fdc->fdct = FDC_NE765; 638 break; 639 case 0x81: 640 device_set_desc(dev, "Intel 82077 or clone"); 641 fdc->fdct = FDC_I82077; 642 break; 643 case 0x90: 644 device_set_desc(dev, "NEC 72065B or clone"); 645 fdc->fdct = FDC_NE72065; 646 break; 647 default: 648 device_set_desc(dev, "generic floppy controller"); 649 fdc->fdct = FDC_UNKNOWN; 650 break; 651 } 652 } 653 654 snprintf(myname, sizeof(myname), "%s%d", device_get_name(dev), 655 device_get_unit(dev)); 656 for (i = resource_query_string(-1, "at", myname); i != -1; 657 i = resource_query_string(i, "at", myname)) 658 fdc_add_device(dev, resource_query_name(i), 659 resource_query_unit(i)); 660#ifdef FDC_YE 661 /* 662 * don't succeed on probe; wait 663 * for PCCARD subsystem to do it 664 */ 665 if (dev->id_flags & FDC_IS_PCMCIA) 666 return(0); 667#endif 668 return (0); 669 670out: 671 if (fdc->fdc_intr) 672 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 673 fdc->fdc_intr); 674 if (fdc->res_irq != 0) { 675 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 676 fdc->res_irq); 677 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 678 fdc->res_irq); 679 } 680 if (fdc->res_ioport != 0) { 681 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 682 fdc->res_ioport); 683 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 684 fdc->res_ioport); 685 } 686 if (fdc->res_drq != 0) { 687 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 688 fdc->res_drq); 689 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 690 fdc->res_drq); 691 } 692 return (error); 693} 694 695/* 696 * Aped dfr@freebsd.org's isa_add_device(). 697 */ 698static void 699fdc_add_device(device_t dev, const char *name, int unit) 700{ 701 int disabled, *ivar; 702 device_t child; 703 704 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT); 705 if (ivar == 0) 706 return; 707 if (resource_int_value(name, unit, "drive", ivar) == 0) 708 *ivar = 0; 709 child = device_add_child(dev, name, unit, ivar); 710 if (child == 0) 711 return; 712 if (resource_int_value(name, unit, "disabled", &disabled) == 0) 713 device_disable(child); 714} 715 716static int 717fdc_attach(device_t dev) 718{ 719 struct fdc_data *fdc = device_get_softc(dev); 720 fdcu_t fdcu = device_get_unit(dev); 721 722 fdc->fdcu = fdcu; 723 fdc->flags |= FDC_ATTACHED; 724 725 /* Acquire the DMA channel forever, The driver will do the rest */ 726 /* XXX should integrate with rman */ 727 isa_dma_acquire(fdc->dmachan); 728 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); 729 fdc->state = DEVIDLE; 730 731 /* reset controller, turn motor off, clear fdout mirror reg */ 732 outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); 733 bufq_init(&fdc->head); 734 735#ifdef FIFO_BEFORE_MOTORON 736 /* Hmm, this doesn't work here - is set_motor() magic? -Peter */ 737 if (fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 738 && enable_fifo(fdc) == 0) { 739 device_print_prettyname(dev); 740 printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); 741 } 742#endif 743 /* 744 * Probe and attach any children as were configured above. 745 */ 746 return (bus_generic_attach(dev)); 747} 748 749static void 750fdc_print_child(device_t me, device_t child) 751{ 752 printf(" at %s%d drive %d", device_get_name(me), device_get_unit(me), 753 *(int *)device_get_ivars(child)); 754} 755 756static int 757fd_probe(device_t dev) 758{ 759 int i; 760 u_int fdt, st0, st3; 761 struct fd_data *fd; 762 struct fdc_data *fdc; 763 fdsu_t fdsu; 764#ifndef FIFO_BEFORE_MOTORON 765 static int fd_fifo = 0; 766#endif 767 768 fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */ 769 fd = device_get_softc(dev); 770 fdc = device_get_softc(device_get_parent(dev)); 771 772 bzero(fd, sizeof *fd); 773 fd->dev = dev; 774 fd->fdc = fdc; 775 fd->fdsu = fdsu; 776 fd->fdu = device_get_unit(dev); 777 778 /* look up what bios thinks we have */ 779 switch (fd->fdu) { 780 case 0: 781 if (isa_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0) 782 fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; 783 else 784 fdt = (rtcin(RTC_FDISKETTE) & 0xf0); 785 break; 786 case 1: 787 fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); 788 break; 789 default: 790 fdt = RTCFDT_NONE; 791 break; 792 } 793 794 /* is there a unit? */ 795 if (fdt == RTCFDT_NONE) 796 return (ENXIO); 797 798 /* select it */ 799 set_motor(fdc, fdsu, TURNON); 800 DELAY(1000000); /* 1 sec */ 801 802#ifndef FIFO_BEFORE_MOTORON 803 if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 804 && enable_fifo(fdc) == 0) { 805 device_print_prettyname(device_get_parent(dev)); 806 printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); 807 } 808 fd_fifo = 1; 809#endif 810 811 if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) 812 && (st3 & NE7_ST3_T0)) { 813 /* if at track 0, first seek inwards */ 814 /* seek some steps: */ 815 fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0); 816 DELAY(300000); /* ...wait a moment... */ 817 fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 818 } 819 820 /* If we're at track 0 first seek inwards. */ 821 if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { 822 /* Seek some steps... */ 823 if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 824 /* ...wait a moment... */ 825 DELAY(300000); 826 /* make ctrlr happy: */ 827 fd_sense_int(fdc, 0, 0); 828 } 829 } 830 831 for (i = 0; i < 2; i++) { 832 /* 833 * we must recalibrate twice, just in case the 834 * heads have been beyond cylinder 76, since most 835 * FDCs still barf when attempting to recalibrate 836 * more than 77 steps 837 */ 838 /* go back to 0: */ 839 if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 840 /* a second being enough for full stroke seek*/ 841 DELAY(i == 0 ? 1000000 : 300000); 842 843 /* anything responding? */ 844 if (fd_sense_int(fdc, &st0, 0) == 0 && 845 (st0 & NE7_ST0_EC) == 0) 846 break; /* already probed succesfully */ 847 } 848 } 849 850 set_motor(fdc, fdsu, TURNOFF); 851 852 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 853 return (ENXIO); 854 855 fd->track = FD_NO_TRACK; 856 fd->fdc = fdc; 857 fd->fdsu = fdsu; 858 fd->options = 0; 859 callout_handle_init(&fd->toffhandle); 860 callout_handle_init(&fd->tohandle); 861 862 switch (fdt) { 863 case RTCFDT_12M: 864 device_set_desc(dev, "1200-KB 5.25\" drive"); 865 fd->type = FD_1200; 866 break; 867 case RTCFDT_144M | RTCFDT_144M_PRETENDED: 868 device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive"); 869 fdt = RTCFDT_144M; 870 fd->type = FD_1440; 871 case RTCFDT_144M: 872 device_set_desc(dev, "1440-KB 3.5\" drive"); 873 fd->type = FD_1440; 874 break; 875 case RTCFDT_288M: 876 case RTCFDT_288M_1: 877 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)"); 878 fd->type = FD_1440; 879 break; 880 case RTCFDT_360K: 881 device_set_desc(dev, "360-KB 5.25\" drive"); 882 fd->type = FD_360; 883 break; 884 case RTCFDT_720K: 885 printf("720-KB 3.5\" drive"); 886 fd->type = FD_720; 887 break; 888 default: 889 return (ENXIO); 890 } 891 return (0); 892} 893 894static int 895fd_attach(device_t dev) 896{ 897 struct fd_data *fd; 898#ifdef DEVFS 899 int i; 900 int mynor; 901 int typemynor; 902 int typesize; 903#endif 904 905 fd = device_get_softc(dev); 906 907#ifdef DEVFS /* XXX bitrot */ 908 mynor = fd->fdu << 6; 909 fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, 910 UID_ROOT, GID_OPERATOR, 0640, 911 "fd%d", fd->fdu); 912 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, 913 UID_ROOT, GID_OPERATOR, 0640, 914 "rfd%d", fd->fdu); 915 for (i = 1; i < 1 + NUMDENS; i++) { 916 /* 917 * XXX this and the lookup in Fdopen() should be 918 * data driven. 919 */ 920 switch (fd->type) { 921 case FD_360: 922 if (i != FD_360) 923 continue; 924 break; 925 case FD_720: 926 if (i != FD_720 && i != FD_800 && i != FD_820) 927 continue; 928 break; 929 case FD_1200: 930 if (i != FD_360 && i != FD_720 && i != FD_800 931 && i != FD_820 && i != FD_1200 932 && i != FD_1440 && i != FD_1480) 933 continue; 934 break; 935 case FD_1440: 936 if (i != FD_720 && i != FD_800 && i != FD_820 937 && i != FD_1200 && i != FD_1440 938 && i != FD_1480 && i != FD_1720) 939 continue; 940 break; 941 } 942 typesize = fd_types[i - 1].size / 2; 943 /* 944 * XXX all these conversions give bloated code and 945 * confusing names. 946 */ 947 if (typesize == 1476) 948 typesize = 1480; 949 if (typesize == 1722) 950 typesize = 1720; 951 typemynor = mynor | i; 952 fd->bdevs[i] = 953 devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, 954 UID_ROOT, GID_OPERATOR, 0640, 955 "fd%d.%d", fd->fdu, typesize); 956 fd->cdevs[i] = 957 devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, 958 UID_ROOT, GID_OPERATOR, 0640, 959 "rfd%d.%d", fd->fdu, typesize); 960 } 961 962 for (i = 0; i < MAXPARTITIONS; i++) { 963 fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], 964 "fd%d%c", fd->fdu, 'a' + i); 965 fd->cdevs[1 + NUMDENS + i] = 966 devfs_makelink(fd->cdevs[0], 967 "rfd%d%c", fd->fdu, 'a' + i); 968 } 969#endif /* DEVFS */ 970 /* 971 * Export the drive to the devstat interface. 972 */ 973 devstat_add_entry(&fd->device_stats, device_get_name(dev), 974 device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS, 975 DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, 976 DEVSTAT_PRIORITY_FD); 977 return (0); 978} 979 980#ifdef FDC_YE 981/* 982 * this is a subset of fdattach() optimized for the Y-E Data 983 * PCMCIA floppy drive. 984 */ 985static int yeattach(struct isa_device *dev) 986{ 987 fdcu_t fdcu = dev->id_unit; 988 fdc_p fdc = fdc_data + fdcu; 989 fdsu_t fdsu = 0; /* assume 1 drive per YE controller */ 990 fdu_t fdu; 991 fd_p fd; 992 int st0, st3, i; 993#ifdef DEVFS 994 int mynor; 995 int typemynor; 996 int typesize; 997#endif 998 fdc->fdcu = fdcu; 999 /* 1000 * the FDC_PCMCIA flag is used to to indicate special PIO is used 1001 * instead of DMA 1002 */ 1003 fdc->flags = FDC_ATTACHED|FDC_PCMCIA; 1004 fdc->state = DEVIDLE; 1005 /* reset controller, turn motor off, clear fdout mirror reg */ 1006 outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); 1007 bufq_init(&fdc->head); 1008 /* 1009 * assume 2 drives/ "normal" controller 1010 */ 1011 fdu = fdcu * 2; 1012 if (fdu >= NFD) { 1013 printf("fdu %d >= NFD\n",fdu); 1014 return(0); 1015 }; 1016 fd = &fd_data[fdu]; 1017 1018 set_motor(fdcu, fdsu, TURNON); 1019 DELAY(1000000); /* 1 sec */ 1020 fdc->fdct = FDC_NE765; 1021 1022 if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) && 1023 (st3 & NE7_ST3_T0)) { 1024 /* if at track 0, first seek inwards */ 1025 /* seek some steps: */ 1026 (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0); 1027 DELAY(300000); /* ...wait a moment... */ 1028 (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 1029 } 1030 1031 /* If we're at track 0 first seek inwards. */ 1032 if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { 1033 /* Seek some steps... */ 1034 if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 1035 /* ...wait a moment... */ 1036 DELAY(300000); 1037 /* make ctrlr happy: */ 1038 (void)fd_sense_int(fdc, 0, 0); 1039 } 1040 } 1041 1042 for(i = 0; i < 2; i++) { 1043 /* 1044 * we must recalibrate twice, just in case the 1045 * heads have been beyond cylinder 76, since most 1046 * FDCs still barf when attempting to recalibrate 1047 * more than 77 steps 1048 */ 1049 /* go back to 0: */ 1050 if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 1051 /* a second being enough for full stroke seek*/ 1052 DELAY(i == 0? 1000000: 300000); 1053 1054 /* anything responding? */ 1055 if (fd_sense_int(fdc, &st0, 0) == 0 && 1056 (st0 & NE7_ST0_EC) == 0) 1057 break; /* already probed succesfully */ 1058 } 1059 } 1060 1061 set_motor(fdcu, fdsu, TURNOFF); 1062 1063 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 1064 return(0); 1065 1066 fd->track = FD_NO_TRACK; 1067 fd->fdc = fdc; 1068 fd->fdsu = fdsu; 1069 fd->options = 0; 1070 printf("fdc%d: 1.44MB 3.5in PCMCIA\n", fdcu); 1071 fd->type = FD_1440; 1072 1073#ifdef DEVFS 1074 mynor = fdcu << 6; 1075 fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, 1076 UID_ROOT, GID_OPERATOR, 0640, 1077 "fd%d", fdu); 1078 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, 1079 UID_ROOT, GID_OPERATOR, 0640, 1080 "rfd%d", fdu); 1081 /* 1082 * XXX this and the lookup in Fdopen() should be 1083 * data driven. 1084 */ 1085 typemynor = mynor | FD_1440; 1086 typesize = fd_types[FD_1440 - 1].size / 2; 1087 /* 1088 * XXX all these conversions give bloated code and 1089 * confusing names. 1090 */ 1091 if (typesize == 1476) 1092 typesize = 1480; 1093 if (typesize == 1722) 1094 typesize = 1720; 1095 fd->bdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor, 1096 DV_BLK, UID_ROOT, GID_OPERATOR, 1097 0640, "fd%d.%d", fdu, typesize); 1098 fd->cdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor, 1099 DV_CHR, UID_ROOT, GID_OPERATOR, 1100 0640,"rfd%d.%d", fdu, typesize); 1101 for (i = 0; i < MAXPARTITIONS; i++) { 1102 fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], 1103 "fd%d%c", fdu, 'a' + i); 1104 fd->cdevs[1 + NUMDENS + i] = devfs_makelink(fd->cdevs[0], 1105 "rfd%d%c", fdu, 'a' + i); 1106 } 1107#endif /* DEVFS */ 1108 return (1); 1109} 1110#endif 1111 1112/****************************************************************************/ 1113/* motor control stuff */ 1114/* remember to not deselect the drive we're working on */ 1115/****************************************************************************/ 1116static void 1117set_motor(struct fdc_data *fdc, int fdsu, int turnon) 1118{ 1119 int fdout = fdc->fdout; 1120 int needspecify = 0; 1121 1122 if(turnon) { 1123 fdout &= ~FDO_FDSEL; 1124 fdout |= (FDO_MOEN0 << fdsu) + fdsu; 1125 } else 1126 fdout &= ~(FDO_MOEN0 << fdsu); 1127 1128 if(!turnon 1129 && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0) 1130 /* gonna turn off the last drive, put FDC to bed */ 1131 fdout &= ~ (FDO_FRST|FDO_FDMAEN); 1132 else { 1133 /* make sure controller is selected and specified */ 1134 if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0) 1135 needspecify = 1; 1136 fdout |= (FDO_FRST|FDO_FDMAEN); 1137 } 1138 1139 outb(fdc->baseport+FDOUT, fdout); 1140 fdc->fdout = fdout; 1141 TRACE1("[0x%x->FDOUT]", fdout); 1142 1143 if (needspecify) { 1144 /* 1145 * XXX 1146 * special case: since we have just woken up the FDC 1147 * from its sleep, we silently assume the command will 1148 * be accepted, and do not test for a timeout 1149 */ 1150 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, 1151 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1152 0); 1153 if (fdc->flags & FDC_HAS_FIFO) 1154 (void) enable_fifo(fdc); 1155 } 1156} 1157 1158static void 1159fd_turnoff(void *xfd) 1160{ 1161 int s; 1162 fd_p fd = xfd; 1163 1164 TRACE1("[fd%d: turnoff]", fd->fdu); 1165 1166 /* 1167 * Don't turn off the motor yet if the drive is active. 1168 * XXX shouldn't even schedule turnoff until drive is inactive 1169 * and nothing is queued on it. 1170 */ 1171 if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) { 1172 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); 1173 return; 1174 } 1175 1176 s = splbio(); 1177 fd->flags &= ~FD_MOTOR; 1178 set_motor(fd->fdc, fd->fdsu, TURNOFF); 1179 splx(s); 1180} 1181 1182static void 1183fd_motor_on(void *xfd) 1184{ 1185 int s; 1186 fd_p fd = xfd; 1187 1188 s = splbio(); 1189 fd->flags &= ~FD_MOTOR_WAIT; 1190 if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) 1191 { 1192 fdc_intr(fd->fdc); 1193 } 1194 splx(s); 1195} 1196 1197static void 1198fd_turnon(fd_p fd) 1199{ 1200 if(!(fd->flags & FD_MOTOR)) 1201 { 1202 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); 1203 set_motor(fd->fdc, fd->fdsu, TURNON); 1204 timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */ 1205 } 1206} 1207 1208static void 1209fdc_reset(fdc_p fdc) 1210{ 1211 /* Try a reset, keep motor on */ 1212 outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1213 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1214 DELAY(100); 1215 /* enable FDC, but defer interrupts a moment */ 1216 outb(fdc->baseport + FDOUT, fdc->fdout & ~FDO_FDMAEN); 1217 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN); 1218 DELAY(100); 1219 outb(fdc->baseport + FDOUT, fdc->fdout); 1220 TRACE1("[0x%x->FDOUT]", fdc->fdout); 1221 1222 /* XXX after a reset, silently believe the FDC will accept commands */ 1223 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, 1224 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1225 0); 1226 if (fdc->flags & FDC_HAS_FIFO) 1227 (void) enable_fifo(fdc); 1228} 1229 1230/****************************************************************************/ 1231/* fdc in/out */ 1232/****************************************************************************/ 1233int 1234in_fdc(struct fdc_data *fdc) 1235{ 1236 int baseport = fdc->baseport; 1237 int i, j = 100000; 1238 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1239 != (NE7_DIO|NE7_RQM) && j-- > 0) 1240 if (i == NE7_RQM) 1241 return fdc_err(fdc, "ready for output in input\n"); 1242 if (j <= 0) 1243 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); 1244#ifdef FDC_DEBUG 1245 i = inb(baseport+FDDATA); 1246 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1247 return(i); 1248#else /* !FDC_DEBUG */ 1249 return inb(baseport+FDDATA); 1250#endif /* FDC_DEBUG */ 1251} 1252 1253/* 1254 * fd_in: Like in_fdc, but allows you to see if it worked. 1255 */ 1256static int 1257fd_in(struct fdc_data *fdc, int *ptr) 1258{ 1259 int baseport = fdc->baseport; 1260 int i, j = 100000; 1261 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1262 != (NE7_DIO|NE7_RQM) && j-- > 0) 1263 if (i == NE7_RQM) 1264 return fdc_err(fdc, "ready for output in input\n"); 1265 if (j <= 0) 1266 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); 1267#ifdef FDC_DEBUG 1268 i = inb(baseport+FDDATA); 1269 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1270 *ptr = i; 1271 return 0; 1272#else /* !FDC_DEBUG */ 1273 i = inb(baseport+FDDATA); 1274 if (ptr) 1275 *ptr = i; 1276 return 0; 1277#endif /* FDC_DEBUG */ 1278} 1279 1280int 1281out_fdc(struct fdc_data *fdc, int x) 1282{ 1283 int baseport = fdc->baseport; 1284 int i; 1285 1286 /* Check that the direction bit is set */ 1287 i = 100000; 1288 while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0); 1289 if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); 1290 1291 /* Check that the floppy controller is ready for a command */ 1292 i = 100000; 1293 while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0); 1294 if (i <= 0) 1295 return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); 1296 1297 /* Send the command and return */ 1298 outb(baseport+FDDATA, x); 1299 TRACE1("[0x%x->FDDATA]", x); 1300 return (0); 1301} 1302 1303/****************************************************************************/ 1304/* fdopen/fdclose */ 1305/****************************************************************************/ 1306int 1307Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1308{ 1309 fdu_t fdu = FDUNIT(minor(dev)); 1310 int type = FDTYPE(minor(dev)); 1311 fd_p fd; 1312 fdc_p fdc; 1313 1314 /* check bounds */ 1315 if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0) 1316 return (ENXIO); 1317 fdc = fd->fdc; 1318 if ((fdc == NULL) || (fd->type == NO_TYPE)) 1319 return (ENXIO); 1320 if (type > NUMDENS) 1321 return (ENXIO); 1322 if (type == 0) 1323 type = fd->type; 1324 else { 1325 /* 1326 * For each type of basic drive, make sure we are trying 1327 * to open a type it can do, 1328 */ 1329 if (type != fd->type) { 1330 switch (fd->type) { 1331 case FD_360: 1332 return (ENXIO); 1333 case FD_720: 1334 if ( type != FD_820 1335 && type != FD_800 1336 ) 1337 return (ENXIO); 1338 break; 1339 case FD_1200: 1340 switch (type) { 1341 case FD_1480: 1342 type = FD_1480in5_25; 1343 break; 1344 case FD_1440: 1345 type = FD_1440in5_25; 1346 break; 1347 case FD_820: 1348 type = FD_820in5_25; 1349 break; 1350 case FD_800: 1351 type = FD_800in5_25; 1352 break; 1353 case FD_720: 1354 type = FD_720in5_25; 1355 break; 1356 case FD_360: 1357 type = FD_360in5_25; 1358 break; 1359 default: 1360 return(ENXIO); 1361 } 1362 break; 1363 case FD_1440: 1364 if ( type != FD_1720 1365 && type != FD_1480 1366 && type != FD_1200 1367 && type != FD_820 1368 && type != FD_800 1369 && type != FD_720 1370 ) 1371 return(ENXIO); 1372 break; 1373 } 1374 } 1375 } 1376 fd->ft = fd_types + type - 1; 1377 fd->flags |= FD_OPEN; 1378 device_busy(fd->dev); 1379 device_busy(fd->fdc->fdc_dev); 1380 return 0; 1381} 1382 1383int 1384fdclose(dev_t dev, int flags, int mode, struct proc *p) 1385{ 1386 fdu_t fdu = FDUNIT(minor(dev)); 1387 struct fd_data *fd; 1388 1389 fd = devclass_get_softc(fd_devclass, fdu); 1390 fd->flags &= ~FD_OPEN; 1391 fd->options &= ~FDOPT_NORETRY; 1392 1393 return (0); 1394} 1395 1396static int 1397fdread(dev_t dev, struct uio *uio, int ioflag) 1398{ 1399 return (physio(fdstrategy, NULL, dev, 1, minphys, uio)); 1400} 1401 1402static int 1403fdwrite(dev_t dev, struct uio *uio, int ioflag) 1404{ 1405 return (physio(fdstrategy, NULL, dev, 0, minphys, uio)); 1406} 1407 1408 1409/****************************************************************************/ 1410/* fdstrategy */ 1411/****************************************************************************/ 1412void 1413fdstrategy(struct buf *bp) 1414{ 1415 unsigned nblocks, blknum, cando; 1416 int s; 1417 fdu_t fdu; 1418 fdc_p fdc; 1419 fd_p fd; 1420 size_t fdblk; 1421 1422 fdu = FDUNIT(minor(bp->b_dev)); 1423 fd = devclass_get_softc(fd_devclass, fdu); 1424 if (fd == 0) 1425 panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)", 1426 (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev)); 1427 fdc = fd->fdc; 1428#ifdef FDC_YE 1429 if (fd->type == NO_TYPE) { 1430 bp->b_error = ENXIO; 1431 bp->b_flags |= B_ERROR; 1432 /* 1433 * I _refuse_ to use a goto 1434 */ 1435 biodone(bp); 1436 return; 1437 }; 1438#endif 1439 1440 fdblk = 128 << (fd->ft->secsize); 1441 if (!(bp->b_flags & B_FORMAT)) { 1442 if (bp->b_blkno < 0) { 1443 printf( 1444 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", 1445 fdu, (u_long)bp->b_blkno, bp->b_bcount); 1446 bp->b_error = EINVAL; 1447 bp->b_flags |= B_ERROR; 1448 goto bad; 1449 } 1450 if ((bp->b_bcount % fdblk) != 0) { 1451 bp->b_error = EINVAL; 1452 bp->b_flags |= B_ERROR; 1453 goto bad; 1454 } 1455 } 1456 1457 /* 1458 * Set up block calculations. 1459 */ 1460 if (bp->b_blkno > 20000000) { 1461 /* 1462 * Reject unreasonably high block number, prevent the 1463 * multiplication below from overflowing. 1464 */ 1465 bp->b_error = EINVAL; 1466 bp->b_flags |= B_ERROR; 1467 goto bad; 1468 } 1469 blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk; 1470 nblocks = fd->ft->size; 1471 bp->b_resid = 0; 1472 if (blknum + (bp->b_bcount / fdblk) > nblocks) { 1473 if (blknum <= nblocks) { 1474 cando = (nblocks - blknum) * fdblk; 1475 bp->b_resid = bp->b_bcount - cando; 1476 if (cando == 0) 1477 goto bad; /* not actually bad but EOF */ 1478 } else { 1479 bp->b_error = EINVAL; 1480 bp->b_flags |= B_ERROR; 1481 goto bad; 1482 } 1483 } 1484 bp->b_pblkno = bp->b_blkno; 1485 s = splbio(); 1486 bufqdisksort(&fdc->head, bp); 1487 untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */ 1488 1489 /* Tell devstat we are starting on the transaction */ 1490 devstat_start_transaction(&fd->device_stats); 1491 1492 fdstart(fdc); 1493 splx(s); 1494 return; 1495 1496bad: 1497 biodone(bp); 1498} 1499 1500/***************************************************************\ 1501* fdstart * 1502* We have just queued something.. if the controller is not busy * 1503* then simulate the case where it has just finished a command * 1504* So that it (the interrupt routine) looks on the queue for more* 1505* work to do and picks up what we just added. * 1506* If the controller is already busy, we need do nothing, as it * 1507* will pick up our work when the present work completes * 1508\***************************************************************/ 1509static void 1510fdstart(struct fdc_data *fdc) 1511{ 1512 int s; 1513 1514 s = splbio(); 1515 if(fdc->state == DEVIDLE) 1516 { 1517 fdc_intr(fdc); 1518 } 1519 splx(s); 1520} 1521 1522static void 1523fd_iotimeout(void *xfdc) 1524{ 1525 fdc_p fdc; 1526 int s; 1527 1528 fdc = xfdc; 1529 TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); 1530 1531 /* 1532 * Due to IBM's brain-dead design, the FDC has a faked ready 1533 * signal, hardwired to ready == true. Thus, any command 1534 * issued if there's no diskette in the drive will _never_ 1535 * complete, and must be aborted by resetting the FDC. 1536 * Many thanks, Big Blue! 1537 * The FDC must not be reset directly, since that would 1538 * interfere with the state machine. Instead, pretend that 1539 * the command completed but was invalid. The state machine 1540 * will reset the FDC and retry once. 1541 */ 1542 s = splbio(); 1543 fdc->status[0] = NE7_ST0_IC_IV; 1544 fdc->flags &= ~FDC_STAT_VALID; 1545 fdc->state = IOTIMEDOUT; 1546 fdc_intr(fdc); 1547 splx(s); 1548} 1549 1550/* just ensure it has the right spl */ 1551static void 1552fd_pseudointr(void *xfdc) 1553{ 1554 int s; 1555 1556 s = splbio(); 1557 fdc_intr(xfdc); 1558 splx(s); 1559} 1560 1561/***********************************************************************\ 1562* fdintr * 1563* keep calling the state machine until it returns a 0 * 1564* ALWAYS called at SPLBIO * 1565\***********************************************************************/ 1566static void 1567fdc_intr(void *xfdc) 1568{ 1569 fdc_p fdc = xfdc; 1570 while(fdstate(fdc)) 1571 ; 1572} 1573 1574#ifdef FDC_YE 1575/* 1576 * magic pseudo-DMA initialization for YE FDC. Sets count and 1577 * direction 1578 */ 1579#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \ 1580 outb(port+1,((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f))) 1581 1582/* 1583 * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy 1584 */ 1585static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count) 1586{ 1587 u_char *cptr = (u_char *)addr; 1588 fdc_p fdc = &fdc_data[fdcu]; 1589 int io = fdc->baseport; 1590 1591 if (flags & B_READ) { 1592 if (fdc->state != PIOREAD) { 1593 fdc->state = PIOREAD; 1594 return(0); 1595 }; 1596 SET_BCDR(0,count,io); 1597 insb(io+FDC_YE_DATAPORT,cptr,count); 1598 } else { 1599 outsb(io+FDC_YE_DATAPORT,cptr,count); 1600 SET_BCDR(0,count,io); 1601 }; 1602 return(1); 1603} 1604#endif /* FDC_YE */ 1605 1606/***********************************************************************\ 1607* The controller state machine. * 1608* if it returns a non zero value, it should be called again immediatly * 1609\***********************************************************************/ 1610static int 1611fdstate(fdc_p fdc) 1612{ 1613 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3; 1614 unsigned blknum = 0, b_cylinder = 0; 1615 fdu_t fdu = fdc->fdu; 1616 fd_p fd; 1617 register struct buf *bp; 1618 struct fd_formb *finfo = NULL; 1619 size_t fdblk; 1620 1621 bp = fdc->bp; 1622 if (bp == NULL) { 1623 bp = bufq_first(&fdc->head); 1624 if (bp != NULL) { 1625 bufq_remove(&fdc->head, bp); 1626 fdc->bp = bp; 1627 } 1628 } 1629 if (bp == NULL) { 1630 /***********************************************\ 1631 * nothing left for this controller to do * 1632 * Force into the IDLE state, * 1633 \***********************************************/ 1634 fdc->state = DEVIDLE; 1635 if (fdc->fd) { 1636 device_print_prettyname(fdc->fdc_dev); 1637 printf("unexpected valid fd pointer\n"); 1638 fdc->fd = (fd_p) 0; 1639 fdc->fdu = -1; 1640 } 1641 TRACE1("[fdc%d IDLE]", fdc->fdcu); 1642 return (0); 1643 } 1644 fdu = FDUNIT(minor(bp->b_dev)); 1645 fd = devclass_get_softc(fd_devclass, fdu); 1646 fdblk = 128 << fd->ft->secsize; 1647 if (fdc->fd && (fd != fdc->fd)) { 1648 device_print_prettyname(fd->dev); 1649 printf("confused fd pointers\n"); 1650 } 1651 read = bp->b_flags & B_READ; 1652 format = bp->b_flags & B_FORMAT; 1653 if (format) { 1654 finfo = (struct fd_formb *)bp->b_data; 1655 fd->skip = (char *)&(finfo->fd_formb_cylno(0)) 1656 - (char *)finfo; 1657 } 1658 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { 1659 blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk + 1660 fd->skip/fdblk; 1661 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1662 } 1663 TRACE1("fd%d", fdu); 1664 TRACE1("[%s]", fdstates[fdc->state]); 1665 TRACE1("(0x%x)", fd->flags); 1666 untimeout(fd_turnoff, fd, fd->toffhandle); 1667 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); 1668 switch (fdc->state) 1669 { 1670 case DEVIDLE: 1671 case FINDWORK: /* we have found new work */ 1672 fdc->retry = 0; 1673 fd->skip = 0; 1674 fdc->fd = fd; 1675 fdc->fdu = fdu; 1676 outb(fdc->baseport+FDCTL, fd->ft->trans); 1677 TRACE1("[0x%x->FDCTL]", fd->ft->trans); 1678 /*******************************************************\ 1679 * If the next drive has a motor startup pending, then * 1680 * it will start up in its own good time * 1681 \*******************************************************/ 1682 if(fd->flags & FD_MOTOR_WAIT) { 1683 fdc->state = MOTORWAIT; 1684 return (0); /* come back later */ 1685 } 1686 /*******************************************************\ 1687 * Maybe if it's not starting, it SHOULD be starting * 1688 \*******************************************************/ 1689 if (!(fd->flags & FD_MOTOR)) 1690 { 1691 fdc->state = MOTORWAIT; 1692 fd_turnon(fd); 1693 return (0); 1694 } 1695 else /* at least make sure we are selected */ 1696 { 1697 set_motor(fdc, fd->fdsu, TURNON); 1698 } 1699 if (fdc->flags & FDC_NEEDS_RESET) { 1700 fdc->state = RESETCTLR; 1701 fdc->flags &= ~FDC_NEEDS_RESET; 1702 } else 1703 fdc->state = DOSEEK; 1704 break; 1705 case DOSEEK: 1706 if (b_cylinder == (unsigned)fd->track) 1707 { 1708 fdc->state = SEEKCOMPLETE; 1709 break; 1710 } 1711 if (fd_cmd(fdc, 3, NE7CMD_SEEK, 1712 fd->fdsu, b_cylinder * fd->ft->steptrac, 1713 0)) 1714 { 1715 /* 1716 * seek command not accepted, looks like 1717 * the FDC went off to the Saints... 1718 */ 1719 fdc->retry = 6; /* try a reset */ 1720 return(retrier(fdc)); 1721 } 1722 fd->track = FD_NO_TRACK; 1723 fdc->state = SEEKWAIT; 1724 return(0); /* will return later */ 1725 case SEEKWAIT: 1726 /* allow heads to settle */ 1727 timeout(fd_pseudointr, fdc, hz / 16); 1728 fdc->state = SEEKCOMPLETE; 1729 return(0); /* will return later */ 1730 case SEEKCOMPLETE : /* SEEK DONE, START DMA */ 1731 /* Make sure seek really happened*/ 1732 if(fd->track == FD_NO_TRACK) { 1733 int descyl = b_cylinder * fd->ft->steptrac; 1734 do { 1735 /* 1736 * This might be a "ready changed" interrupt, 1737 * which cannot really happen since the 1738 * RDY pin is hardwired to + 5 volts. This 1739 * generally indicates a "bouncing" intr 1740 * line, so do one of the following: 1741 * 1742 * When running on an enhanced FDC that is 1743 * known to not go stuck after responding 1744 * with INVALID, fetch all interrupt states 1745 * until seeing either an INVALID or a 1746 * real interrupt condition. 1747 * 1748 * When running on a dumb old NE765, give 1749 * up immediately. The controller will 1750 * provide up to four dummy RC interrupt 1751 * conditions right after reset (for the 1752 * corresponding four drives), so this is 1753 * our only chance to get notice that it 1754 * was not the FDC that caused the interrupt. 1755 */ 1756 if (fd_sense_int(fdc, &st0, &cyl) 1757 == FD_NOT_VALID) 1758 return 0; 1759 if(fdc->fdct == FDC_NE765 1760 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 1761 return 0; /* hope for a real intr */ 1762 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 1763 1764 if (0 == descyl) { 1765 int failed = 0; 1766 /* 1767 * seek to cyl 0 requested; make sure we are 1768 * really there 1769 */ 1770 if (fd_sense_drive_status(fdc, &st3)) 1771 failed = 1; 1772 if ((st3 & NE7_ST3_T0) == 0) { 1773 printf( 1774 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n", 1775 fdu, st3, NE7_ST3BITS); 1776 failed = 1; 1777 } 1778 1779 if (failed) { 1780 if(fdc->retry < 3) 1781 fdc->retry = 3; 1782 return (retrier(fdc)); 1783 } 1784 } 1785 1786 if (cyl != descyl) { 1787 printf( 1788 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", 1789 fdu, descyl, cyl, st0); 1790 if (fdc->retry < 3) 1791 fdc->retry = 3; 1792 return (retrier(fdc)); 1793 } 1794 } 1795 1796 fd->track = b_cylinder; 1797#ifdef FDC_YE 1798 if (!(fdc->flags & FDC_PCMCIA)) 1799#endif 1800 isa_dmastart(bp->b_flags, bp->b_data+fd->skip, 1801 format ? bp->b_bcount : fdblk, fdc->dmachan); 1802 sectrac = fd->ft->sectrac; 1803 sec = blknum % (sectrac * fd->ft->heads); 1804 head = sec / sectrac; 1805 sec = sec % sectrac + 1; 1806 fd->hddrv = ((head&1)<<2)+fdu; 1807 1808 if(format || !read) 1809 { 1810 /* make sure the drive is writable */ 1811 if(fd_sense_drive_status(fdc, &st3) != 0) 1812 { 1813 /* stuck controller? */ 1814 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1815 format ? bp->b_bcount : fdblk, 1816 fdc->dmachan); 1817 fdc->retry = 6; /* reset the beast */ 1818 return (retrier(fdc)); 1819 } 1820 if(st3 & NE7_ST3_WP) 1821 { 1822 /* 1823 * XXX YES! this is ugly. 1824 * in order to force the current operation 1825 * to fail, we will have to fake an FDC 1826 * error - all error handling is done 1827 * by the retrier() 1828 */ 1829 fdc->status[0] = NE7_ST0_IC_AT; 1830 fdc->status[1] = NE7_ST1_NW; 1831 fdc->status[2] = 0; 1832 fdc->status[3] = fd->track; 1833 fdc->status[4] = head; 1834 fdc->status[5] = sec; 1835 fdc->retry = 8; /* break out immediately */ 1836 fdc->state = IOTIMEDOUT; /* not really... */ 1837 return (1); 1838 } 1839 } 1840 1841 if (format) { 1842#ifdef FDC_YE 1843 if (fdc->flags & FDC_PCMCIA) 1844 (void)fdcpio(fdcu,bp->b_flags, 1845 bp->b_data+fd->skip, 1846 bp->b_bcount); 1847#endif 1848 /* formatting */ 1849 if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu, 1850 finfo->fd_formb_secshift, 1851 finfo->fd_formb_nsecs, 1852 finfo->fd_formb_gaplen, 1853 finfo->fd_formb_fillbyte, 0)) { 1854 /* controller fell over */ 1855 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1856 format ? bp->b_bcount : fdblk, 1857 fdc->dmachan); 1858 fdc->retry = 6; 1859 return (retrier(fdc)); 1860 } 1861 } else { 1862#ifdef FDC_YE 1863 if (fdc->flags & FDC_PCMCIA) { 1864 /* 1865 * this seems to be necessary even when 1866 * reading data 1867 */ 1868 SET_BCDR(1,fdblk,fdc->baseport); 1869 1870 /* 1871 * perform the write pseudo-DMA before 1872 * the WRITE command is sent 1873 */ 1874 if (!read) 1875 (void)fdcpio(fdcu,bp->b_flags, 1876 bp->b_data+fd->skip, 1877 fdblk); 1878 } 1879#endif 1880 if (fd_cmd(fdc, 9, 1881 (read ? NE7CMD_READ : NE7CMD_WRITE), 1882 head << 2 | fdu, /* head & unit */ 1883 fd->track, /* track */ 1884 head, 1885 sec, /* sector + 1 */ 1886 fd->ft->secsize, /* sector size */ 1887 sectrac, /* sectors/track */ 1888 fd->ft->gap, /* gap size */ 1889 fd->ft->datalen, /* data length */ 1890 0)) { 1891 /* the beast is sleeping again */ 1892 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1893 format ? bp->b_bcount : fdblk, 1894 fdc->dmachan); 1895 fdc->retry = 6; 1896 return (retrier(fdc)); 1897 } 1898 } 1899#ifdef FDC_YE 1900 if (fdc->flags & FDC_PCMCIA) 1901 /* 1902 * if this is a read, then simply await interrupt 1903 * before performing PIO 1904 */ 1905 if (read && !fdcpio(fdcu,bp->b_flags, 1906 bp->b_data+fd->skip,fdblk)) { 1907 fd->tohandle = timeout(fd_iotimeout, 1908 (caddr_t)fdcu, hz); 1909 return(0); /* will return later */ 1910 }; 1911 1912 /* 1913 * write (or format) operation will fall through and 1914 * await completion interrupt 1915 */ 1916#endif 1917 fdc->state = IOCOMPLETE; 1918 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 1919 return (0); /* will return later */ 1920#ifdef FDC_YE 1921 case PIOREAD: 1922 /* 1923 * actually perform the PIO read. The IOCOMPLETE case 1924 * removes the timeout for us. 1925 */ 1926 (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk); 1927 fdc->state = IOCOMPLETE; 1928 /* FALLTHROUGH */ 1929#endif 1930 case IOCOMPLETE: /* IO DONE, post-analyze */ 1931 untimeout(fd_iotimeout, fdc, fd->tohandle); 1932 1933 if (fd_read_status(fdc, fd->fdsu)) { 1934 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1935 format ? bp->b_bcount : fdblk, 1936 fdc->dmachan); 1937 if (fdc->retry < 6) 1938 fdc->retry = 6; /* force a reset */ 1939 return (retrier(fdc)); 1940 } 1941 1942 fdc->state = IOTIMEDOUT; 1943 1944 /* FALLTHROUGH */ 1945 1946 case IOTIMEDOUT: 1947#ifdef FDC_YE 1948 if (!(fdc->flags & FDC_PCMCIA)) 1949#endif 1950 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1951 format ? bp->b_bcount : fdblk, fdc->dmachan); 1952 if (fdc->status[0] & NE7_ST0_IC) { 1953 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 1954 && fdc->status[1] & NE7_ST1_OR) { 1955 /* 1956 * DMA overrun. Someone hogged the bus 1957 * and didn't release it in time for the 1958 * next FDC transfer. 1959 * Just restart it, don't increment retry 1960 * count. (vak) 1961 */ 1962 fdc->state = SEEKCOMPLETE; 1963 return (1); 1964 } 1965 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 1966 && fdc->retry < 6) 1967 fdc->retry = 6; /* force a reset */ 1968 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 1969 && fdc->status[2] & NE7_ST2_WC 1970 && fdc->retry < 3) 1971 fdc->retry = 3; /* force recalibrate */ 1972 return (retrier(fdc)); 1973 } 1974 /* All OK */ 1975 fd->skip += fdblk; 1976 if (!format && fd->skip < bp->b_bcount - bp->b_resid) { 1977 /* set up next transfer */ 1978 fdc->state = DOSEEK; 1979 } else { 1980 /* ALL DONE */ 1981 fd->skip = 0; 1982 fdc->bp = NULL; 1983 /* Tell devstat we have finished with the transaction */ 1984 devstat_end_transaction(&fd->device_stats, 1985 bp->b_bcount - bp->b_resid, 1986 DEVSTAT_TAG_NONE, 1987 (bp->b_flags & B_READ) ? 1988 DEVSTAT_READ : DEVSTAT_WRITE); 1989 biodone(bp); 1990 fdc->fd = (fd_p) 0; 1991 fdc->fdu = -1; 1992 fdc->state = FINDWORK; 1993 } 1994 return (1); 1995 case RESETCTLR: 1996 fdc_reset(fdc); 1997 fdc->retry++; 1998 fdc->state = RESETCOMPLETE; 1999 return (0); 2000 case RESETCOMPLETE: 2001 /* 2002 * Discard all the results from the reset so that they 2003 * can't cause an unexpected interrupt later. 2004 */ 2005 for (i = 0; i < 4; i++) 2006 (void)fd_sense_int(fdc, &st0, &cyl); 2007 fdc->state = STARTRECAL; 2008 /* Fall through. */ 2009 case STARTRECAL: 2010 if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) { 2011 /* arrgl */ 2012 fdc->retry = 6; 2013 return (retrier(fdc)); 2014 } 2015 fdc->state = RECALWAIT; 2016 return (0); /* will return later */ 2017 case RECALWAIT: 2018 /* allow heads to settle */ 2019 timeout(fd_pseudointr, fdc, hz / 8); 2020 fdc->state = RECALCOMPLETE; 2021 return (0); /* will return later */ 2022 case RECALCOMPLETE: 2023 do { 2024 /* 2025 * See SEEKCOMPLETE for a comment on this: 2026 */ 2027 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 2028 return 0; 2029 if(fdc->fdct == FDC_NE765 2030 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 2031 return 0; /* hope for a real intr */ 2032 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 2033 if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0) 2034 { 2035 if(fdc->retry > 3) 2036 /* 2037 * a recalibrate from beyond cylinder 77 2038 * will "fail" due to the FDC limitations; 2039 * since people used to complain much about 2040 * the failure message, try not logging 2041 * this one if it seems to be the first 2042 * time in a line 2043 */ 2044 printf("fd%d: recal failed ST0 %b cyl %d\n", 2045 fdu, st0, NE7_ST0BITS, cyl); 2046 if(fdc->retry < 3) fdc->retry = 3; 2047 return (retrier(fdc)); 2048 } 2049 fd->track = 0; 2050 /* Seek (probably) necessary */ 2051 fdc->state = DOSEEK; 2052 return (1); /* will return immediatly */ 2053 case MOTORWAIT: 2054 if(fd->flags & FD_MOTOR_WAIT) 2055 { 2056 return (0); /* time's not up yet */ 2057 } 2058 if (fdc->flags & FDC_NEEDS_RESET) { 2059 fdc->state = RESETCTLR; 2060 fdc->flags &= ~FDC_NEEDS_RESET; 2061 } else { 2062 /* 2063 * If all motors were off, then the controller was 2064 * reset, so it has lost track of the current 2065 * cylinder. Recalibrate to handle this case. 2066 */ 2067 fdc->state = STARTRECAL; 2068 } 2069 return (1); /* will return immediatly */ 2070 default: 2071 device_print_prettyname(fdc->fdc_dev); 2072 printf("unexpected FD int->"); 2073 if (fd_read_status(fdc, fd->fdsu) == 0) 2074 printf("FDC status :%x %x %x %x %x %x %x ", 2075 fdc->status[0], 2076 fdc->status[1], 2077 fdc->status[2], 2078 fdc->status[3], 2079 fdc->status[4], 2080 fdc->status[5], 2081 fdc->status[6] ); 2082 else 2083 printf("No status available "); 2084 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2085 { 2086 printf("[controller is dead now]\n"); 2087 return (0); 2088 } 2089 printf("ST0 = %x, PCN = %x\n", st0, cyl); 2090 return (0); 2091 } 2092 /*XXX confusing: some branches return immediately, others end up here*/ 2093 return (1); /* Come back immediatly to new state */ 2094} 2095 2096static int 2097retrier(struct fdc_data *fdc) 2098{ 2099 register struct buf *bp; 2100 struct fd_data *fd; 2101 int fdu; 2102 2103 bp = fdc->bp; 2104 2105 /* XXX shouldn't this be cached somewhere? */ 2106 fdu = FDUNIT(minor(bp->b_dev)); 2107 fd = devclass_get_softc(fd_devclass, fdu); 2108 if (fd->options & FDOPT_NORETRY) 2109 goto fail; 2110 2111 switch (fdc->retry) { 2112 case 0: case 1: case 2: 2113 fdc->state = SEEKCOMPLETE; 2114 break; 2115 case 3: case 4: case 5: 2116 fdc->state = STARTRECAL; 2117 break; 2118 case 6: 2119 fdc->state = RESETCTLR; 2120 break; 2121 case 7: 2122 break; 2123 default: 2124 fail: 2125 { 2126 dev_t sav_b_dev = bp->b_dev; 2127 /* Trick diskerr */ 2128 bp->b_dev = makedev(major(bp->b_dev), 2129 (FDUNIT(minor(bp->b_dev))<<3)|RAW_PART); 2130 diskerr(bp, "fd", "hard error", LOG_PRINTF, 2131 fdc->fd->skip / DEV_BSIZE, 2132 (struct disklabel *)NULL); 2133 bp->b_dev = sav_b_dev; 2134 if (fdc->flags & FDC_STAT_VALID) 2135 { 2136 printf( 2137 " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n", 2138 fdc->status[0], NE7_ST0BITS, 2139 fdc->status[1], NE7_ST1BITS, 2140 fdc->status[2], NE7_ST2BITS, 2141 fdc->status[3], fdc->status[4], 2142 fdc->status[5]); 2143 } 2144 else 2145 printf(" (No status)\n"); 2146 } 2147 bp->b_flags |= B_ERROR; 2148 bp->b_error = EIO; 2149 bp->b_resid += bp->b_bcount - fdc->fd->skip; 2150 fdc->bp = NULL; 2151 2152 /* Tell devstat we have finished with the transaction */ 2153 devstat_end_transaction(&fdc->fd->device_stats, 2154 bp->b_bcount - bp->b_resid, 2155 DEVSTAT_TAG_NONE, 2156 (bp->b_flags & B_READ) ? DEVSTAT_READ : 2157 DEVSTAT_WRITE); 2158 fdc->fd->skip = 0; 2159 biodone(bp); 2160 fdc->state = FINDWORK; 2161 fdc->flags |= FDC_NEEDS_RESET; 2162 fdc->fd = (fd_p) 0; 2163 fdc->fdu = -1; 2164 return (1); 2165 } 2166 fdc->retry++; 2167 return (1); 2168} 2169 2170static int 2171fdformat(dev, finfo, p) 2172 dev_t dev; 2173 struct fd_formb *finfo; 2174 struct proc *p; 2175{ 2176 fdu_t fdu; 2177 fd_p fd; 2178 2179 struct buf *bp; 2180 int rv = 0, s; 2181 size_t fdblk; 2182 2183 fdu = FDUNIT(minor(dev)); 2184 fd = devclass_get_softc(fd_devclass, fdu); 2185 fdblk = 128 << fd->ft->secsize; 2186 2187 /* set up a buffer header for fdstrategy() */ 2188 bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT); 2189 if(bp == 0) 2190 return ENOBUFS; 2191 /* 2192 * keep the process from being swapped 2193 */ 2194 PHOLD(p); 2195 bzero((void *)bp, sizeof(struct buf)); 2196 bp->b_flags = B_BUSY | B_PHYS | B_FORMAT;
| 51 * 52 */ 53 54#include "fd.h" 55#include "opt_devfs.h" 56#include "opt_fdc.h" 57 58#if NFDC > 0 59 60#include <sys/param.h> 61#include <sys/systm.h> 62#include <sys/kernel.h> 63#include <sys/buf.h> 64#include <sys/bus.h> 65#include <sys/conf.h> 66#include <sys/disklabel.h> 67#include <sys/devicestat.h> 68#include <sys/fcntl.h> 69#include <sys/malloc.h> 70#include <sys/module.h> 71#include <sys/proc.h> 72#include <sys/syslog.h> 73 74#include <sys/bus.h> 75#include <machine/bus.h> 76#include <sys/rman.h> 77 78#include <machine/clock.h> 79#include <machine/ioctl_fd.h> 80#include <machine/resource.h> 81#include <machine/stdarg.h> 82 83#ifdef DEVFS 84#include <sys/devfsext.h> 85#endif /* DEVFS */ 86 87#include <isa/isavar.h> 88#include <i386/isa/isa.h> 89#include <i386/isa/isa_dma.h> 90#include <i386/isa/fdreg.h> 91#include <i386/isa/fdc.h> 92#include <i386/isa/rtc.h> 93 94#ifdef FDC_YE 95#undef FDC_YE 96#warning "fix FDC_YE! - newbus casualty" 97#endif 98 99/* misuse a flag to identify format operation */ 100#define B_FORMAT B_XXX 101 102/* configuration flags */ 103#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 104#ifdef FDC_YE 105#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's 106 a PCMCIA device */ 107#endif 108 109/* internally used only, not really from CMOS: */ 110#define RTCFDT_144M_PRETENDED 0x1000 111 112/* 113 * this biotab field doubles as a field for the physical unit number 114 * on the controller 115 */ 116#define id_physid id_scsiid 117 118/* error returns for fd_cmd() */ 119#define FD_FAILED -1 120#define FD_NOT_VALID -2 121#define FDC_ERRMAX 100 /* do not log more */ 122 123#define NUMTYPES 14 124#define NUMDENS (NUMTYPES - 6) 125 126/* These defines (-1) must match index for fd_types */ 127#define F_TAPE_TYPE 0x020 /* bit for fd_types to indicate tape */ 128#define NO_TYPE 0 /* must match NO_TYPE in ft.c */ 129#define FD_1720 1 130#define FD_1480 2 131#define FD_1440 3 132#define FD_1200 4 133#define FD_820 5 134#define FD_800 6 135#define FD_720 7 136#define FD_360 8 137 138#define FD_1480in5_25 9 139#define FD_1440in5_25 10 140#define FD_820in5_25 11 141#define FD_800in5_25 12 142#define FD_720in5_25 13 143#define FD_360in5_25 14 144 145 146static struct fd_type fd_types[NUMTYPES] = 147{ 148{ 21,2,0xFF,0x04,82,3444,1,FDC_500KBPS,2,0x0C,2 }, /* 1.72M in HD 3.5in */ 149{ 18,2,0xFF,0x1B,82,2952,1,FDC_500KBPS,2,0x6C,1 }, /* 1.48M in HD 3.5in */ 150{ 18,2,0xFF,0x1B,80,2880,1,FDC_500KBPS,2,0x6C,1 }, /* 1.44M in HD 3.5in */ 151{ 15,2,0xFF,0x1B,80,2400,1,FDC_500KBPS,2,0x54,1 }, /* 1.2M in HD 5.25/3.5 */ 152{ 10,2,0xFF,0x10,82,1640,1,FDC_250KBPS,2,0x2E,1 }, /* 820K in HD 3.5in */ 153{ 10,2,0xFF,0x10,80,1600,1,FDC_250KBPS,2,0x2E,1 }, /* 800K in HD 3.5in */ 154{ 9,2,0xFF,0x20,80,1440,1,FDC_250KBPS,2,0x50,1 }, /* 720K in HD 3.5in */ 155{ 9,2,0xFF,0x2A,40, 720,1,FDC_250KBPS,2,0x50,1 }, /* 360K in DD 5.25in */ 156 157{ 18,2,0xFF,0x02,82,2952,1,FDC_500KBPS,2,0x02,2 }, /* 1.48M in HD 5.25in */ 158{ 18,2,0xFF,0x02,80,2880,1,FDC_500KBPS,2,0x02,2 }, /* 1.44M in HD 5.25in */ 159{ 10,2,0xFF,0x10,82,1640,1,FDC_300KBPS,2,0x2E,1 }, /* 820K in HD 5.25in */ 160{ 10,2,0xFF,0x10,80,1600,1,FDC_300KBPS,2,0x2E,1 }, /* 800K in HD 5.25in */ 161{ 9,2,0xFF,0x20,80,1440,1,FDC_300KBPS,2,0x50,1 }, /* 720K in HD 5.25in */ 162{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */ 163}; 164 165#define DRVS_PER_CTLR 2 /* 2 floppies */ 166 167/***********************************************************************\ 168* Per controller structure. * 169\***********************************************************************/ 170static devclass_t fdc_devclass; 171 172/***********************************************************************\ 173* Per drive structure. * 174* N per controller (DRVS_PER_CTLR) * 175\***********************************************************************/ 176struct fd_data { 177 struct fdc_data *fdc; /* pointer to controller structure */ 178 int fdsu; /* this units number on this controller */ 179 int type; /* Drive type (FD_1440...) */ 180 struct fd_type *ft; /* pointer to the type descriptor */ 181 int flags; 182#define FD_OPEN 0x01 /* it's open */ 183#define FD_ACTIVE 0x02 /* it's active */ 184#define FD_MOTOR 0x04 /* motor should be on */ 185#define FD_MOTOR_WAIT 0x08 /* motor coming up */ 186 int skip; 187 int hddrv; 188#define FD_NO_TRACK -2 189 int track; /* where we think the head is */ 190 int options; /* user configurable options, see ioctl_fd.h */ 191 struct callout_handle toffhandle; 192 struct callout_handle tohandle; 193 struct devstat device_stats; 194#ifdef DEVFS 195 void *bdevs[1 + NUMDENS + MAXPARTITIONS]; 196 void *cdevs[1 + NUMDENS + MAXPARTITIONS]; 197#endif 198 device_t dev; 199 fdu_t fdu; 200}; 201static devclass_t fd_devclass; 202 203/***********************************************************************\ 204* Throughout this file the following conventions will be used: * 205* fd is a pointer to the fd_data struct for the drive in question * 206* fdc is a pointer to the fdc_data struct for the controller * 207* fdu is the floppy drive unit number * 208* fdcu is the floppy controller unit number * 209* fdsu is the floppy drive unit number on that controller. (sub-unit) * 210\***********************************************************************/ 211 212#ifdef FDC_YE 213#include "card.h" 214static int yeattach(struct isa_device *); 215#endif 216 217/* needed for ft driver, thus exported */ 218int in_fdc(struct fdc_data *); 219int out_fdc(struct fdc_data *, int); 220 221/* internal functions */ 222static void fdc_add_device(device_t, const char *, int); 223static void fdc_intr(void *); 224static void set_motor(struct fdc_data *, int, int); 225# define TURNON 1 226# define TURNOFF 0 227static timeout_t fd_turnoff; 228static timeout_t fd_motor_on; 229static void fd_turnon(struct fd_data *); 230static void fdc_reset(fdc_p); 231static int fd_in(struct fdc_data *, int *); 232static void fdstart(struct fdc_data *); 233static timeout_t fd_iotimeout; 234static timeout_t fd_pseudointr; 235static int fdstate(struct fdc_data *); 236static int retrier(struct fdc_data *); 237static int fdformat(dev_t, struct fd_formb *, struct proc *); 238 239static int enable_fifo(fdc_p fdc); 240 241static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 242 243 244#define DEVIDLE 0 245#define FINDWORK 1 246#define DOSEEK 2 247#define SEEKCOMPLETE 3 248#define IOCOMPLETE 4 249#define RECALCOMPLETE 5 250#define STARTRECAL 6 251#define RESETCTLR 7 252#define SEEKWAIT 8 253#define RECALWAIT 9 254#define MOTORWAIT 10 255#define IOTIMEDOUT 11 256#define RESETCOMPLETE 12 257#ifdef FDC_YE 258#define PIOREAD 13 259#endif 260 261#ifdef FDC_DEBUG 262static char const * const fdstates[] = 263{ 264"DEVIDLE", 265"FINDWORK", 266"DOSEEK", 267"SEEKCOMPLETE", 268"IOCOMPLETE", 269"RECALCOMPLETE", 270"STARTRECAL", 271"RESETCTLR", 272"SEEKWAIT", 273"RECALWAIT", 274"MOTORWAIT", 275"IOTIMEDOUT", 276"RESETCOMPLETE", 277#ifdef FDC_YE 278"PIOREAD", 279#endif 280}; 281 282/* CAUTION: fd_debug causes huge amounts of logging output */ 283static int volatile fd_debug = 0; 284#define TRACE0(arg) if(fd_debug) printf(arg) 285#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2) 286#else /* FDC_DEBUG */ 287#define TRACE0(arg) 288#define TRACE1(arg1, arg2) 289#endif /* FDC_DEBUG */ 290 291#ifdef FDC_YE 292#if NCARD > 0 293#include <sys/select.h> 294#include <sys/module.h> 295#include <pccard/cardinfo.h> 296#include <pccard/driver.h> 297#include <pccard/slot.h> 298 299/* 300 * PC-Card (PCMCIA) specific code. 301 */ 302static int yeinit(struct pccard_devinfo *); /* init device */ 303static void yeunload(struct pccard_devinfo *); /* Disable driver */ 304static int yeintr(struct pccard_devinfo *); /* Interrupt handler */ 305 306PCCARD_MODULE(fdc, yeinit, yeunload, yeintr, 0, bio_imask); 307 308/* 309 * this is the secret PIO data port (offset from base) 310 */ 311#define FDC_YE_DATAPORT 6 312 313/* 314 * Initialize the device - called from Slot manager. 315 */ 316static int yeinit(struct pccard_devinfo *devi) 317{ 318 fdc_p fdc = &fdc_data[devi->isahd.id_unit]; 319 320 /* validate unit number. */ 321 if (devi->isahd.id_unit >= NFDC) 322 return(ENODEV); 323 fdc->baseport = devi->isahd.id_iobase; 324 /* 325 * reset controller 326 */ 327 outb(fdc->baseport+FDOUT, 0); 328 DELAY(100); 329 outb(fdc->baseport+FDOUT, FDO_FRST); 330 331 /* 332 * wire into system 333 */ 334 if (yeattach(&devi->isahd) == 0) 335 return(ENXIO); 336 337 return(0); 338} 339 340/* 341 * yeunload - unload the driver and clear the table. 342 * XXX TODO: 343 * This is usually called when the card is ejected, but 344 * can be caused by a modunload of a controller driver. 345 * The idea is to reset the driver's view of the device 346 * and ensure that any driver entry points such as 347 * read and write do not hang. 348 */ 349static void yeunload(struct pccard_devinfo *devi) 350{ 351 if (fd_data[devi->isahd.id_unit].type == NO_TYPE) 352 return; 353 354 /* 355 * this prevents Fdopen() and fdstrategy() from attempting 356 * to access unloaded controller 357 */ 358 fd_data[devi->isahd.id_unit].type = NO_TYPE; 359 360 printf("fdc%d: unload\n", devi->isahd.id_unit); 361} 362 363/* 364 * yeintr - Shared interrupt called from 365 * front end of PC-Card handler. 366 */ 367static int yeintr(struct pccard_devinfo *devi) 368{ 369 fdintr((fdcu_t)devi->isahd.id_unit); 370 return(1); 371} 372#endif /* NCARD > 0 */ 373#endif /* FDC_YE */ 374 375static d_open_t Fdopen; /* NOTE, not fdopen */ 376static d_read_t fdread; 377static d_write_t fdwrite; 378static d_close_t fdclose; 379static d_ioctl_t fdioctl; 380static d_strategy_t fdstrategy; 381 382static struct cdevsw fd_cdevsw = { 383 Fdopen, fdclose, fdread, fdwrite, 384 fdioctl, nostop, nullreset, nodevtotty, 385 seltrue, nommap, fdstrategy, "fd", 386 NULL, -1, nodump, nopsize, 387 D_DISK, 0, -1 388}; 389#define CDEV_MAJOR 9 390#define BDEV_MAJOR 2 391 392static int 393fdc_err(struct fdc_data *fdc, const char *s) 394{ 395 fdc->fdc_errs++; 396 if (s) { 397 if (fdc->fdc_errs < FDC_ERRMAX) { 398 device_print_prettyname(fdc->fdc_dev); 399 printf("%s", s); 400 } else if (fdc->fdc_errs == FDC_ERRMAX) { 401 device_print_prettyname(fdc->fdc_dev); 402 printf("too many errors, not logging any more\n"); 403 } 404 } 405 406 return FD_FAILED; 407} 408 409/* 410 * fd_cmd: Send a command to the chip. Takes a varargs with this structure: 411 * Unit number, 412 * # of output bytes, output bytes as ints ..., 413 * # of input bytes, input bytes as ints ... 414 */ 415static int 416fd_cmd(struct fdc_data *fdc, int n_out, ...) 417{ 418 u_char cmd; 419 int n_in; 420 int n; 421 va_list ap; 422 423 va_start(ap, n_out); 424 cmd = (u_char)(va_arg(ap, int)); 425 va_end(ap); 426 va_start(ap, n_out); 427 for (n = 0; n < n_out; n++) 428 { 429 if (out_fdc(fdc, va_arg(ap, int)) < 0) 430 { 431 char msg[50]; 432 snprintf(msg, sizeof(msg), 433 "cmd %x failed at out byte %d of %d\n", 434 cmd, n + 1, n_out); 435 return fdc_err(fdc, msg); 436 } 437 } 438 n_in = va_arg(ap, int); 439 for (n = 0; n < n_in; n++) 440 { 441 int *ptr = va_arg(ap, int *); 442 if (fd_in(fdc, ptr) < 0) 443 { 444 char msg[50]; 445 snprintf(msg, sizeof(msg), 446 "cmd %02x failed at in byte %d of %d\n", 447 cmd, n + 1, n_in); 448 return fdc_err(fdc, msg); 449 } 450 } 451 452 return 0; 453} 454 455static int 456enable_fifo(fdc_p fdc) 457{ 458 int i, j; 459 460 if ((fdc->flags & FDC_HAS_FIFO) == 0) { 461 462 /* 463 * XXX: 464 * Cannot use fd_cmd the normal way here, since 465 * this might be an invalid command. Thus we send the 466 * first byte, and check for an early turn of data directon. 467 */ 468 469 if (out_fdc(fdc, I8207X_CONFIGURE) < 0) 470 return fdc_err(fdc, "Enable FIFO failed\n"); 471 472 /* If command is invalid, return */ 473 j = 100000; 474 while ((i = inb(fdc->baseport + FDSTS) & (NE7_DIO | NE7_RQM)) 475 != NE7_RQM && j-- > 0) 476 if (i == (NE7_DIO | NE7_RQM)) { 477 fdc_reset(fdc); 478 return FD_FAILED; 479 } 480 if (j<0 || 481 fd_cmd(fdc, 3, 482 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 483 fdc_reset(fdc); 484 return fdc_err(fdc, "Enable FIFO failed\n"); 485 } 486 fdc->flags |= FDC_HAS_FIFO; 487 return 0; 488 } 489 if (fd_cmd(fdc, 4, 490 I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) 491 return fdc_err(fdc, "Re-enable FIFO failed\n"); 492 return 0; 493} 494 495static int 496fd_sense_drive_status(fdc_p fdc, int *st3p) 497{ 498 int st3; 499 500 if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) 501 { 502 return fdc_err(fdc, "Sense Drive Status failed\n"); 503 } 504 if (st3p) 505 *st3p = st3; 506 507 return 0; 508} 509 510static int 511fd_sense_int(fdc_p fdc, int *st0p, int *cylp) 512{ 513 int cyl, st0, ret; 514 515 ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0); 516 if (ret) { 517 (void)fdc_err(fdc, 518 "sense intr err reading stat reg 0\n"); 519 return ret; 520 } 521 522 if (st0p) 523 *st0p = st0; 524 525 if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) { 526 /* 527 * There doesn't seem to have been an interrupt. 528 */ 529 return FD_NOT_VALID; 530 } 531 532 if (fd_in(fdc, &cyl) < 0) { 533 return fdc_err(fdc, "can't get cyl num\n"); 534 } 535 536 if (cylp) 537 *cylp = cyl; 538 539 return 0; 540} 541 542 543static int 544fd_read_status(fdc_p fdc, int fdsu) 545{ 546 int i, ret; 547 548 for (i = 0; i < 7; i++) { 549 /* 550 * XXX types are poorly chosen. Only bytes can by read 551 * from the hardware, but fdc->status[] wants u_ints and 552 * fd_in() gives ints. 553 */ 554 int status; 555 556 ret = fd_in(fdc, &status); 557 fdc->status[i] = status; 558 if (ret != 0) 559 break; 560 } 561 562 if (ret == 0) 563 fdc->flags |= FDC_STAT_VALID; 564 else 565 fdc->flags &= ~FDC_STAT_VALID; 566 567 return ret; 568} 569 570/****************************************************************************/ 571/* autoconfiguration stuff */ 572/****************************************************************************/ 573 574static int 575fdc_probe(device_t dev) 576{ 577 int error, i, ic_type; 578 struct fdc_data *fdc; 579 char myname[8]; /* better be long enough */ 580 581 fdc = device_get_softc(dev); 582 bzero(fdc, sizeof *fdc); 583 fdc->fdc_dev = dev; 584 fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0; 585 fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0; 586 587 fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, 588 &fdc->rid_ioport, 0ul, ~0ul, 589 IO_FDCSIZE, RF_ACTIVE); 590 if (fdc->res_ioport == 0) { 591 device_print_prettyname(dev); 592 printf("cannot reserve I/O port range\n"); 593 error = ENXIO; 594 goto out; 595 } 596 fdc->baseport = fdc->res_ioport->r_start; 597 598 fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, 599 &fdc->rid_irq, 0ul, ~0ul, 1, 600 RF_ACTIVE); 601 if (fdc->res_irq == 0) { 602 device_print_prettyname(dev); 603 printf("cannot reserve interrupt line\n"); 604 error = ENXIO; 605 goto out; 606 } 607 fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, 608 &fdc->rid_drq, 0ul, ~0ul, 1, 609 RF_ACTIVE); 610 if (fdc->res_drq == 0) { 611 device_print_prettyname(dev); 612 printf("cannot reserve DMA request line\n"); 613 error = ENXIO; 614 goto out; 615 } 616 fdc->dmachan = fdc->res_drq->r_start; 617 error = BUS_SETUP_INTR(device_get_parent(dev), dev, 618 fdc->res_irq, fdc_intr, fdc, &fdc->fdc_intr); 619 620 /* First - lets reset the floppy controller */ 621 outb(fdc->baseport + FDOUT, 0); 622 DELAY(100); 623 outb(fdc->baseport + FDOUT, FDO_FRST); 624 625 /* see if it can handle a command */ 626 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 627 NE7_SPEC_2(2, 0), 0)) { 628 error = ENXIO; 629 goto out; 630 } 631 632 if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) { 633 ic_type = (u_char)ic_type; 634 switch (ic_type) { 635 case 0x80: 636 device_set_desc(dev, "NEC 765 or clone"); 637 fdc->fdct = FDC_NE765; 638 break; 639 case 0x81: 640 device_set_desc(dev, "Intel 82077 or clone"); 641 fdc->fdct = FDC_I82077; 642 break; 643 case 0x90: 644 device_set_desc(dev, "NEC 72065B or clone"); 645 fdc->fdct = FDC_NE72065; 646 break; 647 default: 648 device_set_desc(dev, "generic floppy controller"); 649 fdc->fdct = FDC_UNKNOWN; 650 break; 651 } 652 } 653 654 snprintf(myname, sizeof(myname), "%s%d", device_get_name(dev), 655 device_get_unit(dev)); 656 for (i = resource_query_string(-1, "at", myname); i != -1; 657 i = resource_query_string(i, "at", myname)) 658 fdc_add_device(dev, resource_query_name(i), 659 resource_query_unit(i)); 660#ifdef FDC_YE 661 /* 662 * don't succeed on probe; wait 663 * for PCCARD subsystem to do it 664 */ 665 if (dev->id_flags & FDC_IS_PCMCIA) 666 return(0); 667#endif 668 return (0); 669 670out: 671 if (fdc->fdc_intr) 672 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 673 fdc->fdc_intr); 674 if (fdc->res_irq != 0) { 675 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 676 fdc->res_irq); 677 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 678 fdc->res_irq); 679 } 680 if (fdc->res_ioport != 0) { 681 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 682 fdc->res_ioport); 683 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 684 fdc->res_ioport); 685 } 686 if (fdc->res_drq != 0) { 687 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 688 fdc->res_drq); 689 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 690 fdc->res_drq); 691 } 692 return (error); 693} 694 695/* 696 * Aped dfr@freebsd.org's isa_add_device(). 697 */ 698static void 699fdc_add_device(device_t dev, const char *name, int unit) 700{ 701 int disabled, *ivar; 702 device_t child; 703 704 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT); 705 if (ivar == 0) 706 return; 707 if (resource_int_value(name, unit, "drive", ivar) == 0) 708 *ivar = 0; 709 child = device_add_child(dev, name, unit, ivar); 710 if (child == 0) 711 return; 712 if (resource_int_value(name, unit, "disabled", &disabled) == 0) 713 device_disable(child); 714} 715 716static int 717fdc_attach(device_t dev) 718{ 719 struct fdc_data *fdc = device_get_softc(dev); 720 fdcu_t fdcu = device_get_unit(dev); 721 722 fdc->fdcu = fdcu; 723 fdc->flags |= FDC_ATTACHED; 724 725 /* Acquire the DMA channel forever, The driver will do the rest */ 726 /* XXX should integrate with rman */ 727 isa_dma_acquire(fdc->dmachan); 728 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); 729 fdc->state = DEVIDLE; 730 731 /* reset controller, turn motor off, clear fdout mirror reg */ 732 outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); 733 bufq_init(&fdc->head); 734 735#ifdef FIFO_BEFORE_MOTORON 736 /* Hmm, this doesn't work here - is set_motor() magic? -Peter */ 737 if (fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 738 && enable_fifo(fdc) == 0) { 739 device_print_prettyname(dev); 740 printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); 741 } 742#endif 743 /* 744 * Probe and attach any children as were configured above. 745 */ 746 return (bus_generic_attach(dev)); 747} 748 749static void 750fdc_print_child(device_t me, device_t child) 751{ 752 printf(" at %s%d drive %d", device_get_name(me), device_get_unit(me), 753 *(int *)device_get_ivars(child)); 754} 755 756static int 757fd_probe(device_t dev) 758{ 759 int i; 760 u_int fdt, st0, st3; 761 struct fd_data *fd; 762 struct fdc_data *fdc; 763 fdsu_t fdsu; 764#ifndef FIFO_BEFORE_MOTORON 765 static int fd_fifo = 0; 766#endif 767 768 fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */ 769 fd = device_get_softc(dev); 770 fdc = device_get_softc(device_get_parent(dev)); 771 772 bzero(fd, sizeof *fd); 773 fd->dev = dev; 774 fd->fdc = fdc; 775 fd->fdsu = fdsu; 776 fd->fdu = device_get_unit(dev); 777 778 /* look up what bios thinks we have */ 779 switch (fd->fdu) { 780 case 0: 781 if (isa_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0) 782 fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; 783 else 784 fdt = (rtcin(RTC_FDISKETTE) & 0xf0); 785 break; 786 case 1: 787 fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); 788 break; 789 default: 790 fdt = RTCFDT_NONE; 791 break; 792 } 793 794 /* is there a unit? */ 795 if (fdt == RTCFDT_NONE) 796 return (ENXIO); 797 798 /* select it */ 799 set_motor(fdc, fdsu, TURNON); 800 DELAY(1000000); /* 1 sec */ 801 802#ifndef FIFO_BEFORE_MOTORON 803 if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 804 && enable_fifo(fdc) == 0) { 805 device_print_prettyname(device_get_parent(dev)); 806 printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); 807 } 808 fd_fifo = 1; 809#endif 810 811 if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) 812 && (st3 & NE7_ST3_T0)) { 813 /* if at track 0, first seek inwards */ 814 /* seek some steps: */ 815 fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0); 816 DELAY(300000); /* ...wait a moment... */ 817 fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 818 } 819 820 /* If we're at track 0 first seek inwards. */ 821 if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { 822 /* Seek some steps... */ 823 if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 824 /* ...wait a moment... */ 825 DELAY(300000); 826 /* make ctrlr happy: */ 827 fd_sense_int(fdc, 0, 0); 828 } 829 } 830 831 for (i = 0; i < 2; i++) { 832 /* 833 * we must recalibrate twice, just in case the 834 * heads have been beyond cylinder 76, since most 835 * FDCs still barf when attempting to recalibrate 836 * more than 77 steps 837 */ 838 /* go back to 0: */ 839 if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 840 /* a second being enough for full stroke seek*/ 841 DELAY(i == 0 ? 1000000 : 300000); 842 843 /* anything responding? */ 844 if (fd_sense_int(fdc, &st0, 0) == 0 && 845 (st0 & NE7_ST0_EC) == 0) 846 break; /* already probed succesfully */ 847 } 848 } 849 850 set_motor(fdc, fdsu, TURNOFF); 851 852 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 853 return (ENXIO); 854 855 fd->track = FD_NO_TRACK; 856 fd->fdc = fdc; 857 fd->fdsu = fdsu; 858 fd->options = 0; 859 callout_handle_init(&fd->toffhandle); 860 callout_handle_init(&fd->tohandle); 861 862 switch (fdt) { 863 case RTCFDT_12M: 864 device_set_desc(dev, "1200-KB 5.25\" drive"); 865 fd->type = FD_1200; 866 break; 867 case RTCFDT_144M | RTCFDT_144M_PRETENDED: 868 device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive"); 869 fdt = RTCFDT_144M; 870 fd->type = FD_1440; 871 case RTCFDT_144M: 872 device_set_desc(dev, "1440-KB 3.5\" drive"); 873 fd->type = FD_1440; 874 break; 875 case RTCFDT_288M: 876 case RTCFDT_288M_1: 877 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)"); 878 fd->type = FD_1440; 879 break; 880 case RTCFDT_360K: 881 device_set_desc(dev, "360-KB 5.25\" drive"); 882 fd->type = FD_360; 883 break; 884 case RTCFDT_720K: 885 printf("720-KB 3.5\" drive"); 886 fd->type = FD_720; 887 break; 888 default: 889 return (ENXIO); 890 } 891 return (0); 892} 893 894static int 895fd_attach(device_t dev) 896{ 897 struct fd_data *fd; 898#ifdef DEVFS 899 int i; 900 int mynor; 901 int typemynor; 902 int typesize; 903#endif 904 905 fd = device_get_softc(dev); 906 907#ifdef DEVFS /* XXX bitrot */ 908 mynor = fd->fdu << 6; 909 fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, 910 UID_ROOT, GID_OPERATOR, 0640, 911 "fd%d", fd->fdu); 912 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, 913 UID_ROOT, GID_OPERATOR, 0640, 914 "rfd%d", fd->fdu); 915 for (i = 1; i < 1 + NUMDENS; i++) { 916 /* 917 * XXX this and the lookup in Fdopen() should be 918 * data driven. 919 */ 920 switch (fd->type) { 921 case FD_360: 922 if (i != FD_360) 923 continue; 924 break; 925 case FD_720: 926 if (i != FD_720 && i != FD_800 && i != FD_820) 927 continue; 928 break; 929 case FD_1200: 930 if (i != FD_360 && i != FD_720 && i != FD_800 931 && i != FD_820 && i != FD_1200 932 && i != FD_1440 && i != FD_1480) 933 continue; 934 break; 935 case FD_1440: 936 if (i != FD_720 && i != FD_800 && i != FD_820 937 && i != FD_1200 && i != FD_1440 938 && i != FD_1480 && i != FD_1720) 939 continue; 940 break; 941 } 942 typesize = fd_types[i - 1].size / 2; 943 /* 944 * XXX all these conversions give bloated code and 945 * confusing names. 946 */ 947 if (typesize == 1476) 948 typesize = 1480; 949 if (typesize == 1722) 950 typesize = 1720; 951 typemynor = mynor | i; 952 fd->bdevs[i] = 953 devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, 954 UID_ROOT, GID_OPERATOR, 0640, 955 "fd%d.%d", fd->fdu, typesize); 956 fd->cdevs[i] = 957 devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, 958 UID_ROOT, GID_OPERATOR, 0640, 959 "rfd%d.%d", fd->fdu, typesize); 960 } 961 962 for (i = 0; i < MAXPARTITIONS; i++) { 963 fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], 964 "fd%d%c", fd->fdu, 'a' + i); 965 fd->cdevs[1 + NUMDENS + i] = 966 devfs_makelink(fd->cdevs[0], 967 "rfd%d%c", fd->fdu, 'a' + i); 968 } 969#endif /* DEVFS */ 970 /* 971 * Export the drive to the devstat interface. 972 */ 973 devstat_add_entry(&fd->device_stats, device_get_name(dev), 974 device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS, 975 DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, 976 DEVSTAT_PRIORITY_FD); 977 return (0); 978} 979 980#ifdef FDC_YE 981/* 982 * this is a subset of fdattach() optimized for the Y-E Data 983 * PCMCIA floppy drive. 984 */ 985static int yeattach(struct isa_device *dev) 986{ 987 fdcu_t fdcu = dev->id_unit; 988 fdc_p fdc = fdc_data + fdcu; 989 fdsu_t fdsu = 0; /* assume 1 drive per YE controller */ 990 fdu_t fdu; 991 fd_p fd; 992 int st0, st3, i; 993#ifdef DEVFS 994 int mynor; 995 int typemynor; 996 int typesize; 997#endif 998 fdc->fdcu = fdcu; 999 /* 1000 * the FDC_PCMCIA flag is used to to indicate special PIO is used 1001 * instead of DMA 1002 */ 1003 fdc->flags = FDC_ATTACHED|FDC_PCMCIA; 1004 fdc->state = DEVIDLE; 1005 /* reset controller, turn motor off, clear fdout mirror reg */ 1006 outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); 1007 bufq_init(&fdc->head); 1008 /* 1009 * assume 2 drives/ "normal" controller 1010 */ 1011 fdu = fdcu * 2; 1012 if (fdu >= NFD) { 1013 printf("fdu %d >= NFD\n",fdu); 1014 return(0); 1015 }; 1016 fd = &fd_data[fdu]; 1017 1018 set_motor(fdcu, fdsu, TURNON); 1019 DELAY(1000000); /* 1 sec */ 1020 fdc->fdct = FDC_NE765; 1021 1022 if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) && 1023 (st3 & NE7_ST3_T0)) { 1024 /* if at track 0, first seek inwards */ 1025 /* seek some steps: */ 1026 (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0); 1027 DELAY(300000); /* ...wait a moment... */ 1028 (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 1029 } 1030 1031 /* If we're at track 0 first seek inwards. */ 1032 if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { 1033 /* Seek some steps... */ 1034 if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 1035 /* ...wait a moment... */ 1036 DELAY(300000); 1037 /* make ctrlr happy: */ 1038 (void)fd_sense_int(fdc, 0, 0); 1039 } 1040 } 1041 1042 for(i = 0; i < 2; i++) { 1043 /* 1044 * we must recalibrate twice, just in case the 1045 * heads have been beyond cylinder 76, since most 1046 * FDCs still barf when attempting to recalibrate 1047 * more than 77 steps 1048 */ 1049 /* go back to 0: */ 1050 if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 1051 /* a second being enough for full stroke seek*/ 1052 DELAY(i == 0? 1000000: 300000); 1053 1054 /* anything responding? */ 1055 if (fd_sense_int(fdc, &st0, 0) == 0 && 1056 (st0 & NE7_ST0_EC) == 0) 1057 break; /* already probed succesfully */ 1058 } 1059 } 1060 1061 set_motor(fdcu, fdsu, TURNOFF); 1062 1063 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 1064 return(0); 1065 1066 fd->track = FD_NO_TRACK; 1067 fd->fdc = fdc; 1068 fd->fdsu = fdsu; 1069 fd->options = 0; 1070 printf("fdc%d: 1.44MB 3.5in PCMCIA\n", fdcu); 1071 fd->type = FD_1440; 1072 1073#ifdef DEVFS 1074 mynor = fdcu << 6; 1075 fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, 1076 UID_ROOT, GID_OPERATOR, 0640, 1077 "fd%d", fdu); 1078 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, 1079 UID_ROOT, GID_OPERATOR, 0640, 1080 "rfd%d", fdu); 1081 /* 1082 * XXX this and the lookup in Fdopen() should be 1083 * data driven. 1084 */ 1085 typemynor = mynor | FD_1440; 1086 typesize = fd_types[FD_1440 - 1].size / 2; 1087 /* 1088 * XXX all these conversions give bloated code and 1089 * confusing names. 1090 */ 1091 if (typesize == 1476) 1092 typesize = 1480; 1093 if (typesize == 1722) 1094 typesize = 1720; 1095 fd->bdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor, 1096 DV_BLK, UID_ROOT, GID_OPERATOR, 1097 0640, "fd%d.%d", fdu, typesize); 1098 fd->cdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor, 1099 DV_CHR, UID_ROOT, GID_OPERATOR, 1100 0640,"rfd%d.%d", fdu, typesize); 1101 for (i = 0; i < MAXPARTITIONS; i++) { 1102 fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], 1103 "fd%d%c", fdu, 'a' + i); 1104 fd->cdevs[1 + NUMDENS + i] = devfs_makelink(fd->cdevs[0], 1105 "rfd%d%c", fdu, 'a' + i); 1106 } 1107#endif /* DEVFS */ 1108 return (1); 1109} 1110#endif 1111 1112/****************************************************************************/ 1113/* motor control stuff */ 1114/* remember to not deselect the drive we're working on */ 1115/****************************************************************************/ 1116static void 1117set_motor(struct fdc_data *fdc, int fdsu, int turnon) 1118{ 1119 int fdout = fdc->fdout; 1120 int needspecify = 0; 1121 1122 if(turnon) { 1123 fdout &= ~FDO_FDSEL; 1124 fdout |= (FDO_MOEN0 << fdsu) + fdsu; 1125 } else 1126 fdout &= ~(FDO_MOEN0 << fdsu); 1127 1128 if(!turnon 1129 && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0) 1130 /* gonna turn off the last drive, put FDC to bed */ 1131 fdout &= ~ (FDO_FRST|FDO_FDMAEN); 1132 else { 1133 /* make sure controller is selected and specified */ 1134 if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0) 1135 needspecify = 1; 1136 fdout |= (FDO_FRST|FDO_FDMAEN); 1137 } 1138 1139 outb(fdc->baseport+FDOUT, fdout); 1140 fdc->fdout = fdout; 1141 TRACE1("[0x%x->FDOUT]", fdout); 1142 1143 if (needspecify) { 1144 /* 1145 * XXX 1146 * special case: since we have just woken up the FDC 1147 * from its sleep, we silently assume the command will 1148 * be accepted, and do not test for a timeout 1149 */ 1150 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, 1151 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1152 0); 1153 if (fdc->flags & FDC_HAS_FIFO) 1154 (void) enable_fifo(fdc); 1155 } 1156} 1157 1158static void 1159fd_turnoff(void *xfd) 1160{ 1161 int s; 1162 fd_p fd = xfd; 1163 1164 TRACE1("[fd%d: turnoff]", fd->fdu); 1165 1166 /* 1167 * Don't turn off the motor yet if the drive is active. 1168 * XXX shouldn't even schedule turnoff until drive is inactive 1169 * and nothing is queued on it. 1170 */ 1171 if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) { 1172 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); 1173 return; 1174 } 1175 1176 s = splbio(); 1177 fd->flags &= ~FD_MOTOR; 1178 set_motor(fd->fdc, fd->fdsu, TURNOFF); 1179 splx(s); 1180} 1181 1182static void 1183fd_motor_on(void *xfd) 1184{ 1185 int s; 1186 fd_p fd = xfd; 1187 1188 s = splbio(); 1189 fd->flags &= ~FD_MOTOR_WAIT; 1190 if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) 1191 { 1192 fdc_intr(fd->fdc); 1193 } 1194 splx(s); 1195} 1196 1197static void 1198fd_turnon(fd_p fd) 1199{ 1200 if(!(fd->flags & FD_MOTOR)) 1201 { 1202 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); 1203 set_motor(fd->fdc, fd->fdsu, TURNON); 1204 timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */ 1205 } 1206} 1207 1208static void 1209fdc_reset(fdc_p fdc) 1210{ 1211 /* Try a reset, keep motor on */ 1212 outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1213 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); 1214 DELAY(100); 1215 /* enable FDC, but defer interrupts a moment */ 1216 outb(fdc->baseport + FDOUT, fdc->fdout & ~FDO_FDMAEN); 1217 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN); 1218 DELAY(100); 1219 outb(fdc->baseport + FDOUT, fdc->fdout); 1220 TRACE1("[0x%x->FDOUT]", fdc->fdout); 1221 1222 /* XXX after a reset, silently believe the FDC will accept commands */ 1223 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, 1224 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1225 0); 1226 if (fdc->flags & FDC_HAS_FIFO) 1227 (void) enable_fifo(fdc); 1228} 1229 1230/****************************************************************************/ 1231/* fdc in/out */ 1232/****************************************************************************/ 1233int 1234in_fdc(struct fdc_data *fdc) 1235{ 1236 int baseport = fdc->baseport; 1237 int i, j = 100000; 1238 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1239 != (NE7_DIO|NE7_RQM) && j-- > 0) 1240 if (i == NE7_RQM) 1241 return fdc_err(fdc, "ready for output in input\n"); 1242 if (j <= 0) 1243 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); 1244#ifdef FDC_DEBUG 1245 i = inb(baseport+FDDATA); 1246 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1247 return(i); 1248#else /* !FDC_DEBUG */ 1249 return inb(baseport+FDDATA); 1250#endif /* FDC_DEBUG */ 1251} 1252 1253/* 1254 * fd_in: Like in_fdc, but allows you to see if it worked. 1255 */ 1256static int 1257fd_in(struct fdc_data *fdc, int *ptr) 1258{ 1259 int baseport = fdc->baseport; 1260 int i, j = 100000; 1261 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1262 != (NE7_DIO|NE7_RQM) && j-- > 0) 1263 if (i == NE7_RQM) 1264 return fdc_err(fdc, "ready for output in input\n"); 1265 if (j <= 0) 1266 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); 1267#ifdef FDC_DEBUG 1268 i = inb(baseport+FDDATA); 1269 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1270 *ptr = i; 1271 return 0; 1272#else /* !FDC_DEBUG */ 1273 i = inb(baseport+FDDATA); 1274 if (ptr) 1275 *ptr = i; 1276 return 0; 1277#endif /* FDC_DEBUG */ 1278} 1279 1280int 1281out_fdc(struct fdc_data *fdc, int x) 1282{ 1283 int baseport = fdc->baseport; 1284 int i; 1285 1286 /* Check that the direction bit is set */ 1287 i = 100000; 1288 while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0); 1289 if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); 1290 1291 /* Check that the floppy controller is ready for a command */ 1292 i = 100000; 1293 while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0); 1294 if (i <= 0) 1295 return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); 1296 1297 /* Send the command and return */ 1298 outb(baseport+FDDATA, x); 1299 TRACE1("[0x%x->FDDATA]", x); 1300 return (0); 1301} 1302 1303/****************************************************************************/ 1304/* fdopen/fdclose */ 1305/****************************************************************************/ 1306int 1307Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1308{ 1309 fdu_t fdu = FDUNIT(minor(dev)); 1310 int type = FDTYPE(minor(dev)); 1311 fd_p fd; 1312 fdc_p fdc; 1313 1314 /* check bounds */ 1315 if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0) 1316 return (ENXIO); 1317 fdc = fd->fdc; 1318 if ((fdc == NULL) || (fd->type == NO_TYPE)) 1319 return (ENXIO); 1320 if (type > NUMDENS) 1321 return (ENXIO); 1322 if (type == 0) 1323 type = fd->type; 1324 else { 1325 /* 1326 * For each type of basic drive, make sure we are trying 1327 * to open a type it can do, 1328 */ 1329 if (type != fd->type) { 1330 switch (fd->type) { 1331 case FD_360: 1332 return (ENXIO); 1333 case FD_720: 1334 if ( type != FD_820 1335 && type != FD_800 1336 ) 1337 return (ENXIO); 1338 break; 1339 case FD_1200: 1340 switch (type) { 1341 case FD_1480: 1342 type = FD_1480in5_25; 1343 break; 1344 case FD_1440: 1345 type = FD_1440in5_25; 1346 break; 1347 case FD_820: 1348 type = FD_820in5_25; 1349 break; 1350 case FD_800: 1351 type = FD_800in5_25; 1352 break; 1353 case FD_720: 1354 type = FD_720in5_25; 1355 break; 1356 case FD_360: 1357 type = FD_360in5_25; 1358 break; 1359 default: 1360 return(ENXIO); 1361 } 1362 break; 1363 case FD_1440: 1364 if ( type != FD_1720 1365 && type != FD_1480 1366 && type != FD_1200 1367 && type != FD_820 1368 && type != FD_800 1369 && type != FD_720 1370 ) 1371 return(ENXIO); 1372 break; 1373 } 1374 } 1375 } 1376 fd->ft = fd_types + type - 1; 1377 fd->flags |= FD_OPEN; 1378 device_busy(fd->dev); 1379 device_busy(fd->fdc->fdc_dev); 1380 return 0; 1381} 1382 1383int 1384fdclose(dev_t dev, int flags, int mode, struct proc *p) 1385{ 1386 fdu_t fdu = FDUNIT(minor(dev)); 1387 struct fd_data *fd; 1388 1389 fd = devclass_get_softc(fd_devclass, fdu); 1390 fd->flags &= ~FD_OPEN; 1391 fd->options &= ~FDOPT_NORETRY; 1392 1393 return (0); 1394} 1395 1396static int 1397fdread(dev_t dev, struct uio *uio, int ioflag) 1398{ 1399 return (physio(fdstrategy, NULL, dev, 1, minphys, uio)); 1400} 1401 1402static int 1403fdwrite(dev_t dev, struct uio *uio, int ioflag) 1404{ 1405 return (physio(fdstrategy, NULL, dev, 0, minphys, uio)); 1406} 1407 1408 1409/****************************************************************************/ 1410/* fdstrategy */ 1411/****************************************************************************/ 1412void 1413fdstrategy(struct buf *bp) 1414{ 1415 unsigned nblocks, blknum, cando; 1416 int s; 1417 fdu_t fdu; 1418 fdc_p fdc; 1419 fd_p fd; 1420 size_t fdblk; 1421 1422 fdu = FDUNIT(minor(bp->b_dev)); 1423 fd = devclass_get_softc(fd_devclass, fdu); 1424 if (fd == 0) 1425 panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)", 1426 (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev)); 1427 fdc = fd->fdc; 1428#ifdef FDC_YE 1429 if (fd->type == NO_TYPE) { 1430 bp->b_error = ENXIO; 1431 bp->b_flags |= B_ERROR; 1432 /* 1433 * I _refuse_ to use a goto 1434 */ 1435 biodone(bp); 1436 return; 1437 }; 1438#endif 1439 1440 fdblk = 128 << (fd->ft->secsize); 1441 if (!(bp->b_flags & B_FORMAT)) { 1442 if (bp->b_blkno < 0) { 1443 printf( 1444 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", 1445 fdu, (u_long)bp->b_blkno, bp->b_bcount); 1446 bp->b_error = EINVAL; 1447 bp->b_flags |= B_ERROR; 1448 goto bad; 1449 } 1450 if ((bp->b_bcount % fdblk) != 0) { 1451 bp->b_error = EINVAL; 1452 bp->b_flags |= B_ERROR; 1453 goto bad; 1454 } 1455 } 1456 1457 /* 1458 * Set up block calculations. 1459 */ 1460 if (bp->b_blkno > 20000000) { 1461 /* 1462 * Reject unreasonably high block number, prevent the 1463 * multiplication below from overflowing. 1464 */ 1465 bp->b_error = EINVAL; 1466 bp->b_flags |= B_ERROR; 1467 goto bad; 1468 } 1469 blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk; 1470 nblocks = fd->ft->size; 1471 bp->b_resid = 0; 1472 if (blknum + (bp->b_bcount / fdblk) > nblocks) { 1473 if (blknum <= nblocks) { 1474 cando = (nblocks - blknum) * fdblk; 1475 bp->b_resid = bp->b_bcount - cando; 1476 if (cando == 0) 1477 goto bad; /* not actually bad but EOF */ 1478 } else { 1479 bp->b_error = EINVAL; 1480 bp->b_flags |= B_ERROR; 1481 goto bad; 1482 } 1483 } 1484 bp->b_pblkno = bp->b_blkno; 1485 s = splbio(); 1486 bufqdisksort(&fdc->head, bp); 1487 untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */ 1488 1489 /* Tell devstat we are starting on the transaction */ 1490 devstat_start_transaction(&fd->device_stats); 1491 1492 fdstart(fdc); 1493 splx(s); 1494 return; 1495 1496bad: 1497 biodone(bp); 1498} 1499 1500/***************************************************************\ 1501* fdstart * 1502* We have just queued something.. if the controller is not busy * 1503* then simulate the case where it has just finished a command * 1504* So that it (the interrupt routine) looks on the queue for more* 1505* work to do and picks up what we just added. * 1506* If the controller is already busy, we need do nothing, as it * 1507* will pick up our work when the present work completes * 1508\***************************************************************/ 1509static void 1510fdstart(struct fdc_data *fdc) 1511{ 1512 int s; 1513 1514 s = splbio(); 1515 if(fdc->state == DEVIDLE) 1516 { 1517 fdc_intr(fdc); 1518 } 1519 splx(s); 1520} 1521 1522static void 1523fd_iotimeout(void *xfdc) 1524{ 1525 fdc_p fdc; 1526 int s; 1527 1528 fdc = xfdc; 1529 TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); 1530 1531 /* 1532 * Due to IBM's brain-dead design, the FDC has a faked ready 1533 * signal, hardwired to ready == true. Thus, any command 1534 * issued if there's no diskette in the drive will _never_ 1535 * complete, and must be aborted by resetting the FDC. 1536 * Many thanks, Big Blue! 1537 * The FDC must not be reset directly, since that would 1538 * interfere with the state machine. Instead, pretend that 1539 * the command completed but was invalid. The state machine 1540 * will reset the FDC and retry once. 1541 */ 1542 s = splbio(); 1543 fdc->status[0] = NE7_ST0_IC_IV; 1544 fdc->flags &= ~FDC_STAT_VALID; 1545 fdc->state = IOTIMEDOUT; 1546 fdc_intr(fdc); 1547 splx(s); 1548} 1549 1550/* just ensure it has the right spl */ 1551static void 1552fd_pseudointr(void *xfdc) 1553{ 1554 int s; 1555 1556 s = splbio(); 1557 fdc_intr(xfdc); 1558 splx(s); 1559} 1560 1561/***********************************************************************\ 1562* fdintr * 1563* keep calling the state machine until it returns a 0 * 1564* ALWAYS called at SPLBIO * 1565\***********************************************************************/ 1566static void 1567fdc_intr(void *xfdc) 1568{ 1569 fdc_p fdc = xfdc; 1570 while(fdstate(fdc)) 1571 ; 1572} 1573 1574#ifdef FDC_YE 1575/* 1576 * magic pseudo-DMA initialization for YE FDC. Sets count and 1577 * direction 1578 */ 1579#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \ 1580 outb(port+1,((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f))) 1581 1582/* 1583 * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy 1584 */ 1585static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count) 1586{ 1587 u_char *cptr = (u_char *)addr; 1588 fdc_p fdc = &fdc_data[fdcu]; 1589 int io = fdc->baseport; 1590 1591 if (flags & B_READ) { 1592 if (fdc->state != PIOREAD) { 1593 fdc->state = PIOREAD; 1594 return(0); 1595 }; 1596 SET_BCDR(0,count,io); 1597 insb(io+FDC_YE_DATAPORT,cptr,count); 1598 } else { 1599 outsb(io+FDC_YE_DATAPORT,cptr,count); 1600 SET_BCDR(0,count,io); 1601 }; 1602 return(1); 1603} 1604#endif /* FDC_YE */ 1605 1606/***********************************************************************\ 1607* The controller state machine. * 1608* if it returns a non zero value, it should be called again immediatly * 1609\***********************************************************************/ 1610static int 1611fdstate(fdc_p fdc) 1612{ 1613 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3; 1614 unsigned blknum = 0, b_cylinder = 0; 1615 fdu_t fdu = fdc->fdu; 1616 fd_p fd; 1617 register struct buf *bp; 1618 struct fd_formb *finfo = NULL; 1619 size_t fdblk; 1620 1621 bp = fdc->bp; 1622 if (bp == NULL) { 1623 bp = bufq_first(&fdc->head); 1624 if (bp != NULL) { 1625 bufq_remove(&fdc->head, bp); 1626 fdc->bp = bp; 1627 } 1628 } 1629 if (bp == NULL) { 1630 /***********************************************\ 1631 * nothing left for this controller to do * 1632 * Force into the IDLE state, * 1633 \***********************************************/ 1634 fdc->state = DEVIDLE; 1635 if (fdc->fd) { 1636 device_print_prettyname(fdc->fdc_dev); 1637 printf("unexpected valid fd pointer\n"); 1638 fdc->fd = (fd_p) 0; 1639 fdc->fdu = -1; 1640 } 1641 TRACE1("[fdc%d IDLE]", fdc->fdcu); 1642 return (0); 1643 } 1644 fdu = FDUNIT(minor(bp->b_dev)); 1645 fd = devclass_get_softc(fd_devclass, fdu); 1646 fdblk = 128 << fd->ft->secsize; 1647 if (fdc->fd && (fd != fdc->fd)) { 1648 device_print_prettyname(fd->dev); 1649 printf("confused fd pointers\n"); 1650 } 1651 read = bp->b_flags & B_READ; 1652 format = bp->b_flags & B_FORMAT; 1653 if (format) { 1654 finfo = (struct fd_formb *)bp->b_data; 1655 fd->skip = (char *)&(finfo->fd_formb_cylno(0)) 1656 - (char *)finfo; 1657 } 1658 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { 1659 blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk + 1660 fd->skip/fdblk; 1661 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1662 } 1663 TRACE1("fd%d", fdu); 1664 TRACE1("[%s]", fdstates[fdc->state]); 1665 TRACE1("(0x%x)", fd->flags); 1666 untimeout(fd_turnoff, fd, fd->toffhandle); 1667 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); 1668 switch (fdc->state) 1669 { 1670 case DEVIDLE: 1671 case FINDWORK: /* we have found new work */ 1672 fdc->retry = 0; 1673 fd->skip = 0; 1674 fdc->fd = fd; 1675 fdc->fdu = fdu; 1676 outb(fdc->baseport+FDCTL, fd->ft->trans); 1677 TRACE1("[0x%x->FDCTL]", fd->ft->trans); 1678 /*******************************************************\ 1679 * If the next drive has a motor startup pending, then * 1680 * it will start up in its own good time * 1681 \*******************************************************/ 1682 if(fd->flags & FD_MOTOR_WAIT) { 1683 fdc->state = MOTORWAIT; 1684 return (0); /* come back later */ 1685 } 1686 /*******************************************************\ 1687 * Maybe if it's not starting, it SHOULD be starting * 1688 \*******************************************************/ 1689 if (!(fd->flags & FD_MOTOR)) 1690 { 1691 fdc->state = MOTORWAIT; 1692 fd_turnon(fd); 1693 return (0); 1694 } 1695 else /* at least make sure we are selected */ 1696 { 1697 set_motor(fdc, fd->fdsu, TURNON); 1698 } 1699 if (fdc->flags & FDC_NEEDS_RESET) { 1700 fdc->state = RESETCTLR; 1701 fdc->flags &= ~FDC_NEEDS_RESET; 1702 } else 1703 fdc->state = DOSEEK; 1704 break; 1705 case DOSEEK: 1706 if (b_cylinder == (unsigned)fd->track) 1707 { 1708 fdc->state = SEEKCOMPLETE; 1709 break; 1710 } 1711 if (fd_cmd(fdc, 3, NE7CMD_SEEK, 1712 fd->fdsu, b_cylinder * fd->ft->steptrac, 1713 0)) 1714 { 1715 /* 1716 * seek command not accepted, looks like 1717 * the FDC went off to the Saints... 1718 */ 1719 fdc->retry = 6; /* try a reset */ 1720 return(retrier(fdc)); 1721 } 1722 fd->track = FD_NO_TRACK; 1723 fdc->state = SEEKWAIT; 1724 return(0); /* will return later */ 1725 case SEEKWAIT: 1726 /* allow heads to settle */ 1727 timeout(fd_pseudointr, fdc, hz / 16); 1728 fdc->state = SEEKCOMPLETE; 1729 return(0); /* will return later */ 1730 case SEEKCOMPLETE : /* SEEK DONE, START DMA */ 1731 /* Make sure seek really happened*/ 1732 if(fd->track == FD_NO_TRACK) { 1733 int descyl = b_cylinder * fd->ft->steptrac; 1734 do { 1735 /* 1736 * This might be a "ready changed" interrupt, 1737 * which cannot really happen since the 1738 * RDY pin is hardwired to + 5 volts. This 1739 * generally indicates a "bouncing" intr 1740 * line, so do one of the following: 1741 * 1742 * When running on an enhanced FDC that is 1743 * known to not go stuck after responding 1744 * with INVALID, fetch all interrupt states 1745 * until seeing either an INVALID or a 1746 * real interrupt condition. 1747 * 1748 * When running on a dumb old NE765, give 1749 * up immediately. The controller will 1750 * provide up to four dummy RC interrupt 1751 * conditions right after reset (for the 1752 * corresponding four drives), so this is 1753 * our only chance to get notice that it 1754 * was not the FDC that caused the interrupt. 1755 */ 1756 if (fd_sense_int(fdc, &st0, &cyl) 1757 == FD_NOT_VALID) 1758 return 0; 1759 if(fdc->fdct == FDC_NE765 1760 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 1761 return 0; /* hope for a real intr */ 1762 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 1763 1764 if (0 == descyl) { 1765 int failed = 0; 1766 /* 1767 * seek to cyl 0 requested; make sure we are 1768 * really there 1769 */ 1770 if (fd_sense_drive_status(fdc, &st3)) 1771 failed = 1; 1772 if ((st3 & NE7_ST3_T0) == 0) { 1773 printf( 1774 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n", 1775 fdu, st3, NE7_ST3BITS); 1776 failed = 1; 1777 } 1778 1779 if (failed) { 1780 if(fdc->retry < 3) 1781 fdc->retry = 3; 1782 return (retrier(fdc)); 1783 } 1784 } 1785 1786 if (cyl != descyl) { 1787 printf( 1788 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", 1789 fdu, descyl, cyl, st0); 1790 if (fdc->retry < 3) 1791 fdc->retry = 3; 1792 return (retrier(fdc)); 1793 } 1794 } 1795 1796 fd->track = b_cylinder; 1797#ifdef FDC_YE 1798 if (!(fdc->flags & FDC_PCMCIA)) 1799#endif 1800 isa_dmastart(bp->b_flags, bp->b_data+fd->skip, 1801 format ? bp->b_bcount : fdblk, fdc->dmachan); 1802 sectrac = fd->ft->sectrac; 1803 sec = blknum % (sectrac * fd->ft->heads); 1804 head = sec / sectrac; 1805 sec = sec % sectrac + 1; 1806 fd->hddrv = ((head&1)<<2)+fdu; 1807 1808 if(format || !read) 1809 { 1810 /* make sure the drive is writable */ 1811 if(fd_sense_drive_status(fdc, &st3) != 0) 1812 { 1813 /* stuck controller? */ 1814 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1815 format ? bp->b_bcount : fdblk, 1816 fdc->dmachan); 1817 fdc->retry = 6; /* reset the beast */ 1818 return (retrier(fdc)); 1819 } 1820 if(st3 & NE7_ST3_WP) 1821 { 1822 /* 1823 * XXX YES! this is ugly. 1824 * in order to force the current operation 1825 * to fail, we will have to fake an FDC 1826 * error - all error handling is done 1827 * by the retrier() 1828 */ 1829 fdc->status[0] = NE7_ST0_IC_AT; 1830 fdc->status[1] = NE7_ST1_NW; 1831 fdc->status[2] = 0; 1832 fdc->status[3] = fd->track; 1833 fdc->status[4] = head; 1834 fdc->status[5] = sec; 1835 fdc->retry = 8; /* break out immediately */ 1836 fdc->state = IOTIMEDOUT; /* not really... */ 1837 return (1); 1838 } 1839 } 1840 1841 if (format) { 1842#ifdef FDC_YE 1843 if (fdc->flags & FDC_PCMCIA) 1844 (void)fdcpio(fdcu,bp->b_flags, 1845 bp->b_data+fd->skip, 1846 bp->b_bcount); 1847#endif 1848 /* formatting */ 1849 if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu, 1850 finfo->fd_formb_secshift, 1851 finfo->fd_formb_nsecs, 1852 finfo->fd_formb_gaplen, 1853 finfo->fd_formb_fillbyte, 0)) { 1854 /* controller fell over */ 1855 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1856 format ? bp->b_bcount : fdblk, 1857 fdc->dmachan); 1858 fdc->retry = 6; 1859 return (retrier(fdc)); 1860 } 1861 } else { 1862#ifdef FDC_YE 1863 if (fdc->flags & FDC_PCMCIA) { 1864 /* 1865 * this seems to be necessary even when 1866 * reading data 1867 */ 1868 SET_BCDR(1,fdblk,fdc->baseport); 1869 1870 /* 1871 * perform the write pseudo-DMA before 1872 * the WRITE command is sent 1873 */ 1874 if (!read) 1875 (void)fdcpio(fdcu,bp->b_flags, 1876 bp->b_data+fd->skip, 1877 fdblk); 1878 } 1879#endif 1880 if (fd_cmd(fdc, 9, 1881 (read ? NE7CMD_READ : NE7CMD_WRITE), 1882 head << 2 | fdu, /* head & unit */ 1883 fd->track, /* track */ 1884 head, 1885 sec, /* sector + 1 */ 1886 fd->ft->secsize, /* sector size */ 1887 sectrac, /* sectors/track */ 1888 fd->ft->gap, /* gap size */ 1889 fd->ft->datalen, /* data length */ 1890 0)) { 1891 /* the beast is sleeping again */ 1892 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1893 format ? bp->b_bcount : fdblk, 1894 fdc->dmachan); 1895 fdc->retry = 6; 1896 return (retrier(fdc)); 1897 } 1898 } 1899#ifdef FDC_YE 1900 if (fdc->flags & FDC_PCMCIA) 1901 /* 1902 * if this is a read, then simply await interrupt 1903 * before performing PIO 1904 */ 1905 if (read && !fdcpio(fdcu,bp->b_flags, 1906 bp->b_data+fd->skip,fdblk)) { 1907 fd->tohandle = timeout(fd_iotimeout, 1908 (caddr_t)fdcu, hz); 1909 return(0); /* will return later */ 1910 }; 1911 1912 /* 1913 * write (or format) operation will fall through and 1914 * await completion interrupt 1915 */ 1916#endif 1917 fdc->state = IOCOMPLETE; 1918 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 1919 return (0); /* will return later */ 1920#ifdef FDC_YE 1921 case PIOREAD: 1922 /* 1923 * actually perform the PIO read. The IOCOMPLETE case 1924 * removes the timeout for us. 1925 */ 1926 (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk); 1927 fdc->state = IOCOMPLETE; 1928 /* FALLTHROUGH */ 1929#endif 1930 case IOCOMPLETE: /* IO DONE, post-analyze */ 1931 untimeout(fd_iotimeout, fdc, fd->tohandle); 1932 1933 if (fd_read_status(fdc, fd->fdsu)) { 1934 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1935 format ? bp->b_bcount : fdblk, 1936 fdc->dmachan); 1937 if (fdc->retry < 6) 1938 fdc->retry = 6; /* force a reset */ 1939 return (retrier(fdc)); 1940 } 1941 1942 fdc->state = IOTIMEDOUT; 1943 1944 /* FALLTHROUGH */ 1945 1946 case IOTIMEDOUT: 1947#ifdef FDC_YE 1948 if (!(fdc->flags & FDC_PCMCIA)) 1949#endif 1950 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 1951 format ? bp->b_bcount : fdblk, fdc->dmachan); 1952 if (fdc->status[0] & NE7_ST0_IC) { 1953 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 1954 && fdc->status[1] & NE7_ST1_OR) { 1955 /* 1956 * DMA overrun. Someone hogged the bus 1957 * and didn't release it in time for the 1958 * next FDC transfer. 1959 * Just restart it, don't increment retry 1960 * count. (vak) 1961 */ 1962 fdc->state = SEEKCOMPLETE; 1963 return (1); 1964 } 1965 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 1966 && fdc->retry < 6) 1967 fdc->retry = 6; /* force a reset */ 1968 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 1969 && fdc->status[2] & NE7_ST2_WC 1970 && fdc->retry < 3) 1971 fdc->retry = 3; /* force recalibrate */ 1972 return (retrier(fdc)); 1973 } 1974 /* All OK */ 1975 fd->skip += fdblk; 1976 if (!format && fd->skip < bp->b_bcount - bp->b_resid) { 1977 /* set up next transfer */ 1978 fdc->state = DOSEEK; 1979 } else { 1980 /* ALL DONE */ 1981 fd->skip = 0; 1982 fdc->bp = NULL; 1983 /* Tell devstat we have finished with the transaction */ 1984 devstat_end_transaction(&fd->device_stats, 1985 bp->b_bcount - bp->b_resid, 1986 DEVSTAT_TAG_NONE, 1987 (bp->b_flags & B_READ) ? 1988 DEVSTAT_READ : DEVSTAT_WRITE); 1989 biodone(bp); 1990 fdc->fd = (fd_p) 0; 1991 fdc->fdu = -1; 1992 fdc->state = FINDWORK; 1993 } 1994 return (1); 1995 case RESETCTLR: 1996 fdc_reset(fdc); 1997 fdc->retry++; 1998 fdc->state = RESETCOMPLETE; 1999 return (0); 2000 case RESETCOMPLETE: 2001 /* 2002 * Discard all the results from the reset so that they 2003 * can't cause an unexpected interrupt later. 2004 */ 2005 for (i = 0; i < 4; i++) 2006 (void)fd_sense_int(fdc, &st0, &cyl); 2007 fdc->state = STARTRECAL; 2008 /* Fall through. */ 2009 case STARTRECAL: 2010 if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) { 2011 /* arrgl */ 2012 fdc->retry = 6; 2013 return (retrier(fdc)); 2014 } 2015 fdc->state = RECALWAIT; 2016 return (0); /* will return later */ 2017 case RECALWAIT: 2018 /* allow heads to settle */ 2019 timeout(fd_pseudointr, fdc, hz / 8); 2020 fdc->state = RECALCOMPLETE; 2021 return (0); /* will return later */ 2022 case RECALCOMPLETE: 2023 do { 2024 /* 2025 * See SEEKCOMPLETE for a comment on this: 2026 */ 2027 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 2028 return 0; 2029 if(fdc->fdct == FDC_NE765 2030 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 2031 return 0; /* hope for a real intr */ 2032 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 2033 if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0) 2034 { 2035 if(fdc->retry > 3) 2036 /* 2037 * a recalibrate from beyond cylinder 77 2038 * will "fail" due to the FDC limitations; 2039 * since people used to complain much about 2040 * the failure message, try not logging 2041 * this one if it seems to be the first 2042 * time in a line 2043 */ 2044 printf("fd%d: recal failed ST0 %b cyl %d\n", 2045 fdu, st0, NE7_ST0BITS, cyl); 2046 if(fdc->retry < 3) fdc->retry = 3; 2047 return (retrier(fdc)); 2048 } 2049 fd->track = 0; 2050 /* Seek (probably) necessary */ 2051 fdc->state = DOSEEK; 2052 return (1); /* will return immediatly */ 2053 case MOTORWAIT: 2054 if(fd->flags & FD_MOTOR_WAIT) 2055 { 2056 return (0); /* time's not up yet */ 2057 } 2058 if (fdc->flags & FDC_NEEDS_RESET) { 2059 fdc->state = RESETCTLR; 2060 fdc->flags &= ~FDC_NEEDS_RESET; 2061 } else { 2062 /* 2063 * If all motors were off, then the controller was 2064 * reset, so it has lost track of the current 2065 * cylinder. Recalibrate to handle this case. 2066 */ 2067 fdc->state = STARTRECAL; 2068 } 2069 return (1); /* will return immediatly */ 2070 default: 2071 device_print_prettyname(fdc->fdc_dev); 2072 printf("unexpected FD int->"); 2073 if (fd_read_status(fdc, fd->fdsu) == 0) 2074 printf("FDC status :%x %x %x %x %x %x %x ", 2075 fdc->status[0], 2076 fdc->status[1], 2077 fdc->status[2], 2078 fdc->status[3], 2079 fdc->status[4], 2080 fdc->status[5], 2081 fdc->status[6] ); 2082 else 2083 printf("No status available "); 2084 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2085 { 2086 printf("[controller is dead now]\n"); 2087 return (0); 2088 } 2089 printf("ST0 = %x, PCN = %x\n", st0, cyl); 2090 return (0); 2091 } 2092 /*XXX confusing: some branches return immediately, others end up here*/ 2093 return (1); /* Come back immediatly to new state */ 2094} 2095 2096static int 2097retrier(struct fdc_data *fdc) 2098{ 2099 register struct buf *bp; 2100 struct fd_data *fd; 2101 int fdu; 2102 2103 bp = fdc->bp; 2104 2105 /* XXX shouldn't this be cached somewhere? */ 2106 fdu = FDUNIT(minor(bp->b_dev)); 2107 fd = devclass_get_softc(fd_devclass, fdu); 2108 if (fd->options & FDOPT_NORETRY) 2109 goto fail; 2110 2111 switch (fdc->retry) { 2112 case 0: case 1: case 2: 2113 fdc->state = SEEKCOMPLETE; 2114 break; 2115 case 3: case 4: case 5: 2116 fdc->state = STARTRECAL; 2117 break; 2118 case 6: 2119 fdc->state = RESETCTLR; 2120 break; 2121 case 7: 2122 break; 2123 default: 2124 fail: 2125 { 2126 dev_t sav_b_dev = bp->b_dev; 2127 /* Trick diskerr */ 2128 bp->b_dev = makedev(major(bp->b_dev), 2129 (FDUNIT(minor(bp->b_dev))<<3)|RAW_PART); 2130 diskerr(bp, "fd", "hard error", LOG_PRINTF, 2131 fdc->fd->skip / DEV_BSIZE, 2132 (struct disklabel *)NULL); 2133 bp->b_dev = sav_b_dev; 2134 if (fdc->flags & FDC_STAT_VALID) 2135 { 2136 printf( 2137 " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n", 2138 fdc->status[0], NE7_ST0BITS, 2139 fdc->status[1], NE7_ST1BITS, 2140 fdc->status[2], NE7_ST2BITS, 2141 fdc->status[3], fdc->status[4], 2142 fdc->status[5]); 2143 } 2144 else 2145 printf(" (No status)\n"); 2146 } 2147 bp->b_flags |= B_ERROR; 2148 bp->b_error = EIO; 2149 bp->b_resid += bp->b_bcount - fdc->fd->skip; 2150 fdc->bp = NULL; 2151 2152 /* Tell devstat we have finished with the transaction */ 2153 devstat_end_transaction(&fdc->fd->device_stats, 2154 bp->b_bcount - bp->b_resid, 2155 DEVSTAT_TAG_NONE, 2156 (bp->b_flags & B_READ) ? DEVSTAT_READ : 2157 DEVSTAT_WRITE); 2158 fdc->fd->skip = 0; 2159 biodone(bp); 2160 fdc->state = FINDWORK; 2161 fdc->flags |= FDC_NEEDS_RESET; 2162 fdc->fd = (fd_p) 0; 2163 fdc->fdu = -1; 2164 return (1); 2165 } 2166 fdc->retry++; 2167 return (1); 2168} 2169 2170static int 2171fdformat(dev, finfo, p) 2172 dev_t dev; 2173 struct fd_formb *finfo; 2174 struct proc *p; 2175{ 2176 fdu_t fdu; 2177 fd_p fd; 2178 2179 struct buf *bp; 2180 int rv = 0, s; 2181 size_t fdblk; 2182 2183 fdu = FDUNIT(minor(dev)); 2184 fd = devclass_get_softc(fd_devclass, fdu); 2185 fdblk = 128 << fd->ft->secsize; 2186 2187 /* set up a buffer header for fdstrategy() */ 2188 bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT); 2189 if(bp == 0) 2190 return ENOBUFS; 2191 /* 2192 * keep the process from being swapped 2193 */ 2194 PHOLD(p); 2195 bzero((void *)bp, sizeof(struct buf)); 2196 bp->b_flags = B_BUSY | B_PHYS | B_FORMAT;
|