fdc.c (45364) | fdc.c (45783) |
---|---|
1/* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Don Ahn. 7 * 8 * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu) --- 33 unchanged lines hidden (view full) --- 42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * 49 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 | 1/* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Don Ahn. 7 * 8 * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu) --- 33 unchanged lines hidden (view full) --- 42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * 49 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 |
50 * $Id: fd.c,v 1.52 1999/02/10 00:03:58 ken Exp $ | 50 * $Id: fd.c,v 1.53 1999/04/06 03:12:22 peter Exp $ |
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> | 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> |
|
63#include <sys/conf.h> | 65#include <sys/conf.h> |
64#include <sys/fcntl.h> 65#include <machine/clock.h> 66#include <machine/ioctl_fd.h> | |
67#include <sys/disklabel.h> | 66#include <sys/disklabel.h> |
68#include <sys/buf.h> | |
69#include <sys/devicestat.h> | 67#include <sys/devicestat.h> |
68#include <sys/fcntl.h> |
|
70#include <sys/malloc.h> | 69#include <sys/malloc.h> |
70#include <sys/module.h> |
|
71#include <sys/proc.h> 72#include <sys/syslog.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> |
|
73#ifdef PC98 74#include <pc98/pc98/pc98.h> 75#include <pc98/pc98/pc98_machdep.h> 76#include <pc98/pc98/epsonio.h> | 88#ifdef PC98 89#include <pc98/pc98/pc98.h> 90#include <pc98/pc98/pc98_machdep.h> 91#include <pc98/pc98/epsonio.h> |
77#include <i386/isa/isa_device.h> | 92#include <i386/isa/isa_dma.h> |
78#include <pc98/pc98/fdreg.h> 79#else 80#include <i386/isa/isa.h> | 93#include <pc98/pc98/fdreg.h> 94#else 95#include <i386/isa/isa.h> |
81#include <i386/isa/isa_device.h> | 96#include <i386/isa/isa_dma.h> |
82#include <i386/isa/fdreg.h> | 97#include <i386/isa/fdreg.h> |
83#include <i386/isa/rtc.h> | |
84#endif 85#include <i386/isa/fdc.h> | 98#endif 99#include <i386/isa/fdc.h> |
86#include <machine/stdarg.h> 87#ifdef DEVFS 88#include <sys/devfsext.h> 89#endif /* DEVFS */ | 100#include <i386/isa/rtc.h> |
90 91/* misuse a flag to identify format operation */ 92#define B_FORMAT B_XXX 93 94/* configuration flags */ 95#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 96#ifdef FDC_YE 97#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's --- 85 unchanged lines hidden (view full) --- 183#define DRVS_PER_CTLR 4 /* 4 floppies */ 184#else 185#define DRVS_PER_CTLR 2 /* 2 floppies */ 186#endif 187 188/***********************************************************************\ 189* Per controller structure. * 190\***********************************************************************/ | 101 102/* misuse a flag to identify format operation */ 103#define B_FORMAT B_XXX 104 105/* configuration flags */ 106#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ 107#ifdef FDC_YE 108#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's --- 85 unchanged lines hidden (view full) --- 194#define DRVS_PER_CTLR 4 /* 4 floppies */ 195#else 196#define DRVS_PER_CTLR 2 /* 2 floppies */ 197#endif 198 199/***********************************************************************\ 200* Per controller structure. * 201\***********************************************************************/ |
191struct fdc_data fdc_data[NFDC]; | 202static devclass_t fdc_devclass; |
192 193/***********************************************************************\ 194* Per drive structure. * 195* N per controller (DRVS_PER_CTLR) * 196\***********************************************************************/ | 203 204/***********************************************************************\ 205* Per drive structure. * 206* N per controller (DRVS_PER_CTLR) * 207\***********************************************************************/ |
197static struct fd_data { | 208struct fd_data { |
198 struct fdc_data *fdc; /* pointer to controller structure */ 199 int fdsu; /* this units number on this controller */ 200 int type; /* Drive type (FD_1440...) */ 201 struct fd_type *ft; /* pointer to the type descriptor */ 202 int flags; 203#define FD_OPEN 0x01 /* it's open */ 204#define FD_ACTIVE 0x02 /* it's active */ 205#define FD_MOTOR 0x04 /* motor should be on */ --- 8 unchanged lines hidden (view full) --- 214 struct devstat device_stats; 215#ifdef DEVFS 216 void *bdevs[1 + NUMDENS + MAXPARTITIONS]; 217 void *cdevs[1 + NUMDENS + MAXPARTITIONS]; 218#endif 219#ifdef PC98 220 int pc98_trans; 221#endif | 209 struct fdc_data *fdc; /* pointer to controller structure */ 210 int fdsu; /* this units number on this controller */ 211 int type; /* Drive type (FD_1440...) */ 212 struct fd_type *ft; /* pointer to the type descriptor */ 213 int flags; 214#define FD_OPEN 0x01 /* it's open */ 215#define FD_ACTIVE 0x02 /* it's active */ 216#define FD_MOTOR 0x04 /* motor should be on */ --- 8 unchanged lines hidden (view full) --- 225 struct devstat device_stats; 226#ifdef DEVFS 227 void *bdevs[1 + NUMDENS + MAXPARTITIONS]; 228 void *cdevs[1 + NUMDENS + MAXPARTITIONS]; 229#endif 230#ifdef PC98 231 int pc98_trans; 232#endif |
222} fd_data[NFD]; | 233 device_t dev; 234 fdu_t fdu; 235}; 236static devclass_t fd_devclass; |
223 224#ifdef EPSON_NRDISK 225typedef unsigned int nrd_t; 226 227#define P_NRD_ADDRH 0xc24 228#define P_NRD_ADDRM 0xc22 229#define P_NRD_ADDRL 0xc20 230#define P_NRD_CHECK 0xc20 --- 54 unchanged lines hidden (view full) --- 285* fdsu is the floppy drive unit number on that controller. (sub-unit) * 286\***********************************************************************/ 287 288#ifdef FDC_YE 289#include "card.h" 290static int yeattach(struct isa_device *); 291#endif 292 | 237 238#ifdef EPSON_NRDISK 239typedef unsigned int nrd_t; 240 241#define P_NRD_ADDRH 0xc24 242#define P_NRD_ADDRM 0xc22 243#define P_NRD_ADDRL 0xc20 244#define P_NRD_CHECK 0xc20 --- 54 unchanged lines hidden (view full) --- 299* fdsu is the floppy drive unit number on that controller. (sub-unit) * 300\***********************************************************************/ 301 302#ifdef FDC_YE 303#include "card.h" 304static int yeattach(struct isa_device *); 305#endif 306 |
293/* autoconfig functions */ 294static int fdprobe(struct isa_device *); 295static int fdattach(struct isa_device *); 296 | |
297/* needed for ft driver, thus exported */ | 307/* needed for ft driver, thus exported */ |
298int in_fdc(fdcu_t); 299int out_fdc(fdcu_t, int); | 308int in_fdc(struct fdc_data *); 309int out_fdc(struct fdc_data *, int); |
300 301/* internal functions */ | 310 311/* internal functions */ |
302static void set_motor(fdcu_t, int, int); | 312static void fdc_add_device(device_t, const char *, int); 313static void fdc_intr(void *); 314static void set_motor(struct fdc_data *, int, int); |
303# define TURNON 1 304# define TURNOFF 0 305static timeout_t fd_turnoff; 306static timeout_t fd_motor_on; | 315# define TURNON 1 316# define TURNOFF 0 317static timeout_t fd_turnoff; 318static timeout_t fd_motor_on; |
307static void fd_turnon(fdu_t); | 319static void fd_turnon(struct fd_data *); |
308static void fdc_reset(fdc_p); | 320static void fdc_reset(fdc_p); |
309static int fd_in(fdcu_t, int *); 310static void fdstart(fdcu_t); | 321static int fd_in(struct fdc_data *, int *); 322static void fdstart(struct fdc_data *); |
311static timeout_t fd_iotimeout; 312static timeout_t fd_pseudointr; | 323static timeout_t fd_iotimeout; 324static timeout_t fd_pseudointr; |
313static ointhand2_t fdintr; 314static int fdstate(fdcu_t, fdc_p); 315static int retrier(fdcu_t); | 325static int fdstate(struct fdc_data *); 326static int retrier(struct fdc_data *); |
316static int fdformat(dev_t, struct fd_formb *, struct proc *); 317 318static int enable_fifo(fdc_p fdc); 319 320static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 321 322 323#define DEVIDLE 0 --- 122 unchanged lines hidden (view full) --- 446static int yeintr(struct pccard_devinfo *devi) 447{ 448 fdintr((fdcu_t)devi->isahd.id_unit); 449 return(1); 450} 451#endif /* NCARD > 0 */ 452#endif /* FDC_YE */ 453 | 327static int fdformat(dev_t, struct fd_formb *, struct proc *); 328 329static int enable_fifo(fdc_p fdc); 330 331static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ 332 333 334#define DEVIDLE 0 --- 122 unchanged lines hidden (view full) --- 457static int yeintr(struct pccard_devinfo *devi) 458{ 459 fdintr((fdcu_t)devi->isahd.id_unit); 460 return(1); 461} 462#endif /* NCARD > 0 */ 463#endif /* FDC_YE */ 464 |
454 455/* autoconfig structure */ 456 457struct isa_driver fdcdriver = { 458 fdprobe, fdattach, "fdc", 459}; 460 | |
461static d_open_t Fdopen; /* NOTE, not fdopen */ 462static d_read_t fdread; 463static d_write_t fdwrite; 464static d_close_t fdclose; 465static d_ioctl_t fdioctl; 466static d_strategy_t fdstrategy; 467 468/* even if SLICE defined, these are needed for the ft support. */ 469#define CDEV_MAJOR 9 470#define BDEV_MAJOR 2 471 | 465static d_open_t Fdopen; /* NOTE, not fdopen */ 466static d_read_t fdread; 467static d_write_t fdwrite; 468static d_close_t fdclose; 469static d_ioctl_t fdioctl; 470static d_strategy_t fdstrategy; 471 472/* even if SLICE defined, these are needed for the ft support. */ 473#define CDEV_MAJOR 9 474#define BDEV_MAJOR 2 475 |
472 473static struct cdevsw fd_cdevsw = { 474 Fdopen, fdclose, fdread, fdwrite, 475 fdioctl, nostop, nullreset, nodevtotty, 476 seltrue, nommap, fdstrategy, "fd", 477 NULL, -1, nodump, nopsize, 478 D_DISK, 0, -1 }; 479 480 481static struct isa_device *fdcdevs[NFDC]; 482 483 | |
484static int | 476static int |
485fdc_err(fdcu_t fdcu, const char *s) | 477fdc_err(struct fdc_data *fdc, const char *s) |
486{ | 478{ |
487 fdc_data[fdcu].fdc_errs++; 488 if(s) { 489 if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX) 490 printf("fdc%d: %s", fdcu, s); 491 else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX) 492 printf("fdc%d: too many errors, not logging any more\n", 493 fdcu); | 479 fdc->fdc_errs++; 480 if (s) { 481 if (fdc->fdc_errs < FDC_ERRMAX) { 482 device_print_prettyname(fdc->fdc_dev); 483 printf("%s", s); 484 } else if (fdc->fdc_errs == FDC_ERRMAX) { 485 device_print_prettyname(fdc->fdc_dev); 486 printf("too many errors, not logging any more\n"); 487 } |
494 } 495 496 return FD_FAILED; 497} 498 499/* 500 * fd_cmd: Send a command to the chip. Takes a varargs with this structure: 501 * Unit number, 502 * # of output bytes, output bytes as ints ..., 503 * # of input bytes, input bytes as ints ... 504 */ | 488 } 489 490 return FD_FAILED; 491} 492 493/* 494 * fd_cmd: Send a command to the chip. Takes a varargs with this structure: 495 * Unit number, 496 * # of output bytes, output bytes as ints ..., 497 * # of input bytes, input bytes as ints ... 498 */ |
505 | |
506static int | 499static int |
507fd_cmd(fdcu_t fdcu, int n_out, ...) | 500fd_cmd(struct fdc_data *fdc, int n_out, ...) |
508{ 509 u_char cmd; 510 int n_in; 511 int n; 512 va_list ap; 513 514 va_start(ap, n_out); 515 cmd = (u_char)(va_arg(ap, int)); 516 va_end(ap); 517 va_start(ap, n_out); 518 for (n = 0; n < n_out; n++) 519 { | 501{ 502 u_char cmd; 503 int n_in; 504 int n; 505 va_list ap; 506 507 va_start(ap, n_out); 508 cmd = (u_char)(va_arg(ap, int)); 509 va_end(ap); 510 va_start(ap, n_out); 511 for (n = 0; n < n_out; n++) 512 { |
520 if (out_fdc(fdcu, va_arg(ap, int)) < 0) | 513 if (out_fdc(fdc, va_arg(ap, int)) < 0) |
521 { 522 char msg[50]; 523 snprintf(msg, sizeof(msg), 524 "cmd %x failed at out byte %d of %d\n", 525 cmd, n + 1, n_out); | 514 { 515 char msg[50]; 516 snprintf(msg, sizeof(msg), 517 "cmd %x failed at out byte %d of %d\n", 518 cmd, n + 1, n_out); |
526 return fdc_err(fdcu, msg); | 519 return fdc_err(fdc, msg); |
527 } 528 } 529 n_in = va_arg(ap, int); 530 for (n = 0; n < n_in; n++) 531 { 532 int *ptr = va_arg(ap, int *); | 520 } 521 } 522 n_in = va_arg(ap, int); 523 for (n = 0; n < n_in; n++) 524 { 525 int *ptr = va_arg(ap, int *); |
533 if (fd_in(fdcu, ptr) < 0) | 526 if (fd_in(fdc, ptr) < 0) |
534 { 535 char msg[50]; 536 snprintf(msg, sizeof(msg), 537 "cmd %02x failed at in byte %d of %d\n", 538 cmd, n + 1, n_in); | 527 { 528 char msg[50]; 529 snprintf(msg, sizeof(msg), 530 "cmd %02x failed at in byte %d of %d\n", 531 cmd, n + 1, n_in); |
539 return fdc_err(fdcu, msg); | 532 return fdc_err(fdc, msg); |
540 } 541 } 542 543 return 0; 544} 545 546static int 547enable_fifo(fdc_p fdc) --- 4 unchanged lines hidden (view full) --- 552 553 /* 554 * XXX: 555 * Cannot use fd_cmd the normal way here, since 556 * this might be an invalid command. Thus we send the 557 * first byte, and check for an early turn of data directon. 558 */ 559 | 533 } 534 } 535 536 return 0; 537} 538 539static int 540enable_fifo(fdc_p fdc) --- 4 unchanged lines hidden (view full) --- 545 546 /* 547 * XXX: 548 * Cannot use fd_cmd the normal way here, since 549 * this might be an invalid command. Thus we send the 550 * first byte, and check for an early turn of data directon. 551 */ 552 |
560 if (out_fdc(fdc->fdcu, I8207X_CONFIGURE) < 0) 561 return fdc_err(fdc->fdcu, "Enable FIFO failed\n"); | 553 if (out_fdc(fdc, I8207X_CONFIGURE) < 0) 554 return fdc_err(fdc, "Enable FIFO failed\n"); |
562 563 /* If command is invalid, return */ 564 j = 100000; 565 while ((i = inb(fdc->baseport + FDSTS) & (NE7_DIO | NE7_RQM)) 566 != NE7_RQM && j-- > 0) 567 if (i == (NE7_DIO | NE7_RQM)) { 568 fdc_reset(fdc); 569 return FD_FAILED; 570 } 571 if (j<0 || | 555 556 /* If command is invalid, return */ 557 j = 100000; 558 while ((i = inb(fdc->baseport + FDSTS) & (NE7_DIO | NE7_RQM)) 559 != NE7_RQM && j-- > 0) 560 if (i == (NE7_DIO | NE7_RQM)) { 561 fdc_reset(fdc); 562 return FD_FAILED; 563 } 564 if (j<0 || |
572 fd_cmd(fdc->fdcu, 3, | 565 fd_cmd(fdc, 3, |
573 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 574 fdc_reset(fdc); | 566 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 567 fdc_reset(fdc); |
575 return fdc_err(fdc->fdcu, "Enable FIFO failed\n"); | 568 return fdc_err(fdc, "Enable FIFO failed\n"); |
576 } 577 fdc->flags |= FDC_HAS_FIFO; 578 return 0; 579 } | 569 } 570 fdc->flags |= FDC_HAS_FIFO; 571 return 0; 572 } |
580 if (fd_cmd(fdc->fdcu, 4, | 573 if (fd_cmd(fdc, 4, |
581 I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) | 574 I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) |
582 return fdc_err(fdc->fdcu, "Re-enable FIFO failed\n"); | 575 return fdc_err(fdc, "Re-enable FIFO failed\n"); |
583 return 0; 584} 585 586static int 587fd_sense_drive_status(fdc_p fdc, int *st3p) 588{ 589 int st3; 590 | 576 return 0; 577} 578 579static int 580fd_sense_drive_status(fdc_p fdc, int *st3p) 581{ 582 int st3; 583 |
591 if (fd_cmd(fdc->fdcu, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) | 584 if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) |
592 { | 585 { |
593 return fdc_err(fdc->fdcu, "Sense Drive Status failed\n"); | 586 return fdc_err(fdc, "Sense Drive Status failed\n"); |
594 } 595 if (st3p) 596 *st3p = st3; 597 598 return 0; 599} 600 601static int 602fd_sense_int(fdc_p fdc, int *st0p, int *cylp) 603{ | 587 } 588 if (st3p) 589 *st3p = st3; 590 591 return 0; 592} 593 594static int 595fd_sense_int(fdc_p fdc, int *st0p, int *cylp) 596{ |
604 int st0, cyl; | 597 int cyl, st0, ret; |
605 606#ifdef EPSON_NRDISK 607 if (fdc->fdu == nrdu) { 608 if (fdc->fd->track >= 0) nrdaddr = (fdc->fd->track + 1) * 8; 609 else nrdaddr = 0x0; 610 *st0p = nrd_head() ? NRD_ST0_HD : NRD_STATUS; 611 *cylp = nrd_trac(); 612 } 613 else { 614#endif /* EPSON_NRDISK */ | 598 599#ifdef EPSON_NRDISK 600 if (fdc->fdu == nrdu) { 601 if (fdc->fd->track >= 0) nrdaddr = (fdc->fd->track + 1) * 8; 602 else nrdaddr = 0x0; 603 *st0p = nrd_head() ? NRD_ST0_HD : NRD_STATUS; 604 *cylp = nrd_trac(); 605 } 606 else { 607#endif /* EPSON_NRDISK */ |
615 int ret = fd_cmd(fdc->fdcu, 1, NE7CMD_SENSEI, 1, &st0); 616 617 if (ret) 618 { 619 (void)fdc_err(fdc->fdcu, | 608 ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0); 609 if (ret) { 610 (void)fdc_err(fdc, |
620 "sense intr err reading stat reg 0\n"); 621 return ret; 622 } 623 624 if (st0p) 625 *st0p = st0; 626 | 611 "sense intr err reading stat reg 0\n"); 612 return ret; 613 } 614 615 if (st0p) 616 *st0p = st0; 617 |
627 if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) 628 { | 618 if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) { |
629 /* 630 * There doesn't seem to have been an interrupt. 631 */ 632 return FD_NOT_VALID; 633 } 634 | 619 /* 620 * There doesn't seem to have been an interrupt. 621 */ 622 return FD_NOT_VALID; 623 } 624 |
635 if (fd_in(fdc->fdcu, &cyl) < 0) 636 { 637 return fdc_err(fdc->fdcu, "can't get cyl num\n"); | 625 if (fd_in(fdc, &cyl) < 0) { 626 return fdc_err(fdc, "can't get cyl num\n"); |
638 } 639 640 if (cylp) 641 *cylp = cyl; 642 643#ifdef EPSON_NRDISK 644 } 645#endif /* EPSON_NRDISK */ 646 return 0; 647} 648 649 650static int 651fd_read_status(fdc_p fdc, int fdsu) 652{ 653 int i, ret; 654 | 627 } 628 629 if (cylp) 630 *cylp = cyl; 631 632#ifdef EPSON_NRDISK 633 } 634#endif /* EPSON_NRDISK */ 635 return 0; 636} 637 638 639static int 640fd_read_status(fdc_p fdc, int fdsu) 641{ 642 int i, ret; 643 |
655 for (i = 0; i < 7; i++) 656 { | 644 for (i = 0; i < 7; i++) { |
657 /* 658 * XXX types are poorly chosen. Only bytes can by read 659 * from the hardware, but fdc->status[] wants u_ints and 660 * fd_in() gives ints. 661 */ 662 int status; 663 664#ifdef EPSON_NRDISK --- 7 unchanged lines hidden (view full) --- 672 case 4: fdc->status[i] = nrd_head(); break; 673 case 5: fdc->status[i] = nrdsec; break; 674 case 6: fdc->status[i] = nrd_secsize(); break; 675 } 676 ret = 0; 677 } 678 else { 679#endif /* EPSON_NRDISK */ | 645 /* 646 * XXX types are poorly chosen. Only bytes can by read 647 * from the hardware, but fdc->status[] wants u_ints and 648 * fd_in() gives ints. 649 */ 650 int status; 651 652#ifdef EPSON_NRDISK --- 7 unchanged lines hidden (view full) --- 660 case 4: fdc->status[i] = nrd_head(); break; 661 case 5: fdc->status[i] = nrdsec; break; 662 case 6: fdc->status[i] = nrd_secsize(); break; 663 } 664 ret = 0; 665 } 666 else { 667#endif /* EPSON_NRDISK */ |
680 ret = fd_in(fdc->fdcu, &status); | 668 ret = fd_in(fdc, &status); |
681 fdc->status[i] = status; 682 if (ret != 0) 683 break; 684#ifdef EPSON_NRDISK 685 } 686#endif /* EPSON_NRDISK */ 687 } 688 --- 7 unchanged lines hidden (view full) --- 696 697/****************************************************************************/ 698/* autoconfiguration stuff */ 699/****************************************************************************/ 700#ifdef PC98 701static int pc98_trans = 0; /* 0 : HD , 1 : DD , 2 : 1.44 */ 702static int pc98_trans_prev = 0; 703 | 669 fdc->status[i] = status; 670 if (ret != 0) 671 break; 672#ifdef EPSON_NRDISK 673 } 674#endif /* EPSON_NRDISK */ 675 } 676 --- 7 unchanged lines hidden (view full) --- 684 685/****************************************************************************/ 686/* autoconfiguration stuff */ 687/****************************************************************************/ 688#ifdef PC98 689static int pc98_trans = 0; /* 0 : HD , 1 : DD , 2 : 1.44 */ 690static int pc98_trans_prev = 0; 691 |
704static void set_density(fdcu_t, fdu_t); 705static int pc98_fd_check_ready(fdu_t); 706 707static void set_density(fdcu, fdu) 708 fdcu_t fdcu; 709 fdu_t fdu; | 692static void set_density(fdc_p fdc) |
710{ 711 /* always motor on */ | 693{ 694 /* always motor on */ |
712 outb(IO_FDPORT, 713 (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC); | 695 outb(IO_FDPORT, (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC); |
714 DELAY(100); | 696 DELAY(100); |
715 outb(fdc_data[fdcu].baseport + FDOUT, FDO_RST | FDO_DMAE); | 697 outb(fdc->baseport + FDOUT, FDO_RST | FDO_DMAE); |
716 /* in the case of note W, always inhibit 100ms timer */ 717} 718 | 698 /* in the case of note W, always inhibit 100ms timer */ 699} 700 |
719static int pc98_fd_check_ready(fdu) 720 fdu_t fdu; | 701static int pc98_fd_check_ready(fdu_t fdu) |
721{ | 702{ |
722 fd_p fd = fd_data + fdu; 723 fdcu_t fdcu = fd->fdc->fdcu; | 703 fd_p fd = devclass_get_softc(fd_devclass, fdu); 704 struct fdc_data *fdc = fd->fdc; |
724 int retry = 0; 725 726#ifdef EPSON_NRDISK 727 if (fdu == nrdu) { 728 if (nrd_check_ready()) return 0; 729 else return -1; 730 } 731#endif 732 while (retry++ < 30000) { | 705 int retry = 0; 706 707#ifdef EPSON_NRDISK 708 if (fdu == nrdu) { 709 if (nrd_check_ready()) return 0; 710 else return -1; 711 } 712#endif 713 while (retry++ < 30000) { |
733 set_motor(fdcu, fd->fdsu, TURNON); 734 out_fdc(fdcu, NE7CMD_SENSED); /* Sense Drive Status */ | 714 set_motor(fdc, fd->fdsu, TURNON); 715 out_fdc(fdc, NE7CMD_SENSED); /* Sense Drive Status */ |
735 DELAY(100); | 716 DELAY(100); |
736 out_fdc(fdcu, fdu); /* Drive number */ | 717 out_fdc(fdc, fdu); /* Drive number */ |
737 DELAY(100); | 718 DELAY(100); |
738 if ((in_fdc(fdcu) & NE7_ST3_RD)){ 739 outb(fdc_data[fdcu].baseport + FDOUT, | 719 if ((in_fdc(fdc) & NE7_ST3_RD)){ 720 outb(fdc->baseport + FDOUT, |
740 FDO_DMAE | FDO_MTON); 741 DELAY(10); 742 return 0; 743 } 744 } 745 return -1; 746} 747#endif 748 | 721 FDO_DMAE | FDO_MTON); 722 DELAY(10); 723 return 0; 724 } 725 } 726 return -1; 727} 728#endif 729 |
749 750/* 751 * probe for existance of controller 752 */ | |
753static int | 730static int |
754fdprobe(struct isa_device *dev) | 731fdc_probe(device_t dev) |
755{ | 732{ |
756 fdcu_t fdcu = dev->id_unit; 757 if(fdc_data[fdcu].flags & FDC_ATTACHED) 758 { 759 printf("fdc%d: unit used multiple times\n", fdcu); 760 return 0; | 733 int error, i, ic_type; 734 struct fdc_data *fdc; 735 char myname[8]; /* better be long enough */ 736 737 fdc = device_get_softc(dev); 738 bzero(fdc, sizeof *fdc); 739 fdc->fdc_dev = dev; 740 fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0; 741 fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0; 742 743 fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, 744 &fdc->rid_ioport, 0ul, ~0ul, 745 IO_FDCSIZE, RF_ACTIVE); 746 if (fdc->res_ioport == 0) { 747 device_print_prettyname(dev); 748 printf("cannot reserve I/O port range\n"); 749 error = ENXIO; 750 goto out; |
761 } | 751 } |
752 fdc->baseport = fdc->res_ioport->r_start; |
|
762 | 753 |
763 fdcdevs[fdcu] = dev; 764 fdc_data[fdcu].baseport = dev->id_iobase; | 754 fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, 755 &fdc->rid_irq, 0ul, ~0ul, 1, 756 RF_ACTIVE); 757 if (fdc->res_irq == 0) { 758 device_print_prettyname(dev); 759 printf("cannot reserve interrupt line\n"); 760 error = ENXIO; 761 goto out; 762 } 763 fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, 764 &fdc->rid_drq, 0ul, ~0ul, 1, 765 RF_ACTIVE); 766 if (fdc->res_drq == 0) { 767 device_print_prettyname(dev); 768 printf("cannot reserve DMA request line\n"); 769 error = ENXIO; 770 goto out; 771 } 772 fdc->dmachan = fdc->res_drq->r_start; 773 error = BUS_SETUP_INTR(device_get_parent(dev), dev, 774 fdc->res_irq, fdc_intr, fdc, &fdc->fdc_intr); |
765 766#ifndef PC98 767 /* First - lets reset the floppy controller */ | 775 776#ifndef PC98 777 /* First - lets reset the floppy controller */ |
768 outb(dev->id_iobase+FDOUT, 0); | 778 outb(fdc->baseport + FDOUT, 0); |
769 DELAY(100); | 779 DELAY(100); |
770 outb(dev->id_iobase+FDOUT, FDO_FRST); | 780 outb(fdc->baseport + FDOUT, FDO_FRST); |
771#endif 772 773 /* see if it can handle a command */ 774#ifdef PC98 | 781#endif 782 783 /* see if it can handle a command */ 784#ifdef PC98 |
775 if (fd_cmd(fdcu, 776 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0), 777 0)) | 785 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240), 786 NE7_SPEC_2(2, 0), 0)) { 787 error = ENXIO; 788 goto out; 789 } |
778#else | 790#else |
779 if (fd_cmd(fdcu, 780 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 781 0)) | 791 if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 792 NE7_SPEC_2(2, 0), 0)) { 793 error = ENXIO; 794 goto out; 795 } |
782#endif | 796#endif |
783 { 784 return(0); | 797 798#ifndef PC98 799 if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) { 800 ic_type = (u_char)ic_type; 801 switch (ic_type) { 802 case 0x80: 803 device_set_desc(dev, "NEC 765 or clone"); 804 fdc->fdct = FDC_NE765; 805 break; 806 case 0x81: 807 device_set_desc(dev, "Intel 82077 or clone"); 808 fdc->fdct = FDC_I82077; 809 break; 810 case 0x90: 811 device_set_desc(dev, "NEC 72065B or clone"); 812 fdc->fdct = FDC_NE72065; 813 break; 814 default: 815 device_set_desc(dev, "generic floppy controller"); 816 fdc->fdct = FDC_UNKNOWN; 817 break; 818 } |
785 } | 819 } |
820#endif 821 822 snprintf(myname, sizeof(myname), "%s%d", device_get_name(dev), 823 device_get_unit(dev)); 824 for (i = resource_query_string(-1, "at", myname); i != -1; 825 i = resource_query_string(i, "at", myname)) 826 fdc_add_device(dev, resource_query_name(i), 827 resource_query_unit(i)); |
|
786#ifdef FDC_YE 787 /* 788 * don't succeed on probe; wait 789 * for PCCARD subsystem to do it 790 */ 791 if (dev->id_flags & FDC_IS_PCMCIA) 792 return(0); 793#endif | 828#ifdef FDC_YE 829 /* 830 * don't succeed on probe; wait 831 * for PCCARD subsystem to do it 832 */ 833 if (dev->id_flags & FDC_IS_PCMCIA) 834 return(0); 835#endif |
794 return (IO_FDCSIZE); | 836 return (0); 837 838out: 839 if (fdc->fdc_intr) 840 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 841 fdc->fdc_intr); 842 if (fdc->res_irq != 0) { 843 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 844 fdc->res_irq); 845 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 846 fdc->res_irq); 847 } 848 if (fdc->res_ioport != 0) { 849 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 850 fdc->res_ioport); 851 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 852 fdc->res_ioport); 853 } 854 if (fdc->res_drq != 0) { 855 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 856 fdc->res_drq); 857 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 858 fdc->res_drq); 859 } 860 return (error); |
795} 796 797/* | 861} 862 863/* |
798 * wire controller into system, look for floppy units | 864 * Aped dfr@freebsd.org's isa_add_device(). |
799 */ | 865 */ |
866static void 867fdc_add_device(device_t dev, const char *name, int unit) 868{ 869 int disabled, *ivar; 870 device_t child; 871 872 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT); 873 if (ivar == 0) 874 return; 875 if (resource_int_value(name, unit, "drive", ivar) == 0) 876 *ivar = 0; 877 child = device_add_child(dev, name, unit, ivar); 878 if (child == 0) 879 return; 880 if (resource_int_value(name, unit, "disabled", &disabled) == 0) 881 device_disable(child); 882} 883 |
|
800static int | 884static int |
801fdattach(struct isa_device *dev) | 885fdc_attach(device_t dev) |
802{ | 886{ |
803 unsigned fdt; 804 fdu_t fdu; 805 fdcu_t fdcu = dev->id_unit; 806 fdc_p fdc = fdc_data + fdcu; 807 fd_p fd; 808#ifdef PC98 809 int fdsu; 810#else 811 int fdsu, st0, st3, i; 812#endif 813 struct isa_device *fdup; 814#ifndef PC98 815 int ic_type = 0; 816#endif 817#ifdef DEVFS 818 int mynor; 819 int typemynor; 820 int typesize; 821#endif | 887 struct fdc_data *fdc = device_get_softc(dev); 888 fdcu_t fdcu = device_get_unit(dev); |
822 | 889 |
823 dev->id_ointr = fdintr; | |
824 fdc->fdcu = fdcu; 825 fdc->flags |= FDC_ATTACHED; | 890 fdc->fdcu = fdcu; 891 fdc->flags |= FDC_ATTACHED; |
826#ifdef PC98 827 fdc->dmachan = 2; 828 if (fdc->dmachan != dev->id_drq) { 829 dev->id_drq = fdc->dmachan; 830 printf(" [dma is changed to #%d]", fdc->dmachan); 831 } | 892 |
832 /* Acquire the DMA channel forever, The driver will do the rest */ | 893 /* Acquire the DMA channel forever, The driver will do the rest */ |
894 /* XXX should integrate with rman */ |
|
833 isa_dma_acquire(fdc->dmachan); 834 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); 835 fdc->state = DEVIDLE; | 895 isa_dma_acquire(fdc->dmachan); 896 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); 897 fdc->state = DEVIDLE; |
898 899#ifdef PC98 900 /* reset controller, turn motor off, clear fdout mirror reg */ |
|
836 fdc_reset(fdc); 837#else | 901 fdc_reset(fdc); 902#else |
838 fdc->dmachan = dev->id_drq; 839 /* Acquire the DMA channel forever, The driver will do the rest */ 840 isa_dma_acquire(fdc->dmachan); 841 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); 842 fdc->state = DEVIDLE; | |
843 /* reset controller, turn motor off, clear fdout mirror reg */ 844 outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); 845#endif 846 bufq_init(&fdc->head); 847 | 903 /* reset controller, turn motor off, clear fdout mirror reg */ 904 outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); 905#endif 906 bufq_init(&fdc->head); 907 |
848 /* check for each floppy drive */ 849 for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) { 850 if (fdup->id_iobase != dev->id_iobase) 851 continue; 852 fdu = fdup->id_unit; 853 fd = &fd_data[fdu]; 854 if (fdu >= (NFD)) 855 continue; 856 fdsu = fdup->id_physid; 857 /* look up what bios thinks we have */ 858 switch (fdu) { | 908#ifdef FIFO_BEFORE_MOTORON 909 /* Hmm, this doesn't work here - is set_motor() magic? -Peter */ 910 if (fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 911 && enable_fifo(fdc) == 0) { 912 device_print_prettyname(dev); 913 printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); 914 } 915#endif 916 /* 917 * Probe and attach any children as were configured above. 918 */ 919 return (bus_generic_attach(dev)); 920} 921 922static void 923fdc_print_child(device_t me, device_t child) 924{ 925 printf(" at %s%d drive %d", device_get_name(me), device_get_unit(me), 926 *(int *)device_get_ivars(child)); 927} 928 929static int 930fd_probe(device_t dev) 931{ 932 int i; 933 u_int fdt, st0, st3; 934 struct fd_data *fd; 935 struct fdc_data *fdc; 936 fdsu_t fdsu; 937#ifndef FIFO_BEFORE_MOTORON 938 static int fd_fifo = 0; 939#endif 940 941 fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */ 942 fd = device_get_softc(dev); 943 fdc = device_get_softc(device_get_parent(dev)); 944 945 bzero(fd, sizeof *fd); 946 fd->dev = dev; 947 fd->fdc = fdc; 948 fd->fdsu = fdsu; 949 fd->fdu = device_get_unit(dev); 950 |
859#ifdef PC98 | 951#ifdef PC98 |
860 case 0: case 1: case 2: case 3: 861 if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fdu) & 0x01) 862 fdt = FDT_144M; | 952 /* look up what bios thinks we have */ 953 switch (fd->fdu) { 954 case 0: case 1: case 2: case 3: 955 if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fd->fdu) & 0x01) 956 fdt = FDT_144M; |
863#ifdef EPSON_NRDISK | 957#ifdef EPSON_NRDISK |
864 else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fdu) & 0x01) { 865 fdt = FDT_12M; 866 switch (epson_machine_id) { 867 case 0x20: case 0x27: 868 if ((PC98_SYSTEM_PARAMETER(0x488) >> fdu) & 0x01) { 869 if (nrd_check_ready()) { 870 nrd_LED_on(); 871 nrdu = fdu; 872 } 873 else fdt = FDT_NONE; 874 } | 958 else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fd->fdu) & 0x01) { 959 fdt = FDT_12M; 960 switch (epson_machine_id) { 961 case 0x20: case 0x27: 962 if ((PC98_SYSTEM_PARAMETER(0x488) >> fd->fdu) & 0x01) { 963 if (nrd_check_ready()) { 964 nrd_LED_on(); 965 nrdu = fd->fdu; 966 } else { 967 fdt = FDT_NONE; |
875 } | 968 } |
969 } |
|
876 } | 970 } |
971 } |
|
877#else /* !EPSON_NRDISK */ | 972#else /* !EPSON_NRDISK */ |
878 else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fdu) & 0x01) { 879 fdt = FDT_12M; 880 switch (epson_machine_id) { 881 case 0x20: case 0x27: 882 if ((PC98_SYSTEM_PARAMETER(0x488) >> fdu) & 0x01) 883 fdt = FDT_NONE; 884 } | 973 else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fd->fdu) & 0x01) { 974 fdt = FDT_12M; 975 switch (epson_machine_id) { 976 case 0x20: case 0x27: 977 if ((PC98_SYSTEM_PARAMETER(0x488) >> fd->fdu) & 0x01) 978 fdt = FDT_NONE; |
885 } | 979 } |
980 } |
|
886#endif /* EPSON_NRDISK */ | 981#endif /* EPSON_NRDISK */ |
887 else fdt = FDT_NONE; 888 break; 889 default: | 982 else |
890 fdt = FDT_NONE; | 983 fdt = FDT_NONE; |
891 break; | 984 break; 985 default: 986 fdt = FDT_NONE; 987 break; 988 } |
892#else | 989#else |
893 case 0: if (dev->id_flags & FDC_PRETEND_D0) 894 fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; 895 else 896 fdt = (rtcin(RTC_FDISKETTE) & 0xf0); 897 break; 898 case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); 899 break; 900 default: fdt = RTCFDT_NONE; 901 break; | 990 /* look up what bios thinks we have */ 991 switch (fd->fdu) { 992 case 0: 993 if (isa_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0) 994 fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; 995 else 996 fdt = (rtcin(RTC_FDISKETTE) & 0xf0); 997 break; 998 case 1: 999 fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); 1000 break; 1001 default: 1002 fdt = RTCFDT_NONE; 1003 break; 1004 } |
902#endif | 1005#endif |
903 } 904 /* is there a unit? */ | 1006 1007 /* is there a unit? */ |
905#ifdef PC98 | 1008#ifdef PC98 |
906 if ((fdt == FDT_NONE) | 1009 if (fdt == FDT_NONE) 1010 return (ENXIO); |
907#else | 1011#else |
908 if ((fdt == RTCFDT_NONE) | 1012 if (fdt == RTCFDT_NONE) 1013 return (ENXIO); |
909#endif | 1014#endif |
910 ) { 911#ifdef PC98 912 fd->fdc = fdc; 913#endif 914 fd->type = NO_TYPE; 915 continue; 916 } | |
917 918#ifndef PC98 | 1015 1016#ifndef PC98 |
919 /* select it */ 920 set_motor(fdcu, fdsu, TURNON); 921 DELAY(1000000); /* 1 sec */ | 1017 /* select it */ 1018 set_motor(fdc, fdsu, TURNON); 1019 DELAY(1000000); /* 1 sec */ |
922 | 1020 |
923 if (ic_type == 0 && 924 fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0) 925 { 926#ifdef FDC_PRINT_BOGUS_CHIPTYPE 927 printf("fdc%d: ", fdcu); | 1021#ifndef FIFO_BEFORE_MOTORON 1022 if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN 1023 && enable_fifo(fdc) == 0) { 1024 device_print_prettyname(device_get_parent(dev)); 1025 printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); 1026 } 1027 fd_fifo = 1; |
928#endif | 1028#endif |
929 ic_type = (u_char)ic_type; 930 switch( ic_type ) { 931 case 0x80: 932#ifdef FDC_PRINT_BOGUS_CHIPTYPE 933 printf("NEC 765\n"); 934#endif 935 fdc->fdct = FDC_NE765; 936 break; 937 case 0x81: 938#ifdef FDC_PRINT_BOGUS_CHIPTYPE 939 printf("Intel 82077\n"); 940#endif 941 fdc->fdct = FDC_I82077; 942 break; 943 case 0x90: 944#ifdef FDC_PRINT_BOGUS_CHIPTYPE 945 printf("NEC 72065B\n"); 946#endif 947 fdc->fdct = FDC_NE72065; 948 break; 949 default: 950#ifdef FDC_PRINT_BOGUS_CHIPTYPE 951 printf("unknown IC type %02x\n", ic_type); 952#endif 953 fdc->fdct = FDC_UNKNOWN; 954 break; 955 } 956 if (fdc->fdct != FDC_NE765 && 957 fdc->fdct != FDC_UNKNOWN && 958 enable_fifo(fdc) == 0) { 959 printf("fdc%d: FIFO enabled", fdcu); 960 printf(", %d bytes threshold\n", 961 fifo_threshold); 962 } 963 } 964 if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) && 965 (st3 & NE7_ST3_T0)) { 966 /* if at track 0, first seek inwards */ 967 /* seek some steps: */ 968 (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0); 969 DELAY(300000); /* ...wait a moment... */ 970 (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 971 } | |
972 | 1029 |
973 /* If we're at track 0 first seek inwards. */ 974 if ((fd_sense_drive_status(fdc, &st3) == 0) && 975 (st3 & NE7_ST3_T0)) { 976 /* Seek some steps... */ 977 if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 978 /* ...wait a moment... */ 979 DELAY(300000); 980 /* make ctrlr happy: */ 981 (void)fd_sense_int(fdc, 0, 0); 982 } | 1030 if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) 1031 && (st3 & NE7_ST3_T0)) { 1032 /* if at track 0, first seek inwards */ 1033 /* seek some steps: */ 1034 fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0); 1035 DELAY(300000); /* ...wait a moment... */ 1036 fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ 1037 } 1038 1039 /* If we're at track 0 first seek inwards. */ 1040 if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { 1041 /* Seek some steps... */ 1042 if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { 1043 /* ...wait a moment... */ 1044 DELAY(300000); 1045 /* make ctrlr happy: */ 1046 fd_sense_int(fdc, 0, 0); |
983 } | 1047 } |
1048 } |
|
984 | 1049 |
985 for(i = 0; i < 2; i++) { 986 /* 987 * we must recalibrate twice, just in case the 988 * heads have been beyond cylinder 76, since most 989 * FDCs still barf when attempting to recalibrate 990 * more than 77 steps 991 */ 992 /* go back to 0: */ 993 if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 994 /* a second being enough for full stroke seek*/ 995 DELAY(i == 0? 1000000: 300000); | 1050 for (i = 0; i < 2; i++) { 1051 /* 1052 * we must recalibrate twice, just in case the 1053 * heads have been beyond cylinder 76, since most 1054 * FDCs still barf when attempting to recalibrate 1055 * more than 77 steps 1056 */ 1057 /* go back to 0: */ 1058 if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) { 1059 /* a second being enough for full stroke seek*/ 1060 DELAY(i == 0 ? 1000000 : 300000); |
996 | 1061 |
997 /* anything responding? */ 998 if (fd_sense_int(fdc, &st0, 0) == 0 && 999 (st0 & NE7_ST0_EC) == 0) 1000 break; /* already probed succesfully */ 1001 } | 1062 /* anything responding? */ 1063 if (fd_sense_int(fdc, &st0, 0) == 0 && 1064 (st0 & NE7_ST0_EC) == 0) 1065 break; /* already probed succesfully */ |
1002 } | 1066 } |
1067 } |
|
1003 | 1068 |
1004 set_motor(fdcu, fdsu, TURNOFF); | 1069 set_motor(fdc, fdsu, TURNOFF); |
1005 | 1070 |
1006 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 1007 continue; | 1071 if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ 1072 return (ENXIO); 1073#endif /* PC98 */ 1074 1075 fd->track = FD_NO_TRACK; 1076 fd->fdc = fdc; 1077 fd->fdsu = fdsu; 1078 fd->options = 0; 1079 callout_handle_init(&fd->toffhandle); 1080 callout_handle_init(&fd->tohandle); 1081 1082#ifdef PC98 1083 switch (fdt) { 1084 case FDT_12M: 1085#ifdef EPSON_NRDISK 1086 if (fdu == nrdu) { 1087 device_set_desc(dev, "EPSON RAM DRIVE"); 1088 nrd_LED_off(); 1089 } else 1090 device_set_desc(dev, "1M/640M FDD"); 1091#else 1092 device_set_desc(dev, "1M/640M FDD"); |
1008#endif | 1093#endif |
1094 fd->type = FD_1200; 1095 fd->pc98_trans = 0; 1096 break; 1097 case FDT_144M: 1098 device_set_desc(dev, "1.44M FDD"); 1099 fd->type = FD_1200; 1100 fd->pc98_trans = 0; 1101 outb(0x4be, (fd->fdu << 5) | 0x10); 1102 break; 1103 default: 1104 return (ENXIO); 1105 } 1106#else 1107 switch (fdt) { 1108 case RTCFDT_12M: 1109 device_set_desc(dev, "1200-KB 5.25\" drive"); 1110 fd->type = FD_1200; 1111 break; 1112 case RTCFDT_144M | RTCFDT_144M_PRETENDED: 1113 device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive"); 1114 fdt = RTCFDT_144M; 1115 fd->type = FD_1440; 1116 case RTCFDT_144M: 1117 device_set_desc(dev, "1440-KB 3.5\" drive"); 1118 fd->type = FD_1440; 1119 break; 1120 case RTCFDT_288M: 1121 case RTCFDT_288M_1: 1122 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)"); 1123 fd->type = FD_1440; 1124 break; 1125 case RTCFDT_360K: 1126 device_set_desc(dev, "360-KB 5.25\" drive"); 1127 fd->type = FD_360; 1128 break; 1129 case RTCFDT_720K: 1130 printf("720-KB 3.5\" drive"); 1131 fd->type = FD_720; 1132 break; 1133 default: 1134 return (ENXIO); 1135 } 1136#endif 1137 return (0); 1138} |
|
1009 | 1139 |
1010 fd->track = FD_NO_TRACK; 1011 fd->fdc = fdc; 1012 fd->fdsu = fdsu; 1013 fd->options = 0; 1014 callout_handle_init(&fd->toffhandle); 1015 callout_handle_init(&fd->tohandle); 1016 printf("fd%d: ", fdu); | 1140static int 1141fd_attach(device_t dev) 1142{ 1143 struct fd_data *fd; |
1017 | 1144 |
1018 switch (fdt) { | 1145 fd = device_get_softc(dev); 1146 1147#ifdef DEVFS /* XXX bitrot */ 1148 mynor = fdu << 6; 1149 fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, 1150 UID_ROOT, GID_OPERATOR, 0640, 1151 "fd%d", fdu); 1152 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, 1153 UID_ROOT, GID_OPERATOR, 0640, 1154 "rfd%d", fdu); 1155 for (i = 1; i < 1 + NUMDENS; i++) { 1156 /* 1157 * XXX this and the lookup in Fdopen() should be 1158 * data driven. 1159 */ |
1019#ifdef PC98 | 1160#ifdef PC98 |
1161 switch (fd->type) { |
|
1020 case FDT_12M: | 1162 case FDT_12M: |
1021#ifdef EPSON_NRDISK 1022 if (fdu == nrdu) { 1023 printf("EPSON RAM DRIVE\n"); 1024 nrd_LED_off(); 1025 } 1026 else printf("1M/640M FDD\n"); 1027#else /* !EPSON_NRDISK */ 1028 printf("1M/640K FDD\n"); 1029#endif /* EPSON_NRDISK */ 1030 fd->type = FD_1200; 1031 fd->pc98_trans = 0; | 1163 if (i != FD_1200 && i != FD_1232 1164 && i != FD_720 && i != FD_640) 1165 continue; |
1032 break; 1033 case FDT_144M: | 1166 break; 1167 case FDT_144M: |
1034 printf("1.44M FDD\n"); 1035 fd->type = FD_1200; 1036 fd->pc98_trans = 0; 1037 outb(0x4be, (fdu << 5) | 0x10); | 1168 if (i != FD_1200 && i != FD_1232 1169 && i != FD_720 && i != FD_640 1170 && i != FD_1440) 1171 continue; |
1038 break; | 1172 break; |
1173 } |
|
1039#else | 1174#else |
1040 case RTCFDT_12M: 1041 printf("1.2MB 5.25in\n"); 1042 fd->type = FD_1200; | 1175 switch (fd->type) { 1176 case FD_360: 1177 if (i != FD_360) 1178 continue; |
1043 break; | 1179 break; |
1044 case RTCFDT_144M | RTCFDT_144M_PRETENDED: 1045 printf("config-pretended "); 1046 fdt = RTCFDT_144M; 1047 /* fallthrough */ 1048 case RTCFDT_144M: 1049 printf("1.44MB 3.5in\n"); 1050 fd->type = FD_1440; | 1180 case FD_720: 1181 if (i != FD_720 && i != FD_800 && i != FD_820) 1182 continue; |
1051 break; | 1183 break; |
1052 case RTCFDT_288M: 1053 case RTCFDT_288M_1: 1054 printf("2.88MB 3.5in - 1.44MB mode\n"); 1055 fd->type = FD_1440; | 1184 case FD_1200: 1185 if (i != FD_360 && i != FD_720 && i != FD_800 1186 && i != FD_820 && i != FD_1200 1187 && i != FD_1440 && i != FD_1480) 1188 continue; |
1056 break; | 1189 break; |
1057 case RTCFDT_360K: 1058 printf("360KB 5.25in\n"); 1059 fd->type = FD_360; | 1190 case FD_1440: 1191 if (i != FD_720 && i != FD_800 && i != FD_820 1192 && i != FD_1200 && i != FD_1440 1193 && i != FD_1480 && i != FD_1720) 1194 continue; |
1060 break; | 1195 break; |
1061 case RTCFDT_720K: 1062 printf("720KB 3.5in\n"); 1063 fd->type = FD_720; 1064 break; 1065#endif 1066 default: 1067 printf("unknown\n"); 1068 fd->type = NO_TYPE; 1069 continue; | |
1070 } | 1196 } |
1071#ifdef DEVFS 1072 mynor = fdu << 6; 1073 fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, 1074 UID_ROOT, GID_OPERATOR, 0640, 1075 "fd%d", fdu); 1076 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, 1077 UID_ROOT, GID_OPERATOR, 0640, 1078 "rfd%d", fdu); 1079 for (i = 1; i < 1 + NUMDENS; i++) { 1080 /* 1081 * XXX this and the lookup in Fdopen() should be 1082 * data driven. 1083 */ 1084#ifdef PC98 1085 switch (fdt) { 1086 case FDT_12M: 1087 if (i != FD_1200 && i != FD_1232 1088 && i != FD_720 && i != FD_640) 1089 continue; 1090 break; 1091 case FDT_144M: 1092 if (i != FD_1200 && i != FD_1232 1093 && i != FD_720 && i != FD_640 1094 && i != FD_1440) 1095 continue; 1096 break; 1097 } 1098#else 1099 switch (fd->type) { 1100 case FD_360: 1101 if (i != FD_360) 1102 continue; 1103 break; 1104 case FD_720: 1105 if (i != FD_720 && i != FD_800 && i != FD_820) 1106 continue; 1107 break; 1108 case FD_1200: 1109 if (i != FD_360 && i != FD_720 && i != FD_800 1110 && i != FD_820 && i != FD_1200 1111 && i != FD_1440 && i != FD_1480) 1112 continue; 1113 break; 1114 case FD_1440: 1115 if (i != FD_720 && i != FD_800 && i != FD_820 1116 && i != FD_1200 && i != FD_1440 1117 && i != FD_1480 && i != FD_1720) 1118 continue; 1119 break; 1120 } | |
1121#endif 1122#ifdef PC98 | 1197#endif 1198#ifdef PC98 |
1123 if (i == FD_1232) 1124 typesize = fd_types[i - 1].size; 1125 else 1126 typesize = fd_types[i - 1].size / 2; 1127#else | 1199 if (i == FD_1232) 1200 typesize = fd_types[i - 1].size; 1201 else |
1128 typesize = fd_types[i - 1].size / 2; | 1202 typesize = fd_types[i - 1].size / 2; |
1129 /* 1130 * XXX all these conversions give bloated code and 1131 * confusing names. 1132 */ 1133 if (typesize == 1476) 1134 typesize = 1480; 1135 if (typesize == 1722) 1136 typesize = 1720; 1137#endif 1138 typemynor = mynor | i; 1139 fd->bdevs[i] = 1140 devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, 1141 UID_ROOT, GID_OPERATOR, 0640, 1142 "fd%d.%d", fdu, typesize); 1143 fd->cdevs[i] = 1144 devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, 1145 UID_ROOT, GID_OPERATOR, 0640, 1146 "rfd%d.%d", fdu, typesize); 1147 } 1148 1149 for (i = 0; i < MAXPARTITIONS; i++) { 1150 fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], 1151 "fd%d%c", fdu, 'a' + i); 1152 fd->cdevs[1 + NUMDENS + i] = 1153 devfs_makelink(fd->cdevs[0], 1154 "rfd%d%c", fdu, 'a' + i); 1155 } 1156#endif /* DEVFS */ | 1203#else 1204 typesize = fd_types[i - 1].size / 2; |
1157 /* | 1205 /* |
1158 * Export the drive to the devstat interface. | 1206 * XXX all these conversions give bloated code and 1207 * confusing names. |
1159 */ | 1208 */ |
1160 devstat_add_entry(&fd->device_stats, "fd", 1161 fdu, 512, 1162 DEVSTAT_NO_ORDERED_TAGS, 1163 DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, 1164 DEVSTAT_PRIORITY_FD); 1165 | 1209 if (typesize == 1476) 1210 typesize = 1480; 1211 if (typesize == 1722) 1212 typesize = 1720; 1213#endif 1214 typemynor = mynor | i; 1215 fd->bdevs[i] = 1216 devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, 1217 UID_ROOT, GID_OPERATOR, 0640, 1218 "fd%d.%d", fdu, typesize); 1219 fd->cdevs[i] = 1220 devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, 1221 UID_ROOT, GID_OPERATOR, 0640, 1222 "rfd%d.%d", fdu, typesize); |
1166 } 1167 | 1223 } 1224 |
1168 return (1); | 1225 for (i = 0; i < MAXPARTITIONS; i++) { 1226 fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], 1227 "fd%d%c", fdu, 'a' + i); 1228 fd->cdevs[1 + NUMDENS + i] = 1229 devfs_makelink(fd->cdevs[0], 1230 "rfd%d%c", fdu, 'a' + i); 1231 } 1232#endif /* DEVFS */ 1233 /* 1234 * Export the drive to the devstat interface. 1235 */ 1236 devstat_add_entry(&fd->device_stats, device_get_name(dev), 1237 device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS, 1238 DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, 1239 DEVSTAT_PRIORITY_FD); 1240 return (0); |
1169} 1170 | 1241} 1242 |
1171 1172 | |
1173#ifdef FDC_YE 1174/* 1175 * this is a subset of fdattach() optimized for the Y-E Data 1176 * PCMCIA floppy drive. 1177 */ 1178static int yeattach(struct isa_device *dev) 1179{ 1180 fdcu_t fdcu = dev->id_unit; --- 121 unchanged lines hidden (view full) --- 1302} 1303#endif 1304 1305/****************************************************************************/ 1306/* motor control stuff */ 1307/* remember to not deselect the drive we're working on */ 1308/****************************************************************************/ 1309static void | 1243#ifdef FDC_YE 1244/* 1245 * this is a subset of fdattach() optimized for the Y-E Data 1246 * PCMCIA floppy drive. 1247 */ 1248static int yeattach(struct isa_device *dev) 1249{ 1250 fdcu_t fdcu = dev->id_unit; --- 121 unchanged lines hidden (view full) --- 1372} 1373#endif 1374 1375/****************************************************************************/ 1376/* motor control stuff */ 1377/* remember to not deselect the drive we're working on */ 1378/****************************************************************************/ 1379static void |
1310set_motor(fdcu_t fdcu, int fdsu, int turnon) | 1380set_motor(struct fdc_data *fdc, int fdsu, int turnon) |
1311{ | 1381{ |
1312 int fdout = fdc_data[fdcu].fdout; | 1382 int fdout = fdc->fdout; |
1313 int needspecify = 0; 1314 1315#ifdef PC98 1316 outb(IO_FDPORT, (pc98_trans != 1 ? FDP_FDDEXC : 0)|FDP_PORTEXC); 1317 DELAY(10); 1318 fdout = FDO_DMAE|FDO_MTON; 1319#else 1320 if(turnon) { --- 9 unchanged lines hidden (view full) --- 1330 else { 1331 /* make sure controller is selected and specified */ 1332 if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0) 1333 needspecify = 1; 1334 fdout |= (FDO_FRST|FDO_FDMAEN); 1335 } 1336#endif 1337 | 1383 int needspecify = 0; 1384 1385#ifdef PC98 1386 outb(IO_FDPORT, (pc98_trans != 1 ? FDP_FDDEXC : 0)|FDP_PORTEXC); 1387 DELAY(10); 1388 fdout = FDO_DMAE|FDO_MTON; 1389#else 1390 if(turnon) { --- 9 unchanged lines hidden (view full) --- 1400 else { 1401 /* make sure controller is selected and specified */ 1402 if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0) 1403 needspecify = 1; 1404 fdout |= (FDO_FRST|FDO_FDMAEN); 1405 } 1406#endif 1407 |
1338 outb(fdc_data[fdcu].baseport+FDOUT, fdout); 1339 DELAY(10); 1340 fdc_data[fdcu].fdout = fdout; | 1408 outb(fdc->baseport+FDOUT, fdout); 1409 fdc->fdout = fdout; |
1341 TRACE1("[0x%x->FDOUT]", fdout); 1342 | 1410 TRACE1("[0x%x->FDOUT]", fdout); 1411 |
1343 if(needspecify) { | 1412 if (needspecify) { |
1344 /* 1345 * XXX 1346 * special case: since we have just woken up the FDC 1347 * from its sleep, we silently assume the command will 1348 * be accepted, and do not test for a timeout 1349 */ 1350#ifdef PC98 | 1413 /* 1414 * XXX 1415 * special case: since we have just woken up the FDC 1416 * from its sleep, we silently assume the command will 1417 * be accepted, and do not test for a timeout 1418 */ 1419#ifdef PC98 |
1351 (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY, | 1420 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, |
1352 NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0), 1353 0); 1354#else | 1421 NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0), 1422 0); 1423#else |
1355 (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY, | 1424 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, |
1356 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1357 0); 1358#endif | 1425 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1426 0); 1427#endif |
1359 if (fdc_data[fdcu].flags & FDC_HAS_FIFO) 1360 (void) enable_fifo(&fdc_data[fdcu]); 1361 | 1428 if (fdc->flags & FDC_HAS_FIFO) 1429 (void) enable_fifo(fdc); |
1362 } 1363} 1364 1365static void | 1430 } 1431} 1432 1433static void |
1366fd_turnoff(void *arg1) | 1434fd_turnoff(void *xfd) |
1367{ | 1435{ |
1368 fdu_t fdu = (fdu_t)arg1; | |
1369 int s; | 1436 int s; |
1370 fd_p fd = fd_data + fdu; | 1437 fd_p fd = xfd; |
1371 | 1438 |
1372 TRACE1("[fd%d: turnoff]", fdu); | 1439 TRACE1("[fd%d: turnoff]", fd->fdu); |
1373 1374 /* 1375 * Don't turn off the motor yet if the drive is active. 1376 * XXX shouldn't even schedule turnoff until drive is inactive 1377 * and nothing is queued on it. 1378 */ | 1440 1441 /* 1442 * Don't turn off the motor yet if the drive is active. 1443 * XXX shouldn't even schedule turnoff until drive is inactive 1444 * and nothing is queued on it. 1445 */ |
1379 if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fdu) { 1380 fd->toffhandle = timeout(fd_turnoff, arg1, 4 * hz); | 1446 if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) { 1447 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); |
1381 return; 1382 } 1383 1384 s = splbio(); 1385 fd->flags &= ~FD_MOTOR; | 1448 return; 1449 } 1450 1451 s = splbio(); 1452 fd->flags &= ~FD_MOTOR; |
1386 set_motor(fd->fdc->fdcu, fd->fdsu, TURNOFF); | 1453 set_motor(fd->fdc, fd->fdsu, TURNOFF); |
1387 splx(s); 1388} 1389 1390static void | 1454 splx(s); 1455} 1456 1457static void |
1391fd_motor_on(void *arg1) | 1458fd_motor_on(void *xfd) |
1392{ | 1459{ |
1393 fdu_t fdu = (fdu_t)arg1; | |
1394 int s; | 1460 int s; |
1461 fd_p fd = xfd; |
|
1395 | 1462 |
1396 fd_p fd = fd_data + fdu; | |
1397 s = splbio(); 1398 fd->flags &= ~FD_MOTOR_WAIT; 1399 if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) 1400 { | 1463 s = splbio(); 1464 fd->flags &= ~FD_MOTOR_WAIT; 1465 if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) 1466 { |
1401 fdintr(fd->fdc->fdcu); | 1467 fdc_intr(fd->fdc); |
1402 } 1403 splx(s); 1404} 1405 1406static void | 1468 } 1469 splx(s); 1470} 1471 1472static void |
1407fd_turnon(fdu_t fdu) | 1473fd_turnon(fd_p fd) |
1408{ | 1474{ |
1409 fd_p fd = fd_data + fdu; | |
1410 if(!(fd->flags & FD_MOTOR)) 1411 { 1412 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); | 1475 if(!(fd->flags & FD_MOTOR)) 1476 { 1477 fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); |
1413 set_motor(fd->fdc->fdcu, fd->fdsu, TURNON); 1414 timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */ | 1478 set_motor(fd->fdc, fd->fdsu, TURNON); 1479 timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */ |
1415 } 1416} 1417 1418static void 1419fdc_reset(fdc_p fdc) 1420{ | 1480 } 1481} 1482 1483static void 1484fdc_reset(fdc_p fdc) 1485{ |
1421 fdcu_t fdcu = fdc->fdcu; 1422 | |
1423 /* Try a reset, keep motor on */ 1424#ifdef PC98 | 1486 /* Try a reset, keep motor on */ 1487#ifdef PC98 |
1425 set_density(fdcu, 0); | 1488 set_density(fdc); |
1426 if (pc98_machine_type & M_EPSON_PC98) 1427 outb(fdc->baseport + FDOUT, 0xe8); 1428 else 1429 outb(fdc->baseport + FDOUT, 0xd8); 1430 DELAY(200); 1431 outb(fdc->baseport + FDOUT, 0x18); 1432 DELAY(10); 1433#else --- 5 unchanged lines hidden (view full) --- 1439 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN); 1440 DELAY(100); 1441 outb(fdc->baseport + FDOUT, fdc->fdout); 1442 TRACE1("[0x%x->FDOUT]", fdc->fdout); 1443#endif 1444 1445 /* XXX after a reset, silently believe the FDC will accept commands */ 1446#ifdef PC98 | 1489 if (pc98_machine_type & M_EPSON_PC98) 1490 outb(fdc->baseport + FDOUT, 0xe8); 1491 else 1492 outb(fdc->baseport + FDOUT, 0xd8); 1493 DELAY(200); 1494 outb(fdc->baseport + FDOUT, 0x18); 1495 DELAY(10); 1496#else --- 5 unchanged lines hidden (view full) --- 1502 TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN); 1503 DELAY(100); 1504 outb(fdc->baseport + FDOUT, fdc->fdout); 1505 TRACE1("[0x%x->FDOUT]", fdc->fdout); 1506#endif 1507 1508 /* XXX after a reset, silently believe the FDC will accept commands */ 1509#ifdef PC98 |
1447 (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY, | 1510 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, |
1448 NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0), 1449 0); 1450#else | 1511 NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0), 1512 0); 1513#else |
1451 (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY, | 1514 (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, |
1452 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1453 0); 1454#endif 1455 if (fdc->flags & FDC_HAS_FIFO) 1456 (void) enable_fifo(fdc); 1457} 1458 1459/****************************************************************************/ 1460/* fdc in/out */ 1461/****************************************************************************/ 1462int | 1515 NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 1516 0); 1517#endif 1518 if (fdc->flags & FDC_HAS_FIFO) 1519 (void) enable_fifo(fdc); 1520} 1521 1522/****************************************************************************/ 1523/* fdc in/out */ 1524/****************************************************************************/ 1525int |
1463in_fdc(fdcu_t fdcu) | 1526in_fdc(struct fdc_data *fdc) |
1464{ | 1527{ |
1465 int baseport = fdc_data[fdcu].baseport; | 1528 int baseport = fdc->baseport; |
1466 int i, j = 100000; 1467 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1468 != (NE7_DIO|NE7_RQM) && j-- > 0) 1469 if (i == NE7_RQM) | 1529 int i, j = 100000; 1530 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1531 != (NE7_DIO|NE7_RQM) && j-- > 0) 1532 if (i == NE7_RQM) |
1470 return fdc_err(fdcu, "ready for output in input\n"); | 1533 return fdc_err(fdc, "ready for output in input\n"); |
1471 if (j <= 0) | 1534 if (j <= 0) |
1472 return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0); | 1535 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); |
1473#ifdef FDC_DEBUG 1474 i = inb(baseport+FDDATA); 1475 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1476 return(i); 1477#else /* !FDC_DEBUG */ 1478 return inb(baseport+FDDATA); 1479#endif /* FDC_DEBUG */ 1480} 1481 1482/* 1483 * fd_in: Like in_fdc, but allows you to see if it worked. 1484 */ 1485static int | 1536#ifdef FDC_DEBUG 1537 i = inb(baseport+FDDATA); 1538 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1539 return(i); 1540#else /* !FDC_DEBUG */ 1541 return inb(baseport+FDDATA); 1542#endif /* FDC_DEBUG */ 1543} 1544 1545/* 1546 * fd_in: Like in_fdc, but allows you to see if it worked. 1547 */ 1548static int |
1486fd_in(fdcu_t fdcu, int *ptr) | 1549fd_in(struct fdc_data *fdc, int *ptr) |
1487{ | 1550{ |
1488 int baseport = fdc_data[fdcu].baseport; | 1551 int baseport = fdc->baseport; |
1489 int i, j = 100000; 1490 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1491 != (NE7_DIO|NE7_RQM) && j-- > 0) 1492 if (i == NE7_RQM) | 1552 int i, j = 100000; 1553 while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) 1554 != (NE7_DIO|NE7_RQM) && j-- > 0) 1555 if (i == NE7_RQM) |
1493 return fdc_err(fdcu, "ready for output in input\n"); | 1556 return fdc_err(fdc, "ready for output in input\n"); |
1494 if (j <= 0) | 1557 if (j <= 0) |
1495 return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0); | 1558 return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); |
1496#ifdef FDC_DEBUG 1497 i = inb(baseport+FDDATA); 1498 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1499 *ptr = i; 1500 return 0; 1501#else /* !FDC_DEBUG */ 1502 i = inb(baseport+FDDATA); 1503 if (ptr) 1504 *ptr = i; 1505 return 0; 1506#endif /* FDC_DEBUG */ 1507} 1508 1509int | 1559#ifdef FDC_DEBUG 1560 i = inb(baseport+FDDATA); 1561 TRACE1("[FDDATA->0x%x]", (unsigned char)i); 1562 *ptr = i; 1563 return 0; 1564#else /* !FDC_DEBUG */ 1565 i = inb(baseport+FDDATA); 1566 if (ptr) 1567 *ptr = i; 1568 return 0; 1569#endif /* FDC_DEBUG */ 1570} 1571 1572int |
1510out_fdc(fdcu_t fdcu, int x) | 1573out_fdc(struct fdc_data *fdc, int x) |
1511{ | 1574{ |
1512 int baseport = fdc_data[fdcu].baseport; | 1575 int baseport = fdc->baseport; |
1513 int i; 1514 1515 /* Check that the direction bit is set */ 1516 i = 100000; 1517 while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0); | 1576 int i; 1577 1578 /* Check that the direction bit is set */ 1579 i = 100000; 1580 while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0); |
1518 if (i <= 0) return fdc_err(fdcu, "direction bit not set\n"); | 1581 if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); |
1519 1520 /* Check that the floppy controller is ready for a command */ 1521 i = 100000; 1522 while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0); 1523 if (i <= 0) | 1582 1583 /* Check that the floppy controller is ready for a command */ 1584 i = 100000; 1585 while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0); 1586 if (i <= 0) |
1524 return fdc_err(fdcu, bootverbose? "output ready timeout\n": 0); | 1587 return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); |
1525 1526 /* Send the command and return */ 1527 outb(baseport+FDDATA, x); 1528 TRACE1("[0x%x->FDDATA]", x); 1529 return (0); 1530} 1531 1532/****************************************************************************/ 1533/* fdopen/fdclose */ 1534/****************************************************************************/ 1535int 1536Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1537{ 1538 fdu_t fdu = FDUNIT(minor(dev)); 1539 int type = FDTYPE(minor(dev)); | 1588 1589 /* Send the command and return */ 1590 outb(baseport+FDDATA, x); 1591 TRACE1("[0x%x->FDDATA]", x); 1592 return (0); 1593} 1594 1595/****************************************************************************/ 1596/* fdopen/fdclose */ 1597/****************************************************************************/ 1598int 1599Fdopen(dev_t dev, int flags, int mode, struct proc *p) 1600{ 1601 fdu_t fdu = FDUNIT(minor(dev)); 1602 int type = FDTYPE(minor(dev)); |
1603 fd_p fd; |
|
1540 fdc_p fdc; 1541 1542 /* check bounds */ | 1604 fdc_p fdc; 1605 1606 /* check bounds */ |
1543 if (fdu >= NFD) 1544 return(ENXIO); 1545 fdc = fd_data[fdu].fdc; 1546 if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE)) 1547 return(ENXIO); | 1607 if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0) 1608 return (ENXIO); 1609 fdc = fd->fdc; 1610 if ((fdc == NULL) || (fd->type == NO_TYPE)) 1611 return (ENXIO); |
1548 if (type > NUMDENS) | 1612 if (type > NUMDENS) |
1549 return(ENXIO); | 1613 return (ENXIO); |
1550#ifdef PC98 1551 if (pc98_fd_check_ready(fdu) == -1) 1552 return(EIO); 1553#endif 1554 if (type == 0) | 1614#ifdef PC98 1615 if (pc98_fd_check_ready(fdu) == -1) 1616 return(EIO); 1617#endif 1618 if (type == 0) |
1555 type = fd_data[fdu].type; | 1619 type = fd->type; |
1556#ifndef PC98 1557 else { 1558 /* 1559 * For each type of basic drive, make sure we are trying 1560 * to open a type it can do, 1561 */ | 1620#ifndef PC98 1621 else { 1622 /* 1623 * For each type of basic drive, make sure we are trying 1624 * to open a type it can do, 1625 */ |
1562 if (type != fd_data[fdu].type) { 1563 switch (fd_data[fdu].type) { | 1626 if (type != fd->type) { 1627 switch (fd->type) { |
1564 case FD_360: | 1628 case FD_360: |
1565 return(ENXIO); | 1629 return (ENXIO); |
1566 case FD_720: 1567 if ( type != FD_820 1568 && type != FD_800 1569 ) | 1630 case FD_720: 1631 if ( type != FD_820 1632 && type != FD_800 1633 ) |
1570 return(ENXIO); | 1634 return (ENXIO); |
1571 break; 1572 case FD_1200: 1573 switch (type) { 1574 case FD_1480: 1575 type = FD_1480in5_25; 1576 break; 1577 case FD_1440: 1578 type = FD_1440in5_25; --- 23 unchanged lines hidden (view full) --- 1602 && type != FD_720 1603 ) 1604 return(ENXIO); 1605 break; 1606 } 1607 } 1608 } 1609#endif | 1635 break; 1636 case FD_1200: 1637 switch (type) { 1638 case FD_1480: 1639 type = FD_1480in5_25; 1640 break; 1641 case FD_1440: 1642 type = FD_1440in5_25; --- 23 unchanged lines hidden (view full) --- 1666 && type != FD_720 1667 ) 1668 return(ENXIO); 1669 break; 1670 } 1671 } 1672 } 1673#endif |
1610 fd_data[fdu].ft = fd_types + type - 1; 1611 fd_data[fdu].flags |= FD_OPEN; 1612 | 1674 fd->ft = fd_types + type - 1; 1675 fd->flags |= FD_OPEN; 1676 device_busy(fd->dev); 1677 device_busy(fd->fdc->fdc_dev); |
1613 return 0; 1614} 1615 1616int 1617fdclose(dev_t dev, int flags, int mode, struct proc *p) 1618{ 1619 fdu_t fdu = FDUNIT(minor(dev)); | 1678 return 0; 1679} 1680 1681int 1682fdclose(dev_t dev, int flags, int mode, struct proc *p) 1683{ 1684 fdu_t fdu = FDUNIT(minor(dev)); |
1685 struct fd_data *fd; |
|
1620 | 1686 |
1621 fd_data[fdu].flags &= ~FD_OPEN; 1622 fd_data[fdu].options &= ~FDOPT_NORETRY; | 1687 fd = devclass_get_softc(fd_devclass, fdu); 1688 fd->flags &= ~FD_OPEN; 1689 fd->options &= ~FDOPT_NORETRY; |
1623 | 1690 |
1624 return(0); | 1691 return (0); |
1625} 1626 1627static int 1628fdread(dev_t dev, struct uio *uio, int ioflag) 1629{ 1630 return (physio(fdstrategy, NULL, dev, 1, minphys, uio)); 1631} 1632 --- 7 unchanged lines hidden (view full) --- 1640/****************************************************************************/ 1641/* fdstrategy */ 1642/****************************************************************************/ 1643void 1644fdstrategy(struct buf *bp) 1645{ 1646 unsigned nblocks, blknum, cando; 1647 int s; | 1692} 1693 1694static int 1695fdread(dev_t dev, struct uio *uio, int ioflag) 1696{ 1697 return (physio(fdstrategy, NULL, dev, 1, minphys, uio)); 1698} 1699 --- 7 unchanged lines hidden (view full) --- 1707/****************************************************************************/ 1708/* fdstrategy */ 1709/****************************************************************************/ 1710void 1711fdstrategy(struct buf *bp) 1712{ 1713 unsigned nblocks, blknum, cando; 1714 int s; |
1648 fdcu_t fdcu; | |
1649 fdu_t fdu; 1650 fdc_p fdc; 1651 fd_p fd; 1652 size_t fdblk; 1653 1654 fdu = FDUNIT(minor(bp->b_dev)); | 1715 fdu_t fdu; 1716 fdc_p fdc; 1717 fd_p fd; 1718 size_t fdblk; 1719 1720 fdu = FDUNIT(minor(bp->b_dev)); |
1655 fd = &fd_data[fdu]; | 1721 fd = devclass_get_softc(fd_devclass, fdu); 1722 if (fd == 0) 1723 panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)", 1724 (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev)); |
1656 fdc = fd->fdc; | 1725 fdc = fd->fdc; |
1657 fdcu = fdc->fdcu; | |
1658#ifdef FDC_YE 1659 if (fd->type == NO_TYPE) { 1660 bp->b_error = ENXIO; 1661 bp->b_flags |= B_ERROR; 1662 /* 1663 * I _refuse_ to use a goto 1664 */ 1665 biodone(bp); 1666 return; 1667 }; 1668#endif 1669 1670 fdblk = 128 << (fd->ft->secsize); 1671 if (!(bp->b_flags & B_FORMAT)) { | 1726#ifdef FDC_YE 1727 if (fd->type == NO_TYPE) { 1728 bp->b_error = ENXIO; 1729 bp->b_flags |= B_ERROR; 1730 /* 1731 * I _refuse_ to use a goto 1732 */ 1733 biodone(bp); 1734 return; 1735 }; 1736#endif 1737 1738 fdblk = 128 << (fd->ft->secsize); 1739 if (!(bp->b_flags & B_FORMAT)) { |
1672 if ((fdu >= NFD) || (bp->b_blkno < 0)) { | 1740 if (bp->b_blkno < 0) { |
1673 printf( 1674 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", 1675 fdu, (u_long)bp->b_blkno, bp->b_bcount); 1676 bp->b_error = EINVAL; 1677 bp->b_flags |= B_ERROR; 1678 goto bad; 1679 } 1680 if ((bp->b_bcount % fdblk) != 0) { --- 13 unchanged lines hidden (view full) --- 1694 */ 1695 bp->b_error = EINVAL; 1696 bp->b_flags |= B_ERROR; 1697 goto bad; 1698 } 1699 blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk; 1700 nblocks = fd->ft->size; 1701 bp->b_resid = 0; | 1741 printf( 1742 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", 1743 fdu, (u_long)bp->b_blkno, bp->b_bcount); 1744 bp->b_error = EINVAL; 1745 bp->b_flags |= B_ERROR; 1746 goto bad; 1747 } 1748 if ((bp->b_bcount % fdblk) != 0) { --- 13 unchanged lines hidden (view full) --- 1762 */ 1763 bp->b_error = EINVAL; 1764 bp->b_flags |= B_ERROR; 1765 goto bad; 1766 } 1767 blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk; 1768 nblocks = fd->ft->size; 1769 bp->b_resid = 0; |
1702#ifdef PC98 1703#define B_XXX2 0x8000000 1704 if (bp->b_flags & B_XXX2) { 1705 blknum *= 2; 1706 bp->b_blkno *= 2; 1707 bp->b_flags &= ~B_XXX2; 1708 } 1709#endif | |
1710 if (blknum + (bp->b_bcount / fdblk) > nblocks) { 1711 if (blknum <= nblocks) { 1712 cando = (nblocks - blknum) * fdblk; 1713 bp->b_resid = bp->b_bcount - cando; 1714 if (cando == 0) 1715 goto bad; /* not actually bad but EOF */ 1716 } else { 1717 bp->b_error = EINVAL; 1718 bp->b_flags |= B_ERROR; 1719 goto bad; 1720 } 1721 } 1722 bp->b_pblkno = bp->b_blkno; 1723 s = splbio(); 1724 bufqdisksort(&fdc->head, bp); | 1770 if (blknum + (bp->b_bcount / fdblk) > nblocks) { 1771 if (blknum <= nblocks) { 1772 cando = (nblocks - blknum) * fdblk; 1773 bp->b_resid = bp->b_bcount - cando; 1774 if (cando == 0) 1775 goto bad; /* not actually bad but EOF */ 1776 } else { 1777 bp->b_error = EINVAL; 1778 bp->b_flags |= B_ERROR; 1779 goto bad; 1780 } 1781 } 1782 bp->b_pblkno = bp->b_blkno; 1783 s = splbio(); 1784 bufqdisksort(&fdc->head, bp); |
1725 untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); /* a good idea */ | 1785 untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */ |
1726 1727 /* Tell devstat we are starting on the transaction */ 1728 devstat_start_transaction(&fd->device_stats); 1729 | 1786 1787 /* Tell devstat we are starting on the transaction */ 1788 devstat_start_transaction(&fd->device_stats); 1789 |
1730 fdstart(fdcu); | 1790 fdstart(fdc); |
1731 splx(s); 1732 return; 1733 1734bad: 1735 biodone(bp); 1736} 1737 1738/***************************************************************\ 1739* fdstart * 1740* We have just queued something.. if the controller is not busy * 1741* then simulate the case where it has just finished a command * 1742* So that it (the interrupt routine) looks on the queue for more* 1743* work to do and picks up what we just added. * 1744* If the controller is already busy, we need do nothing, as it * 1745* will pick up our work when the present work completes * 1746\***************************************************************/ 1747static void | 1791 splx(s); 1792 return; 1793 1794bad: 1795 biodone(bp); 1796} 1797 1798/***************************************************************\ 1799* fdstart * 1800* We have just queued something.. if the controller is not busy * 1801* then simulate the case where it has just finished a command * 1802* So that it (the interrupt routine) looks on the queue for more* 1803* work to do and picks up what we just added. * 1804* If the controller is already busy, we need do nothing, as it * 1805* will pick up our work when the present work completes * 1806\***************************************************************/ 1807static void |
1748fdstart(fdcu_t fdcu) | 1808fdstart(struct fdc_data *fdc) |
1749{ 1750 int s; 1751 1752 s = splbio(); | 1809{ 1810 int s; 1811 1812 s = splbio(); |
1753 if(fdc_data[fdcu].state == DEVIDLE) | 1813 if(fdc->state == DEVIDLE) |
1754 { | 1814 { |
1755 fdintr(fdcu); | 1815 fdc_intr(fdc); |
1756 } 1757 splx(s); 1758} 1759 1760static void | 1816 } 1817 splx(s); 1818} 1819 1820static void |
1761fd_iotimeout(void *arg1) | 1821fd_iotimeout(void *xfdc) |
1762{ 1763 fdc_p fdc; | 1822{ 1823 fdc_p fdc; |
1764 fdcu_t fdcu; | |
1765 int s; 1766 | 1824 int s; 1825 |
1767 fdcu = (fdcu_t)arg1; 1768 fdc = fdc_data + fdcu; | 1826 fdc = xfdc; |
1769 TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); 1770 1771 /* 1772 * Due to IBM's brain-dead design, the FDC has a faked ready 1773 * signal, hardwired to ready == true. Thus, any command 1774 * issued if there's no diskette in the drive will _never_ 1775 * complete, and must be aborted by resetting the FDC. 1776 * Many thanks, Big Blue! 1777 * The FDC must not be reset directly, since that would 1778 * interfere with the state machine. Instead, pretend that 1779 * the command completed but was invalid. The state machine 1780 * will reset the FDC and retry once. 1781 */ 1782 s = splbio(); 1783 fdc->status[0] = NE7_ST0_IC_IV; 1784 fdc->flags &= ~FDC_STAT_VALID; 1785 fdc->state = IOTIMEDOUT; | 1827 TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); 1828 1829 /* 1830 * Due to IBM's brain-dead design, the FDC has a faked ready 1831 * signal, hardwired to ready == true. Thus, any command 1832 * issued if there's no diskette in the drive will _never_ 1833 * complete, and must be aborted by resetting the FDC. 1834 * Many thanks, Big Blue! 1835 * The FDC must not be reset directly, since that would 1836 * interfere with the state machine. Instead, pretend that 1837 * the command completed but was invalid. The state machine 1838 * will reset the FDC and retry once. 1839 */ 1840 s = splbio(); 1841 fdc->status[0] = NE7_ST0_IC_IV; 1842 fdc->flags &= ~FDC_STAT_VALID; 1843 fdc->state = IOTIMEDOUT; |
1786 fdintr(fdcu); | 1844 fdc_intr(fdc); |
1787 splx(s); 1788} 1789 1790/* just ensure it has the right spl */ 1791static void | 1845 splx(s); 1846} 1847 1848/* just ensure it has the right spl */ 1849static void |
1792fd_pseudointr(void *arg1) | 1850fd_pseudointr(void *xfdc) |
1793{ | 1851{ |
1794 fdcu_t fdcu = (fdcu_t)arg1; | |
1795 int s; 1796 1797 s = splbio(); | 1852 int s; 1853 1854 s = splbio(); |
1798 fdintr(fdcu); | 1855 fdc_intr(xfdc); |
1799 splx(s); 1800} 1801 1802/***********************************************************************\ 1803* fdintr * 1804* keep calling the state machine until it returns a 0 * 1805* ALWAYS called at SPLBIO * 1806\***********************************************************************/ 1807static void | 1856 splx(s); 1857} 1858 1859/***********************************************************************\ 1860* fdintr * 1861* keep calling the state machine until it returns a 0 * 1862* ALWAYS called at SPLBIO * 1863\***********************************************************************/ 1864static void |
1808fdintr(fdcu_t fdcu) | 1865fdc_intr(void *xfdc) |
1809{ | 1866{ |
1810 fdc_p fdc = fdc_data + fdcu; 1811 while(fdstate(fdcu, fdc)) 1812 ; | 1867 fdc_p fdc = xfdc; 1868 while(fdstate(fdc)) 1869 ; |
1813} 1814 1815#ifdef FDC_YE 1816/* 1817 * magic pseudo-DMA initialization for YE FDC. Sets count and 1818 * direction 1819 */ 1820#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \ --- 23 unchanged lines hidden (view full) --- 1844} 1845#endif /* FDC_YE */ 1846 1847/***********************************************************************\ 1848* The controller state machine. * 1849* if it returns a non zero value, it should be called again immediatly * 1850\***********************************************************************/ 1851static int | 1870} 1871 1872#ifdef FDC_YE 1873/* 1874 * magic pseudo-DMA initialization for YE FDC. Sets count and 1875 * direction 1876 */ 1877#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \ --- 23 unchanged lines hidden (view full) --- 1901} 1902#endif /* FDC_YE */ 1903 1904/***********************************************************************\ 1905* The controller state machine. * 1906* if it returns a non zero value, it should be called again immediatly * 1907\***********************************************************************/ 1908static int |
1852fdstate(fdcu_t fdcu, fdc_p fdc) | 1909fdstate(fdc_p fdc) |
1853{ 1854 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3; 1855 unsigned blknum = 0, b_cylinder = 0; 1856 fdu_t fdu = fdc->fdu; 1857 fd_p fd; 1858 register struct buf *bp; 1859 struct fd_formb *finfo = NULL; 1860 size_t fdblk; --- 7 unchanged lines hidden (view full) --- 1868 } 1869 } 1870 if (bp == NULL) { 1871 /***********************************************\ 1872 * nothing left for this controller to do * 1873 * Force into the IDLE state, * 1874 \***********************************************/ 1875 fdc->state = DEVIDLE; | 1910{ 1911 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3; 1912 unsigned blknum = 0, b_cylinder = 0; 1913 fdu_t fdu = fdc->fdu; 1914 fd_p fd; 1915 register struct buf *bp; 1916 struct fd_formb *finfo = NULL; 1917 size_t fdblk; --- 7 unchanged lines hidden (view full) --- 1925 } 1926 } 1927 if (bp == NULL) { 1928 /***********************************************\ 1929 * nothing left for this controller to do * 1930 * Force into the IDLE state, * 1931 \***********************************************/ 1932 fdc->state = DEVIDLE; |
1876 if(fdc->fd) 1877 { 1878 printf("fd%d: unexpected valid fd pointer\n", 1879 fdc->fdu); | 1933 if (fdc->fd) { 1934 device_print_prettyname(fdc->fdc_dev); 1935 printf("unexpected valid fd pointer\n"); |
1880 fdc->fd = (fd_p) 0; 1881 fdc->fdu = -1; 1882 } | 1936 fdc->fd = (fd_p) 0; 1937 fdc->fdu = -1; 1938 } |
1883 TRACE1("[fdc%d IDLE]", fdcu); 1884 return(0); | 1939 TRACE1("[fdc%d IDLE]", fdc->fdcu); 1940 return (0); |
1885 } 1886 fdu = FDUNIT(minor(bp->b_dev)); | 1941 } 1942 fdu = FDUNIT(minor(bp->b_dev)); |
1887 fd = fd_data + fdu; | 1943 fd = devclass_get_softc(fd_devclass, fdu); |
1888 fdblk = 128 << fd->ft->secsize; | 1944 fdblk = 128 << fd->ft->secsize; |
1889 if (fdc->fd && (fd != fdc->fd)) 1890 { 1891 printf("fd%d: confused fd pointers\n", fdu); | 1945 if (fdc->fd && (fd != fdc->fd)) { 1946 device_print_prettyname(fd->dev); 1947 printf("confused fd pointers\n"); |
1892 } 1893 read = bp->b_flags & B_READ; 1894 format = bp->b_flags & B_FORMAT; | 1948 } 1949 read = bp->b_flags & B_READ; 1950 format = bp->b_flags & B_FORMAT; |
1895 if(format) { | 1951 if (format) { |
1896 finfo = (struct fd_formb *)bp->b_data; 1897 fd->skip = (char *)&(finfo->fd_formb_cylno(0)) 1898 - (char *)finfo; 1899 } 1900 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { 1901 blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk + 1902 fd->skip/fdblk; 1903 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1904 } 1905 TRACE1("fd%d", fdu); 1906 TRACE1("[%s]", fdstates[fdc->state]); 1907 TRACE1("(0x%x)", fd->flags); | 1952 finfo = (struct fd_formb *)bp->b_data; 1953 fd->skip = (char *)&(finfo->fd_formb_cylno(0)) 1954 - (char *)finfo; 1955 } 1956 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { 1957 blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk + 1958 fd->skip/fdblk; 1959 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); 1960 } 1961 TRACE1("fd%d", fdu); 1962 TRACE1("[%s]", fdstates[fdc->state]); 1963 TRACE1("(0x%x)", fd->flags); |
1908 untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); 1909 fd->toffhandle = timeout(fd_turnoff, (caddr_t)fdu, 4 * hz); | 1964 untimeout(fd_turnoff, fd, fd->toffhandle); 1965 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); |
1910 switch (fdc->state) 1911 { 1912 case DEVIDLE: 1913 case FINDWORK: /* we have found new work */ 1914 fdc->retry = 0; 1915 fd->skip = 0; 1916 fdc->fd = fd; 1917 fdc->fdu = fdu; 1918#ifdef PC98 1919 pc98_trans = fd->ft->trans; 1920 if (pc98_trans_prev != pc98_trans) { 1921 int i; | 1966 switch (fdc->state) 1967 { 1968 case DEVIDLE: 1969 case FINDWORK: /* we have found new work */ 1970 fdc->retry = 0; 1971 fd->skip = 0; 1972 fdc->fd = fd; 1973 fdc->fdu = fdu; 1974#ifdef PC98 1975 pc98_trans = fd->ft->trans; 1976 if (pc98_trans_prev != pc98_trans) { 1977 int i; |
1922 set_density(fdcu, fdu); | 1978 set_density(fdc); |
1923 for (i = 0; i < 10; i++) { 1924 outb(0x5f, 0); 1925 outb(0x5f, 0); 1926 } 1927 pc98_trans_prev = pc98_trans; 1928 } 1929 if (pc98_trans != fd->pc98_trans) { 1930 if (pc98_trans != 1 && --- 7 unchanged lines hidden (view full) --- 1938#else 1939 outb(fdc->baseport+FDCTL, fd->ft->trans); 1940#endif 1941 TRACE1("[0x%x->FDCTL]", fd->ft->trans); 1942 /*******************************************************\ 1943 * If the next drive has a motor startup pending, then * 1944 * it will start up in its own good time * 1945 \*******************************************************/ | 1979 for (i = 0; i < 10; i++) { 1980 outb(0x5f, 0); 1981 outb(0x5f, 0); 1982 } 1983 pc98_trans_prev = pc98_trans; 1984 } 1985 if (pc98_trans != fd->pc98_trans) { 1986 if (pc98_trans != 1 && --- 7 unchanged lines hidden (view full) --- 1994#else 1995 outb(fdc->baseport+FDCTL, fd->ft->trans); 1996#endif 1997 TRACE1("[0x%x->FDCTL]", fd->ft->trans); 1998 /*******************************************************\ 1999 * If the next drive has a motor startup pending, then * 2000 * it will start up in its own good time * 2001 \*******************************************************/ |
1946 if(fd->flags & FD_MOTOR_WAIT) 1947 { | 2002 if(fd->flags & FD_MOTOR_WAIT) { |
1948 fdc->state = MOTORWAIT; | 2003 fdc->state = MOTORWAIT; |
1949 return(0); /* come back later */ | 2004 return (0); /* come back later */ |
1950 } 1951 /*******************************************************\ 1952 * Maybe if it's not starting, it SHOULD be starting * 1953 \*******************************************************/ 1954#ifdef EPSON_NRDISK 1955 if (fdu != nrdu) { 1956 if (!(fd->flags & FD_MOTOR)) 1957 { --- 5 unchanged lines hidden (view full) --- 1963 { 1964 set_motor(fdcu, fd->fdsu, TURNON); 1965 } 1966 } 1967#else /* !EPSON_NRDISK */ 1968 if (!(fd->flags & FD_MOTOR)) 1969 { 1970 fdc->state = MOTORWAIT; | 2005 } 2006 /*******************************************************\ 2007 * Maybe if it's not starting, it SHOULD be starting * 2008 \*******************************************************/ 2009#ifdef EPSON_NRDISK 2010 if (fdu != nrdu) { 2011 if (!(fd->flags & FD_MOTOR)) 2012 { --- 5 unchanged lines hidden (view full) --- 2018 { 2019 set_motor(fdcu, fd->fdsu, TURNON); 2020 } 2021 } 2022#else /* !EPSON_NRDISK */ 2023 if (!(fd->flags & FD_MOTOR)) 2024 { 2025 fdc->state = MOTORWAIT; |
1971 fd_turnon(fdu); 1972 return(0); | 2026 fd_turnon(fd); 2027 return (0); |
1973 } 1974 else /* at least make sure we are selected */ 1975 { | 2028 } 2029 else /* at least make sure we are selected */ 2030 { |
1976 set_motor(fdcu, fd->fdsu, TURNON); | 2031 set_motor(fdc, fd->fdsu, TURNON); |
1977 } 1978#endif 1979 if (fdc->flags & FDC_NEEDS_RESET) { 1980 fdc->state = RESETCTLR; 1981 fdc->flags &= ~FDC_NEEDS_RESET; 1982 } else 1983 fdc->state = DOSEEK; 1984 break; 1985 case DOSEEK: 1986 if (b_cylinder == (unsigned)fd->track) 1987 { 1988 fdc->state = SEEKCOMPLETE; 1989 break; 1990 } 1991#ifdef PC98 1992 pc98_fd_check_ready(fdu); 1993#endif | 2032 } 2033#endif 2034 if (fdc->flags & FDC_NEEDS_RESET) { 2035 fdc->state = RESETCTLR; 2036 fdc->flags &= ~FDC_NEEDS_RESET; 2037 } else 2038 fdc->state = DOSEEK; 2039 break; 2040 case DOSEEK: 2041 if (b_cylinder == (unsigned)fd->track) 2042 { 2043 fdc->state = SEEKCOMPLETE; 2044 break; 2045 } 2046#ifdef PC98 2047 pc98_fd_check_ready(fdu); 2048#endif |
1994 if (fd_cmd(fdcu, 3, NE7CMD_SEEK, | 2049 if (fd_cmd(fdc, 3, NE7CMD_SEEK, |
1995 fd->fdsu, b_cylinder * fd->ft->steptrac, 1996 0)) 1997 { 1998 /* 1999 * seek command not accepted, looks like 2000 * the FDC went off to the Saints... 2001 */ 2002 fdc->retry = 6; /* try a reset */ | 2050 fd->fdsu, b_cylinder * fd->ft->steptrac, 2051 0)) 2052 { 2053 /* 2054 * seek command not accepted, looks like 2055 * the FDC went off to the Saints... 2056 */ 2057 fdc->retry = 6; /* try a reset */ |
2003 return(retrier(fdcu)); | 2058 return(retrier(fdc)); |
2004 } 2005 fd->track = FD_NO_TRACK; 2006 fdc->state = SEEKWAIT; 2007 return(0); /* will return later */ 2008 case SEEKWAIT: 2009 /* allow heads to settle */ | 2059 } 2060 fd->track = FD_NO_TRACK; 2061 fdc->state = SEEKWAIT; 2062 return(0); /* will return later */ 2063 case SEEKWAIT: 2064 /* allow heads to settle */ |
2010 timeout(fd_pseudointr, (caddr_t)fdcu, hz / 16); | 2065 timeout(fd_pseudointr, fdc, hz / 16); |
2011 fdc->state = SEEKCOMPLETE; 2012 return(0); /* will return later */ 2013 case SEEKCOMPLETE : /* SEEK DONE, START DMA */ 2014 /* Make sure seek really happened*/ | 2066 fdc->state = SEEKCOMPLETE; 2067 return(0); /* will return later */ 2068 case SEEKCOMPLETE : /* SEEK DONE, START DMA */ 2069 /* Make sure seek really happened*/ |
2015 if(fd->track == FD_NO_TRACK) 2016 { | 2070 if(fd->track == FD_NO_TRACK) { |
2017 int descyl = b_cylinder * fd->ft->steptrac; 2018 do { 2019 /* 2020 * This might be a "ready changed" interrupt, 2021 * which cannot really happen since the 2022 * RDY pin is hardwired to + 5 volts. This 2023 * generally indicates a "bouncing" intr 2024 * line, so do one of the following: --- 15 unchanged lines hidden (view full) --- 2040 if (fd_sense_int(fdc, &st0, &cyl) 2041 == FD_NOT_VALID) 2042 return 0; 2043 if(fdc->fdct == FDC_NE765 2044 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 2045 return 0; /* hope for a real intr */ 2046 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 2047 | 2071 int descyl = b_cylinder * fd->ft->steptrac; 2072 do { 2073 /* 2074 * This might be a "ready changed" interrupt, 2075 * which cannot really happen since the 2076 * RDY pin is hardwired to + 5 volts. This 2077 * generally indicates a "bouncing" intr 2078 * line, so do one of the following: --- 15 unchanged lines hidden (view full) --- 2094 if (fd_sense_int(fdc, &st0, &cyl) 2095 == FD_NOT_VALID) 2096 return 0; 2097 if(fdc->fdct == FDC_NE765 2098 && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) 2099 return 0; /* hope for a real intr */ 2100 } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); 2101 |
2048 if (0 == descyl) 2049 { | 2102 if (0 == descyl) { |
2050 int failed = 0; 2051 /* 2052 * seek to cyl 0 requested; make sure we are 2053 * really there 2054 */ 2055 if (fd_sense_drive_status(fdc, &st3)) 2056 failed = 1; 2057#ifdef EPSON_NRDISK 2058 if (fdu == nrdu) st3 = NE7_ST3_T0; 2059#endif /* EPSON_NRDISK */ 2060 if ((st3 & NE7_ST3_T0) == 0) { 2061 printf( 2062 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n", 2063 fdu, st3, NE7_ST3BITS); 2064 failed = 1; 2065 } 2066 | 2103 int failed = 0; 2104 /* 2105 * seek to cyl 0 requested; make sure we are 2106 * really there 2107 */ 2108 if (fd_sense_drive_status(fdc, &st3)) 2109 failed = 1; 2110#ifdef EPSON_NRDISK 2111 if (fdu == nrdu) st3 = NE7_ST3_T0; 2112#endif /* EPSON_NRDISK */ 2113 if ((st3 & NE7_ST3_T0) == 0) { 2114 printf( 2115 "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n", 2116 fdu, st3, NE7_ST3BITS); 2117 failed = 1; 2118 } 2119 |
2067 if (failed) 2068 { | 2120 if (failed) { |
2069 if(fdc->retry < 3) 2070 fdc->retry = 3; | 2121 if(fdc->retry < 3) 2122 fdc->retry = 3; |
2071 return(retrier(fdcu)); | 2123 return (retrier(fdc)); |
2072 } 2073 } 2074#ifdef EPSON_NRDISK 2075 if (fdu == nrdu) cyl = descyl; 2076#endif 2077 | 2124 } 2125 } 2126#ifdef EPSON_NRDISK 2127 if (fdu == nrdu) cyl = descyl; 2128#endif 2129 |
2078 if (cyl != descyl) 2079 { | 2130 if (cyl != descyl) { |
2080 printf( 2081 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", 2082 fdu, descyl, cyl, st0); 2083 if (fdc->retry < 3) 2084 fdc->retry = 3; | 2131 printf( 2132 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", 2133 fdu, descyl, cyl, st0); 2134 if (fdc->retry < 3) 2135 fdc->retry = 3; |
2085 return(retrier(fdcu)); | 2136 return (retrier(fdc)); |
2086 } 2087 } 2088 2089 fd->track = b_cylinder; 2090#ifdef EPSON_NRDISK 2091 if (fdu != nrdu) { 2092#endif /* EPSON_NRDISK */ 2093#ifdef FDC_YE 2094 if (!(fdc->flags & FDC_PCMCIA)) 2095#endif 2096 isa_dmastart(bp->b_flags, bp->b_data+fd->skip, 2097 format ? bp->b_bcount : fdblk, fdc->dmachan); 2098 sectrac = fd->ft->sectrac; 2099 sec = blknum % (sectrac * fd->ft->heads); 2100 head = sec / sectrac; 2101 sec = sec % sectrac + 1; 2102 fd->hddrv = ((head&1)<<2)+fdu; | 2137 } 2138 } 2139 2140 fd->track = b_cylinder; 2141#ifdef EPSON_NRDISK 2142 if (fdu != nrdu) { 2143#endif /* EPSON_NRDISK */ 2144#ifdef FDC_YE 2145 if (!(fdc->flags & FDC_PCMCIA)) 2146#endif 2147 isa_dmastart(bp->b_flags, bp->b_data+fd->skip, 2148 format ? bp->b_bcount : fdblk, fdc->dmachan); 2149 sectrac = fd->ft->sectrac; 2150 sec = blknum % (sectrac * fd->ft->heads); 2151 head = sec / sectrac; 2152 sec = sec % sectrac + 1; 2153 fd->hddrv = ((head&1)<<2)+fdu; |
2154 |
|
2103 if(format || !read) 2104 { 2105 /* make sure the drive is writable */ 2106 if(fd_sense_drive_status(fdc, &st3) != 0) 2107 { 2108 /* stuck controller? */ 2109 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2110 format ? bp->b_bcount : fdblk, 2111 fdc->dmachan); 2112 fdc->retry = 6; /* reset the beast */ | 2155 if(format || !read) 2156 { 2157 /* make sure the drive is writable */ 2158 if(fd_sense_drive_status(fdc, &st3) != 0) 2159 { 2160 /* stuck controller? */ 2161 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2162 format ? bp->b_bcount : fdblk, 2163 fdc->dmachan); 2164 fdc->retry = 6; /* reset the beast */ |
2113 return(retrier(fdcu)); | 2165 return (retrier(fdc)); |
2114 } 2115 if(st3 & NE7_ST3_WP) 2116 { 2117 /* 2118 * XXX YES! this is ugly. 2119 * in order to force the current operation 2120 * to fail, we will have to fake an FDC 2121 * error - all error handling is done --- 6 unchanged lines hidden (view full) --- 2128 fdc->status[4] = head; 2129 fdc->status[5] = sec; 2130 fdc->retry = 8; /* break out immediately */ 2131 fdc->state = IOTIMEDOUT; /* not really... */ 2132 return (1); 2133 } 2134 } 2135 | 2166 } 2167 if(st3 & NE7_ST3_WP) 2168 { 2169 /* 2170 * XXX YES! this is ugly. 2171 * in order to force the current operation 2172 * to fail, we will have to fake an FDC 2173 * error - all error handling is done --- 6 unchanged lines hidden (view full) --- 2180 fdc->status[4] = head; 2181 fdc->status[5] = sec; 2182 fdc->retry = 8; /* break out immediately */ 2183 fdc->state = IOTIMEDOUT; /* not really... */ 2184 return (1); 2185 } 2186 } 2187 |
2136 if(format) 2137 { | 2188 if (format) { |
2138#ifdef FDC_YE 2139 if (fdc->flags & FDC_PCMCIA) 2140 (void)fdcpio(fdcu,bp->b_flags, 2141 bp->b_data+fd->skip, 2142 bp->b_bcount); 2143#endif 2144 /* formatting */ | 2189#ifdef FDC_YE 2190 if (fdc->flags & FDC_PCMCIA) 2191 (void)fdcpio(fdcu,bp->b_flags, 2192 bp->b_data+fd->skip, 2193 bp->b_bcount); 2194#endif 2195 /* formatting */ |
2145 if(fd_cmd(fdcu, 6, 2146 NE7CMD_FORMAT, 2147 head << 2 | fdu, | 2196 if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu, |
2148 finfo->fd_formb_secshift, 2149 finfo->fd_formb_nsecs, 2150 finfo->fd_formb_gaplen, | 2197 finfo->fd_formb_secshift, 2198 finfo->fd_formb_nsecs, 2199 finfo->fd_formb_gaplen, |
2151 finfo->fd_formb_fillbyte, 2152 0)) 2153 { | 2200 finfo->fd_formb_fillbyte, 0)) { |
2154 /* controller fell over */ 2155 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2156 format ? bp->b_bcount : fdblk, 2157 fdc->dmachan); 2158 fdc->retry = 6; | 2201 /* controller fell over */ 2202 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2203 format ? bp->b_bcount : fdblk, 2204 fdc->dmachan); 2205 fdc->retry = 6; |
2159 return(retrier(fdcu)); | 2206 return (retrier(fdc)); |
2160 } | 2207 } |
2161 } 2162 else 2163 { | 2208 } else { |
2164#ifdef FDC_YE 2165 if (fdc->flags & FDC_PCMCIA) { 2166 /* 2167 * this seems to be necessary even when 2168 * reading data 2169 */ 2170 SET_BCDR(1,fdblk,fdc->baseport); 2171 2172 /* 2173 * perform the write pseudo-DMA before 2174 * the WRITE command is sent 2175 */ 2176 if (!read) 2177 (void)fdcpio(fdcu,bp->b_flags, 2178 bp->b_data+fd->skip, 2179 fdblk); 2180 } 2181#endif | 2209#ifdef FDC_YE 2210 if (fdc->flags & FDC_PCMCIA) { 2211 /* 2212 * this seems to be necessary even when 2213 * reading data 2214 */ 2215 SET_BCDR(1,fdblk,fdc->baseport); 2216 2217 /* 2218 * perform the write pseudo-DMA before 2219 * the WRITE command is sent 2220 */ 2221 if (!read) 2222 (void)fdcpio(fdcu,bp->b_flags, 2223 bp->b_data+fd->skip, 2224 fdblk); 2225 } 2226#endif |
2182 if (fd_cmd(fdcu, 9, | 2227 if (fd_cmd(fdc, 9, |
2183 (read ? NE7CMD_READ : NE7CMD_WRITE), 2184 head << 2 | fdu, /* head & unit */ 2185 fd->track, /* track */ 2186 head, 2187 sec, /* sector + 1 */ 2188 fd->ft->secsize, /* sector size */ 2189 sectrac, /* sectors/track */ 2190 fd->ft->gap, /* gap size */ 2191 fd->ft->datalen, /* data length */ | 2228 (read ? NE7CMD_READ : NE7CMD_WRITE), 2229 head << 2 | fdu, /* head & unit */ 2230 fd->track, /* track */ 2231 head, 2232 sec, /* sector + 1 */ 2233 fd->ft->secsize, /* sector size */ 2234 sectrac, /* sectors/track */ 2235 fd->ft->gap, /* gap size */ 2236 fd->ft->datalen, /* data length */ |
2192 0)) 2193 { | 2237 0)) { |
2194 /* the beast is sleeping again */ 2195 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2196 format ? bp->b_bcount : fdblk, 2197 fdc->dmachan); 2198 fdc->retry = 6; | 2238 /* the beast is sleeping again */ 2239 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2240 format ? bp->b_bcount : fdblk, 2241 fdc->dmachan); 2242 fdc->retry = 6; |
2199 return(retrier(fdcu)); | 2243 return (retrier(fdc)); |
2200 } 2201 } 2202#ifdef FDC_YE 2203 if (fdc->flags & FDC_PCMCIA) 2204 /* 2205 * if this is a read, then simply await interrupt 2206 * before performing PIO 2207 */ --- 5 unchanged lines hidden (view full) --- 2213 }; 2214 2215 /* 2216 * write (or format) operation will fall through and 2217 * await completion interrupt 2218 */ 2219#endif 2220 fdc->state = IOCOMPLETE; | 2244 } 2245 } 2246#ifdef FDC_YE 2247 if (fdc->flags & FDC_PCMCIA) 2248 /* 2249 * if this is a read, then simply await interrupt 2250 * before performing PIO 2251 */ --- 5 unchanged lines hidden (view full) --- 2257 }; 2258 2259 /* 2260 * write (or format) operation will fall through and 2261 * await completion interrupt 2262 */ 2263#endif 2264 fdc->state = IOCOMPLETE; |
2221 fd->tohandle = timeout(fd_iotimeout, (caddr_t)fdcu, hz); 2222 return(0); /* will return later */ | 2265 fd->tohandle = timeout(fd_iotimeout, fdc, hz); 2266 return (0); /* will return later */ |
2223#ifdef EPSON_NRDISK 2224 } 2225 else { 2226 nrdblkn = (nrd_t)((unsigned long)bp->b_blkno*DEV_BSIZE/fdblk 2227 + fd->skip/fdblk); 2228 nrd_LED_on(); 2229 nrd_addrset(fdblk * nrdblkn); 2230 while (!nrd_check_ready()) DELAY(1); --- 27 unchanged lines hidden (view full) --- 2258 */ 2259 (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk); 2260 fdc->state = IOCOMPLETE; 2261 /* FALLTHROUGH */ 2262#endif 2263 case IOCOMPLETE: /* IO DONE, post-analyze */ 2264#ifdef EPSON_NRDISK 2265 if (fdu != nrdu) | 2267#ifdef EPSON_NRDISK 2268 } 2269 else { 2270 nrdblkn = (nrd_t)((unsigned long)bp->b_blkno*DEV_BSIZE/fdblk 2271 + fd->skip/fdblk); 2272 nrd_LED_on(); 2273 nrd_addrset(fdblk * nrdblkn); 2274 while (!nrd_check_ready()) DELAY(1); --- 27 unchanged lines hidden (view full) --- 2302 */ 2303 (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk); 2304 fdc->state = IOCOMPLETE; 2305 /* FALLTHROUGH */ 2306#endif 2307 case IOCOMPLETE: /* IO DONE, post-analyze */ 2308#ifdef EPSON_NRDISK 2309 if (fdu != nrdu) |
2266 untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle); | 2310 untimeout(fd_iotimeout, fdc, fd->tohandle); |
2267#else | 2311#else |
2268 untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle); | 2312 untimeout(fd_iotimeout, fdc, fd->tohandle); |
2269#endif 2270 | 2313#endif 2314 |
2271 if (fd_read_status(fdc, fd->fdsu)) 2272 { | 2315 if (fd_read_status(fdc, fd->fdsu)) { |
2273 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2274 format ? bp->b_bcount : fdblk, 2275 fdc->dmachan); 2276 if (fdc->retry < 6) 2277 fdc->retry = 6; /* force a reset */ | 2316 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2317 format ? bp->b_bcount : fdblk, 2318 fdc->dmachan); 2319 if (fdc->retry < 6) 2320 fdc->retry = 6; /* force a reset */ |
2278 return retrier(fdcu); | 2321 return (retrier(fdc)); |
2279 } 2280 2281 fdc->state = IOTIMEDOUT; 2282 2283 /* FALLTHROUGH */ 2284 2285 case IOTIMEDOUT: 2286#ifdef EPSON_NRDISK 2287 if (fdu != nrdu) { 2288#endif /* EPSON_NRDISK */ 2289#ifdef FDC_YE 2290 if (!(fdc->flags & FDC_PCMCIA)) 2291#endif 2292 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2293 format ? bp->b_bcount : fdblk, fdc->dmachan); 2294#ifdef EPSON_NRDISK 2295 } 2296 else nrd_LED_off(); 2297#endif /* EPSON_NRDISK */ | 2322 } 2323 2324 fdc->state = IOTIMEDOUT; 2325 2326 /* FALLTHROUGH */ 2327 2328 case IOTIMEDOUT: 2329#ifdef EPSON_NRDISK 2330 if (fdu != nrdu) { 2331#endif /* EPSON_NRDISK */ 2332#ifdef FDC_YE 2333 if (!(fdc->flags & FDC_PCMCIA)) 2334#endif 2335 isa_dmadone(bp->b_flags, bp->b_data + fd->skip, 2336 format ? bp->b_bcount : fdblk, fdc->dmachan); 2337#ifdef EPSON_NRDISK 2338 } 2339 else nrd_LED_off(); 2340#endif /* EPSON_NRDISK */ |
2298 if (fdc->status[0] & NE7_ST0_IC) 2299 { | 2341 if (fdc->status[0] & NE7_ST0_IC) { |
2300 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 2301 && fdc->status[1] & NE7_ST1_OR) { 2302 /* 2303 * DMA overrun. Someone hogged the bus 2304 * and didn't release it in time for the 2305 * next FDC transfer. 2306 * Just restart it, don't increment retry 2307 * count. (vak) 2308 */ 2309 fdc->state = SEEKCOMPLETE; 2310 return (1); 2311 } 2312 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 2313 && fdc->retry < 6) 2314 fdc->retry = 6; /* force a reset */ 2315 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 2316 && fdc->status[2] & NE7_ST2_WC 2317 && fdc->retry < 3) 2318 fdc->retry = 3; /* force recalibrate */ | 2342 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 2343 && fdc->status[1] & NE7_ST1_OR) { 2344 /* 2345 * DMA overrun. Someone hogged the bus 2346 * and didn't release it in time for the 2347 * next FDC transfer. 2348 * Just restart it, don't increment retry 2349 * count. (vak) 2350 */ 2351 fdc->state = SEEKCOMPLETE; 2352 return (1); 2353 } 2354 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV 2355 && fdc->retry < 6) 2356 fdc->retry = 6; /* force a reset */ 2357 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT 2358 && fdc->status[2] & NE7_ST2_WC 2359 && fdc->retry < 3) 2360 fdc->retry = 3; /* force recalibrate */ |
2319 return(retrier(fdcu)); | 2361 return (retrier(fdc)); |
2320 } 2321 /* All OK */ 2322 fd->skip += fdblk; | 2362 } 2363 /* All OK */ 2364 fd->skip += fdblk; |
2323 if (!format && fd->skip < bp->b_bcount - bp->b_resid) 2324 { | 2365 if (!format && fd->skip < bp->b_bcount - bp->b_resid) { |
2325 /* set up next transfer */ 2326 fdc->state = DOSEEK; | 2366 /* set up next transfer */ 2367 fdc->state = DOSEEK; |
2327 } 2328 else 2329 { | 2368 } else { |
2330 /* ALL DONE */ 2331 fd->skip = 0; 2332 fdc->bp = NULL; 2333 /* Tell devstat we have finished with the transaction */ 2334 devstat_end_transaction(&fd->device_stats, 2335 bp->b_bcount - bp->b_resid, 2336 DEVSTAT_TAG_NONE, 2337 (bp->b_flags & B_READ) ? 2338 DEVSTAT_READ : DEVSTAT_WRITE); 2339 biodone(bp); 2340 fdc->fd = (fd_p) 0; 2341 fdc->fdu = -1; 2342 fdc->state = FINDWORK; 2343 } | 2369 /* ALL DONE */ 2370 fd->skip = 0; 2371 fdc->bp = NULL; 2372 /* Tell devstat we have finished with the transaction */ 2373 devstat_end_transaction(&fd->device_stats, 2374 bp->b_bcount - bp->b_resid, 2375 DEVSTAT_TAG_NONE, 2376 (bp->b_flags & B_READ) ? 2377 DEVSTAT_READ : DEVSTAT_WRITE); 2378 biodone(bp); 2379 fdc->fd = (fd_p) 0; 2380 fdc->fdu = -1; 2381 fdc->state = FINDWORK; 2382 } |
2344 return(1); | 2383 return (1); |
2345 case RESETCTLR: 2346 fdc_reset(fdc); 2347 fdc->retry++; 2348 fdc->state = RESETCOMPLETE; 2349 return (0); 2350 case RESETCOMPLETE: 2351 /* 2352 * Discard all the results from the reset so that they 2353 * can't cause an unexpected interrupt later. 2354 */ 2355 for (i = 0; i < 4; i++) 2356 (void)fd_sense_int(fdc, &st0, &cyl); 2357 fdc->state = STARTRECAL; 2358 /* Fall through. */ 2359 case STARTRECAL: 2360#ifdef PC98 2361 pc98_fd_check_ready(fdu); 2362#endif | 2384 case RESETCTLR: 2385 fdc_reset(fdc); 2386 fdc->retry++; 2387 fdc->state = RESETCOMPLETE; 2388 return (0); 2389 case RESETCOMPLETE: 2390 /* 2391 * Discard all the results from the reset so that they 2392 * can't cause an unexpected interrupt later. 2393 */ 2394 for (i = 0; i < 4; i++) 2395 (void)fd_sense_int(fdc, &st0, &cyl); 2396 fdc->state = STARTRECAL; 2397 /* Fall through. */ 2398 case STARTRECAL: 2399#ifdef PC98 2400 pc98_fd_check_ready(fdu); 2401#endif |
2363 if(fd_cmd(fdcu, 2364 2, NE7CMD_RECAL, fdu, 2365 0)) /* Recalibrate Function */ 2366 { | 2402 if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) { |
2367 /* arrgl */ 2368 fdc->retry = 6; | 2403 /* arrgl */ 2404 fdc->retry = 6; |
2369 return(retrier(fdcu)); | 2405 return (retrier(fdc)); |
2370 } 2371 fdc->state = RECALWAIT; | 2406 } 2407 fdc->state = RECALWAIT; |
2372 return(0); /* will return later */ | 2408 return (0); /* will return later */ |
2373 case RECALWAIT: 2374 /* allow heads to settle */ | 2409 case RECALWAIT: 2410 /* allow heads to settle */ |
2375 timeout(fd_pseudointr, (caddr_t)fdcu, hz / 8); | 2411 timeout(fd_pseudointr, fdc, hz / 8); |
2376 fdc->state = RECALCOMPLETE; | 2412 fdc->state = RECALCOMPLETE; |
2377 return(0); /* will return later */ | 2413 return (0); /* will return later */ |
2378 case RECALCOMPLETE: 2379 do { 2380 /* 2381 * See SEEKCOMPLETE for a comment on this: 2382 */ 2383 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 2384 return 0; 2385 if(fdc->fdct == FDC_NE765 --- 15 unchanged lines hidden (view full) --- 2401 * since people used to complain much about 2402 * the failure message, try not logging 2403 * this one if it seems to be the first 2404 * time in a line 2405 */ 2406 printf("fd%d: recal failed ST0 %b cyl %d\n", 2407 fdu, st0, NE7_ST0BITS, cyl); 2408 if(fdc->retry < 3) fdc->retry = 3; | 2414 case RECALCOMPLETE: 2415 do { 2416 /* 2417 * See SEEKCOMPLETE for a comment on this: 2418 */ 2419 if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 2420 return 0; 2421 if(fdc->fdct == FDC_NE765 --- 15 unchanged lines hidden (view full) --- 2437 * since people used to complain much about 2438 * the failure message, try not logging 2439 * this one if it seems to be the first 2440 * time in a line 2441 */ 2442 printf("fd%d: recal failed ST0 %b cyl %d\n", 2443 fdu, st0, NE7_ST0BITS, cyl); 2444 if(fdc->retry < 3) fdc->retry = 3; |
2409 return(retrier(fdcu)); | 2445 return (retrier(fdc)); |
2410 } 2411 fd->track = 0; 2412 /* Seek (probably) necessary */ 2413 fdc->state = DOSEEK; | 2446 } 2447 fd->track = 0; 2448 /* Seek (probably) necessary */ 2449 fdc->state = DOSEEK; |
2414 return(1); /* will return immediatly */ | 2450 return (1); /* will return immediatly */ |
2415 case MOTORWAIT: 2416 if(fd->flags & FD_MOTOR_WAIT) 2417 { | 2451 case MOTORWAIT: 2452 if(fd->flags & FD_MOTOR_WAIT) 2453 { |
2418 return(0); /* time's not up yet */ | 2454 return (0); /* time's not up yet */ |
2419 } 2420 if (fdc->flags & FDC_NEEDS_RESET) { 2421 fdc->state = RESETCTLR; 2422 fdc->flags &= ~FDC_NEEDS_RESET; 2423 } else { 2424 /* 2425 * If all motors were off, then the controller was 2426 * reset, so it has lost track of the current 2427 * cylinder. Recalibrate to handle this case. 2428 */ 2429 fdc->state = STARTRECAL; 2430 } | 2455 } 2456 if (fdc->flags & FDC_NEEDS_RESET) { 2457 fdc->state = RESETCTLR; 2458 fdc->flags &= ~FDC_NEEDS_RESET; 2459 } else { 2460 /* 2461 * If all motors were off, then the controller was 2462 * reset, so it has lost track of the current 2463 * cylinder. Recalibrate to handle this case. 2464 */ 2465 fdc->state = STARTRECAL; 2466 } |
2431 return(1); /* will return immediatly */ | 2467 return (1); /* will return immediatly */ |
2432 default: | 2468 default: |
2433 printf("fdc%d: Unexpected FD int->", fdcu); | 2469 device_print_prettyname(fdc->fdc_dev); 2470 printf("unexpected FD int->"); |
2434 if (fd_read_status(fdc, fd->fdsu) == 0) 2435 printf("FDC status :%x %x %x %x %x %x %x ", 2436 fdc->status[0], 2437 fdc->status[1], 2438 fdc->status[2], 2439 fdc->status[3], 2440 fdc->status[4], 2441 fdc->status[5], 2442 fdc->status[6] ); 2443 else 2444 printf("No status available "); 2445 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2446 { 2447 printf("[controller is dead now]\n"); | 2471 if (fd_read_status(fdc, fd->fdsu) == 0) 2472 printf("FDC status :%x %x %x %x %x %x %x ", 2473 fdc->status[0], 2474 fdc->status[1], 2475 fdc->status[2], 2476 fdc->status[3], 2477 fdc->status[4], 2478 fdc->status[5], 2479 fdc->status[6] ); 2480 else 2481 printf("No status available "); 2482 if (fd_sense_int(fdc, &st0, &cyl) != 0) 2483 { 2484 printf("[controller is dead now]\n"); |
2448 return(0); | 2485 return (0); |
2449 } 2450 printf("ST0 = %x, PCN = %x\n", st0, cyl); | 2486 } 2487 printf("ST0 = %x, PCN = %x\n", st0, cyl); |
2451 return(0); | 2488 return (0); |
2452 } 2453 /*XXX confusing: some branches return immediately, others end up here*/ | 2489 } 2490 /*XXX confusing: some branches return immediately, others end up here*/ |
2454 return(1); /* Come back immediatly to new state */ | 2491 return (1); /* Come back immediatly to new state */ |
2455} 2456 2457static int | 2492} 2493 2494static int |
2458retrier(fdcu) 2459 fdcu_t fdcu; | 2495retrier(struct fdc_data *fdc) |
2460{ | 2496{ |
2461 fdc_p fdc = fdc_data + fdcu; | |
2462 register struct buf *bp; | 2497 register struct buf *bp; |
2498 struct fd_data *fd; 2499 int fdu; |
|
2463 2464 bp = fdc->bp; 2465 | 2500 2501 bp = fdc->bp; 2502 |
2466 if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY) | 2503 /* XXX shouldn't this be cached somewhere? */ 2504 fdu = FDUNIT(minor(bp->b_dev)); 2505 fd = devclass_get_softc(fd_devclass, fdu); 2506 if (fd->options & FDOPT_NORETRY) |
2467 goto fail; | 2507 goto fail; |
2468 switch(fdc->retry) 2469 { | 2508 2509 switch (fdc->retry) { |
2470 case 0: case 1: case 2: 2471 fdc->state = SEEKCOMPLETE; 2472 break; 2473 case 3: case 4: case 5: 2474 fdc->state = STARTRECAL; 2475 break; 2476 case 6: 2477 fdc->state = RESETCTLR; --- 36 unchanged lines hidden (view full) --- 2514 (bp->b_flags & B_READ) ? DEVSTAT_READ : 2515 DEVSTAT_WRITE); 2516 fdc->fd->skip = 0; 2517 biodone(bp); 2518 fdc->state = FINDWORK; 2519 fdc->flags |= FDC_NEEDS_RESET; 2520 fdc->fd = (fd_p) 0; 2521 fdc->fdu = -1; | 2510 case 0: case 1: case 2: 2511 fdc->state = SEEKCOMPLETE; 2512 break; 2513 case 3: case 4: case 5: 2514 fdc->state = STARTRECAL; 2515 break; 2516 case 6: 2517 fdc->state = RESETCTLR; --- 36 unchanged lines hidden (view full) --- 2554 (bp->b_flags & B_READ) ? DEVSTAT_READ : 2555 DEVSTAT_WRITE); 2556 fdc->fd->skip = 0; 2557 biodone(bp); 2558 fdc->state = FINDWORK; 2559 fdc->flags |= FDC_NEEDS_RESET; 2560 fdc->fd = (fd_p) 0; 2561 fdc->fdu = -1; |
2522 return(1); | 2562 return (1); |
2523 } 2524 fdc->retry++; | 2563 } 2564 fdc->retry++; |
2525 return(1); | 2565 return (1); |
2526} 2527 2528static int 2529fdformat(dev, finfo, p) 2530 dev_t dev; 2531 struct fd_formb *finfo; 2532 struct proc *p; 2533{ 2534 fdu_t fdu; 2535 fd_p fd; 2536 2537 struct buf *bp; 2538 int rv = 0, s; 2539 size_t fdblk; 2540 2541 fdu = FDUNIT(minor(dev)); | 2566} 2567 2568static int 2569fdformat(dev, finfo, p) 2570 dev_t dev; 2571 struct fd_formb *finfo; 2572 struct proc *p; 2573{ 2574 fdu_t fdu; 2575 fd_p fd; 2576 2577 struct buf *bp; 2578 int rv = 0, s; 2579 size_t fdblk; 2580 2581 fdu = FDUNIT(minor(dev)); |
2542 fd = &fd_data[fdu]; | 2582 fd = devclass_get_softc(fd_devclass, fdu); |
2543 fdblk = 128 << fd->ft->secsize; 2544 2545 /* set up a buffer header for fdstrategy() */ 2546 bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT); 2547 if(bp == 0) 2548 return ENOBUFS; 2549 /* 2550 * keep the process from being swapped --- 14 unchanged lines hidden (view full) --- 2565 bp->b_data = (caddr_t)finfo; 2566 2567 /* now do the format */ 2568 bp->b_dev = dev; 2569 fdstrategy(bp); 2570 2571 /* ...and wait for it to complete */ 2572 s = splbio(); | 2583 fdblk = 128 << fd->ft->secsize; 2584 2585 /* set up a buffer header for fdstrategy() */ 2586 bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT); 2587 if(bp == 0) 2588 return ENOBUFS; 2589 /* 2590 * keep the process from being swapped --- 14 unchanged lines hidden (view full) --- 2605 bp->b_data = (caddr_t)finfo; 2606 2607 /* now do the format */ 2608 bp->b_dev = dev; 2609 fdstrategy(bp); 2610 2611 /* ...and wait for it to complete */ 2612 s = splbio(); |
2573 while(!(bp->b_flags & B_DONE)) 2574 { | 2613 while(!(bp->b_flags & B_DONE)) { |
2575 rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz); | 2614 rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz); |
2576 if(rv == EWOULDBLOCK) | 2615 if (rv == EWOULDBLOCK) |
2577 break; 2578 } 2579 splx(s); 2580 | 2616 break; 2617 } 2618 splx(s); 2619 |
2581 if(rv == EWOULDBLOCK) { | 2620 if (rv == EWOULDBLOCK) { |
2582 /* timed out */ 2583 rv = EIO; 2584 biodone(bp); 2585 } | 2621 /* timed out */ 2622 rv = EIO; 2623 biodone(bp); 2624 } |
2586 if(bp->b_flags & B_ERROR) | 2625 if (bp->b_flags & B_ERROR) |
2587 rv = bp->b_error; 2588 /* 2589 * allow the process to be swapped 2590 */ 2591 PRELE(p); 2592 free(bp, M_TEMP); 2593 return rv; 2594} --- 6 unchanged lines hidden (view full) --- 2601fdioctl(dev, cmd, addr, flag, p) 2602 dev_t dev; 2603 u_long cmd; 2604 caddr_t addr; 2605 int flag; 2606 struct proc *p; 2607{ 2608 fdu_t fdu = FDUNIT(minor(dev)); | 2626 rv = bp->b_error; 2627 /* 2628 * allow the process to be swapped 2629 */ 2630 PRELE(p); 2631 free(bp, M_TEMP); 2632 return rv; 2633} --- 6 unchanged lines hidden (view full) --- 2640fdioctl(dev, cmd, addr, flag, p) 2641 dev_t dev; 2642 u_long cmd; 2643 caddr_t addr; 2644 int flag; 2645 struct proc *p; 2646{ 2647 fdu_t fdu = FDUNIT(minor(dev)); |
2609 fd_p fd = &fd_data[fdu]; | 2648 fd_p fd = devclass_get_softc(fd_devclass, fdu); |
2610 size_t fdblk; 2611 2612 struct fd_type *fdt; 2613 struct disklabel *dl; 2614 char buffer[DEV_BSIZE]; 2615 int error = 0; 2616 2617 fdblk = 128 << fd->ft->secsize; 2618 2619#ifdef PC98 | 2649 size_t fdblk; 2650 2651 struct fd_type *fdt; 2652 struct disklabel *dl; 2653 char buffer[DEV_BSIZE]; 2654 int error = 0; 2655 2656 fdblk = 128 << fd->ft->secsize; 2657 2658#ifdef PC98 |
2620 pc98_fd_check_ready(fdu); | 2659 pc98_fd_check_ready(fdu); |
2621#endif | 2660#endif |
2622 switch (cmd) 2623 { | 2661 switch (cmd) { |
2624 case DIOCGDINFO: 2625 bzero(buffer, sizeof (buffer)); 2626 dl = (struct disklabel *)buffer; 2627 dl->d_secsize = fdblk; | 2662 case DIOCGDINFO: 2663 bzero(buffer, sizeof (buffer)); 2664 dl = (struct disklabel *)buffer; 2665 dl->d_secsize = fdblk; |
2628 fdt = fd_data[FDUNIT(minor(dev))].ft; | 2666 fdt = fd->ft; |
2629 dl->d_secpercyl = fdt->size / fdt->tracks; 2630 dl->d_type = DTYPE_FLOPPY; 2631 2632 if (readdisklabel(dkmodpart(dev, RAW_PART), fdstrategy, dl) 2633 == NULL) 2634 error = 0; 2635 else 2636 error = EINVAL; --- 7 unchanged lines hidden (view full) --- 2644 break; 2645 2646 case DIOCWLABEL: 2647 if ((flag & FWRITE) == 0) 2648 error = EBADF; 2649 break; 2650 2651 case DIOCWDINFO: | 2667 dl->d_secpercyl = fdt->size / fdt->tracks; 2668 dl->d_type = DTYPE_FLOPPY; 2669 2670 if (readdisklabel(dkmodpart(dev, RAW_PART), fdstrategy, dl) 2671 == NULL) 2672 error = 0; 2673 else 2674 error = EINVAL; --- 7 unchanged lines hidden (view full) --- 2682 break; 2683 2684 case DIOCWLABEL: 2685 if ((flag & FWRITE) == 0) 2686 error = EBADF; 2687 break; 2688 2689 case DIOCWDINFO: |
2652 if ((flag & FWRITE) == 0) 2653 { | 2690 if ((flag & FWRITE) == 0) { |
2654 error = EBADF; 2655 break; 2656 } 2657 2658 dl = (struct disklabel *)addr; 2659 2660 if ((error = setdisklabel((struct disklabel *)buffer, dl, 2661 (u_long)0)) != 0) 2662 break; 2663 2664 error = writedisklabel(dev, fdstrategy, 2665 (struct disklabel *)buffer); 2666 break; 2667 case FD_FORM: | 2691 error = EBADF; 2692 break; 2693 } 2694 2695 dl = (struct disklabel *)addr; 2696 2697 if ((error = setdisklabel((struct disklabel *)buffer, dl, 2698 (u_long)0)) != 0) 2699 break; 2700 2701 error = writedisklabel(dev, fdstrategy, 2702 (struct disklabel *)buffer); 2703 break; 2704 case FD_FORM: |
2668 if((flag & FWRITE) == 0) | 2705 if ((flag & FWRITE) == 0) |
2669 error = EBADF; /* must be opened for writing */ | 2706 error = EBADF; /* must be opened for writing */ |
2670 else if(((struct fd_formb *)addr)->format_version != | 2707 else if (((struct fd_formb *)addr)->format_version != |
2671 FD_FORMAT_VERSION) 2672 error = EINVAL; /* wrong version of formatting prog */ 2673 else 2674 error = fdformat(dev, (struct fd_formb *)addr, p); 2675 break; 2676 2677 case FD_GTYPE: /* get drive type */ 2678 *(struct fd_type *)addr = *fd->ft; 2679 break; 2680 2681 case FD_STYPE: /* set drive type */ 2682 /* this is considered harmful; only allow for superuser */ | 2708 FD_FORMAT_VERSION) 2709 error = EINVAL; /* wrong version of formatting prog */ 2710 else 2711 error = fdformat(dev, (struct fd_formb *)addr, p); 2712 break; 2713 2714 case FD_GTYPE: /* get drive type */ 2715 *(struct fd_type *)addr = *fd->ft; 2716 break; 2717 2718 case FD_STYPE: /* set drive type */ 2719 /* this is considered harmful; only allow for superuser */ |
2683 if(suser(p->p_ucred, &p->p_acflag) != 0) | 2720 if (suser(p->p_ucred, &p->p_acflag) != 0) |
2684 return EPERM; 2685 *fd->ft = *(struct fd_type *)addr; 2686 break; 2687 2688 case FD_GOPTS: /* get drive options */ 2689 *(int *)addr = fd->options; 2690 break; 2691 2692 case FD_SOPTS: /* set drive options */ 2693 fd->options = *(int *)addr; 2694 break; 2695 2696 default: 2697 error = ENOTTY; 2698 break; 2699 } 2700 return (error); 2701} 2702 | 2721 return EPERM; 2722 *fd->ft = *(struct fd_type *)addr; 2723 break; 2724 2725 case FD_GOPTS: /* get drive options */ 2726 *(int *)addr = fd->options; 2727 break; 2728 2729 case FD_SOPTS: /* set drive options */ 2730 fd->options = *(int *)addr; 2731 break; 2732 2733 default: 2734 error = ENOTTY; 2735 break; 2736 } 2737 return (error); 2738} 2739 |
2740static device_method_t fdc_methods[] = { 2741 /* Device interface */ 2742 DEVMETHOD(device_probe, fdc_probe), 2743 DEVMETHOD(device_attach, fdc_attach), 2744 DEVMETHOD(device_detach, bus_generic_detach), 2745 DEVMETHOD(device_shutdown, bus_generic_shutdown), 2746 DEVMETHOD(device_suspend, bus_generic_suspend), 2747 DEVMETHOD(device_resume, bus_generic_resume), |
|
2703 | 2748 |
2704static fd_devsw_installed = 0; | 2749 /* Bus interface */ 2750 DEVMETHOD(bus_print_child, fdc_print_child), 2751 /* Our children never use any other bus interface methods. */ |
2705 | 2752 |
2706static void fd_drvinit(void *notused ) 2707{ | 2753 { 0, 0 } 2754}; |
2708 | 2755 |
2709 if( ! fd_devsw_installed ) { 2710 cdevsw_add_generic(BDEV_MAJOR,CDEV_MAJOR, &fd_cdevsw); 2711 fd_devsw_installed = 1; 2712 } 2713} | 2756static driver_t fdc_driver = { 2757 "fdc", 2758 fdc_methods, 2759 DRIVER_TYPE_BIO, 2760 sizeof(struct fdc_data) 2761}; |
2714 | 2762 |
2715SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL) | 2763DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0); |
2716 | 2764 |
2765static device_method_t fd_methods[] = { 2766 /* Device interface */ 2767 DEVMETHOD(device_probe, fd_probe), 2768 DEVMETHOD(device_attach, fd_attach), 2769 DEVMETHOD(device_detach, bus_generic_detach), 2770 DEVMETHOD(device_shutdown, bus_generic_shutdown), 2771 DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */ 2772 DEVMETHOD(device_resume, bus_generic_resume), /* XXX */ |
|
2717 | 2773 |
2718#endif | 2774 { 0, 0 } 2775}; |
2719 | 2776 |
2777static driver_t fd_driver = { 2778 "fd", 2779 fd_methods, 2780 DRIVER_TYPE_BIO, 2781 sizeof(struct fd_data) 2782}; 2783 2784static struct cdevsw fd_cdevsw = { 2785 Fdopen, fdclose, fdread, fdwrite, 2786 fdioctl, nostop, nullreset, nodevtotty, 2787 seltrue, nommap, fdstrategy, "fd", 2788 NULL, -1, nodump, nopsize, 2789 D_DISK, 0, -1 2790}; 2791 2792BDEV_DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, BDEV_MAJOR, CDEV_MAJOR, 2793 fd_cdevsw, 0, 0); 2794 2795#endif /* NFDC > 0 */ 2796 |
|
2720/* 2721 * Hello emacs, these are the 2722 * Local Variables: 2723 * c-indent-level: 8 2724 * c-continued-statement-offset: 8 2725 * c-continued-brace-offset: 0 2726 * c-brace-offset: -8 2727 * c-brace-imaginary-offset: 0 2728 * c-argdecl-indent: 8 2729 * c-label-offset: -8 2730 * c++-hanging-braces: 1 2731 * c++-access-specifier-offset: -8 2732 * c++-empty-arglist-indent: 8 2733 * c++-friend-offset: 0 2734 * End: 2735 */ | 2797/* 2798 * Hello emacs, these are the 2799 * Local Variables: 2800 * c-indent-level: 8 2801 * c-continued-statement-offset: 8 2802 * c-continued-brace-offset: 0 2803 * c-brace-offset: -8 2804 * c-brace-imaginary-offset: 0 2805 * c-argdecl-indent: 8 2806 * c-label-offset: -8 2807 * c++-hanging-braces: 1 2808 * c++-access-specifier-offset: -8 2809 * c++-empty-arglist-indent: 8 2810 * c++-friend-offset: 0 2811 * End: 2812 */ |