Deleted Added
full compact
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 */