Deleted Added
full compact
fdc.c (18010) fdc.c (18208)
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 * Copyright (c) 1993, 1994 by

--- 29 unchanged lines hidden (view full) ---

38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 *
45 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
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 * Copyright (c) 1993, 1994 by

--- 29 unchanged lines hidden (view full) ---

38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 *
45 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
46 * $Id: fd.c,v 1.4 1996/08/31 15:06:42 asami Exp $
46 * $Id: fd.c,v 1.5 1996/09/03 10:23:25 asami Exp $
47 *
48 */
49
50#include "ft.h"
51#if NFT < 1
52#undef NFDC
53#endif
54#include "fd.h"

--- 9 unchanged lines hidden (view full) ---

64#include <machine/clock.h>
65#include <machine/ioctl_fd.h>
66#include <sys/disklabel.h>
67#include <sys/buf.h>
68#include <sys/uio.h>
69#include <sys/malloc.h>
70#include <sys/proc.h>
71#include <sys/syslog.h>
47 *
48 */
49
50#include "ft.h"
51#if NFT < 1
52#undef NFDC
53#endif
54#include "fd.h"

--- 9 unchanged lines hidden (view full) ---

64#include <machine/clock.h>
65#include <machine/ioctl_fd.h>
66#include <sys/disklabel.h>
67#include <sys/buf.h>
68#include <sys/uio.h>
69#include <sys/malloc.h>
70#include <sys/proc.h>
71#include <sys/syslog.h>
72#include <sys/devconf.h>
73#include <sys/dkstat.h>
74#ifdef PC98
75#include <pc98/pc98/pc98.h>
76#include <i386/isa/isa_device.h>
77#include <pc98/pc98/fdreg.h>
78#include <pc98/pc98/fdc.h>
79#else
80#include <i386/isa/isa.h>
81#include <i386/isa/isa_device.h>
82#include <i386/isa/fdreg.h>
83#include <i386/isa/fdc.h>
84#include <i386/isa/rtc.h>
85#endif
86#include <machine/stdarg.h>
87#if NFT > 0
88#include <sys/ftape.h>
72#include <sys/dkstat.h>
73#ifdef PC98
74#include <pc98/pc98/pc98.h>
75#include <i386/isa/isa_device.h>
76#include <pc98/pc98/fdreg.h>
77#include <pc98/pc98/fdc.h>
78#else
79#include <i386/isa/isa.h>
80#include <i386/isa/isa_device.h>
81#include <i386/isa/fdreg.h>
82#include <i386/isa/fdc.h>
83#include <i386/isa/rtc.h>
84#endif
85#include <machine/stdarg.h>
86#if NFT > 0
87#include <sys/ftape.h>
89#ifdef PC98
90#include <pc98/pc98/ftreg.h>
91#else
92#include <i386/isa/ftreg.h>
93#endif
88#include <i386/isa/ftreg.h>
89#endif
94#endif
95#ifdef DEVFS
96#include <sys/devfsext.h>
97#endif
98
90#ifdef DEVFS
91#include <sys/devfsext.h>
92#endif
93
99
100static int fd_goaway(struct kern_devconf *, int);
101static int fdc_goaway(struct kern_devconf *, int);
102static int fd_externalize(struct kern_devconf *, struct sysctl_req *);
103
104/*
105 * Templates for the kern_devconf structures used when we attach.
106 */
107static struct kern_devconf kdc_fd[NFD] = { {
108 0, 0, 0, /* filled in by kern_devconf.c */
109 "fd", 0, { MDDT_DISK, 0 },
110 fd_externalize, 0, fd_goaway, DISK_EXTERNALLEN,
111 0, /* parent */
112 0, /* parentdata */
113 DC_UNCONFIGURED, /* state */
114 "floppy disk",
115 DC_CLS_DISK /* class */
116} };
117
118struct kern_devconf kdc_fdc[NFDC] = { {
119 0, 0, 0, /* filled in by kern_devconf.c */
120 "fdc", 0, { MDDT_ISA, 0, "bio" },
121 isa_generic_externalize, 0, fdc_goaway, ISA_EXTERNALLEN,
122 0, /* parent */
123 0, /* parentdata */
124 DC_UNCONFIGURED, /* state */
125 "floppy disk/tape controller",
126 DC_CLS_MISC /* class */
127} };
128
129static inline void
130fd_registerdev(int ctlr, int unit)
131{
132 if(unit != 0)
133 kdc_fd[unit] = kdc_fd[0];
134
135 kdc_fd[unit].kdc_unit = unit;
136 kdc_fd[unit].kdc_parent = &kdc_fdc[ctlr];
137 kdc_fd[unit].kdc_parentdata = 0;
138 dev_attach(&kdc_fd[unit]);
139}
140
141static inline void
142fdc_registerdev(struct isa_device *dvp)
143{
144 int unit = dvp->id_unit;
145
146 if(unit != 0)
147 kdc_fdc[unit] = kdc_fdc[0];
148
149 kdc_fdc[unit].kdc_unit = unit;
150 kdc_fdc[unit].kdc_parent = &kdc_isa0;
151 kdc_fdc[unit].kdc_parentdata = dvp;
152 dev_attach(&kdc_fdc[unit]);
153}
154
155static int
156fdc_goaway(struct kern_devconf *kdc, int force)
157{
158 if(force) {
159 dev_detach(kdc);
160 return 0;
161 } else {
162 return EBUSY; /* XXX fix */
163 }
164}
165
166static int
167fd_goaway(struct kern_devconf *kdc, int force)
168{
169 dev_detach(kdc);
170 return 0;
171}
172
173#define b_cylin b_resid /* XXX now spelled b_cylinder elsewhere */
174
175/* misuse a flag to identify format operation */
176#define B_FORMAT B_XXX
177
178/*
179 * this biotab field doubles as a field for the physical unit number
180 * on the controller

--- 266 unchanged lines hidden (view full) ---

447static struct cdevsw fd_cdevsw;
448static struct bdevsw fd_bdevsw =
449 { Fdopen, fdclose, fdstrategy, fdioctl, /*2*/
450 nodump, nopsize, 0, "fd", &fd_cdevsw, -1 };
451
452
453static struct isa_device *fdcdevs[NFDC];
454
94#define b_cylin b_resid /* XXX now spelled b_cylinder elsewhere */
95
96/* misuse a flag to identify format operation */
97#define B_FORMAT B_XXX
98
99/*
100 * this biotab field doubles as a field for the physical unit number
101 * on the controller

--- 266 unchanged lines hidden (view full) ---

368static struct cdevsw fd_cdevsw;
369static struct bdevsw fd_bdevsw =
370 { Fdopen, fdclose, fdstrategy, fdioctl, /*2*/
371 nodump, nopsize, 0, "fd", &fd_cdevsw, -1 };
372
373
374static struct isa_device *fdcdevs[NFDC];
375
455/*
456 * Provide hw.devconf information.
457 */
458static int
376static int
459fd_externalize(struct kern_devconf *kdc, struct sysctl_req *req)
460{
461 return disk_externalize(fd_data[kdc->kdc_unit].fdsu, req);
462}
463
464static int
465fdc_err(fdcu_t fdcu, const char *s)
466{
467 fdc_data[fdcu].fdc_errs++;
468 if(s) {
469 if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX)
470 printf("fdc%d: %s", fdcu, s);
471 else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX)
472 printf("fdc%d: too many errors, not logging any more\n",

--- 225 unchanged lines hidden (view full) ---

698 {
699 printf("fdc%d: unit used multiple times\n", fdcu);
700 return 0;
701 }
702
703 fdcdevs[fdcu] = dev;
704 fdc_data[fdcu].baseport = dev->id_iobase;
705
377fdc_err(fdcu_t fdcu, const char *s)
378{
379 fdc_data[fdcu].fdc_errs++;
380 if(s) {
381 if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX)
382 printf("fdc%d: %s", fdcu, s);
383 else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX)
384 printf("fdc%d: too many errors, not logging any more\n",

--- 225 unchanged lines hidden (view full) ---

610 {
611 printf("fdc%d: unit used multiple times\n", fdcu);
612 return 0;
613 }
614
615 fdcdevs[fdcu] = dev;
616 fdc_data[fdcu].baseport = dev->id_iobase;
617
706#ifndef DEV_LKM
707 fdc_registerdev(dev);
708#endif
709
710#ifndef PC98
711 /* First - lets reset the floppy controller */
712 outb(dev->id_iobase+FDOUT, 0);
713 DELAY(100);
714 outb(dev->id_iobase+FDOUT, FDO_FRST);
715#endif
716
717 /* see if it can handle a command */

--- 4 unchanged lines hidden (view full) ---

722#else
723 if (fd_cmd(fdcu,
724 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
725 0))
726#endif
727 {
728 return(0);
729 }
618#ifndef PC98
619 /* First - lets reset the floppy controller */
620 outb(dev->id_iobase+FDOUT, 0);
621 DELAY(100);
622 outb(dev->id_iobase+FDOUT, FDO_FRST);
623#endif
624
625 /* see if it can handle a command */

--- 4 unchanged lines hidden (view full) ---

630#else
631 if (fd_cmd(fdcu,
632 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
633 0))
634#endif
635 {
636 return(0);
637 }
730 kdc_fdc[fdcu].kdc_state = DC_IDLE;
731 return (IO_FDCSIZE);
732}
733
734/*
735 * wire controller into system, look for floppy units
736 */
737static int
738fdattach(struct isa_device *dev)

--- 119 unchanged lines hidden (view full) ---

858 if (ftattach(dev, fdup, unithasfd))
859 continue;
860 if (fdsu < DRVS_PER_CTLR)
861 fd->type = NO_TYPE;
862#endif
863 continue;
864 }
865
638 return (IO_FDCSIZE);
639}
640
641/*
642 * wire controller into system, look for floppy units
643 */
644static int
645fdattach(struct isa_device *dev)

--- 119 unchanged lines hidden (view full) ---

765 if (ftattach(dev, fdup, unithasfd))
766 continue;
767 if (fdsu < DRVS_PER_CTLR)
768 fd->type = NO_TYPE;
769#endif
770 continue;
771 }
772
866#ifdef PC98
867 kdc_fdc[fdcu].kdc_description =
868 "NEC 765 floppy disk/tape controller";
869#else
773#ifndef PC98
870 /* select it */
871 set_motor(fdcu, fdsu, TURNON);
872 DELAY(1000000); /* 1 sec */
873
874 if (ic_type == 0 &&
875 fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0)
876 {
877 printf("fdc%d: ", fdcu);
878 ic_type = (u_char)ic_type;
879 switch( ic_type ) {
880 case 0x80:
881 printf("NEC 765\n");
882 fdc->fdct = FDC_NE765;
774 /* select it */
775 set_motor(fdcu, fdsu, TURNON);
776 DELAY(1000000); /* 1 sec */
777
778 if (ic_type == 0 &&
779 fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0)
780 {
781 printf("fdc%d: ", fdcu);
782 ic_type = (u_char)ic_type;
783 switch( ic_type ) {
784 case 0x80:
785 printf("NEC 765\n");
786 fdc->fdct = FDC_NE765;
883 kdc_fdc[fdcu].kdc_description =
884 "NEC 765 floppy disk/tape controller";
885 break;
886 case 0x81:
887 printf("Intel 82077\n");
888 fdc->fdct = FDC_I82077;
787 break;
788 case 0x81:
789 printf("Intel 82077\n");
790 fdc->fdct = FDC_I82077;
889 kdc_fdc[fdcu].kdc_description =
890 "Intel 82077 floppy disk/tape controller";
891 break;
892 case 0x90:
893 printf("NEC 72065B\n");
894 fdc->fdct = FDC_NE72065;
791 break;
792 case 0x90:
793 printf("NEC 72065B\n");
794 fdc->fdct = FDC_NE72065;
895 kdc_fdc[fdcu].kdc_description =
896 "NEC 72065B floppy disk/tape controller";
897 break;
898 default:
899 printf("unknown IC type %02x\n", ic_type);
900 fdc->fdct = FDC_UNKNOWN;
901 break;
902 }
903 }
904 if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&

--- 43 unchanged lines hidden (view full) ---

948#endif
949
950 fd->track = FD_NO_TRACK;
951 fd->fdc = fdc;
952 fd->fdsu = fdsu;
953 fd->options = 0;
954 printf("fd%d: ", fdu);
955
795 break;
796 default:
797 printf("unknown IC type %02x\n", ic_type);
798 fdc->fdct = FDC_UNKNOWN;
799 break;
800 }
801 }
802 if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&

--- 43 unchanged lines hidden (view full) ---

846#endif
847
848 fd->track = FD_NO_TRACK;
849 fd->fdc = fdc;
850 fd->fdsu = fdsu;
851 fd->options = 0;
852 printf("fd%d: ", fdu);
853
956 fd_registerdev(fdcu, fdu);
957 switch (fdt) {
958#ifdef PC98
959 case FDT_12M:
960#ifdef EPSON_NRDISK
961 if (fdu == nrdu) {
962 printf("EPSON RAM DRIVE\n");
963 nrd_LED_off();
964 }
965 else printf("1M/640M FDD\n");
966#else /* !EPSON_NRDISK */
967 printf("1M/640K FDD\n");
968#endif /* EPSON_NRDISK */
969 fd->type = FD_1200;
970 fd->pc98_trans = 0;
854 switch (fdt) {
855#ifdef PC98
856 case FDT_12M:
857#ifdef EPSON_NRDISK
858 if (fdu == nrdu) {
859 printf("EPSON RAM DRIVE\n");
860 nrd_LED_off();
861 }
862 else printf("1M/640M FDD\n");
863#else /* !EPSON_NRDISK */
864 printf("1M/640K FDD\n");
865#endif /* EPSON_NRDISK */
866 fd->type = FD_1200;
867 fd->pc98_trans = 0;
971 kdc_fd[fdu].kdc_description =
972 "1M/640K floppy disk drive";
973#ifdef DEVFS
974 sprintf(name,"rfd%d.1200",fdu);
975#endif /* DEVFS */
976 break;
977 case FDT_144M:
978 printf("1.44M FDD\n");
979 fd->type = FD_1200;
980 fd->pc98_trans = 0;
981 outb(0x4be, (fdu << 5) | 0x10);
868#ifdef DEVFS
869 sprintf(name,"rfd%d.1200",fdu);
870#endif /* DEVFS */
871 break;
872 case FDT_144M:
873 printf("1.44M FDD\n");
874 fd->type = FD_1200;
875 fd->pc98_trans = 0;
876 outb(0x4be, (fdu << 5) | 0x10);
982 kdc_fd[fdu].kdc_description =
983 "1.44MB (1440K) 3.5in floppy disk drive";
984#ifdef DEVFS
985 sprintf(name,"rfd%d.1440",fdu);
986#endif /* DEVFS */
987 break;
988#else
989 case RTCFDT_12M:
990 printf("1.2MB 5.25in\n");
991 fd->type = FD_1200;
877#ifdef DEVFS
878 sprintf(name,"rfd%d.1440",fdu);
879#endif /* DEVFS */
880 break;
881#else
882 case RTCFDT_12M:
883 printf("1.2MB 5.25in\n");
884 fd->type = FD_1200;
992 kdc_fd[fdu].kdc_description =
993 "1.2MB (1200K) 5.25in floppy disk drive";
994 break;
995 case RTCFDT_144M:
996 printf("1.44MB 3.5in\n");
997 fd->type = FD_1440;
885 break;
886 case RTCFDT_144M:
887 printf("1.44MB 3.5in\n");
888 fd->type = FD_1440;
998 kdc_fd[fdu].kdc_description =
999 "1.44MB (1440K) 3.5in floppy disk drive";
1000 break;
1001 case RTCFDT_288M:
1002 case RTCFDT_288M_1:
1003 printf("2.88MB 3.5in - 1.44MB mode\n");
1004 fd->type = FD_1440;
889 break;
890 case RTCFDT_288M:
891 case RTCFDT_288M_1:
892 printf("2.88MB 3.5in - 1.44MB mode\n");
893 fd->type = FD_1440;
1005 kdc_fd[fdu].kdc_description =
1006 "2.88MB (2880K) 3.5in floppy disk drive in 1.44 mode";
1007 break;
1008 case RTCFDT_360K:
1009 printf("360KB 5.25in\n");
1010 fd->type = FD_360;
894 break;
895 case RTCFDT_360K:
896 printf("360KB 5.25in\n");
897 fd->type = FD_360;
1011 kdc_fd[fdu].kdc_description =
1012 "360KB 5.25in floppy disk drive";
1013 break;
1014 case RTCFDT_720K:
1015 printf("720KB 3.5in\n");
1016 fd->type = FD_720;
898 break;
899 case RTCFDT_720K:
900 printf("720KB 3.5in\n");
901 fd->type = FD_720;
1017 kdc_fd[fdu].kdc_description =
1018 "720KB 3.5in floppy disk drive";
1019 break;
1020#endif
1021 default:
1022 printf("unknown\n");
1023 fd->type = NO_TYPE;
902 break;
903#endif
904 default:
905 printf("unknown\n");
906 fd->type = NO_TYPE;
1024 dev_detach(&kdc_fd[fdu]);
1025 continue;
1026 }
907 continue;
908 }
1027 kdc_fd[fdu].kdc_state = DC_IDLE;
1028#ifdef DEVFS
1029 mynor = fdu << 6;
1030 fd->bdevs[0] = devfs_add_devswf(&fd_bdevsw, mynor, DV_BLK,
1031 UID_ROOT, GID_OPERATOR, 0640,
1032 "fd%d", fdu);
1033 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
1034 UID_ROOT, GID_OPERATOR, 0640,
1035 "rfd%d", fdu);

--- 98 unchanged lines hidden (view full) ---

1134 needspecify = 1;
1135 fdout |= (FDO_FRST|FDO_FDMAEN);
1136 }
1137#endif
1138
1139 outb(fdc_data[fdcu].baseport+FDOUT, fdout);
1140 DELAY(10);
1141 fdc_data[fdcu].fdout = fdout;
909#ifdef DEVFS
910 mynor = fdu << 6;
911 fd->bdevs[0] = devfs_add_devswf(&fd_bdevsw, mynor, DV_BLK,
912 UID_ROOT, GID_OPERATOR, 0640,
913 "fd%d", fdu);
914 fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
915 UID_ROOT, GID_OPERATOR, 0640,
916 "rfd%d", fdu);

--- 98 unchanged lines hidden (view full) ---

1015 needspecify = 1;
1016 fdout |= (FDO_FRST|FDO_FDMAEN);
1017 }
1018#endif
1019
1020 outb(fdc_data[fdcu].baseport+FDOUT, fdout);
1021 DELAY(10);
1022 fdc_data[fdcu].fdout = fdout;
1142#ifndef PC98
1143 kdc_fdc[fdcu].kdc_state = (fdout & FDO_FRST)? DC_BUSY: DC_IDLE;
1144#endif
1145 TRACE1("[0x%x->FDOUT]", fdout);
1146
1147 if(needspecify) {
1148 /*
1149 * XXX
1150 * special case: since we have just woken up the FDC
1151 * from its sleep, we silently assume the command will
1152 * be accepted, and do not test for a timeout

--- 257 unchanged lines hidden (view full) ---

1410 return(ENXIO);
1411 break;
1412 }
1413 }
1414 }
1415#endif
1416 fd_data[fdu].ft = fd_types + type - 1;
1417 fd_data[fdu].flags |= FD_OPEN;
1023 TRACE1("[0x%x->FDOUT]", fdout);
1024
1025 if(needspecify) {
1026 /*
1027 * XXX
1028 * special case: since we have just woken up the FDC
1029 * from its sleep, we silently assume the command will
1030 * be accepted, and do not test for a timeout

--- 257 unchanged lines hidden (view full) ---

1288 return(ENXIO);
1289 break;
1290 }
1291 }
1292 }
1293#endif
1294 fd_data[fdu].ft = fd_types + type - 1;
1295 fd_data[fdu].flags |= FD_OPEN;
1418 kdc_fd[fdu].kdc_state = DC_BUSY;
1419
1420 return 0;
1421}
1422
1423int
1424fdclose(dev_t dev, int flags, int mode, struct proc *p)
1425{
1426 fdu_t fdu = FDUNIT(minor(dev));
1427
1428#if NFT > 0
1429 int type = FDTYPE(minor(dev));
1430
1431 if (type & F_TAPE_TYPE)
1432 return ftclose(dev, flags);
1433#endif
1434 fd_data[fdu].flags &= ~FD_OPEN;
1435 fd_data[fdu].options &= ~FDOPT_NORETRY;
1296
1297 return 0;
1298}
1299
1300int
1301fdclose(dev_t dev, int flags, int mode, struct proc *p)
1302{
1303 fdu_t fdu = FDUNIT(minor(dev));
1304
1305#if NFT > 0
1306 int type = FDTYPE(minor(dev));
1307
1308 if (type & F_TAPE_TYPE)
1309 return ftclose(dev, flags);
1310#endif
1311 fd_data[fdu].flags &= ~FD_OPEN;
1312 fd_data[fdu].options &= ~FDOPT_NORETRY;
1436 kdc_fd[fdu].kdc_state = DC_IDLE;
1437
1438 return(0);
1439}
1440
1441
1442/****************************************************************************/
1443/* fdstrategy */
1444/****************************************************************************/

--- 984 unchanged lines hidden ---
1313
1314 return(0);
1315}
1316
1317
1318/****************************************************************************/
1319/* fdstrategy */
1320/****************************************************************************/

--- 984 unchanged lines hidden ---