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 --- |